(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
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
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,
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.
Open filename and parse its contents as “mime-types” format. This line-oriented file format is briefly described as follows:
mime-type extension extension…, that is, at least one extension must be present. Each extension results in an entry in the hash table.
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.
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
Return the mime-type(s) associated with ext (a symbol or
#f if none are found. Note that generally the
value may be a single mime-type or a list of them.
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.
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) (put-mime-types! '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…