From f4791557e2a1e10f6a8aaadfb94b93372a70e969 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Wed, 2 May 2012 17:18:14 +0200 Subject: [PATCH] org-element: Store fixed-with and comment contents without markers * contrib/lisp/org-element.el (org-element-comment-parser): Store comments without leading hash and maybe plus sign. (org-element-fixed-width-parser): Store fixed-width contents without leading colons. (org-element-comment-interpreter, org-element-fixed-width-interpreter): Apply changes. * contrib/lisp/org-e-odt.el (org-e-odt-fixed-width): Apply changes to fixed-width `:value' property. * contrib/lisp/org-e-latex.el (org-e-latex-fixed-width): Apply changes to fixed-width `:value' property. * contrib/lisp/org-e-html.el (org-e-html-fixed-width): Apply changes to fixed-width `:value' property. * contrib/lisp/org-e-ascii.el (org-e-ascii-fixed-width): Apply changes to fixed-width `:value' property. * testing/lisp/test-org-element.el: Add tests. --- contrib/lisp/org-e-ascii.el | 4 +- contrib/lisp/org-e-html.el | 13 +++-- contrib/lisp/org-e-latex.el | 11 ++--- contrib/lisp/org-e-odt.el | 10 ++-- contrib/lisp/org-element.el | 54 ++++++++++++++------- testing/lisp/test-org-element.el | 81 ++++++++++++++++++++++++++++++-- 6 files changed, 131 insertions(+), 42 deletions(-) diff --git a/contrib/lisp/org-e-ascii.el b/contrib/lisp/org-e-ascii.el index db134136f..11ce9ee0d 100644 --- a/contrib/lisp/org-e-ascii.el +++ b/contrib/lisp/org-e-ascii.el @@ -1116,8 +1116,8 @@ CONTENTS is nil. INFO is a plist holding contextual information." "Transcode a FIXED-WIDTH element from Org to ASCII. CONTENTS is nil. INFO is a plist holding contextual information." (org-e-ascii--box-string - (replace-regexp-in-string - "^[ \t]*: ?" "" (org-element-property :value fixed-width)) info)) + (org-remove-indentation + (org-element-property :value fixed-width)) info)) ;;;; Footnote Definition diff --git a/contrib/lisp/org-e-html.el b/contrib/lisp/org-e-html.el index 2db126be0..4b6d6d5a9 100644 --- a/contrib/lisp/org-e-html.el +++ b/contrib/lisp/org-e-html.el @@ -1972,13 +1972,12 @@ CONTENTS is nil. INFO is a plist holding contextual information." (defun org-e-html-fixed-width (fixed-width contents info) "Transcode a FIXED-WIDTH element from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information." - (let* ((value (org-element-normalize-string - (replace-regexp-in-string - "^[ \t]*: ?" "" - (org-element-property :value fixed-width))))) - (org-e-html--wrap-label - fixed-width (format "\n
\n%s\n
" - (org-e-html-do-format-code value))))) + (org-e-html--wrap-label + fixed-width + (format "\n
\n%s
" + (org-e-html-do-format-code + (org-remove-indentation + (org-element-property :value fixed-width)))))) ;;;; Footnote Definition diff --git a/contrib/lisp/org-e-latex.el b/contrib/lisp/org-e-latex.el index 27d3ae75f..ade6b052a 100644 --- a/contrib/lisp/org-e-latex.el +++ b/contrib/lisp/org-e-latex.el @@ -1073,12 +1073,11 @@ CONTENTS is nil. INFO is a plist holding contextual information." (defun org-e-latex-fixed-width (fixed-width contents info) "Transcode a FIXED-WIDTH element from Org to LaTeX. CONTENTS is nil. INFO is a plist holding contextual information." - (let* ((value (org-element-normalize-string - (replace-regexp-in-string - "^[ \t]*: ?" "" - (org-element-property :value fixed-width))))) - (org-e-latex--wrap-label - fixed-width (format "\\begin{verbatim}\n%s\\end{verbatim}" value)))) + (org-e-latex--wrap-label + fixed-width + (format "\\begin{verbatim}\n%s\\end{verbatim}" + (org-remove-indentation + (org-element-property :value fixed-width))))) ;;;; Footnote Definition diff --git a/contrib/lisp/org-e-odt.el b/contrib/lisp/org-e-odt.el index 74cf3e179..952bdbf57 100644 --- a/contrib/lisp/org-e-odt.el +++ b/contrib/lisp/org-e-odt.el @@ -3051,12 +3051,10 @@ CONTENTS is nil. INFO is a plist holding contextual information." (defun org-e-odt-fixed-width (fixed-width contents info) "Transcode a FIXED-WIDTH element from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information." - (let* ((value (org-element-normalize-string - (replace-regexp-in-string - "^[ \t]*: ?" "" - (org-element-property :value fixed-width))))) - (org-e-odt--wrap-label - fixed-width (org-e-odt-format-source-code-or-example value nil)))) + (org-e-odt--wrap-label + fixed-width + (org-e-odt-format-source-code-or-example + (org-element-property :value fixed-width) nil))) ;;;; Footnote Definition diff --git a/contrib/lisp/org-element.el b/contrib/lisp/org-element.el index cd8802630..a5a273cc9 100644 --- a/contrib/lisp/org-element.el +++ b/contrib/lisp/org-element.el @@ -972,36 +972,42 @@ keywords. Assume point is at comment beginning." (save-excursion - (let* ((com-beg (point)) - (keywords (org-element-collect-affiliated-keywords)) + (let* ((keywords (org-element-collect-affiliated-keywords)) (begin (car keywords)) + value (com-end ;; Get comments ending. This may not be accurate if ;; commented lines within an item are followed by ;; commented lines outside of a list. Though, parser will ;; always get it right as it already knows surrounding ;; element and has narrowed buffer to its contents. - (if (looking-at "#") - (if (re-search-forward "^\\([^#]\\|#\\+[a-z]\\)" nil 'move) - (progn (goto-char (match-beginning 0)) (point)) - (point)) - (while (looking-at "[ \t]*#\\+\\(?: \\|$\\)") + (progn + (while (looking-at "\\(\\(# ?\\)[^+]\\|[ \t]*#\\+\\( \\|$\\)\\)") + ;; Accumulate lines without leading hash and plus sign + ;; if any. First whitespace is also ignored. + (setq value + (concat value + (buffer-substring-no-properties + (or (match-end 2) (match-end 3)) (point-at-eol)) + "\n")) (forward-line)) (point))) (end (progn (goto-char com-end) (org-skip-whitespace) (if (eobp) (point) (point-at-bol))))) `(comment - (:begin ,(or (car keywords) com-beg) + (:begin ,begin :end ,end - :value ,(buffer-substring-no-properties com-beg com-end) + :value ,value :post-blank ,(count-lines com-end end) ,@(cadr keywords)))))) (defun org-element-comment-interpreter (comment contents) "Interpret COMMENT element as Org syntax. CONTENTS is nil." - (org-element-property :value comment)) + (replace-regexp-in-string + "^" "#+ " + (substring (org-element-property :value comment) 0 -1))) ;;;; Comment Block @@ -1164,16 +1170,27 @@ containing `:begin', `:end', `:value' and `:post-blank' keywords. Assume point is at the beginning of the fixed-width area." (save-excursion - (let* ((beg-area (point)) - (keywords (org-element-collect-affiliated-keywords)) + (let* ((keywords (org-element-collect-affiliated-keywords)) (begin (car keywords)) + value (end-area - (progn (while (looking-at "[ \t]*:\\( \\|$\\)") - (forward-line)) - (point))) + ;; Ending position may not be accurate if fixed-width + ;; lines within an item are followed by fixed-width lines + ;; outside of a list. Though, parser will always get it + ;; right as it already knows surrounding element and has + ;; narrowed buffer to its contents. + (progn + (while (looking-at "[ \t]*:\\( \\|$\\)") + ;, Accumulate text without starting colons. + (setq value + (concat value + (buffer-substring-no-properties + (match-end 0) (point-at-eol)) + "\n")) + (forward-line)) + (point))) (end (progn (org-skip-whitespace) - (if (eobp) (point) (point-at-bol)))) - (value (buffer-substring-no-properties beg-area end-area))) + (if (eobp) (point) (point-at-bol))))) `(fixed-width (:begin ,begin :end ,end @@ -1184,7 +1201,8 @@ Assume point is at the beginning of the fixed-width area." (defun org-element-fixed-width-interpreter (fixed-width contents) "Interpret FIXED-WIDTH element as Org syntax. CONTENTS is nil." - (org-remove-indentation (org-element-property :value fixed-width))) + (replace-regexp-in-string + "^" ": " (substring (org-element-property :value fixed-width) 0 -1))) ;;;; Horizontal Rule diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index c061bc59c..6eafb06cf 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -36,6 +36,37 @@ Return interpreted string." ;;; Test Parsers +;;;; Comments + +(ert-deftest test-org-element/comment-parser () + "Test `comment' parsing." + ;; Regular comment. + (should + (equal + (org-test-with-temp-text "# Comment" + (org-element-map (org-element-parse-buffer) 'comment 'identity nil t)) + '(comment (:begin 1 :end 10 :value "Comment\n" :post-blank 0)))) + ;; Inline comment. + (should + (equal + (org-test-with-temp-text "#+ Comment" + (org-element-map (org-element-parse-buffer) 'comment 'identity nil t)) + '(comment (:begin 1 :end 11 :value "Comment\n" :post-blank 0)))) + ;; Preserve indentation. + (should + (equal + (org-test-with-temp-text "#+ No blank\n#+ One blank" + (org-element-map (org-element-parse-buffer) 'comment 'identity nil t)) + '(comment (:begin 1 :end 26 :value "No blank\n One blank\n" :post-blank 0)))) + ;; Comment with blank lines. + (should + (equal + (org-test-with-temp-text "#+ First part\n#+ \n#+\n#+ Second part" + (org-element-map (org-element-parse-buffer) 'comment 'identity nil t)) + '(comment + (:begin 1 :end 36 :value "First part\n\n\nSecond part\n" :post-blank 0))))) + + ;;;; Example-blocks and Src-blocks (ert-deftest test-org-element/block-switches () @@ -152,6 +183,43 @@ Return interpreted string." :value "contents" :begin 1 :end 20 :post-blank 0))))) +;;;; Fixed width + +(ert-deftest test-org-element/fixed-width () + "Test fixed-width area parsing." + ;; Preserve indentation. + (should + (equal + (org-test-with-temp-text ": no blank\n: one blank" + (org-element-map (org-element-parse-buffer) 'fixed-width 'identity nil t)) + '(fixed-width + (:begin 1 :end 24 :value "no blank\n one blank\n" :post-blank 0)))) + ;; Fixed-width with empty lines. + (should + (equal + (org-test-with-temp-text ": first part\n:\n: \n: second part" + (org-element-map (org-element-parse-buffer) 'fixed-width 'identity nil t)) + '(fixed-width + (:begin 1 :end 32 :value "first part\n\n\nsecond part\n" :post-blank 0)))) + ;; Parse indented fixed-width markers. + (should + (equal + (org-test-with-temp-text "Text\n : no blank\n : one blank" + (org-element-map (org-element-parse-buffer) 'fixed-width 'identity nil t)) + '(fixed-width + (:begin 6 :end 33 :value "no blank\n one blank\n" :post-blank 0)))) + ;; Distinguish fixed-width areas within a list and outside of it. + (should + (= 2 + (length + (org-test-with-temp-text " +- Item + : fixed-width inside +: fixed-width outside" + (org-element-map + (org-element-parse-buffer) 'fixed-width 'identity)))))) + + ;;;; Footnotes references (ert-deftest test-org-element/footnote-reference-parser () @@ -613,10 +681,13 @@ CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01")) (ert-deftest test-org-element/comment-interpreter () "Test comment interpreter." ;; Regular comment. - (should (equal (org-test-parse-and-interpret "#Comment") "#Comment\n")) + (should (equal (org-test-parse-and-interpret "#Comment") "#+ Comment\n")) ;; Inline comment. (should (equal (org-test-parse-and-interpret " #+ Comment") - " #+ Comment\n"))) + "#+ Comment\n")) + ;; Preserve indentation. + (should (equal (org-test-parse-and-interpret " #+ No blank\n#+ One blank") + "#+ No blank\n#+ One blank\n"))) (ert-deftest test-org-element/comment-block-interpreter () "Test comment block interpreter." @@ -644,7 +715,11 @@ CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01")) (ert-deftest test-org-element/fixed-width-interpreter () "Test fixed width interpreter." - (should (equal (org-test-parse-and-interpret ": Test") ": Test\n"))) + ;; Standard test. + (should (equal (org-test-parse-and-interpret ": Test") ": Test\n")) + ;; Preserve indentation. + (should (equal (org-test-parse-and-interpret ": 2 blanks\n: 1 blank") + ": 2 blanks\n: 1 blank\n"))) (ert-deftest test-org-element/horizontal-rule-interpreter () "Test horizontal rule interpreter."