diff --git a/lisp/ox.el b/lisp/ox.el index 90c7e7d69..debbe671d 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -1474,6 +1474,7 @@ Assume buffer is in Org mode. Narrowing, if any, is ignored." (dolist (option options properties) (when (equal (nth 1 option) keyword) (pushnew (car option) properties)))))) + to-parse (get-options (lambda (&optional files plist) ;; Recursively read keywords in buffer. FILES is a list @@ -1522,19 +1523,18 @@ Assume buffer is in Org mode. Narrowing, if any, is ignored." ;; BEHAVIOR. (case (nth 4 (assq property options)) (parse + (unless (memq property to-parse) + (push property to-parse)) + ;; Even if `parse' implies `space' + ;; behavior, we separate line with "\n" + ;; so as to preserve line-breaks. + ;; However, empty lines are forbidden + ;; since `parse' doesn't allow more than + ;; one paragraph. (let ((old (plist-get plist property))) - (apply - #'org-element-adopt-elements - old - (org-element-parse-secondary-string - (concat - (and - old - (not (eq (org-element-type (org-last old)) - 'line-break)) - " ") - val) - (org-element-restriction 'keyword))))) + (cond ((not (org-string-nw-p val)) old) + (old (concat old "\n" val)) + (t val)))) (space (if (not (plist-get plist property)) (org-trim val) @@ -1552,10 +1552,23 @@ Assume buffer is in Org mode. Narrowing, if any, is ignored." (otherwise (if (not (plist-member plist property)) val (plist-get plist property))))))))))))) - ;; Return final value. plist)))) ;; Read options in the current buffer and return value. - (funcall get-options (and buffer-file-name (list buffer-file-name)) nil))) + (let ((options (funcall get-options + (and buffer-file-name (list buffer-file-name)) + nil))) + ;; Parse properties in TO-PARSE. Remove newline characters not + ;; involved in line breaks to simulate `space' behaviour. + ;; Finally return options. + (dolist (p to-parse options) + (let ((value (org-element-parse-secondary-string + (plist-get options p) + (org-element-restriction 'keyword)))) + (org-element-map value 'plain-text + (lambda (s) + (org-element-set-element + s (replace-regexp-in-string "\n" " " s)))) + (setq options (plist-put options p value))))))) (defun org-export--get-buffer-attributes () "Return properties related to buffer attributes, as a plist." diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 85713c293..891a32876 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -162,7 +162,8 @@ variable, and communication channel under `info'." (org-test-with-temp-text "#+SELECT_TAGS: a\n#+SELECT_TAGS: b" (org-export--get-inbuffer-options)) '(:select-tags ("a" "b")))) - ;; Test `parse' behaviour. + ;; Test `parse' behaviour. `parse' implies `space' but preserve + ;; line breaks. Multi-line objects are allowed. (should (org-element-map (org-test-with-temp-text "#+TITLE: *bold*" @@ -172,7 +173,17 @@ variable, and communication channel under `info'." (equal (org-test-with-temp-text "#+TITLE: Some title\n#+TITLE: with spaces" (plist-get (org-export--get-inbuffer-options) :title)) - '("Some title" " with spaces"))) + '("Some title with spaces"))) + (should + (org-element-map + (org-test-with-temp-text "#+TITLE: Some title\\\\\n#+TITLE: with spaces" + (plist-get (org-export--get-inbuffer-options) :title)) + 'line-break #'identity nil t)) + (should + (org-element-map + (org-test-with-temp-text "#+TITLE: *bold\n#+TITLE: sentence*" + (plist-get (org-export--get-inbuffer-options) :title)) + 'bold #'identity nil t)) ;; Options set through SETUPFILE. (should (equal @@ -187,7 +198,7 @@ variable, and communication channel under `info'." #+TITLE: c" org-test-dir) (org-export--get-inbuffer-options)) - '(:language "fr" :select-tags ("a" "b" "c") :title ("a" " b" " c")))) + '(:language "fr" :select-tags ("a" "b" "c") :title ("a b c")))) ;; More than one property can refer to the same buffer keyword. (should (equal '(:k2 "value" :k1 "value")