summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2015-02-15 13:33:25 +0100
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2015-02-15 13:33:25 +0100
commit13938b87c2f9b6b5d20787853368aeeed4c371b9 (patch)
treee6db0d5627c62a33a1362c7c460d0735f893bfa0
parent836d9db8a9fe19d790902a1bda7beafb225eb192 (diff)
downloadorg-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.el63
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.