Skip to content

Sort signatures that include Luhmann-style sequences

[ The denote-sequence package (by Protesilaos) covers this use-case and many others (Write sequence notes or folgezettel). It is the superior option for anyone interested in this functionality. We keep the code below for reference, as there may be users of it who need to revisit it. Though long-term, it is better to use denote-sequence. ]

Niklas Luhmann would edit notes to form sequences of thoughts with branching paths, such as ‘1.1’, ‘1.1a’, ‘1.2’, ‘1.2a’, ‘1.2b’, etc. With the Denote file-naming scheme, we make the word separator in each file name component use the same character as the entire field, so words in a title have a dash between them and signatures have the equals sign (The file-naming scheme). Thus, our Luhmann-style signature will be slightly different in their looks: 1=1, 1=1a, 1=2, 1=2a, 1=2b.

When using the denote-sort-dired command with default settings, our signatures will not sort in an intuitive way. This is because they combine numbers and letters, which require a different approach than what the default sorting function is using (Define a sorting function per component). In the following code block, we show a sorting algorithm that should do the right thing while dealing with Luhmann-style signatures.

emacs-lisp
(defun my-denote--split-luhman-sig (signature)
  "Split numbers and letters in Luhmann-style SIGNATURE string."
  (replace-regexp-in-string
   "\\([a-zA-Z]+?\\)\\([0-9]\\)" "\\1=\\2"
   (replace-regexp-in-string
    "\\([0-9]+?\\)\\([a-zA-Z]\\)" "\\1=\\2"
    signature)))

(defun my-denote--pad-sig (signature)
  "Create a new signature with padded spaces for all components"
  (combine-and-quote-strings
   (mapcar
    (lambda (x)
      (string-pad x 5 32 t))
    (split-string (my-denote--split-luhman-sig signature) "=" t))
   "="))

(defun my-denote-sort-for-signatures (sig1 sig2)
  "Return non-nil if SIG1 is smaller that SIG2.
Perform the comparison with `string<'."
  (string< (my-denote--pad-sig sig1) (my-denote--pad-sig sig2)))

;; Change the sorting function only when we sort by signature.
(setq denote-sort-signature-comparison-function #'my-denote-sort-for-signatures)