Skip to Content

Improving My Personal Dictionary

I maintain a personal dictionary within my Emacs configuration. I initially started it for my fantasy writing project, because I wanted an easy way to quickly define and reference an in-universe thing, such as a town or item. I set it up without knowing an Elisp, but now that I know just a little Elisp, I’d like to re-examine my approach.

Here’s an excerpt from my Emacs configuration, showing how the dictionary currently

(setq org-export-global-macros
'(("ref" . "{{{define($1)}}} {{{source($1)}}}")
("define" . "{{{$1-definition}}}")
("source" . "{{{$1-source}}}")
("source-link" . "See [[$1][$1]]")
("domain-name-definition" . "A string (group of letters) defining the name of an area of the Internet.")
("domain-name-source" . "{{{source-link(https://en.wikipedia.org/wiki/Domain_name)}}}.")))

This lets me write {{{ref(domain-name)}}} and get “A string (group of letters) defining the name of an area of the Internet. See https://en.wikipedia.org/wiki/Domain_name.”

Here’s a breakdown of how that works:

  1. Text inside {{{ }}} is interpetted by Org-mode as a macro, and replaced when the document is exported. (I think macros are evaluated first in the export process, but I don’t know how exporting works yet.) So, {{{ref}}} calls the ref macro defined above, and expanded into {{{define()}}} {{{src()}}}
    • $1 is replaced by the first argument given to the macro. $2 would be replaced by the second. So {{{ref(domain-name)}}} expands to {{{define(domain-name)}}} {{{source(domain-name)}}}.
  2. Any macros referenced in that macro are evaluated, and so on. So, {{{define(domain-name)}}} {{{source(domain-name)}}} would expand to {{{domain-name-definition}}} {{{domain-name-source}}}.
  3. Then that would become A string (group of letters) defining the name of an area of the Internet. See {{{source-link(domain-name)}}}.
  4. That would, finally, become A string (group of letters) defining the name of an area of the Internet. See [[https://en.wikipedia.org/wiki/Domain_name][https://en.wikipedia.org/wiki/Domain_name]].

There are quite a few handicaps in this approach though. The biggest and most immediate is that if I don’t have both macros set per term, I can’t use the ref macro - it fails because it tries to call, eventually, fake-term-source, which doesn’t exist.

It also pretty well forces down a structure of how referecences must be constructed, and some other issues I’m having a tough time vocalizing here.

I’m going to start by instead, writing a little draft of what I’d like a personal dictionary entry to look like, as written as an Elisp declaration.

(setq ems-dict
      '(("banana"
	 ("definition" . "an elongated berry, technically")
	 ("sources"
	  ("Wikipedia" . "https://en.wikipedia.org/wiki/Banana")
	  ("Wiktionary" . "https://en.wiktionary.org/wiki/banana")))))
Code Snippet 1: This sets the variable ems-dict to a list of lists, the first and only item of which is a list of information about the "banana" term.

And here’s a small function to pull out the definition:

(defun ems-get-def
    (term)
  "Return the definition of TERM from ems-dict."
  (cdr (assoc "definition" (cdr (assoc term ems-dict)))))
Code Snippet 2: get-def-1

So if I run that function, I should get the definition of the word banana.

(ems-get-def "banana")
Code Snippet 3: lookup-banana-1

Appears to be working; but let’s make a little function for capitalizing the first line of a string.

(defun ems-cap-first-char
    (&optional string)
  "Return STRING with the first character capitalized."
  (when (and string (> (length string) 0))
    (let ((first-char (substring string nil 1))
	  (rest-str (substring string 1)))
      (concat (capitalize first-char) rest-str))))
Code Snippet 4: cap-first-char-1

Here’s that in-use

(ems-cap-first-char (ems-get-def "banana"))
Code Snippet 5: test-cap-def-1

This doesn’t really help me in using it as a tool for referencing these terms in my writing though. For that, I’ll need to set up some macros.

(add-to-list 'org-export-global-macros
	     '("def" . "(eval (ems-get-def $1))"))

So then if I write {{{def(banana)}}} in a sentence, I shoudl be able to get the definition. To test, below I’ll write

(I’ve exported this source file to HTML and it says “A banana is an eloganted berry, technically.” Exactly what it should say.)

Editorial and License Information

My name is emsenn and I wrote this essay for the benefit of the commons. To the extent possible under law, I have waived all copyright and related or neighboring rights to it. If you're viewing it on a remote server, you're encouraged to download your own copy. Essays like this are made possible with financial support from readers like you. Thank you. To read more of my work and to learn more about me, visit https://emsenn.net