summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2012-04-25 22:15:29 +0200
committerNicolas Goaziou <n.goaziou@gmail.com>2012-04-26 14:49:29 +0200
commitc6dc6e3d32619c84d1690b6f67a3b4702b0f2282 (patch)
treed5bba2d773e9ec9ae06601d3cbf58ebc1b13c7a9
parentc3d7d21108506637480977d8cbeceafb6f96991b (diff)
downloadorg-mode-c6dc6e3d32619c84d1690b6f67a3b4702b0f2282.tar.gz
org-element: Verse blocks now contain objects
* contrib/lisp/org-element.el (org-element-verse-block-parser): Verse blocks now contain objects. (org-element-verse-block-interpreter, org-element-current-element): Apply changes to verse blocks. (org-element-secondary-value-alist): Remove verse blocks from elements with a secondary string. * contrib/lisp/org-e-odt.el (org-e-odt-verse-block): Apply changes to verse blocks. * contrib/lisp/org-e-latex.el (org-e-latex-verse-block): Apply changes to verse blocks. * contrib/lisp/org-e-html.el (org-e-html-verse-block): Apply changes to verse blocks. * contrib/lisp/org-e-ascii.el (org-e-ascii-verse-block): Apply changes to verse blocks. * testing/lisp/test-org-element.el: Add tests.
-rw-r--r--contrib/lisp/org-e-ascii.el8
-rw-r--r--contrib/lisp/org-e-html.el9
-rw-r--r--contrib/lisp/org-e-latex.el9
-rw-r--r--contrib/lisp/org-e-odt.el9
-rw-r--r--contrib/lisp/org-element.el137
-rw-r--r--testing/lisp/test-org-element.el53
6 files changed, 125 insertions, 100 deletions
diff --git a/contrib/lisp/org-e-ascii.el b/contrib/lisp/org-e-ascii.el
index d68975e..05f430d 100644
--- a/contrib/lisp/org-e-ascii.el
+++ b/contrib/lisp/org-e-ascii.el
@@ -1730,13 +1730,11 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(defun org-e-ascii-verse-block (verse-block contents info)
"Transcode a VERSE-BLOCK element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
+CONTENTS is verse block contents. INFO is a plist holding
+contextual information."
(let ((verse-width (org-e-ascii--current-text-width verse-block info)))
(org-e-ascii--indent-string
- (org-e-ascii--justify-string
- (org-export-secondary-string
- (org-element-property :value verse-block) 'e-ascii info)
- verse-width 'left)
+ (org-e-ascii--justify-string contents verse-width 'left)
org-e-ascii-quote-margin)))
diff --git a/contrib/lisp/org-e-html.el b/contrib/lisp/org-e-html.el
index 1f20865..d9350ff 100644
--- a/contrib/lisp/org-e-html.el
+++ b/contrib/lisp/org-e-html.el
@@ -2949,17 +2949,14 @@ channel."
(defun org-e-html-verse-block (verse-block contents info)
"Transcode a VERSE-BLOCK element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
+CONTENTS is verse block contents. INFO is a plist holding
+contextual information."
;; Replace each newline character with line break. Also replace
;; each blank line with a line break.
(setq contents (replace-regexp-in-string
"^ *\\\\\\\\$" "<br/>\n"
(replace-regexp-in-string
- "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n"
- (org-remove-indentation
- (org-export-secondary-string
- (org-element-property :value verse-block)
- 'e-html info)))))
+ "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n" contents)))
;; Replace each white space at beginning of a line with a
;; non-breaking space.
(while (string-match "^[ \t]+" contents)
diff --git a/contrib/lisp/org-e-latex.el b/contrib/lisp/org-e-latex.el
index 4483233..3c78b64 100644
--- a/contrib/lisp/org-e-latex.el
+++ b/contrib/lisp/org-e-latex.el
@@ -2118,7 +2118,8 @@ channel."
(defun org-e-latex-verse-block (verse-block contents info)
"Transcode a VERSE-BLOCK element from Org to LaTeX.
-CONTENTS is nil. INFO is a plist holding contextual information."
+CONTENTS is verse block contents. INFO is a plist holding
+contextual information."
(org-e-latex--wrap-label
verse-block
;; In a verse environment, add a line break to each newline
@@ -2129,11 +2130,7 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(setq contents (replace-regexp-in-string
"^ *\\\\\\\\$" "\\\\vspace*{1em}"
(replace-regexp-in-string
- "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n"
- (org-remove-indentation
- (org-export-secondary-string
- (org-element-property :value verse-block)
- 'e-latex info)))))
+ "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n" contents)))
(while (string-match "^[ \t]+" contents)
(let ((new-str (format "\\hspace*{%dem}"
(length (match-string 0 contents)))))
diff --git a/contrib/lisp/org-e-odt.el b/contrib/lisp/org-e-odt.el
index 347c079..263c4eb 100644
--- a/contrib/lisp/org-e-odt.el
+++ b/contrib/lisp/org-e-odt.el
@@ -4148,17 +4148,14 @@ channel."
(defun org-e-odt-verse-block (verse-block contents info)
"Transcode a VERSE-BLOCK element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
+CONTENTS is verse block contents. INFO is a plist holding
+contextual information."
;; Replace each newline character with line break. Also replace
;; each blank line with a line break.
(setq contents (replace-regexp-in-string
"^ *\\\\\\\\$" "<br/>\n"
(replace-regexp-in-string
- "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n"
- (org-remove-indentation
- (org-export-secondary-string
- (org-element-property :value verse-block)
- 'e-odt info)))))
+ "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n" contents)))
;; Replace each white space at beginning of a line with a
;; non-breaking space.
diff --git a/contrib/lisp/org-element.el b/contrib/lisp/org-element.el
index 8b38a54..c9be731 100644
--- a/contrib/lisp/org-element.el
+++ b/contrib/lisp/org-element.el
@@ -25,45 +25,51 @@
;; Org syntax can be divided into three categories: "Greater
;; elements", "Elements" and "Objects".
-;; An object can be defined anywhere on a line. It may span over more
-;; than a line but never contains a blank one. Objects belong to the
-;; following types: `emphasis', `entity', `export-snippet',
-;; `footnote-reference', `inline-babel-call', `inline-src-block',
-;; `latex-fragment', `line-break', `link', `macro', `radio-target',
-;; `statistics-cookie', `subscript', `superscript', `table-cell',
-;; `target', `time-stamp' and `verbatim'.
-
-;; An element always starts and ends at the beginning of a line
-;; (excepted for `table-cell'). The only element's type containing
-;; objects is called a `paragraph'. Other types are: `comment',
-;; `comment-block', `example-block', `export-block', `fixed-width',
-;; `horizontal-rule', `keyword', `latex-environment', `babel-call',
-;; `property-drawer', `quote-section', `src-block', `table',
-;; `table-row' and `verse-block'.
-
-;; Elements containing paragraphs are called greater elements.
-;; Concerned types are: `center-block', `drawer', `dynamic-block',
-;; `footnote-definition', `headline', `inlinetask', `item',
-;; `plain-list', `quote-block', `section' and `special-block'
-
-;; Greater elements (excepted `headline', `item' and `section' types)
-;; and elements (excepted `keyword', `babel-call', `property-drawer'
-;; and `table-row' types) can have a fixed set of keywords as
-;; attributes. Those are called "affiliated keywords", to distinguish
-;; them from others keywords, which are full-fledged elements. In
-;; particular, the "name" affiliated keyword allows to label almost
-;; any element in an Org buffer.
-
+;; Elements are related to the structure of the document. Indeed, all
+;; elements are a cover for the document: each position within belongs
+;; to at least one element.
+
+;; An element always starts and ends at the beginning of a line. With
+;; a few exceptions (namely `headline', `item', `section', `keyword',
+;; `babel-call' and `property-drawer' types), it can also accept
+;; a fixed set of keywords as attributes. Those are called
+;; "affiliated keywords" to distinguish them from other keywords,
+;; which are full-fledged elements.
+;;
+;; Element containing other elements (and only elements) are called
+;; greater elements. Concerned types are: `center-block', `drawer',
+;; `dynamic-block', `footnote-definition', `headline', `inlinetask',
+;; `item', `plain-list', `quote-block', `section' and `special-block'.
+;;
+;; Other element types are: `babel-call', `comment', `comment-block',
+;; `example-block', `export-block', `fixed-width', `horizontal-rule',
+;; `keyword', `latex-environment', `paragraph', `property-drawer',
+;; `quote-section', `src-block', `table', `table-cell', `table-row'
+;; and `verse-blocks'. Among them, `paragraph', `table-cell' and
+;; `verse-block' types can contain Org objects and plain text.
+;;
+;; Objects are related to document's contents. Some of them are
+;; recursive. Associated types are of the following: `emphasis',
+;; `entity', `export-snippet', `footnote-reference',
+;; `inline-babel-call', `inline-src-block', `latex-fragment',
+;; `line-break', `link', `macro', `radio-target', `statistics-cookie',
+;; `subscript', `superscript', `table-cell', `target', `time-stamp'
+;; and `verbatim'.
+;;
+;; Some elements also have special properties whose value can hold
+;; objects themselves (i.e. an item tag or an headline name). Such
+;; values are called "secondary strings". Any object belongs to
+;; either an element or a secondary string.
+;;
;; Notwithstanding affiliated keywords, each greater element, element
;; and object has a fixed set of properties attached to it. Among
;; them, three are shared by all types: `:begin' and `:end', which
;; refer to the beginning and ending buffer positions of the
;; considered element or object, and `:post-blank', which holds the
-;; number of blank lines, or white spaces, at its end.
-
-;; Some elements also have special properties whose value can hold
-;; objects themselves (i.e. an item tag, an headline name, a table
-;; cell). Such values are called "secondary strings".
+;; number of blank lines, or white spaces, at its end. Greater
+;; elements and elements containing objects will also have
+;; `:contents-begin' and `:contents-end' properties to delimit
+;; contents.
;; Lisp-wise, an element or an object can be represented as a list.
;; It follows the pattern (TYPE PROPERTIES CONTENTS), where:
@@ -81,7 +87,7 @@
;; for each type of Org syntax.
;; The next two parts introduce four accessors and a function
-;; retrieving the smallest element starting at point (respectively
+;; retrieving the element starting at point (respectively
;; `org-element-type', `org-element-property', `org-element-contents',
;; `org-element-restriction' and `org-element-current-element').
@@ -1584,56 +1590,40 @@ CONTENTS is the contents of the table row."
;;;; Verse Block
-(defun org-element-verse-block-parser (&optional raw-secondary-p)
+(defun org-element-verse-block-parser ()
"Parse a verse block.
-Return a list whose car is `verse-block' and cdr is a plist
-containing `:begin', `:end', `:hiddenp', `:value' and
-`:post-blank' keywords.
-
-When optional argument RAW-SECONDARY-P is non-nil, verse-block's
-value will not be parsed as a secondary string, but as a plain
-string instead.
+Return a list whose CAR is `verse-block' and CDR is a plist
+containing `:begin', `:end', `:contents-begin', `:contents-end',
+`:hiddenp' and `:post-blank' keywords.
-Assume point is at beginning or end of the block."
+Assume point is at beginning of the block."
(save-excursion
(let* ((case-fold-search t)
- (keywords (progn
- (end-of-line)
- (re-search-backward
- (concat "^[ \t]*#\\+BEGIN_VERSE") nil t)
- (org-element-collect-affiliated-keywords)))
+ (keywords (org-element-collect-affiliated-keywords))
(begin (car keywords))
(hidden (progn (forward-line) (org-truely-invisible-p)))
- (value-begin (point))
- (value-end
+ (contents-begin (point))
+ (contents-end
(progn
(re-search-forward (concat "^[ \t]*#\\+END_VERSE") nil t)
(point-at-bol)))
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
- (if (eobp) (point) (point-at-bol))))
- (value
- (if raw-secondary-p
- (buffer-substring-no-properties value-begin value-end)
- (org-element-parse-secondary-string
- (buffer-substring-no-properties value-begin value-end)
- (org-element-restriction 'verse-block)))))
+ (if (eobp) (point) (point-at-bol)))))
`(verse-block
(:begin ,begin
:end ,end
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
:hiddenp ,hidden
- :value ,value
:post-blank ,(count-lines pos-before-blank end)
,@(cadr keywords))))))
(defun org-element-verse-block-interpreter (verse-block contents)
"Interpret VERSE-BLOCK element as Org syntax.
-CONTENTS is nil."
- (format "#+BEGIN_VERSE\n%s#+END_VERSE"
- (org-remove-indentation
- (org-element-interpret-secondary
- (org-element-property :value verse-block)))))
+CONTENTS is verse block contents."
+ (format "#+BEGIN_VERSE\n%s#+END_VERSE" contents))
@@ -2767,8 +2757,7 @@ still has an entry since one of its properties (`:title') does.")
'((headline . :title)
(inlinetask . :title)
(item . :tag)
- (footnote-reference . :inline-definition)
- (verse-block . :value))
+ (footnote-reference . :inline-definition))
"Alist between element types and location of secondary value.")
@@ -2884,17 +2873,11 @@ it is quicker than its counterpart, albeit more restrictive."
(if (save-excursion
(re-search-forward
(format "[ \t]*#\\+END_%s\\(?: \\|$\\)" type) nil t))
- ;; Build appropriate parser. `verse-block' type
- ;; elements require an additional argument, so they
- ;; must be treated separately.
- (if (string= "VERSE" type)
- (org-element-verse-block-parser raw-secondary-p)
- (funcall
- (intern
- (format
- "org-element-%s-parser"
- (cdr (assoc type
- org-element-non-recursive-block-alist))))))
+ (funcall
+ (intern
+ (format
+ "org-element-%s-parser"
+ (cdr (assoc type org-element-non-recursive-block-alist)))))
(org-element-paragraph-parser)))))
;; Inlinetask.
((org-at-heading-p) (org-element-inlinetask-parser raw-secondary-p))
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 4e184c9..367cddf 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -261,6 +261,44 @@
+;;;; Verse blocks
+
+(ert-deftest test-org-element/verse-block ()
+ "Test verse block parsing."
+ ;; Standard test.
+ (org-test-with-temp-text "#+BEGIN_VERSE\nVerse block\n#+END_VERSE"
+ (should
+ (equal
+ (org-element-map (org-element-parse-buffer) 'verse-block 'identity nil t)
+ '(verse-block
+ (:begin 1 :end 38 :contents-begin 15 :contents-end 27 :hiddenp nil
+ :post-blank 0)
+ "Verse block\n"))))
+ ;; Ignore case.
+ (org-test-with-temp-text "#+begin_verse\nVerse block\n#+end_verse"
+ (should
+ (equal
+ (org-element-map (org-element-parse-buffer) 'verse-block 'identity nil t)
+ '(verse-block
+ (:begin 1 :end 38 :contents-begin 15 :contents-end 27 :hiddenp nil
+ :post-blank 0)
+ "Verse block\n"))))
+ ;; Parse folding.
+ (org-test-with-temp-text "#+BEGIN_VERSE\nVerse block\n#+END_VERSE"
+ (org-hide-block-all)
+ (should
+ (equal
+ (org-element-map (org-element-parse-buffer) 'verse-block 'identity nil t)
+ '(verse-block
+ (:begin 1 :end 38 :contents-begin 15 :contents-end 27
+ :hiddenp org-hide-block :post-blank 0)
+ "Verse block\n"))))
+ ;; Parse objects in verse blocks.
+ (org-test-with-temp-text "#+BEGIN_VERSE\nVerse \\alpha\n#+END_VERSE"
+ (should (org-element-map (org-element-parse-buffer) 'entity 'identity))))
+
+
+
;;;; Granularity
(ert-deftest test-org-element/granularity ()
@@ -367,6 +405,21 @@ Paragraph \\alpha."
'(org-data nil (paragraph (:caption (("long") "short")) "Paragraph")))
"#+CAPTION[short]: long\nParagraph\n")))
+(ert-deftest test-org-element/interpret-elements ()
+ "Test interpretation of elements and objects."
+ (let ((parse-and-interpret
+ (function
+ ;; Parse TEXT string in an Org buffer and transcode it back
+ ;; to Org syntax.
+ (lambda (text)
+ (with-temp-buffer
+ (org-mode)
+ (insert text)
+ (org-element-interpret-data (org-element-parse-buffer)))))))
+ ;; Verse blocks.
+ (equal (funcall parse-and-interpret "#+BEGIN_VERSE\nTest\n#+END_VERSE")
+ "#+BEGIN_VERSE\nTest\n#+END_VERSE\n")))
+
;;;; Normalize contents