diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2015-03-07 01:52:58 +0100 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2015-03-07 01:58:28 +0100 |
commit | bf4a645cacc26377b2847d7d2090a00017f6f114 (patch) | |
tree | bddc0e753c990bd544446b72ce05746a0c78664b | |
parent | d4c19a1c854919630da78544cf2de04572bf38a6 (diff) | |
download | org-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.el | 82 | ||||
-rw-r--r-- | testing/lisp/test-org-element.el | 22 |
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")))) |