From bc1d6aadfd0f0a84f5dcc4681370b14b5d3fbb1c Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Mon, 26 Jun 2017 22:07:05 +0200 Subject: [PATCH] org-element: Fix $...$ parser error * lisp/org-element.el (org-element-latex-fragment-parser): Also check border character right after opening "$" sign. * testing/lisp/test-org-element.el (test-org-element/latex-fragment-parser): Add tests. Reported-by: thomas --- lisp/org-element.el | 33 ++++++++++++++++------------- testing/lisp/test-org-element.el | 36 +++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/lisp/org-element.el b/lisp/org-element.el index 41b4a3ac7..f4fe6447a 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -2983,16 +2983,8 @@ Assume point is at the beginning of the LaTeX fragment." (save-excursion (let* ((begin (point)) (after-fragment - (if (eq (char-after) ?$) - (if (eq (char-after (1+ (point))) ?$) - (search-forward "$$" nil t 2) - (and (not (eq (char-before) ?$)) - (search-forward "$" nil t 2) - (not (memq (char-before (match-beginning 0)) - '(?\s ?\t ?\n ?, ?.))) - (looking-at-p - "\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|'\\|$\\)") - (point))) + (cond + ((not (eq ?$ (char-after))) (pcase (char-after (1+ (point))) (?\( (search-forward "\\)" nil t)) (?\[ (search-forward "\\]" nil t)) @@ -3000,10 +2992,23 @@ Assume point is at the beginning of the LaTeX fragment." ;; Macro. (and (looking-at "\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\ \\|\\({[^{}\n]*}\\)\\)*") - (match-end 0)))))) - (post-blank (if (not after-fragment) (throw 'no-object nil) - (goto-char after-fragment) - (skip-chars-forward " \t"))) + (match-end 0))))) + ((eq ?$ (char-after (1+ (point)))) + (search-forward "$$" nil t 2)) + (t + (and (not (eq ?$ (char-before))) + (not (memq (char-after (1+ (point))) + '(?\s ?\t ?\n ?, ?. ?\;))) + (search-forward "$" nil t 2) + (not (memq (char-before (match-beginning 0)) + '(?\s ?\t ?\n ?, ?.))) + (looking-at-p + "\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|'\\|$\\)") + (point))))) + (post-blank + (if (not after-fragment) (throw 'no-object nil) + (goto-char after-fragment) + (skip-chars-forward " \t"))) (end (point))) (list 'latex-fragment (list :value (buffer-substring-no-properties begin after-fragment) diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index ac08faf35..7b03a27c9 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -1551,10 +1551,16 @@ e^{i\\pi}+1=0 (ert-deftest test-org-element/latex-fragment-parser () "Test `latex-fragment' parser." + ;; Basic $...$ test. (should (eq 'latex-fragment (org-test-with-temp-text "$a$" (org-element-type (org-element-context))))) + ;; Test valid characters after $...$ construct. + (should-not + (eq 'latex-fragment + (org-test-with-temp-text "$a$a" + (org-element-type (org-element-context))))) (should (eq 'latex-fragment (org-test-with-temp-text "$a$!" @@ -1579,18 +1585,46 @@ e^{i\\pi}+1=0 (eq 'latex-fragment (org-test-with-temp-text "$a$'" (org-element-type (org-element-context))))) + ;; Test forbidden characters inside $...$. (should-not (eq 'latex-fragment - (org-test-with-temp-text "$a$a" + (org-test-with-temp-text "$.a$" (org-element-type (org-element-context))))) + (should-not + (eq 'latex-fragment + (org-test-with-temp-text "$,a$" + (org-element-type (org-element-context))))) + (should-not + (eq 'latex-fragment + (org-test-with-temp-text "$;a$" + (org-element-type (org-element-context))))) + (should-not + (eq 'latex-fragment + (org-test-with-temp-text "$ a$" + (org-element-type (org-element-context))))) + (should-not + (eq 'latex-fragment + (org-test-with-temp-text "$a.$" + (org-element-type (org-element-context))))) + (should-not + (eq 'latex-fragment + (org-test-with-temp-text "$a,$" + (org-element-type (org-element-context))))) + (should-not + (eq 'latex-fragment + (org-test-with-temp-text "$a $" + (org-element-type (org-element-context))))) + ;; Test $$...$$. (should (eq 'latex-fragment (org-test-with-temp-text "$$a$$" (org-element-type (org-element-context))))) + ;; Test \(...\). (should (eq 'latex-fragment (org-test-with-temp-text "\\(a\\)" (org-element-type (org-element-context))))) + ;; Test \[...\]. (should (eq 'latex-fragment (org-test-with-temp-text "\\[a\\]"