;;
;; Emacs Lisp tutorial:
;;
;; - http://www.gnu.org/manual/emacs-lisp-intro/emacs-lisp-intro.html
;; "Programming in Emacs Lisp"
;; by Robert J. Chassell.
;; -------------------------------------------
;;
;; See example input/output: - rjc_fill__before.txt
;; - rjc_fill__after.txt
;; Using the function would be something like this:
;; - visit text that needs formatting in an Emacs buffer
;; - load function into memory (if not already there)
;; - make sure any "<p>" tags really are at beginning of paragraph
;; - add "<p>" tags at beginning of paragraphs that need them
;; - execute function
;; - save modified buffer, or send email, or...
;;
;;
(defun rjc-formatter-paragraphs (args)
"Simple formatting based on <p> tags: add newsline(s), indent and fill"
(interactive "p")
(let (
(my-indentation nil)
(my-point nil)
(my-point-end nil)
(paragraph-tag "<[pP]>")
(paragraph-tag-length 3))
(save-excursion
(save-restriction
(beginning-of-buffer)
(while (search-forward-regexp paragraph-tag nil t)
(backward-delete-char paragraph-tag-length)
(setq my-point (point))
; Conditionally insert 1st newline.
; Capture indentation with parentheses.
(search-backward-regexp "\n\\([ \t]*\\)" nil t)
(setq my-point-end (match-end 0)) (goto-char my-point)
(if (= my-point my-point-end)
nil
(newline 1))
; Calculate indentation.
(setq my-indentation "")
(if (not (match-string 1))
nil
(setq n (length (match-string 1)))
(while (> n 0)
(setq my-indentation (concat my-indentation " "))
(setq n (- n 1))))
; Conditionally insert 2nd newline.
(search-backward-regexp "\n[ \t]*\n[ \t]*" nil t)
(setq my-point-end (match-end 0)) (goto-char my-point)
(if (not (= my-point my-point-end))
(newline 1)
nil)
; Insert indentation (could be "").
(insert my-indentation)
; Fill all paragraphs except for last.
(let ((beg (point)))
(if (search-forward-regexp paragraph-tag nil t)
(fill-region beg (match-beginning 0))
nil)
(goto-char beg)))
; Unconditionally fill last paragraph.
(fill-paragraph nil)))))