tom@ssd.harris.com (Tom Horsley) (09/08/89)
Someone was asking about formatting paragraphs with hanging indents. This is a package I wrote which I now use to do all my paragraph filling. It uses several empirical rules to recognize a "paragraph" which seem to work well in practice, at least for the sorts of things I am always typing. For instance: /* This is a sample C comment to be formatted by paraform * this version is * very ragged, but it will come out nicely filled * once formatted. */ 1) This is another sort of paragraph, which can be filled by paraform with no mode changes or variable settings required since filling the C comment. becomes: /* This is a sample C comment to be formatted by paraform this version is * very ragged, but it will come out nicely filled once formatted. */ 1) This is another sort of paragraph, which can be filled by paraform with no mode changes or variable settings required since filling the C comment. The requirement for paraform to figure out what goes on is that in both of the above examples, the cursor was sitting on the 'T' in the first word (This) in each paragraph when it was filled. I replaced the standard fill paragraph key binding with this, but people who normally fill paragraphs with the cursor sitting at the end may not want to do that, paraform only works with the cursor on the first character of the paragraph, also it cannot work at all if you want paragraphs with the first line indented. -------------------cut here for paraform.el------------------------------ ;; This is a paragraph formatting command that combines many elements ;; of the standard paragraph formatting routines in a more convenient ;; to use functionality than the standard fill-paragraph command of ;; emacs - this is NOT a functional replacement - it behaves ;; differently. ;; ;; The primary improvement is in the area of formatting text with ;; hanging indents. You MUST put the cursor on the first character of ;; the paragraph. If there is text to the left of the cursor, it is ;; assumed to be the paragraph label. It searches down from the first ;; character for a line that does not look like it belongs to the ;; paragraph. The criteria are: ;; ;; 1) The end of the buffer is hit. ;; 2) The line is not long enough. ;; 3) The line has white space in the cursor column. ;; 4) The prefix is not identical to the prefix of the second line ;; (for lines beyond the second line). ;; ;; The area defined by this match criteria is formatted. The first ;; line remains prefixed by the first line prefix, any additional ;; lines are prefixed by the second line prefix. ;; ;; With a prefix arg it will right justify the text. (defun paraform (prf) "Format a paragraph starting at point the cursor is on. Anything to the left of the cursor is interpreted as a prefix for line 1 of the paragraph. The paragraph ends at the first line following the cursor line which contains white space in the cursor column, or does not match the previous lines. Any prefix on the second line of the paragraph is used as a fill prefix for all remaining lines. A prefix argument right justifies the paragraph. The variable fill-column determines where the right margin is." (interactive "P") (let ( (start-pos (point)) (start-col (current-column)) (orig-fill-column fill-column) (orig-fill-prefix fill-prefix) (first-line-prefix (buffer-substring (save-excursion (beginning-of-line 1) (point)) (point) ) ) (second-line-prefix nil) (delete-final-newline nil) start-marker end-marker ) ; Make sure this file has a final newline (otherwise while ; loop below might infinite loop). (if (/= (char-after (1- (point-max))) ?\n) (save-excursion (goto-char (point-max)) (insert "\n") (setq delete-final-newline t) ) ) ; Insert a blank line above this so it looks like start ; of paragraph. Record the newline position in start-marker. (save-excursion (beginning-of-line 1) (insert "\n") (backward-char 1) (setq start-marker (point-marker)) ) ; Delete the first line prefix (delete-region (save-excursion (beginning-of-line 1) (point)) (point)) ; This loop moves to first line after paragraph (while (and (equal (forward-line 1) 0) (equal (move-to-column start-col) start-col) (looking-at "[^ \t\n]") (or (not second-line-prefix) (equal second-line-prefix (buffer-substring (save-excursion (beginning-of-line 1) (point)) (point) ) ) ) ) ; remember second line prefix (if second-line-prefix nil (setq second-line-prefix (buffer-substring (save-excursion (beginning-of-line 1) (point) ) (point) ) ) ) ; delete prefix of each line in paragraph (delete-region (save-excursion (beginning-of-line 1) (point)) (point) ) ) ; get a marker to blank line at end of paragraph (beginning-of-line 1) (insert "\n") (backward-char 1) (setq end-marker (point-marker)) ; go fill the paragraph (goto-char (marker-position start-marker)) (forward-line 1) (setq fill-column (- fill-column start-col)) (setq fill-prefix nil) (fill-paragraph prf) (setq fill-column orig-fill-column) (setq fill-prefix orig-fill-prefix) ; if only 1 line, use same prefix for all. (if second-line-prefix nil (setq second-line-prefix first-line-prefix) ) ; Insert first line prefix at first line and ; second line prefix in all other lines. (goto-char (marker-position start-marker)) (set-marker start-marker nil) (delete-char 1) (insert first-line-prefix) (while (and (equal (forward-line 1) 0) (< (point) (marker-position end-marker)) ) (insert second-line-prefix) ) (set-marker end-marker nil) (delete-char 1) ; Leave buffer terminated the way we found it. (if delete-final-newline (save-excursion (goto-char (point-max)) (backward-delete-char 1 nil) ) ) ; go back to the beginning of the paragraph (goto-char start-pos) ) ) -------------------cut here, end of paraform.el------------------------------ -- ===================================================================== usenet: tahorsley@ssd.harris.com USMail: Tom Horsley compuserve: 76505,364 511 Kingbird Circle genie: T.HORSLEY Delray Beach, FL 33444 ======================== Aging: Just say no! ========================