diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2015-02-15 13:33:25 +0100 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2015-02-15 13:33:25 +0100 |
commit | 13938b87c2f9b6b5d20787853368aeeed4c371b9 (patch) | |
tree | e6db0d5627c62a33a1362c7c460d0735f893bfa0 | |
parent | 836d9db8a9fe19d790902a1bda7beafb225eb192 (diff) | |
download | org-mode-13938b87c2f9b6b5d20787853368aeeed4c371b9.tar.gz |
org-element: Faster inline footnotes parsing
* lisp/org-element.el (org-element--pair-square-table): New variable.
(org-element-footnote-reference-parser): Use new variable.
-rw-r--r-- | lisp/org-element.el | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/lisp/org-element.el b/lisp/org-element.el index 8f2d7a4..cb6f36a 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -400,6 +400,15 @@ still has an entry since one of its properties (`:title') does.") (item . :tag)) "Alist between element types and location of secondary value.") +(defconst org-element--pair-square-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?\[ "(]" table) + (modify-syntax-entry ?\] ")[" table) + (dolist (char '(?\{ ?\} ?\( ?\) ?\< ?\>) table) + (modify-syntax-entry char " " table))) + "Table used internally to pair only square brackets. +Other brackets are treated as spaces.") + ;;; Accessors and Setters @@ -2792,35 +2801,31 @@ When at a footnote reference, return a list whose car is `footnote-reference' and cdr a plist with `:label', `:type', `:begin', `:end', `:content-begin', `:contents-end' and `:post-blank' as keywords. Otherwise, return nil." - (catch 'no-object - (when (looking-at org-footnote-re) - (save-excursion - (let* ((begin (point)) - (label - (or (org-match-string-no-properties 2) - (org-match-string-no-properties 3) - (and (match-string 1) - (concat "fn:" (org-match-string-no-properties 1))))) - (type (if (or (not label) (match-string 1)) 'inline 'standard)) - (inner-begin (match-end 0)) - (inner-end - (let ((count 1)) - (forward-char) - (while (and (> count 0) (re-search-forward "[][]" nil t)) - (if (equal (match-string 0) "[") (incf count) (decf count))) - (unless (zerop count) (throw 'no-object nil)) - (1- (point)))) - (post-blank (progn (goto-char (1+ inner-end)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'footnote-reference - (list :label label - :type type - :begin begin - :end end - :contents-begin (and (eq type 'inline) inner-begin) - :contents-end (and (eq type 'inline) inner-end) - :post-blank post-blank))))))) + (when (looking-at org-footnote-re) + (let ((closing (with-syntax-table org-element--pair-square-table + (ignore-errors (scan-lists (point) 1 0))))) + (when closing + (save-excursion + (let* ((begin (point)) + (label + (or (org-match-string-no-properties 2) + (org-match-string-no-properties 3) + (and (match-string 1) + (concat "fn:" (org-match-string-no-properties 1))))) + (type (if (or (not label) (match-string 1)) 'inline 'standard)) + (inner-begin (match-end 0)) + (inner-end (1- closing)) + (post-blank (progn (goto-char closing) + (skip-chars-forward " \t"))) + (end (point))) + (list 'footnote-reference + (list :label label + :type type + :begin begin + :end end + :contents-begin (and (eq type 'inline) inner-begin) + :contents-end (and (eq type 'inline) inner-end) + :post-blank post-blank)))))))) (defun org-element-footnote-reference-interpreter (footnote-reference contents) "Interpret FOOTNOTE-REFERENCE object as Org syntax. |