From 0d616d65a9b6175c9e7ef225f4baff3d185b5d5b Mon Sep 17 00:00:00 2001 From: Aaron Ecay Date: Sun, 15 Dec 2013 21:30:27 -0500 Subject: [PATCH] org-element: use brackets to disambiguate subscript/underline * lisp/org-element.el (org-element--get-next-object-candidates): use brackets to disambiguate subscript/underline In an org-syntax string like 1 or 2 below, both subscript and underline are possible interpretations. This patch uses the presence of brackets to disambiguate these cases, that is, 1 is interpreted as an underline whereas 2 is a subscript (followed by plain-text _) 1: '_foo_ 2: '_{foo}_ This change does not touch the in-buffer highlighting, which will show underline or subscript in these cases depending on the org-use-sub-superscripts variable, which is (close to) deprecated (). --- lisp/org-element.el | 64 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/lisp/org-element.el b/lisp/org-element.el index 089ecfb..7082562 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -4424,26 +4424,50 @@ RESTRICTION should be looked after. Return value is an alist whose CAR is the object type and CDR its beginning position." - (delq - nil - (if (eq objects 'initial) - ;; When searching for the first time, look for every successor - ;; allowed in RESTRICTION. - (mapcar - (lambda (res) - (funcall (intern (format "org-element-%s-successor" res)))) - restriction) - ;; Focus on objects returned during last search. Keep those - ;; still after point. Search again objects before it. - (mapcar - (lambda (obj) - (if (>= (cdr obj) (point)) obj - (let* ((type (car obj)) - (succ (or (cdr (assq type org-element-object-successor-alist)) - type))) - (and succ - (funcall (intern (format "org-element-%s-successor" succ))))))) - objects)))) + (let ((res + (delq + nil + (if (eq objects 'initial) + ;; When searching for the first time, look for every successor + ;; allowed in RESTRICTION. + (mapcar + (lambda (res) + (funcall (intern (format "org-element-%s-successor" res)))) + restriction) + ;; Focus on objects returned during last search. Keep those + ;; still after point. Search again objects before it. + (mapcar + (lambda (obj) + (if (>= (cdr obj) (point)) obj + (let* ((type (car obj)) + (succ (or (cdr (assq type org-element-object-successor-alist)) + type))) + (and succ + (funcall (intern (format "org-element-%s-successor" succ))))))) + objects))))) + ;; To disambiguate between underlines and subscripts, which may + ;; both match at the same position, the heuristic is used that if + ;; there are brackets, the expression is a subscript, whereas + ;; otherwise it is an underline. Thus: + ;; '_foo_ parses as (plain-text "'") (underline "foo") + ;; whereas '_{foo}_ parses as + ;; (plain-text "'") (subscript "foo") (plain-text "_") + (setq res + (sort res + (lambda (a b) + (if (and (= (cdr a) (cdr b)) + (memq 'underline (list (car a) (car b))) + (memq 'subscript (list (car a) (car b)))) + (save-excursion + (goto-char (cdr a)) + (let ((bracketsp + (org-element-property + :use-brackets-p (org-element-subscript-parser)))) + (if (eq (car a) 'underline) + (not bracketsp) + bracketsp))) + (< (cdr a) (cdr b)))))) + res)) -- 1.8.5.1