From 34bbb39454f7a3f7a58432250bd4b127d06437dc Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Sun, 9 Nov 2014 23:55:27 +0100 Subject: [PATCH] Fix parser wrt to defcustom syntax related changes * lisp/org-element.el (org-element-paragraph-separate, org-element--object-regexp): Turn defconst into defvar. (org-element--set-regexps): Properly set previous variables. (org-element-update-syntax): New function. * lisp/org-list.el (org-plain-list-ordered-item-terminator, org-list-allow-alphabetical): Call new function whenever these variables are modified and Org is already loaded. * lisp/org.el (org-add-link-type): Call new function since a new link type triggers a rebuild of syntax regexps, possibly invalidating cache in all Org buffers. Reported-by: Christopher Dannheim --- lisp/org-element.el | 161 +++++++++++++++++++++++++++++----------------------- lisp/org-list.el | 19 +++++-- lisp/org.el | 3 +- 3 files changed, 104 insertions(+), 79 deletions(-) diff --git a/lisp/org-element.el b/lisp/org-element.el index b669de733..b0fbbe2a7 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -128,46 +128,100 @@ ;; along with the affiliated keywords recognized. Also set up ;; restrictions on recursive objects combinations. ;; -;; These variables really act as a control center for the parsing -;; process. - -(defconst org-element-paragraph-separate - (concat "^\\(?:" - ;; Headlines, inlinetasks. - org-outline-regexp "\\|" - ;; Footnote definitions. - "\\[\\(?:[0-9]+\\|fn:[-_[:word:]]+\\)\\]" "\\|" - ;; Diary sexps. - "%%(" "\\|" - "[ \t]*\\(?:" - ;; Empty lines. - "$" "\\|" - ;; Tables (any type). - "\\(?:|\\|\\+-[-+]\\)" "\\|" - ;; Blocks (any type), Babel calls and keywords. Note: this - ;; is only an indication and need some thorough check. - "#\\(?:[+ ]\\|$\\)" "\\|" - ;; Drawers (any type) and fixed-width areas. This is also - ;; only an indication. - ":" "\\|" - ;; Horizontal rules. - "-\\{5,\\}[ \t]*$" "\\|" - ;; LaTeX environments. - "\\\\begin{\\([A-Za-z0-9]+\\*?\\)}" "\\|" - ;; Clock lines. - (regexp-quote org-clock-string) "\\|" - ;; Lists. - (let ((term (case org-plain-list-ordered-item-terminator - (?\) ")") (?. "\\.") (otherwise "[.)]"))) - (alpha (and org-list-allow-alphabetical "\\|[A-Za-z]"))) - (concat "\\(?:[-+*]\\|\\(?:[0-9]+" alpha "\\)" term "\\)" - "\\(?:[ \t]\\|$\\)")) - "\\)\\)") +;; `org-element-update-syntax' builds proper syntax regexps according +;; to current setup. + +(defvar org-element-paragraph-separate nil "Regexp to separate paragraphs in an Org buffer. In the case of lines starting with \"#\" and \":\", this regexp is not sufficient to know if point is at a paragraph ending. See `org-element-paragraph-parser' for more information.") +(defvar org-element--object-regexp nil + "Regexp possibly matching the beginning of an object. +This regexp allows false positives. Dedicated parser (e.g., +`org-export-bold-parser') will take care of further filtering. +Radio links are not matched by this regexp, as they are treated +specially in `org-element--object-lex'.") + +(defun org-element--set-regexps () + "Build variable syntax regexps." + (setq org-element-paragraph-separate + (concat "^\\(?:" + ;; Headlines, inlinetasks. + org-outline-regexp "\\|" + ;; Footnote definitions. + "\\[\\(?:[0-9]+\\|fn:[-_[:word:]]+\\)\\]" "\\|" + ;; Diary sexps. + "%%(" "\\|" + "[ \t]*\\(?:" + ;; Empty lines. + "$" "\\|" + ;; Tables (any type). + "\\(?:|\\|\\+-[-+]\\)" "\\|" + ;; Blocks (any type), Babel calls and keywords. This + ;; is only an indication and need some thorough check. + "#\\(?:[+ ]\\|$\\)" "\\|" + ;; Drawers (any type) and fixed-width areas. This is + ;; also only an indication. + ":" "\\|" + ;; Horizontal rules. + "-\\{5,\\}[ \t]*$" "\\|" + ;; LaTeX environments. + "\\\\begin{\\([A-Za-z0-9]+\\*?\\)}" "\\|" + ;; Clock lines. + (regexp-quote org-clock-string) "\\|" + ;; Lists. + (let ((term (case org-plain-list-ordered-item-terminator + (?\) ")") (?. "\\.") (otherwise "[.)]"))) + (alpha (and org-list-allow-alphabetical "\\|[A-Za-z]"))) + (concat "\\(?:[-+*]\\|\\(?:[0-9]+" alpha "\\)" term "\\)" + "\\(?:[ \t]\\|$\\)")) + "\\)\\)") + org-element--object-regexp + (mapconcat #'identity + (let ((link-types (regexp-opt org-link-types))) + (list + ;; Sub/superscript. + "\\(?:[_^][-{(*+.,[:alnum:]]\\)" + ;; Bold, code, italic, strike-through, underline + ;; and verbatim. + (concat "[*~=+_/]" + (format "[^%s]" + (nth 2 org-emphasis-regexp-components))) + ;; Plain links. + (concat "\\<" link-types ":") + ;; Objects starting with "[": regular link, + ;; footnote reference, statistics cookie, + ;; timestamp (inactive). + "\\[\\(?:fn:\\|\\(?:[0-9]\\|\\(?:%\\|/[0-9]*\\)\\]\\)\\|\\[\\)" + ;; Objects starting with "@": export snippets. + "@@" + ;; Objects starting with "{": macro. + "{{{" + ;; Objects starting with "<" : timestamp + ;; (active, diary), target, radio target and + ;; angular links. + (concat "<\\(?:%%\\|<\\|[0-9]\\|" link-types "\\)") + ;; Objects starting with "$": latex fragment. + "\\$" + ;; Objects starting with "\": line break, + ;; entity, latex fragment. + "\\\\\\(?:[a-zA-Z[(]\\|\\\\[ \t]*$\\)" + ;; Objects starting with raw text: inline Babel + ;; source block, inline Babel call. + "\\(?:call\\|src\\)_")) + "\\|"))) + +(org-element--set-regexps) + +;;;###autoload +(defun org-element-update-syntax () + "Update parser internals." + (interactive) + (org-element--set-regexps) + (org-element-cache-reset 'all)) + (defconst org-element-all-elements '(babel-call center-block clock comment comment-block diary-sexp drawer dynamic-block example-block export-block fixed-width @@ -4130,43 +4184,6 @@ Elements are accumulated into ACC." ;; Return result. acc)) -(defconst org-element--object-regexp - (mapconcat #'identity - (let ((link-types (regexp-opt org-link-types))) - (list - ;; Sub/superscript. - "\\(?:[_^][-{(*+.,[:alnum:]]\\)" - ;; Bold, code, italic, strike-through, underline and - ;; verbatim. - (concat "[*~=+_/]" - (format "[^%s]" (nth 2 org-emphasis-regexp-components))) - ;; Plain links. - (concat "\\<" link-types ":") - ;; Objects starting with "[": regular link, footnote - ;; reference, statistics cookie, timestamp (inactive). - "\\[\\(?:fn:\\|\\(?:[0-9]\\|\\(?:%\\|/[0-9]*\\)\\]\\)\\|\\[\\)" - ;; Objects starting with "@": export snippets. - "@@" - ;; Objects starting with "{": macro. - "{{{" - ;; Objects starting with "<" : timestamp (active, - ;; diary), target, radio target and angular links. - (concat "<\\(?:%%\\|<\\|[0-9]\\|" link-types "\\)") - ;; Objects starting with "$": latex fragment. - "\\$" - ;; Objects starting with "\": line break, entity, - ;; latex fragment. - "\\\\\\(?:[a-zA-Z[(]\\|\\\\[ \t]*$\\)" - ;; Objects starting with raw text: inline Babel - ;; source block, inline Babel call. - "\\(?:call\\|src\\)_")) - "\\|") - "Regexp possibly matching the beginning of an object. -This regexp allows false positives. Dedicated parser (e.g., -`org-export-bold-parser') will take care of further filtering. -Radio links are not matched by this regexp, as they are treated -specially in `org-element--object-lex'.") - (defun org-element--object-lex (restriction) "Return next object in current buffer or nil. RESTRICTION is a list of object types, as symbols, that should be diff --git a/lisp/org-list.el b/lisp/org-list.el index b1d47c995..0dbe590f3 100644 --- a/lisp/org-list.el +++ b/lisp/org-list.el @@ -211,11 +211,19 @@ into (defcustom org-plain-list-ordered-item-terminator t "The character that makes a line with leading number an ordered list item. -Valid values are ?. and ?\). To get both terminators, use t." +Valid values are ?. and ?\). To get both terminators, use t. + +This variable needs to be set before org.el is loaded. If you +need to make a change while Emacs is running, use the customize +interface or run the following code after updating it: + + \\[org-element-update-syntax]" :group 'org-plain-lists :type '(choice (const :tag "dot like in \"2.\"" ?.) (const :tag "paren like in \"2)\"" ?\)) - (const :tag "both" t))) + (const :tag "both" t)) + :set (lambda (var val) (set var val) + (when (featurep 'org-element) (org-element-update-syntax)))) (define-obsolete-variable-alias 'org-alphabetical-lists 'org-list-allow-alphabetical "24.4") ; Since 8.0 @@ -230,13 +238,12 @@ This variable needs to be set before org.el is loaded. If you need to make a change while Emacs is running, use the customize interface or run the following code after updating it: - \(when (featurep 'org-element) (load \"org-element\" t t))" + \\[org-element-update-syntax]" :group 'org-plain-lists :version "24.1" :type 'boolean - :set (lambda (var val) - (when (featurep 'org-element) (load "org-element" t t)) - (set var val))) + :set (lambda (var val) (set var val) + (when (featurep 'org-element) (org-element-update-syntax)))) (defcustom org-list-two-spaces-after-bullet-regexp nil "A regular expression matching bullets that should have 2 spaces after them. diff --git a/lisp/org.el b/lisp/org.el index d76d89d76..2fc2404cf 100755 --- a/lisp/org.el +++ b/lisp/org.el @@ -9665,11 +9665,12 @@ depending on the format. The return value will be put literally into the exported file. If the return value is nil, this means Org should do what it normally does with links which do not have EXPORT defined. -Org-mode has a built-in default for exporting links. If you are happy with +Org mode has a built-in default for exporting links. If you are happy with this default, there is no need to define an export function for the link type. For a simple example of an export function, see `org-bbdb.el'." (add-to-list 'org-link-types type t) (org-make-link-regexps) + (org-element-update-syntax) (if (assoc type org-link-protocols) (setcdr (assoc type org-link-protocols) (list follow export)) (push (list type follow export) org-link-protocols))) -- 2.11.4.GIT