Pastor Rob sends me plain-text outlines (well, they’re plain text, but written in Word; he doesn’t use the outline editor that’s built-in), and it’s my job to turn them into HTML. I spend 5-10 minutes a week doing that. So today I spent 90 minutes and taught Emacs how to do it. Here’s how.
Pastor Rob sends me something that looks like this:
In Matthew 13:3b-8 & 18-23 Jesus uses the Parable of the Sower to explain to us 4 different receptions of God’s word. I. One receives the word with a hard heart. A. Does not understand the word, so . . . (vs. 4a & 19a) B. Satan steals the word (vs. 4b & 19b). II. One receives the word with a shallow heart. A. Immediate reception but no depth, so . . . (vs. 5 & 20-21a) B. Immediate falling away when persecuted (vs. 6 & 21b). III. One receives the word with a double-minded heart. A. Receives the word, but . . . (vs. 7a & 22a) B. Relies on the world and wealth (vs. 7b & 22b). IV. One receives the word with a good heart. A. Understands the word, so . . . (vs. 8a & 23a) B. Bears fruit (vs. 8b & 23b).
I run it through the following Emacs function (colorized by htmlize.el, so it looks kind of like my Emacs at home):
; Formatting Pastor Rob's sermons (defun crs-point-at-last-line () "Returns the value of POINT at the beginning of the last line of the buffer." (save-excursion (goto-char (point-max)) (beginning-of-line) (point))) (defun crs-end-this-list-item () "Find the end of this list item and insert an end-of-list-item HTML tag, removing extraneous space before it." (save-excursion (when (re-search-forward "^\\( *\\w\\. +\\|</ol>\\|<li>\\)" nil t) (replace-match "\\&" t) (beginning-of-line) (insert "</li>\n") (forward-line -1) (beginning-of-line) (when (re-search-backward "\\([^ \015\012]\\)[ \015\012]*" nil t) (replace-match "\\1" t) (forward-line 1))))) (defun crs-outline-to-html (start-re next-re stop-re) "Starting from START-RE, begin an ordered list, marking new list items every NEXT-RE and ending just before STOP-RE." (save-excursion (goto-char (point-min)) (while (re-search-forward start-re nil t) (replace-match "<ol>\n<li>" t) (crs-end-this-list-item) (forward-line 1) (beginning-of-line) (while (not (or (looking-at stop-re) (= (point) (crs-point-at-last-line)))) (when (looking-at next-re) (replace-match "<li>" t) (crs-end-this-list-item)) (forward-line 1) (beginning-of-line)) (insert "</ol>\n")))) (defun crs-format-rob-outline () "Take a text outline like I get from Pastor Rob and turn it into an HTML outline." (interactive) (setq case-fold-search nil) (save-excursion (crs-outline-to-html "^ *I\\. +" "^ *\\(I\\|V\\|X\\)+\\. +" "^ZZZZEND") (crs-outline-to-html "^ *A\\. +" "^ *[A-Z]\\. +" "^\\(<li>\\|</ol>\\)") (crs-outline-to-html "^ *1\\. +" "^ *[0-9]\\. +" "^\\(<li>\\|</ol>\\)") (crs-outline-to-html "^ *a\\. +" "^ *[a-z]\\. +" "^\\(<li>\\|</ol>\\)") (goto-char (point-min)) (perform-replace "(vs." "(vv." nil nil nil) (goto-char (point-min)) (perform-replace " *[ \015\012]+ +" " " nil t nil))) ; Assign this to C-c c o (for outline) (crs-define-key global-map "o" 'crs-format-rob-outline)
There are definitely cases where it could break, but not in one of Pastor Rob’s outlines, I think. The main function is the last one defined, crs-format-rob-outline, in which it turns the main points into an ordered list, followed by the subpoints, followed by the sub-subpoints, and so forth. Then it turns “vs.” (supposed to be verses) into “vv.” and removes extraneous spaces caused by the Pastor’s manual typesetting in Word. The stylesheet on our sermon notes website takes care of knowing that first-level ordered lists are capital Roman numerals, second-level lists are capital letters, and so forth.
The outline then ends up looking like this:
<ol> <li>One receives the word with a hard heart.</li> <ol> <li>Does not understand the word, so . . . (vv. 4a & 19a)</li> <li>Satan steals the word (vv. 4b & 19b).</li> </ol> <li>One receives the word with a shallow heart.</li> <ol> <li>Immediate reception but no depth, so . . . (vv. 5 & 20-21a)</li> <li>Immediate falling away when persecuted (vv. 6 & 21b).</li> </ol> <li>One receives the word with a double-minded heart.</li> <ol> <li>Receives the word, but . . . (vv. 7a & 22a)</li> <li>Relies on the world and wealth (vv. 7b & 22b).</li> </ol> <li>One receives the word with a good heart.</li> <ol> <li>Understands the word, so . . . (vv. 8a & 23a)</li> <li>Bears fruit (vv. 8b & 23b).</li> </ol> </ol>
I really love doing things like this. There are times when I wish that all I did was repetitive text changing tasks.



One Trackback
[...] guess because it’s a challenge. It was fun to write an outline conversion tool this weekend. It’s just my kind of challenge. Every time I do something like this, I learn more about [...]