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 <ch.dannheim@gmail.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/92487>
This commit is contained in:
Nicolas Goaziou 2014-11-09 23:55:27 +01:00
parent a95cfebbc3
commit 34bbb39454
3 changed files with 103 additions and 78 deletions

View File

@ -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.
;; `org-element-update-syntax' builds proper syntax regexps according
;; to current setup.
(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]\\|$\\)"))
"\\)\\)")
(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

View File

@ -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.

View File

@ -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)))