Subject: bug#22472: 25.0.50; org-mode: latex fragments can't be un-rendered after a revert

From: Nicolas Goaziou <[email-masked]>
Date: Thu, 04 Feb 2016 09:35:13 +0100

Hello,

Dima Kogan <[email-masked]> writes:

> Dima Kogan <[email-masked]> writes:
>
>> So a revert puts emacs into an inconsistent state, where the equation is
>> rendered, but the source may or may not be there anymore, and where org
>> doesn't think there's a render there at all.
>
> This looks like an issue in emacs, rather than org. I think the right
> solution is for a revert to delete all overlays. I.e.:
>
>   (add-hook 'before-revert-hook 'delete-all-overlays)
>
> This generally works, but is unideal because:
>
>
> 1. We'd want this to apply to org buffers, not to all emacs buffers
>
> 2. This works only if revert-buffer-function is nil or
> revert-buffer--default.
>
>
> If we don't want to delete overlays on revert, then
> org-latex-fragment-image-overlays must be properly set to reflect the
> overlay state, AND emacs should make sure the overlay is still valid on
> revert.
>
> Any particular thoughts?

Would the following patch (applied on maint) solve the problem?

Regards,

-- 
Nicolas Goaziou
>From eb1de6c2bcd02593a4a704f805faa9020f5fdddb Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <[email-masked]>
Date: Thu, 4 Feb 2016 09:32:51 +0100
Subject: [PATCH] Remove LaTeX overlay when text below is modified

* lisp/org.el (org--format-latex-make-overlay): New function.
(org-format-latex): Use new function.

Reported-by: Dima Kogan <[email-masked]>
<http://permalink.gmane.org/gmane.emacs.orgmode/104800>
---
 lisp/org.el | 41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index fd08292..a48ae70 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -19079,6 +19079,27 @@ for all fragments in the buffer."
 	  (set-window-start nil window-start)
 	  (message (concat msg "done")))))))
 
+(defun org--format-latex-make-overlay (beg end image)
+  "Build an overlay between BEG and END using IMAGE file.
+Register new overlay in `org-latex-fragment-image-overlays'."
+  (let ((ov (make-overlay beg end)))
+    (overlay-put ov 'org-overlay-type 'org-latex-overlay)
+    (overlay-put ov 'evaporate t)
+    (overlay-put ov
+		 'modification-hooks
+		 (list (lambda (o flag beg end &optional l)
+			 (unless flag
+			   (org-remove-latex-fragment-image-overlays
+			    (overlay-start o) (overlay-end o))))))
+    (if (featurep 'xemacs)
+	(progn
+	  (overlay-put ov 'invisible t)
+	  (overlay-put ov 'end-glyph (make-glyph (vector 'png :file image))))
+      (overlay-put ov
+		   'display
+		   (list 'image :type 'png :file image :ascent 'center)))
+    (push ov org-latex-fragment-image-overlays)))
+
 (defun org-format-latex
     (prefix &optional dir overlays msg forbuffer processing-type)
   "Replace LaTeX fragments with links to an image, and produce images.
@@ -19170,25 +19191,7 @@ Some of the options can be changed using the variable
 			     (when (eq (overlay-get o 'org-overlay-type)
 				       'org-latex-overlay)
 			       (delete-overlay o)))
-			   (let ((ov (make-overlay beg end)))
-			     (overlay-put ov
-					  'org-overlay-type
-					  'org-latex-overlay)
-			     (overlay-put ov 'evaporate t)
-			     (if (featurep 'xemacs)
-				 (progn
-				   (overlay-put ov 'invisible t)
-				   (overlay-put
-				    ov 'end-glyph
-				    (make-glyph
-				     (vector 'png :file movefile))))
-			       (overlay-put
-				ov 'display
-				(list 'image
-				      :type 'png
-				      :file movefile
-				      :ascent 'center)))
-			     (push ov org-latex-fragment-image-overlays))
+			   (org--format-latex-make-overlay beg end movefile)
 			   (goto-char end))
 		       (delete-region beg end)
 		       (insert
-- 
2.6.3