org-element: Fix `org-element-normalize-contents'

* lisp/org-element.el (org-element-normalize-contents): Fix return
  value when any line after the first has no indentation.
* testing/lisp/test-org-element.el (test-org-element/normalize-contents):
  Add test.
This commit is contained in:
Nicolas Goaziou 2017-01-12 14:33:17 +01:00
parent 1d57c5670a
commit 5ada73aef6
2 changed files with 49 additions and 40 deletions

View File

@ -4677,47 +4677,51 @@ indentation removed from its contents."
;; the beginnings of the contents or right after a line ;; the beginnings of the contents or right after a line
;; break. ;; break.
(lambda (blob first-flag min-ind) (lambda (blob first-flag min-ind)
(catch 'zero (dolist (datum (org-element-contents blob) min-ind)
(dolist (datum (org-element-contents blob) min-ind) (when first-flag
(when first-flag (setq first-flag nil)
(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 (cond
((stringp datum) ;; Objects cannot start with spaces: in this
(let ((s 0)) ;; case, indentation is 0.
(while (string-match ((not (stringp datum)) (throw :zero 0))
"\n\\([ \t]+\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum s) ((not (string-match
(setq s (match-end 1)) "\\`\\([ \t]+\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum))
(if (equal (match-string 2 datum) "\n") (throw :zero 0))
(put-text-property ((equal (match-string 2 datum) "\n")
(match-beginning 1) (match-end 1) (put-text-property
'org-ind 'empty (match-beginning 1) (match-end 1) 'org-ind 'empty datum))
datum) (t
(let ((i (string-width (match-string 1 datum)))) (let ((i (string-width (match-string 1 datum))))
(put-text-property (put-text-property
(match-beginning 1) (match-end 1) 'org-ind i datum) (match-beginning 1) (match-end 1) 'org-ind i datum)
(setq min-ind (min i min-ind))))))) (setq min-ind (min i min-ind))))))
((eq (org-element-type datum) 'line-break) (cond
(setq first-flag t)) ((stringp datum)
((memq (org-element-type datum) org-element-recursive-objects) (let ((s 0))
(setq min-ind (while (string-match
(funcall find-min-ind datum first-flag min-ind)))))))) "\n\\([ \t]*\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum s)
(min-ind (funcall find-min-ind (setq s (match-end 1))
element (not ignore-first) most-positive-fixnum))) (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))))))))
((eq (org-element-type datum) 'line-break)
(setq first-flag t))
((memq (org-element-type 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 (if (or (zerop min-ind) (= min-ind most-positive-fixnum)) element
;; Build ELEMENT back, replacing each string with the same ;; Build ELEMENT back, replacing each string with the same
;; string minus common indentation. ;; string minus common indentation.

View File

@ -3272,6 +3272,11 @@ Text
(org-element-normalize-contents (org-element-normalize-contents
'(paragraph nil " Two spaces\n Three spaces")) '(paragraph nil " Two spaces\n Three spaces"))
'(paragraph nil "Two spaces\n Three spaces"))) '(paragraph nil "Two spaces\n Three spaces")))
(should
(equal
(org-element-normalize-contents
'(paragraph nil " Two spaces\nNo space"))
'(paragraph nil " Two spaces\nNo space")))
;; Ignore objects within contents when computing maximum common ;; Ignore objects within contents when computing maximum common
;; indentation. However, if contents start with an object, common ;; indentation. However, if contents start with an object, common
;; indentation is 0. ;; indentation is 0.