Function: org-element-normalize-contents
org-element-normalize-contents is a byte-compiled function defined in
org-element.el.gz.
Signature
(org-element-normalize-contents ELEMENT &optional IGNORE-FIRST)
Documentation
Normalize plain text in ELEMENT's contents.
ELEMENT must only contain plain text and objects.
If optional argument IGNORE-FIRST is non-nil, ignore first line's indentation to compute maximal common indentation.
Return the normalized element that is element with global indentation removed from its contents.
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-element.el.gz
(defun org-element-normalize-contents (element &optional ignore-first)
"Normalize plain text in ELEMENT's contents.
ELEMENT must only contain plain text and objects.
If optional argument IGNORE-FIRST is non-nil, ignore first line's
indentation to compute maximal common indentation.
Return the normalized element that is element with global
indentation removed from its contents."
(letrec ((find-min-ind
;; Return minimal common indentation within BLOB. This is
;; done by walking recursively BLOB and updating MIN-IND
;; along the way. FIRST-FLAG is non-nil when the next
;; object is expected to be a string that doesn't start
;; with a newline character. It happens for strings at
;; the beginnings of the contents or right after a line
;; break.
(lambda (blob first-flag min-ind)
(dolist (datum (org-element-contents blob) min-ind)
(when first-flag
(setq first-flag nil)
(cond
;; Objects cannot start with spaces: in this
;; case, indentation is 0.
((not (stringp datum)) (throw :zero 0))
((not (string-match
"\\`\\([ \t]+\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum))
(throw :zero 0))
((equal (match-string 2 datum) "\n")
(put-text-property
(match-beginning 1) (match-end 1) 'org-ind 'empty datum))
(t
(let ((i (string-width (match-string 1 datum))))
(put-text-property
(match-beginning 1) (match-end 1) 'org-ind i datum)
(setq min-ind (min i min-ind))))))
(cond
((stringp datum)
(let ((s 0))
(while (string-match
"\n\\([ \t]*\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum s)
(setq s (match-end 1))
(cond
((equal (match-string 1 datum) "")
(unless (member (match-string 2 datum) '("" "\n"))
(throw :zero 0)))
((equal (match-string 2 datum) "\n")
(put-text-property (match-beginning 1) (match-end 1)
'org-ind 'empty datum))
(t
(let ((i (string-width (match-string 1 datum))))
(put-text-property (match-beginning 1) (match-end 1)
'org-ind i datum)
(setq min-ind (min i min-ind))))))))
((org-element-type-p datum 'line-break)
(setq first-flag t))
((org-element-type-p datum org-element-recursive-objects)
(setq min-ind
(funcall find-min-ind datum first-flag min-ind)))))))
(min-ind
(catch :zero
(funcall find-min-ind
element (not ignore-first) most-positive-fixnum))))
(if (or (zerop min-ind) (= min-ind most-positive-fixnum)) element
;; Build ELEMENT back, replacing each string with the same
;; string minus common indentation.
(letrec ((build
(lambda (datum)
;; Return DATUM with all its strings indentation
;; shortened from MIN-IND white spaces.
(apply
#'org-element-set-contents
datum
(mapcar
(lambda (object)
(cond
((stringp object)
(with-temp-buffer
(insert object)
(let ((s (point-min)))
(while (setq s (text-property-not-all
s (point-max) 'org-ind nil))
(goto-char s)
(let ((i (get-text-property s 'org-ind)))
(delete-region s (progn
(skip-chars-forward " \t")
(point)))
(when (integerp i) (indent-to (- i min-ind))))))
(buffer-string)))
((org-element-type-p object org-element-recursive-objects)
(funcall build object))
(t object)))
(org-element-contents datum)))
datum)))
(funcall build element)))))