diff options
author | Nicholas D Steeves <nsteeves@gmail.com> | 2017-07-03 20:44:19 -0400 |
---|---|---|
committer | Nicholas D Steeves <nsteeves@gmail.com> | 2017-07-03 20:57:31 -0400 |
commit | 3458b4fdfffc1b4f542405325ffa8b6eed0eb1df (patch) | |
tree | 0c9ed6fcddc796bdb92d3fc5fd266fac3b583eda /lisp/org-element.el | |
parent | 969f455bc143bb93c745b82db358392b123661e0 (diff) |
New upstream version 9.0.9+dfsg
Diffstat (limited to 'lisp/org-element.el')
-rw-r--r-- | lisp/org-element.el | 278 |
1 files changed, 120 insertions, 158 deletions
diff --git a/lisp/org-element.el b/lisp/org-element.el index b86244e..41b4a3a 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -1,6 +1,6 @@ ;;; org-element.el --- Parser for Org Syntax -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2016 Free Software Foundation, Inc. +;; Copyright (C) 2012-2017 Free Software Foundation, Inc. ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com> ;; Keywords: outlines, hypermedia, calendar, wp @@ -22,79 +22,21 @@ ;;; Commentary: ;; -;; Org syntax can be divided into three categories: "Greater -;; elements", "Elements" and "Objects". +;; See <http://orgmode.org/worg/dev/org-syntax.html> for details about +;; Org syntax. ;; -;; 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 (`clock', `headline', `inlinetask', `item', -;; `planning', `property-drawer', `node-property', `section' and -;; `table-row' 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. Almost -;; all affiliated keywords are referenced in -;; `org-element-affiliated-keywords'; the others are export attributes -;; and start with "ATTR_" prefix. -;; -;; 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', `property-drawer', `quote-block', `section' -;; and `special-block'. -;; -;; Other element types are: `babel-call', `clock', `comment', -;; `comment-block', `diary-sexp', `example-block', `export-block', -;; `fixed-width', `horizontal-rule', `keyword', `latex-environment', -;; `node-property', `paragraph', `planning', `src-block', `table', -;; `table-row' and `verse-block'. Among them, `paragraph' 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: `bold', `code', -;; `entity', `export-snippet', `footnote-reference', -;; `inline-babel-call', `inline-src-block', `italic', -;; `latex-fragment', `line-break', `link', `macro', `radio-target', -;; `statistics-cookie', `strike-through', `subscript', `superscript', -;; `table-cell', `target', `timestamp', `underline' and `verbatim'. -;; -;; Some elements also have special properties whose value can hold -;; objects themselves (e.g. an item tag or a 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, four are shared by all types: `:begin' and `:end', which -;; refer to the beginning and ending buffer positions of the -;; considered element or object, `:post-blank', which holds the number -;; of blank lines, or white spaces, at its end and `:parent' which -;; refers to the element or object containing it. Greater elements, -;; elements and objects containing objects will also have -;; `:contents-begin' and `:contents-end' properties to delimit -;; contents. Eventually, All elements have a `:post-affiliated' -;; property referring to the buffer position after all affiliated -;; keywords, if any, or to their beginning position otherwise. -;; -;; At the lowest level, a `:parent' property is also attached to any -;; string, as a text property. -;; -;; Lisp-wise, an element or an object can be represented as a list. +;; Lisp-wise, a syntax object can be represented as a list. ;; It follows the pattern (TYPE PROPERTIES CONTENTS), where: -;; TYPE is a symbol describing the Org element or object. +;; TYPE is a symbol describing the object. ;; PROPERTIES is the property list attached to it. See docstring of -;; appropriate parsing function to get an exhaustive -;; list. -;; CONTENTS is a list of elements, objects or raw strings contained -;; in the current element or object, when applicable. +;; appropriate parsing function to get an exhaustive list. +;; CONTENTS is a list of syntax objects or raw strings contained +;; in the current object, when applicable. ;; -;; An Org buffer is a nested list of such elements and objects, whose -;; type is `org-data' and properties is nil. +;; For the whole document, TYPE is `org-data' and PROPERTIES is nil. ;; -;; The first part of this file defines Org syntax, while the second -;; one provide accessors and setters functions. +;; The first part of this file defines constants for the Org syntax, +;; while the second one provide accessors and setters functions. ;; ;; The next part implements a parser and an interpreter for each ;; element and object type in Org syntax. @@ -450,7 +392,7 @@ past the brackets." ;; There is `org-element-put-property', `org-element-set-contents'. ;; These low-level functions are useful to build a parse tree. ;; -;; `org-element-adopt-element', `org-element-set-element', +;; `org-element-adopt-elements', `org-element-set-element', ;; `org-element-extract-element' and `org-element-insert-before' are ;; high-level functions useful to modify a parse tree. ;; @@ -593,16 +535,15 @@ Parse tree is modified by side effect." (specialp (and (not property) (eq siblings parent) (eq (car parent) location)))) - ;; Install ELEMENT at the appropriate POSITION within SIBLINGS. + ;; Install ELEMENT at the appropriate LOCATION within SIBLINGS. (cond (specialp) ((or (null siblings) (eq (car siblings) location)) (push element siblings)) ((null location) (nconc siblings (list element))) - (t (let ((previous (cadr (memq location (reverse siblings))))) - (if (not previous) - (error "No location found to insert element") - (let ((next (memq previous siblings))) - (setcdr next (cons element (cdr next)))))))) + (t + (let ((index (cl-position location siblings))) + (unless index (error "No location found to insert element")) + (push element (cdr (nthcdr (1- index) siblings)))))) ;; Store SIBLINGS at appropriate place in parse tree. (cond (specialp (setcdr parent (copy-sequence parent)) (setcar parent element)) @@ -850,7 +791,7 @@ CONTENTS is the contents of the element." (format "#+BEGIN: %s%s\n%s#+END:" (org-element-property :block-name dynamic-block) (let ((args (org-element-property :arguments dynamic-block))) - (and args (concat " " args))) + (if args (concat " " args) "")) contents)) @@ -880,14 +821,14 @@ Assume point is at the beginning of the footnote definition." (match-string-no-properties 1))) (begin (car affiliated)) (post-affiliated (point)) - (ending + (end (save-excursion (end-of-line) (cond ((not (re-search-forward org-element--footnote-separator limit t)) limit) - ((eq (char-after (match-beginning 0)) ?\[) + ((eq ?\[ (char-after (match-beginning 0))) ;; At a new footnote definition, make sure we end ;; before any affiliated keyword above. (forward-line -1) @@ -895,26 +836,27 @@ Assume point is at the beginning of the footnote definition." (looking-at-p org-element--affiliated-re)) (forward-line -1)) (line-beginning-position 2)) - (t (match-beginning 0))))) + ((eq ?* (char-after (match-beginning 0))) (match-beginning 0)) + (t (skip-chars-forward " \r\t\n" limit) + (if (= limit (point)) limit (line-beginning-position)))))) (contents-begin - (progn - (search-forward "]") - (skip-chars-forward " \r\t\n" ending) - (cond ((= (point) ending) nil) - ((= (line-beginning-position) post-affiliated) (point)) - (t (line-beginning-position))))) - (contents-end (and contents-begin ending)) - (end (progn (goto-char ending) - (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) + (progn (search-forward "]") + (skip-chars-forward " \r\t\n" end) + (cond ((= (point) end) nil) + ((= (line-beginning-position) post-affiliated) (point)) + (t (line-beginning-position))))) + (contents-end + (progn (goto-char end) + (skip-chars-backward " \r\t\n") + (line-beginning-position 2)))) (list 'footnote-definition (nconc (list :label label :begin begin :end end :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines ending end) + :contents-end (and contents-begin contents-end) + :post-blank (count-lines contents-end end) :post-affiliated post-affiliated) (cdr affiliated)))))) @@ -1696,30 +1638,37 @@ containing `:call', `:inside-header', `:arguments', (save-excursion (let* ((begin (car affiliated)) (post-affiliated (point)) - (value (progn (search-forward ":" nil t) + (before-blank (line-beginning-position 2)) + (value (progn (search-forward ":" before-blank t) + (skip-chars-forward " \t") (org-trim (buffer-substring-no-properties (point) (line-end-position))))) - (pos-before-blank (progn (forward-line) (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position)))) - (valid-value - (string-match - "\\([^()\n]+?\\)\\(?:\\[\\(.*?\\)\\]\\)?(\\(.*\\))[ \t]*\\(.*\\)" - value))) + (call + (or (org-string-nw-p + (buffer-substring-no-properties + (point) (progn (skip-chars-forward "^[]()" before-blank) + (point)))))) + (inside-header (org-element--parse-paired-brackets ?\[)) + (arguments (org-string-nw-p + (org-element--parse-paired-brackets ?\())) + (end-header + (org-string-nw-p + (org-trim + (buffer-substring-no-properties (point) (line-end-position))))) + (end (progn (forward-line) + (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) (list 'babel-call (nconc - (list :call (and valid-value (match-string 1 value)) - :inside-header (and valid-value - (org-string-nw-p (match-string 2 value))) - :arguments (and valid-value - (org-string-nw-p (match-string 3 value))) - :end-header (and valid-value - (org-string-nw-p (match-string 4 value))) + (list :call call + :inside-header inside-header + :arguments arguments + :end-header end-header :begin begin :end end :value value - :post-blank (count-lines pos-before-blank end) + :post-blank (count-lines before-blank end) :post-affiliated post-affiliated) (cdr affiliated)))))) @@ -3041,7 +2990,8 @@ Assume point is at the beginning of the LaTeX fragment." (search-forward "$" nil t 2) (not (memq (char-before (match-beginning 0)) '(?\s ?\t ?\n ?, ?.))) - (looking-at "\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|$\\)") + (looking-at-p + "\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|'\\|$\\)") (point))) (pcase (char-after (1+ (point))) (?\( (search-forward "\\)" nil t)) @@ -3196,7 +3146,7 @@ Assume point is at the beginning of the link." (when (string-match "::\\(.*\\)\\'" path) (setq search-option (match-string 1 path)) (setq path (replace-match "" nil nil path))) - (setq path (replace-regexp-in-string "\\`///+" "/" path))) + (setq path (replace-regexp-in-string "\\`///*\\(.:\\)?/" "\\1/" path))) ;; Translate link, if `org-link-translation-function' is set. (let ((trans (and (functionp org-link-translation-function) (funcall org-link-translation-function type path)))) @@ -4031,7 +3981,7 @@ Optional argument GRANULARITY determines the depth of the recursion. It can be set to the following symbols: `headline' Only parse headlines. -`greater-element' Don't recurse into greater elements excepted +`greater-element' Don't recurse into greater elements except headlines and sections. Thus, elements parsed are the top-level ones. `element' Parse everything but objects and plain text. @@ -4040,7 +3990,7 @@ recursion. It can be set to the following symbols: When VISIBLE-ONLY is non-nil, don't parse contents of hidden elements. -An element or an objects is represented as a list with the +An element or object is represented as a list with the pattern (TYPE PROPERTIES CONTENTS), where : TYPE is a symbol describing the element or object. See @@ -4367,6 +4317,10 @@ to an appropriate container (e.g., a paragraph)." (if (memq 'table-cell restriction) (org-element-table-cell-parser) (let* ((start (point)) (limit + ;; Object regexp sometimes needs to have a peek at + ;; a character ahead. Therefore, when there is a hard + ;; limit, make it one more than the true beginning of the + ;; radio target. (save-excursion (cond ((not org-target-link-regexp) nil) ((not (memq 'link restriction)) nil) @@ -4382,8 +4336,8 @@ to an appropriate container (e.g., a paragraph)." ((and (= start (1+ (line-beginning-position))) (= start (match-end 1))) (and (re-search-forward org-target-link-regexp nil t) - (match-beginning 1))) - (t (match-beginning 1))))) + (1+ (match-beginning 1)))) + (t (1+ (match-beginning 1)))))) found) (save-excursion (while (and (not found) @@ -4457,7 +4411,8 @@ to an appropriate container (e.g., a paragraph)." (org-element-link-parser))))))) (or (eobp) (forward-char)))) (cond (found) - (limit (org-element-link-parser)) ;radio link + (limit (forward-char -1) + (org-element-link-parser)) ;radio link (t nil)))))) (defun org-element--parse-objects (beg end acc restriction &optional parent) @@ -4677,47 +4632,51 @@ indentation removed from its contents." ;; the beginnings of the contents or right after a line ;; break. (lambda (blob first-flag min-ind) - (catch 'zero - (dolist (datum (org-element-contents blob) min-ind) - (when first-flag - (setq first-flag nil) - (cond - ;; Objects cannot start with spaces: in this - ;; case, indentation is 0. - ((not (stringp datum)) (throw 'zero 0)) - ((not (string-match - "\\`\\([ \t]+\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum)) - (throw 'zero 0)) - ((equal (match-string 2 datum) "\n") - (put-text-property - (match-beginning 1) (match-end 1) 'org-ind 'empty datum)) - (t - (let ((i (string-width (match-string 1 datum)))) - (put-text-property - (match-beginning 1) (match-end 1) 'org-ind i datum) - (setq min-ind (min i min-ind)))))) + (dolist (datum (org-element-contents blob) min-ind) + (when first-flag + (setq first-flag nil) (cond - ((stringp datum) - (let ((s 0)) - (while (string-match - "\n\\([ \t]+\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum s) - (setq s (match-end 1)) - (if (equal (match-string 2 datum) "\n") - (put-text-property - (match-beginning 1) (match-end 1) - 'org-ind 'empty - datum) - (let ((i (string-width (match-string 1 datum)))) - (put-text-property - (match-beginning 1) (match-end 1) 'org-ind i datum) - (setq min-ind (min i min-ind))))))) - ((eq (org-element-type datum) 'line-break) - (setq first-flag t)) - ((memq (org-element-type datum) org-element-recursive-objects) - (setq min-ind - (funcall find-min-ind datum first-flag min-ind)))))))) - (min-ind (funcall find-min-ind - element (not ignore-first) most-positive-fixnum))) + ;; Objects cannot start with spaces: in this + ;; case, indentation is 0. + ((not (stringp datum)) (throw :zero 0)) + ((not (string-match + "\\`\\([ \t]+\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum)) + (throw :zero 0)) + ((equal (match-string 2 datum) "\n") + (put-text-property + (match-beginning 1) (match-end 1) 'org-ind 'empty datum)) + (t + (let ((i (string-width (match-string 1 datum)))) + (put-text-property + (match-beginning 1) (match-end 1) 'org-ind i datum) + (setq min-ind (min i min-ind)))))) + (cond + ((stringp datum) + (let ((s 0)) + (while (string-match + "\n\\([ \t]*\\)\\([^ \t\n]\\|\n\\|\\'\\)" datum s) + (setq s (match-end 1)) + (cond + ((equal (match-string 1 datum) "") + (unless (member (match-string 2 datum) '("" "\n")) + (throw :zero 0))) + ((equal (match-string 2 datum) "\n") + (put-text-property (match-beginning 1) (match-end 1) + 'org-ind 'empty datum)) + (t + (let ((i (string-width (match-string 1 datum)))) + (put-text-property (match-beginning 1) (match-end 1) + 'org-ind i datum) + (setq min-ind (min i min-ind)))))))) + ((eq (org-element-type datum) 'line-break) + (setq first-flag t)) + ((memq (org-element-type datum) org-element-recursive-objects) + (setq min-ind + (funcall find-min-ind datum first-flag min-ind))))))) + (min-ind + (catch :zero + (funcall find-min-ind + element (not ignore-first) most-positive-fixnum)))) (if (or (zerop min-ind) (= min-ind most-positive-fixnum)) element ;; Build ELEMENT back, replacing each string with the same ;; string minus common indentation. @@ -4800,9 +4759,12 @@ indentation removed from its contents." ;; `org-element--cache-objects'. -(defvar org-element-use-cache t - "Non nil when Org parser should cache its results. -This is mostly for debugging purpose.") +(defvar org-element-use-cache nil + "Non-nil when Org parser should cache its results. + +WARNING: for the time being, using cache sometimes triggers +freezes. Therefore, it is disabled by default. Activate it if +you want to help debugging the issue.") (defvar org-element-cache-sync-idle-time 0.6 "Length, in seconds, of idle time before syncing cache.") |