Next: , Previous: , Up: Top   [Contents][Index]

16 (www data mime-types)

The (www data mime-types) module maintains an internal hash table mapping filename extensions to one or more mime-types.

The exported procedures provide convenience abstractions over the underlying hash-table manipulation operations, including extension and mime-type validation, init from a file in a “standard” format (i.e., that of /etc/mime.types or ~/.mime.types), and support for straightforward incremental init (aka merging). There are two predefined entries in the hash table:

text => text/plain
html => text/html

To support merging, the put-FOO procedures both take a symbol resolve as the first arg, which specifies how conflicts should be handled. This happens when the hash table already contains an entry for extension and new-mime-type differs from old-mime-type.


Throw an error with key mime-type-conflict, displaying a message describing the extension, old-mime-type and new-mime-type.


Make the mime-type of extension a list (unless already one), with new-mime-type at the beginning.


Make the mime-type of extension a list (unless already one), with new-mime-type at the end.


Use new-mime-type directly, discarding old-mime-type.


Discard new-mime-type, keeping old-mime-type.

For any other method, the operation throws an error, with key invalid-resolve.

Validation happens on all “put” operations. The extension must be a symbol, such as txt. The mime-type must be a symbol with exactly one ‘/’ (slash) in its name, such as text/plain, or a proper list of such symbols. The mime-type may also be #f, which means to remove extension from the hash table.

If an entry does not validate, the operation throws an error, with key invalid-extension or invalid-mime-type.

Procedure: reset-mime-types! size

Clear all entries from the mime-types hash table, and prepare it for size (approximately) entries. This procedure must be called before any others in this module.

Procedure: put-mime-types-from-file! resolve filename

Open filename and parse its contents as “mime-types” format. This line-oriented file format is briefly described as follows:

Put those those entries that specify an extension into the hash table, validating both extension and mime-type first. resolve specifies how to resolve extension conflicts.

Procedure: put-mime-types! resolve [extension1 mime-type1 ...]

Put extension1/mime-type1… into the hash table, validating both extension and mime-type first. resolve specifies how to resolve extension conflicts.

If an extension is given but there is no mime-type (i.e., the list has an odd length), throw an error with key missing-mime-type.

Procedure: mime-types<-extension ext

Return the mime-type(s) associated with ext (a symbol or string), or #f if none are found. Note that generally the value may be a single mime-type or a list of them.

Procedure: select-extensions sel

Return a list of extensions in the hash table that match the sel criteria (a symbol). If sel is #t, return all the extensions; if single, only those who have a single mime-type associated; if multiple, only those who have more than one mime-type associated.

why select-extensions?

The last procedure is intended to ease non-generalizable merging, without providing too much exposure to implementation internals. Suppose you want to maintain a local policy of having only one mime-type associated per extension (to keep things simple). In that case, after populating the hash, you can fix up those entries, like so:

(reset-mime-types! 491)
(put-mime-types-from-file! 'prefix "/etc/mime.types")
(define AMBIGUOUS (select-extensions 'multiple))

(use-modules (ice-9 format))
(define (display-ext ext)
  (format #t "~7,@A  ~A~%" ext (mime-types<-extension ext)))

(for-each display-ext AMBIGUOUS)
    ent  (chemical/x-ncbi-asn1-ascii chemical/x-pdb)
    sdf  (application/vnd.stardivision.math chemical/x-mdl-sdfile)
     sh  (application/x-sh text/x-sh)
    csh  (application/x-csh text/x-csh)
    cpt  (application/mac-compactpro image/x-corelphotopaint)
    asn  (chemical/x-ncbi-asn1 chemical/x-ncbi-asn1-spec)
    wrl  (model/vrml x-world/x-vrml)
    tcl  (application/x-tcl text/x-tcl)
     ra  (audio/x-pn-realaudio audio/x-realaudio)
    spl  (application/futuresplash application/x-futuresplash)
    m3u  (audio/mpegurl audio/x-mpegurl)

;; Local policy: For foo.wrl, we want the last variant,
;; but everything else we'll settle for the first.
(define ((keep! yes) ext)
   'stomp ext
   (yes (mime-types<-extension ext))))

((keep! reverse) 'wrl)
(for-each (keep! car) AMBIGUOUS)

(for-each display-ext AMBIGUOUS)
    asn  chemical/x-ncbi-asn1
    wrl  x-world/x-vrml
    tcl  application/x-tcl
     ra  audio/x-pn-realaudio
    spl  application/futuresplash
    m3u  audio/mpegurl
    ent  chemical/x-ncbi-asn1-ascii
    sdf  application/vnd.stardivision.math
     sh  application/x-sh
    csh  application/x-csh
    cpt  application/mac-compactpro

Seasoned schemers will note that the same result could have been achieved if resolve were allowed to be a general resolution procedure instead of simply a method specifier. Perhaps that feature will be added in the future, and select-extensions replaced by map-mime-types. We’ll see…

Next: , Previous: , Up: Top   [Contents][Index]