Posts Tagged ‘association list’

Customizing Emacs Muse – Part 2

Here are part 1 (Creating Squidoo Lenses With Emacs Muse) and part 3 (Emacs Muse Aliases).

We all know what an association list is right? If you want to map keys to values, you’re going to use an assocation list.

(defvar v '((GB "Great Britain")
            (UK "United Kingdom")
            (FR "France")))

(assoc 'GB v)

will return the pair (GB "Great Britain").

They are used in a similar way to a hash in various scripting languages. For example, muse-html uses one, muse-html-markup-strings to determine which text to use for each type of markup.

You might remember that previously I advocated the use of regex transforms to correct the html after generation is complete. However, that can cause problems. We therefore need to fix the association list to have the correct mapping.

Assocation lists have a bunch of functions which operate on them, e.g. assoc and rassoc for looking things up and assq-delete-all for removing elements. However, I couldn’t find one which changes elements.

(defun assoc-replace (seq values)
  "Replace an element within an association list where the cars match."
  (mapcar (lambda (elem)
            (let* ((key (car elem))
                   (val (assoc key values)))
              (if val (cadr val) elem))) seq))

This will allow me to replace both key and value within the association list at the same time. Normally, I’ll just need to replace the value so I made a helper which saves me from having to repeat the key.

(defsubst kv (k v)
  `(,k (,k . ,v)))

And now I can fix the assocation list

(defconst sq-code (concat "<b style=\"font-weight: normal; "
                          "font-size: 115%; background: #eee "
                          "padding: 3px;\">"))

(setq muse-html-markup-strings
      (assoc-replace muse-html-markup-strings
                     (list (kv 'begin-literal sq-code)
                           (kv 'end-literal "</b>"))))

Alternatively, I could delete the existing elements and add the new ones on the start of the list, maybe with something like the following

 (cons 'begin-literal sq-code)
 (cons '(end-literal "</b>")
       (assq-delete-all 'begin-literal
                        (assq-delete-all 'end-literal

But I think my way is neater.


Read Full Post »