Custom has: filter - emacs-citar/citar GitHub Wiki

As well as Org mode notes, I keep paper notes of texts I read (well, I draw maps of them), but I lose track track of where they all are after a decade of making them. So as well as helping me cite things in texts, I would like Citar to help me use my biblatex as a database for my maps. Specifically, I want to be able to list all items with a map, using has:maps, and to display their physical location.

image

This turned out to be very easy. I thought I would share what I did in case anyone else out there might be wanting something similar.

In my BiBLaTeX file I've added my own field notelocation where I store the location of maps. For example

@Book{innis-1986-empir-civil,
  author       = {Innis, Harold A.},
  title        = {Empire \& Communications},
  year         = 1986,
  publisher    = {Press Porcépic},
  notelocation = {map:germany/book2017}, % I prefix with `map:` so I can easily cycle through my locations via hippie-expand
  location     = {Victoria \& Toronto}}

Now I need to process this into citar. The work for this has already been done by Citar's developers. I just need to copy and customize two symbols related to importing links in citar.el.

;; Storing notelocation in a list is overkill as I will only use one field name (notelocation),
;; but it was easy to copy over from `citar-link-fields`.
(defcustom citar-map-fields '((notelocation . "%s"))
  "Bibliography fields to parse into map.

Association list whose keys are symbols naming bibliography
fields and values are URL strings. In each URL, \"%s\" is
replaced by the contents of the corresponding field."
  :group 'citar
  :type '(alist :key-type symbol :value-type string))

;; Modified from `citar-has-links`
(defun citar-has-maps ()
  "Return predicate testing whether entry has map.

Return a function that takes CITEKEY and returns non-nil when the
corresponding bibliography entry has associated map. Map's
existence is sought by presence of notelocation field. See the
documentation of `citar-has-files' and `citar-has-notes', which
have similar usage."
  (let ((notelocationfields (mapcar (lambda (field) (symbol-name (car field))) citar-map-fields)))
    (citar--has-resources
     (apply-partially #'citar-get-field-with-value notelocationfields))))

Now for the icons:

;; I want icons for files, links, org notes and then my maps.
(setq citar-indicators
  (list citar-indicator-files-icons
	citar-indicator-links-icons
        citar-indicator-notes-icons
	citar-indicator-maps-icons))

;; The following isn't strictly necessary, as I want to use an 
;; icon indicator (`citar-indicator-maps-icons`) instead of a text one,  
;; but for completion's sake I'll add it. 
(defvar citar-indicator-map
   (citar-indicator-create
    :symbol "M"
    :function #'citar-has-maps
    :tag "has:maps"))

;; This is where the map icon is defined
(defvar citar-indicator-maps-icons
  (citar-indicator-create
   :symbol (all-the-icons-faicon
            "share-alt"
            :face 'all-the-icons-pink
	    :height 0.6
	    :v-adjust 0.2)
   :function #'citar-has-maps
   :padding " "
   :tag "has:maps"))

;;; And here are how I've defined my other icon indicators, sticking to Font Awesome icons (`all-the-icons-faicon`) for consistency.

;; PDF/general file icon
(defvar citar-indicator-files-icons
  (citar-indicator-create
   :symbol (all-the-icons-faicon
            "file-pdf-o"
            :face 'all-the-icons-red
	    :height 0.6
	    :v-adjust 0.2)
   :function #'citar-has-files
   :padding " "
   :tag "has:file"))

;; Link icon
(defvar citar-indicator-links-icons
  (citar-indicator-create
   :symbol (all-the-icons-faicon
            "link"
            :face 'all-the-icons-yellow
	    :height 0.6
	    :v-adjust 0.2)
   :function #'citar-has-links
   :padding " "
   :tag "has:links"))

;; Org note icon
(defvar citar-indicator-notes-icons
  (citar-indicator-create
   :symbol (all-the-icons-faicon
            "file-text"
            :face 'all-the-icons-blue
	    :height 0.6
	    :v-adjust 0.2)
   :function #'citar-has-notes
   :padding " "
   :tag "has:notes"))

And finally, just add the notelocation field to my citar-templates

;; Aside from `notelocation`, I also add a field for the original date of publication, `origdate`.
(setq citar-templates
  '((main . "${author editor:30%sn} ${origdate:4} ${date year issued:4} ${title:48} ${subtitle:48} ${notelocation:22}")
    (suffix . " ${=key= id:15}  ${=type=:8}  ${tags keywords:10}")
    (preview . "${author editor:%etal} (${year issued date}) ${title}, ${journal journaltitle publisher container-title collection-title}.\n")
    (note . "Notes on ${author editor:%etal}, ${title}")))

Now I can run citar and filter by has:maps.

And there we go, now I know that my map exists and where to find it:

image

Not bad for about 20 lines of boilerplate code!