Elisp Text Processing vs Structured

By Xah Lee. Date: .

Major rewrite of a command, using completely different approaches. Left: text processing. Right: turn the text into nested list. In this case, the nested list is shorter, more readible, and actually more features.

Here's the comparison code. i think the text processing version is faster and uses less memory. but the split string version is clearer, shorter.

(defun my-lines-to-list1 ()
  "Make the current lines or text blocks into a HTML list.
If there is no selection, make each line into a list item.
If there is selection, each text block becomes a list item. (text block is separated by blank lines.)
If `universal-argument' is called first, use ordered list ol instead of ul.
2021-09-04"
  (interactive)
  (let* (($bds (xah-get-bounds-of-thing-or-region 'block))
         ($p1 (car $bds))
         ($p2 (cdr $bds)))
    (save-restriction
      (narrow-to-region $p1 $p2)
      (progn
        (goto-char (point-min))
        (insert "<li>")
        (if mark-active
            (while (re-search-forward " *\n\n+ *" nil 1)
              (replace-match "</li>\n\n<li>" t t))
          (while (re-search-forward " *\n *" nil 1)
            (replace-match "</li>\n<li>" t t)))
        (insert "</li>\n"))
      (if current-prefix-arg
          (progn
            (goto-char (point-min)) (insert "<ol>\n")
            (goto-char (point-max)) (insert "</ol>"))
        (progn
          (goto-char (point-min)) (insert "<ul>\n")
          (goto-char (point-max)) (insert "</ul>")))
      (goto-char (point-min))
      (while (search-forward "<li></li>" nil 1)
        (replace-match "" t t))
      (goto-char (point-min))
      (while (search-forward "<li>\n" nil 1)
        (replace-match "<li>" t t))
      (goto-char (point-min))
      (while (re-search-forward "\n\n+" nil 1)
        (replace-match "\n\n" t t))
      (insert "\n\n"))))
(defun my-lines-to-list2 ()
  "Make the current block or selection into a HTML list.
If there is no selection, make each line into a list item.
If there is selection, each text block becomes a list item. (text block is separated by blank lines.)
If `universal-argument' is called first, use ordered list ol instead of ul.
2021-09-04"
  (interactive)
  (let* (($sep (if mark-active "\n\n+" "\n"))
         ($bds (xah-get-bounds-of-thing-or-region 'block))
         ($p1 (car $bds))
         ($p2 (cdr $bds))
         ($input (buffer-substring-no-properties $p1 $p2))
         ($items (split-string $input $sep t " +"))
         ($sList (mapcar (lambda (x) (format "<li>%s</li>" x)) $items))
         ($listStr (mapconcat 'identity $sList "\n")))
    (save-restriction
      (narrow-to-region $p1 $p2)
      (delete-region (point-min) (point-max))
      (insert (if current-prefix-arg
                  (concat "<ol>\n" $listStr "\n</ol>")
                (concat "<ul>\n" $listStr "\n</ul>"))))))
elisp change algorithm 2021-09-04
elisp change algorithm 2021-09-04
elisp xah-html-lines-to-def-list 2021-09-04
elisp xah-html-lines-to-def-list 2021-09-04