Function: allout-chart-subtree

allout-chart-subtree is a byte-compiled function defined in allout.el.gz.

Signature

(allout-chart-subtree &optional LEVELS VISIBLE ORIG-DEPTH PREV-DEPTH)

Documentation

Produce a location "chart" of subtopics of the containing topic.

Optional argument LEVELS specifies a depth limit (relative to start depth) for the chart. Null LEVELS means no limit.

When optional argument VISIBLE is non-nil, the chart includes only the visible subelements of the charted subjects.

The remaining optional args are for internal use by the function.

Point is left at the end of the subtree.

Charts are used to capture outline structure, so that outline-altering routines need to assess the structure only once, and then use the chart for their elaborate manipulations.

The chart entries for the topics are in reverse order, so the last topic is listed first. The entry for each topic consists of an integer indicating the point at the beginning of the topic prefix. Charts for offspring consist of a list containing, recursively, the charts for the respective subtopics. The chart for a topics' offspring precedes the entry for the topic itself.

The other function parameters are for internal recursion, and should not be specified by external callers. ORIG-DEPTH is depth of topic at starting point, and PREV-DEPTH is depth of prior topic.

Source Code

;; Defined in /usr/src/emacs/lisp/allout.el.gz
;;;_  - Subtree Charting
;;;_   " These routines either produce or assess charts, which are
;; nested lists of the locations of topics within a subtree.
;;
;; Charts enable efficient subtree navigation by providing a reusable basis
;; for elaborate, compound assessment and adjustment of a subtree.

;;;_   > allout-chart-subtree (&optional levels visible orig-depth prev-depth)
(defun allout-chart-subtree (&optional levels visible orig-depth prev-depth)
  "Produce a location \"chart\" of subtopics of the containing topic.

Optional argument LEVELS specifies a depth limit (relative to start
depth) for the chart.  Null LEVELS means no limit.

When optional argument VISIBLE is non-nil, the chart includes
only the visible subelements of the charted subjects.

The remaining optional args are for internal use by the function.

Point is left at the end of the subtree.

Charts are used to capture outline structure, so that outline-altering
routines need to assess the structure only once, and then use the chart
for their elaborate manipulations.

The chart entries for the topics are in reverse order, so the
last topic is listed first.  The entry for each topic consists of
an integer indicating the point at the beginning of the topic
prefix.  Charts for offspring consist of a list containing,
recursively, the charts for the respective subtopics.  The chart
for a topics' offspring precedes the entry for the topic itself.

The other function parameters are for internal recursion, and should
not be specified by external callers.  ORIG-DEPTH is depth of topic at
starting point, and PREV-DEPTH is depth of prior topic."

  (let ((original (not orig-depth))	; `orig-depth' set only in recursion.
	chart curr-depth)

    (if original			; Just starting?
					; Register initial settings and
					; position to first offspring:
	(progn (setq orig-depth (allout-depth))
	       (or prev-depth (setq prev-depth (1+ orig-depth)))
               (if visible
                   (allout-next-visible-heading 1)
                 (allout-next-heading))))

    ;; Loop over the current levels' siblings.  Besides being more
    ;; efficient than tail-recursing over a level, it avoids exceeding
    ;; the typically quite constrained Emacs max-lisp-eval-depth.
    ;;
    ;; Probably would speed things up to implement loop-based stack
    ;; operation rather than recursing for lower levels.  Bah.

    (while (and (not (eobp))
					; Still within original topic?
		(< orig-depth (setq curr-depth allout-recent-depth))
		(cond ((= prev-depth curr-depth)
		       ;; Register this one and move on:
		       (setq chart (cons allout-recent-prefix-beginning chart))
		       (if (and levels (<= levels 1))
			   ;; At depth limit -- skip sublevels:
			   (or (allout-next-sibling curr-depth)
			       ;; or no more siblings -- proceed to
			       ;; next heading at lesser depth:
			       (while (and (<= curr-depth
					       allout-recent-depth)
                                           (if visible
                                               (allout-next-visible-heading 1)
                                             (allout-next-heading)))))
                         (if visible
                             (allout-next-visible-heading 1)
                           (allout-next-heading))))

		      ((and (< prev-depth curr-depth)
			    (or (not levels)
				(> levels 0)))
		       ;; Recurse on deeper level of curr topic:
		       (setq chart
			     (cons (allout-chart-subtree (and levels
							       (1- levels))
                                                         visible
                                                         orig-depth
                                                         curr-depth)
				   chart))
		       ;; ... then continue with this one.
		       )

		      ;; ... else nil if we've ascended back to prev-depth.

		      )))

    (if original			; We're at the last sibling on
					; the original level.  Position
					; to the end of it:
	(progn (and (not (eobp)) (forward-char -1))
	       (and (= (preceding-char) ?\n)
		    (= (aref (buffer-substring (max 1 (- (point) 3))
                                               (point))
                             1)
                       ?\n)
		    (forward-char -1))
	       (setq allout-recent-end-of-subtree (point))))

    chart				; (nreverse chart) not necessary,
					; and maybe not preferable.
    ))