Browse Source

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 <thomas@friendlyvillagers.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/114285>
Nicolas Goaziou 2 years ago
parent
commit
bc1d6aadfd
2 changed files with 54 additions and 15 deletions
  1. 19 14
      lisp/org-element.el
  2. 35 1
      testing/lisp/test-org-element.el

+ 19 - 14
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)

+ 35 - 1
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\\]"