(machine translated from README-ja.org)
el-xmp enhances Emacs with the ability to handle file metadata based on the XMP (Extensible Metadata Platform) specification. It introduces fundamental functions at the Emacs Lisp level, along with several general-purpose commands built on top of them. Additionally, it extends dired and image-dired with features for retrieving, setting, displaying, sorting, and filtering file properties. For example, you can use it to set or retrieve photo ratings and subject information, or extract author details from PDF files.
XMP / JPEG / PDF / TIFF (including ARW, CR2, NEF) / MP3(ID3) / ISO base media file format (MPEG4, JPEG2000, etc) / ORG / any other format that can scan files and find XMPPackets
Note: For some formats, the native metadata of the file format can be converted to XMP for processing.
See the variable xmp-file-name-handler-alist for more information.
To use application commands and extensions to dired and image-dired, use xmp-setup.el.
Operation has been confirmed on Emacs 29 and later.
xmp-commands.el provides a set of commands for manipulating the XMP properties of any file.
The target file of those commands is inferred from the current point, buffer, etc. by xmp-file-name-at-point function. By default, filename inference from Dired, Image Dired, org-mode links, thing-at-point, buffer-file-name, and read-file-name is supported.
When these commands change properties, they do not change the target file directly, but instead create a sidecar file (.xmp file) to record the new property value. This method protects the contents of the target file and allows properties to be shared through network storage, etc. Depending on the settings, properties can also be stored in a SQLite database. This method makes it difficult to share properties, but has the advantage of not having sidecar files scattered all over the place. Depending on the settings, you can choose which to use based on conditions such as directory or extension.
Commands to change properties:
xmp-rate-filexmp-rate-file-1xmp-rate-file-2xmp-rate-file-3xmp-rate-file-4xmp-rate-file-5xmp-rate-file-0xmp-rate-file--1xmp-set-file-labelxmp-set-file-subjectsxmp-add-file-subjectsxmp-remove-file-subjectsxmp-set-file-titlexmp-set-file-descriptionxmp-set-file-creatorsxmp-edit-file-propertiesxmp-edit-file-properties-all
Commands to display properties:
xmp-show-file-propertiesxmp-show-file-properties-allxmp-show-file-ratingxmp-show-file-labelxmp-show-file-subjectsxmp-show-file-titlexmp-show-file-descriptionxmp-show-file-creators
Commands for managing databases:
- List managed data
xmp-list-managed-files-in-dirxmp-list-stray-file-metadata-in-db
- Switch sidecar files and DB
xmp-move-file-properties-from-db-to-sidecarxmp-move-file-properties-from-sidecar-to-dbxmp-move-dir-file-properties-from-db-to-sidecarxmp-move-dir-file-properties-from-sidecar-to-db
- Move stray metadata
xmp-relocate-stray-file-metadata-in-dir
- Clear cache
xmp-clear-file-cachexmp-clear-file-cache-in-dirxmp-clear-file-cache-under-dirxmp-clear-invalid-file-cachexmp-clear-invalid-file-cache-in-dirxmp-clear-invalid-file-cache-under-dir
- Move and delete metadata stored in sidecar files or databases (metadata stored externally to the target file)
xmp-remove-external-file-metadataxmp-remove-external-file-metadata-in-dirxmp-move-external-file-metadataxmp-move-external-file-metadata-in-dir
xmp-dired.el adds XMP-related features to Dired.
Currently, it provides the following commands:
- Mark files
xmp-dired-mark-ratingxmp-dired-mark-labelxmp-dired-mark-subjectsxmp-dired-mark-titlexmp-dired-mark-descriptionxmp-dired-mark-creatorxmp-dired-mark-stray-sidecar-files
- Change properties of marked files
xmp-dired-do-ratexmp-dired-do-set-labelxmp-dired-do-set-subjectsxmp-dired-do-add-subjectsxmp-dired-do-remove-subjectsxmp-dired-do-set-titlexmp-dired-do-set-descriptionxmp-dired-do-set-creatorsxmp-dired-do-edit-propertiesxmp-dired-do-edit-properties-all
- Filter by properties
xmp-dired-filter-propertyxmp-dired-filter-clearxmp-dired-filter-ratingxmp-dired-filter-labelxmp-dired-filter-subjectsxmp-dired-filter-titlexmp-dired-filter-descriptionxmp-dired-filter-creatorsxmp-dired-filter-toggle-sidecarxmp-dired-filter-hide-sidecarxmp-dired-filter-show-sidecar
- Sort by properties
xmp-dired-sort-by-propertyxmp-dired-sort-clearxmp-dired-sort-by-ratingxmp-dired-sort-by-labelxmp-dired-sort-by-subjectsxmp-dired-sort-by-titlexmp-dired-sort-by-descriptionxmp-dired-sort-by-creators
- Add columns to display properties
xmp-dired-add-columnxmp-dired-remove-columnxmp-dired-remove-all-columnsxmp-dired-toggle-columnxmp-dired-toggle-column-ratingxmp-dired-toggle-column-labelxmp-dired-toggle-column-subjectsxmp-dired-toggle-column-titlexmp-dired-toggle-column-descriptionxmp-dired-toggle-column-creators
In addition, the commands in xmp-commands.el can be used with Dired.
(Figure: Filtering files by Rating in Dired and adding Rating and Subject as columns)
xmp-image-dired.el adds XMP-related features to image-dired.
Currently, it provides the following commands:
- Filter thumbnails (temporarily hide thumbnails depending on conditions)
xmp-image-dired-filter-propertyxmp-image-dired-filter-clearxmp-image-dired-filter-ratingxmp-image-dired-filter-labelxmp-image-dired-filter-subjectsxmp-image-dired-filter-titlexmp-image-dired-filter-descriptionxmp-image-dired-filter-creators
- Sort thumbnails
xmp-image-dired-sort-by-propertyxmp-image-dired-sort-by-file-namexmp-image-dired-sort-by-ratingxmp-image-dired-sort-by-labelxmp-image-dired-sort-by-subjectsxmp-image-dired-sort-by-titlexmp-image-dired-sort-by-descriptionxmp-image-dired-sort-by-creators
In addition, the commands in xmp-commands.el can be used with image-dired.
(Figure: Photos are marked based on their ratings in Dired and displayed in image-dired)
xmp-editor.el provides an XMP editor UI using The Emacs Widget Library. Commands such as xmp-edit-file-properties and xmp-dired-do-edit-properties use this library.
For example, you can open an editor to edit XMP properties with the following code:
;; Open a buffer to edit the properties of jpg files in the current directory all at once.
(xmp-editor-open-files (directory-files "." t "\\.jpg$"))
;; Open a buffer to edit files marked in the Dired buffer all at once.
;; The only XMP property to edit is dc:title.
(xmp-editor-open-files (dired-get-marked-files) (list xmp-dc:title))(Figure: Editing photo metadata)
xmp-setup.el provides an example of el-xmp configuration. You can use it by adding the following code to init.el.
(with-eval-after-load "dired"
(require 'xmp-setup)
(xmp-setup-default))Assign keys to operate XMP properties to dired and image-dired.
| Keys | Function |
|---|---|
| ’ S r | Set rating |
| ’ S l | Set label |
| ’ S s | Set subjects |
| ’ A s | Add subjects |
| ’ R s | Remove subjects |
| ’ S t | Set title |
| ’ S d | Set description |
| ’ S c | Set creators |
| ’ E p | Edit properties |
| ’ E a | Edit all properties |
| ’ g p | Get properties |
| ’ g a | Get all properties |
| ’ g r | Get rating |
| ’ g l | Get label |
| ’ g s | Get subjects |
| ’ g t | Get title |
| ’ g d | Get description |
| ’ g c | Get creators |
| ’ m r | Mark by rating |
| ’ m l | Mark by label |
| ’ m s | Mark by subjects |
| ’ m t | Mark by title |
| ’ m d | Mark by description |
| ’ m c | Mark by creators |
| ’ m S | Mark stray sidecar files |
| ’ f p | Filter by property |
| ’ f - | Clear filter |
| ’ f r | Filter by rating |
| ’ f l | Filter by label |
| ’ f s | Filter by subjects |
| ’ f t | Filter by title |
| ’ f d | Filter by description |
| ’ f c | Filter by creators |
| ’ s p | Sort by property |
| ’ s - | Clear sort |
| ’ s r | Sort by rating |
| ’ s l | Sort by label |
| ’ s s | Sort by subjects |
| ’ s t | Sort by title |
| ’ s d | Sort by description |
| ’ s c | Sort by creators |
| ’ c p | Toggle property column |
| ’ c - | Remove all columns |
| ’ c r | Toggle rating column |
| ’ c l | Toggle label column |
| ’ c s | Toggle subjects column |
| ’ c t | Toggle title column |
| ’ c d | Toggle description column |
| ’ c c | Toggle creators column |
| ’ l m | List managed file status |
| ’ l S | List stray metadata |
| ’ R S | Relocate stray metadata |
You can also avoid using this and build your own user interface using Hydra, Transient, etc.
xmp.el provides basic functions for manipulating XMP.
The following code is an example of getting properties from a file.
(require 'xmp)
(xmp-get-file-properties "test/xmp-test-value-types.xmp" 'all)
(xmp-get-file-properties "test/xmp-test-uzumaki.jpg" 'all)
(xmp-get-file-properties "XMPSpecificationPart1.pdf" 'all)
(xmp-get-file-properties "test/xmp-test-uzumaki.jpg"
(list (xmp-xml-ename xmp-xmp: "Rating")
(xmp-xml-ename xmp-dc: "title")))
(xmp-pvalue-as-text
(xmp-get-file-property "test/xmp-test-uzumaki.jpg"
(xmp-xml-ename xmp-xmp: "Rating")))The following code is an example of setting properties to a file.
(xmp-set-file-properties "tmp-example.xmp"
(list
(cons xmp-xmp:Rating "5")
(cons xmp-dc:title
(xmp-pvalue-make-alt
(list
(xmp-pvalue-make-text
"Test Title"
(list (xmp-pvalue-make-named xmp-xml:lang 'text "x-default")))
(xmp-pvalue-make-text
"Test Title"
(list (xmp-pvalue-make-named xmp-xml:lang 'text "en")))
(xmp-pvalue-make-text
"テストタイトル"
(list (xmp-pvalue-make-named xmp-xml:lang 'text "ja"))))))))
(xmp-set-file-property "tmp-example.xmp" xmp-xmp:Rating "3")There are also lower level functions for the DOM after parsing the XML, and functions for manipulating the XMP property values (Parsed Values) after parsing the DOM.
(let* ((dom (xmp-file-read-rdf "test/xmp-test-uzumaki.jpg")) ;; File to XML DOM
(property-elements (xmp-get-property-elements dom 'all)) ;; XML DOM to Property Element List
(property-pvalues (mapcar #'xmp-parse-property-element property-elements)) ;; Property Element List to Parsed Value List
(rating-pvalue (xmp-xml-ename-alist-get xmp-xmp:Rating property-pvalues))) ;; Pick xmp:Rating property
;; PValue to String
(xmp-pvalue-as-text rating-pvalue))xmp-xml.el is the library that xmp.el uses to process XML. Since xmp.el needs to process XML namespaces correctly, it does not use Emacs’ libxml support. xml.el also had bugs so it was not used. We used nxml-parse.el which had the fewest problems. We did not use dom.el either as it cannot handle expanded names.
The most important thing about xmp-xml.el is how it handles XML expanded names. Element names and attribute names are represented not as strings or symbols but as expanded names, which are pairs of namespace names and local names.
The following code creates an object that represents the expanded name whose namespace name is http://ns.adobe.com/xap/1.0/ and whose local name is Label.
(xmp-xml-ename (xmp-xml-ns-name "http://ns.adobe.com/xap/1.0/") "Label")Be sure to use the following functions to create expanded names, get elements, and compare them.
xmp-xml-enamexmp-xml-ename-nsxmp-xml-ename-localxmp-xml-ename-equalxmp-xml-ename<xmp-xml-ename-alist-getxmp-xml-ename-assocxmp-xml-ename-member
Also, use the following functions to convert namespace names.
xmp-xml-ns-namexmp-xml-ns-name-string
Commonly used namespace names and expanded names are defined as variables.
Namespace name:
xmp-xmlns:xmp-xml:
Expanded name:
xmp-xml:langxmp-xml:spacexmp-xml:basexmp-xml:id
Many namespaces and expanded names used in XMP are defined as variables in xmp.el (e.g. xmp-dc:title, xmp-xmp:Rating).
A library that parses EXIF and converts it to XMP.
A library for parsing TIFF and reading tag information.
A library for parsing PDFs and reading metadata.
The Emacs Lisp implementation cannot read many PDF files, so please install pdfinfo and set the variable xmp-file-pdfinfo-program if possible.
A library for reading metadata from file formats that store video and audio.
A library for reading binary files.
A library for adding SQLite-based functionality to xmp.el.
Implement a persistent cache mechanism that will not be lost even if Emacs is terminated. By default it creates the database file in ~/.emacs.d/el-xmp/el-xmp-file-cache.db .
Also, property change data can be stored in the database instead of in the sidecar file. The database is different from the cache, and is created in ~/.emacs.d/el-xmp/el-xmp-file-mod.db by default.
If a user wants to add a new property, first register the namespace information (namespace name (URI) and prefix) in the variable xmp-user-defined-namespaces (if the variable xmp-predefined-namespaces already contains it, this is not necessary. Set the prefix so that it does not overlap with other prefixes). This ensures that the namespace is output and displayed correctly. If this is not set correctly, the namespace prefixes may be output in sequential numbers such as ns1, ns2, ....
Next, register the property information (name and type) in the variable xmp-user-defined-properties. Some commands use this information to change the UI to an appropriate one (even if not set, the UI may be created by inferring it from the value).
The list of properties that the command xmp-show-file-properties displays by default can be set in the variable xmp-show-file-properties-target.
The list of properties that the commands xmp-edit-file-properties and xmp-dired-do-edit-properties edit by default can be set in the variable xmp-editor-target-properties
If a property is read frequently, it is recommended to register it as a cache target. The cache target can be set by the variable xmp-file-cache-target-properties. Cached properties are stored in the in-memory cache and the SQLite database cache when their values are read or written, making subsequent reads faster.


