summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2015-03-07 01:52:58 +0100
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2015-03-07 01:58:28 +0100
commitbf4a645cacc26377b2847d7d2090a00017f6f114 (patch)
treebddc0e753c990bd544446b72ce05746a0c78664b
parentd4c19a1c854919630da78544cf2de04572bf38a6 (diff)
downloadorg-mode-bf4a645cacc26377b2847d7d2090a00017f6f114.tar.gz
org-element: Fix indentation removal with line breaks
* lisp/org-element.el (org-element-line-break-parser): Tiny refactoring. (org-element-normalize-contents): Take into consideration line breaks when removing common indentation. Small refactoring. * testing/lisp/test-org-element.el (test-org-element/normalize-contents): Add tests.
-rw-r--r--lisp/org-element.el82
-rw-r--r--testing/lisp/test-org-element.el22
2 files changed, 65 insertions, 39 deletions
diff --git a/lisp/org-element.el b/lisp/org-element.el
index 711817c..1d8f488 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -2998,7 +2998,7 @@ Assume point is at the beginning of the line break."
(not (eq (char-before) ?\\)))
(list 'line-break
(list :begin (point)
- :end (progn (forward-line) (point))
+ :end (line-beginning-position 2)
:post-blank 0))))
(defun org-element-line-break-interpreter (line-break contents)
@@ -4514,25 +4514,29 @@ indentation is not done with TAB characters."
(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 first
- ;; string hasn't been seen yet. It is required as this
- ;; string is the only one whose indentation doesn't happen
- ;; after a newline character.
+ ;; 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)
(dolist (object (org-element-contents blob))
- (when (and first-flag (stringp object))
+ (when first-flag
(setq first-flag nil)
- (string-match "\\` *" object)
- (let ((len (match-end 0)))
- ;; An indentation of zero means no string will be
- ;; modified. Quit the process.
- (if (zerop len) (throw 'zero (setq min-ind 0))
- (setq min-ind (min len min-ind)))))
+ ;; Objects cannot start with spaces: in this case,
+ ;; indentation is 0.
+ (if (not (stringp object)) (throw 'zero (setq min-ind 0))
+ (string-match "\\` *" object)
+ (let ((len (match-end 0)))
+ ;; An indentation of zero means no string will be
+ ;; modified. Quit the process.
+ (if (zerop len) (throw 'zero (setq min-ind 0))
+ (setq min-ind (min len min-ind))))))
(cond
((stringp object)
(dolist (line (cdr (org-split-string object " *\n")))
(unless (string= line "")
(setq min-ind (min (org-get-indentation line) min-ind)))))
+ ((eq (org-element-type object) 'line-break) (setq first-flag t))
((memq (org-element-type object) org-element-recursive-objects)
(funcall find-min-ind object first-flag)))))))
;; Find minimal indentation in ELEMENT.
@@ -4542,31 +4546,35 @@ indentation is not done with TAB characters."
;; string minus common indentation.
(let* (build ; For byte compiler.
(build
- (function
- (lambda (blob first-flag)
- ;; Return BLOB with all its strings indentation
- ;; shortened from MIN-IND white spaces. FIRST-FLAG
- ;; is non-nil when the first string hasn't been seen
- ;; yet.
- (setcdr (cdr blob)
- (mapcar
- #'(lambda (object)
- (when (and first-flag (stringp object))
- (setq first-flag nil)
- (setq object
- (replace-regexp-in-string
- (format "\\` \\{%d\\}" min-ind)
- "" object)))
- (cond
- ((stringp object)
- (replace-regexp-in-string
- (format "\n \\{%d\\}" min-ind) "\n" object))
- ((memq (org-element-type object)
- org-element-recursive-objects)
- (funcall build object first-flag))
- (t object)))
- (org-element-contents blob)))
- blob))))
+ (lambda (blob first-flag)
+ ;; Return BLOB with all its strings indentation
+ ;; shortened from MIN-IND white spaces. FIRST-FLAG is
+ ;; non-nil when the next object is expected to be
+ ;; a string that doesn't start with a newline
+ ;; character.
+ (setcdr (cdr blob)
+ (mapcar
+ (lambda (object)
+ (when first-flag
+ (setq first-flag nil)
+ (when (stringp object)
+ (setq object
+ (replace-regexp-in-string
+ (format "\\` \\{%d\\}" min-ind)
+ "" object))))
+ (cond
+ ((stringp object)
+ (replace-regexp-in-string
+ (format "\n \\{%d\\}" min-ind) "\n" object))
+ ((memq (org-element-type object)
+ org-element-recursive-objects)
+ (funcall build object first-flag))
+ ((eq (org-element-type object) 'line-break)
+ (setq first-flag t)
+ object)
+ (t object)))
+ (org-element-contents blob)))
+ blob)))
(funcall build element (not ignore-first))))))
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 8d34bb6..e3055dc 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -3067,12 +3067,18 @@ Text
'(paragraph nil " Two spaces\n Three spaces"))
'(paragraph nil "Two spaces\n Three spaces")))
;; Ignore objects within contents when computing maximum common
- ;; indentation.
+ ;; indentation. However, if contents start with an object, common
+ ;; indentation is 0.
(should
(equal
(org-element-normalize-contents
'(paragraph nil " One " (emphasis nil "space") "\n Two spaces"))
'(paragraph nil "One " (emphasis nil "space") "\n Two spaces")))
+ (should
+ (equal
+ (org-element-normalize-contents
+ '(paragraph nil (verbatim nil "V") "No space\n Two\n Three"))
+ '(paragraph nil (verbatim nil "V") "No space\n Two\n Three")))
;; Ignore blank lines.
(should
(equal
@@ -3101,7 +3107,19 @@ Text
(equal
(org-element-normalize-contents
'(paragraph nil "No space\n Two spaces\n Three spaces") t)
- '(paragraph nil "No space\nTwo spaces\n Three spaces"))))
+ '(paragraph nil "No space\nTwo spaces\n Three spaces")))
+ (should
+ (equal
+ (org-element-normalize-contents
+ '(paragraph nil (verbatim nil "V") "No space\n Two\n Three") t)
+ '(paragraph nil (verbatim nil "V") "No space\nTwo\n Three")))
+ ;; Corner case: do not ignore indentation of string right after
+ ;; a line break.
+ (should
+ (equal
+ (org-element-normalize-contents
+ '(paragraph nil " 1 space" (line-break) " 2 spaces"))
+ '(paragraph nil "1 space" (line-break) " 2 spaces"))))