Function: rst-apply-indented-blocks

rst-apply-indented-blocks is a byte-compiled function defined in rst.el.gz.

Signature

(rst-apply-indented-blocks BEG END IND FUN)

Documentation

Apply FUN to all lines from BEG to END in blocks indented to IND.

The first indented block starts with the first non-empty line containing or after BEG and indented to IND. After the first line the indented block may contain more lines with same indentation (the paragraph) followed by empty lines and lines more indented (the sub-blocks). A following line indented to IND starts the next paragraph. A non-empty line with less indentation than IND terminates the current paragraph. FUN is applied to each line like this

  (FUN COUNT IN-FIRST IN-SUB IN-SUPER IN-EMPTY RELIND)

COUNT is 0 before the first paragraph and increments for every paragraph found on level IND. IN-FIRST is non-nil if this is the first line of such a paragraph. IN-SUB is non-nil if this line is part of a sub-block while IN-SUPER is non-nil if this line is part of a less indented block (super-block). IN-EMPTY is non-nil if this line is empty where an empty line is considered being part of the previous block. RELIND is nil for an empty line, 0 for a line indented to IND, and the positive or negative number of columns more or less indented otherwise. When FUN is called point is immediately behind indentation of that line. FUN may change everything as long as a marker at END and at the beginning of the following line is handled correctly by the change. A non-nil return value from FUN breaks the loop and is returned. Otherwise return nil.

Source Code

;; Defined in /usr/src/emacs/lisp/textmodes/rst.el.gz
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Apply to indented block

;; FIXME: These next functions should become part of a larger effort to redo
;;        the bullets in bulleted lists.  The enumerate would just be one of
;;        the possible outputs.
;;
;; FIXME: We need to do the enumeration removal as well.

(defun rst-apply-indented-blocks (beg end ind fun)
  "Apply FUN to all lines from BEG to END in blocks indented to IND.
The first indented block starts with the first non-empty line
containing or after BEG and indented to IND.  After the first
line the indented block may contain more lines with same
indentation (the paragraph) followed by empty lines and lines
more indented (the sub-blocks).  A following line indented to IND
starts the next paragraph.  A non-empty line with less
indentation than IND terminates the current paragraph.  FUN is
applied to each line like this

  (FUN COUNT IN-FIRST IN-SUB IN-SUPER IN-EMPTY RELIND)

COUNT is 0 before the first paragraph and increments for every
paragraph found on level IND.  IN-FIRST is non-nil if this is the
first line of such a paragraph.  IN-SUB is non-nil if this line
is part of a sub-block while IN-SUPER is non-nil if this line is
part of a less indented block (super-block).  IN-EMPTY is non-nil
if this line is empty where an empty line is considered being
part of the previous block.  RELIND is nil for an empty line, 0
for a line indented to IND, and the positive or negative number
of columns more or less indented otherwise.  When FUN is called
point is immediately behind indentation of that line.  FUN may
change everything as long as a marker at END and at the beginning
of the following line is handled correctly by the change.  A
non-nil return value from FUN breaks the loop and is returned.
Otherwise return nil."
  (let ((endm (copy-marker end t))
	(count 0) ; Before first indented block.
	(nxt (when (< beg end)
	       (copy-marker beg t)))
	(broken t)
	in-sub in-super stop)
    (save-match-data
      (save-excursion
	(while (and (not stop) nxt)
	  (set-marker
	   (goto-char nxt) nil)
	  (setq nxt (save-excursion
		      ;; FIXME refactoring: Replace `(forward-line)
		      ;;                    (back-to-indentation)` by
		      ;;                    `(forward-to-indentation)`
		      (when (and (rst-forward-line-strict 1 endm)
				 (< (point) endm))
			(copy-marker (point) t))))
	  (back-to-indentation)
	  (let ((relind (- (current-indentation) ind))
		(in-empty (looking-at (rst-re 'lin-end)))
		in-first)
	    (cond
	     (in-empty
	      (setq relind nil))
	     ((< relind 0)
	      (setq in-sub nil)
	      (setq in-super t))
	     ((> relind 0)
	      (setq in-sub t)
	      (setq in-super nil))
	     (t ; Non-empty line in indented block.
	      (when (or broken in-sub in-super)
		(setq in-first t)
		(cl-incf count))
	      (setq in-sub nil)
	      (setq in-super nil)))
	    (save-excursion
	      (setq
	       stop
	       (funcall fun count in-first in-sub in-super in-empty relind)))
	    (setq broken in-empty)))
	(set-marker endm nil)
	stop))))