emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* SVG Previews for org mode
@ 2024-03-29 22:14 Robert
  2024-03-30 10:18 ` Ihor Radchenko
  0 siblings, 1 reply; 2+ messages in thread
From: Robert @ 2024-03-29 22:14 UTC (permalink / raw)
  To: emacs-orgmode

Hello,

I created the attached code to be able to preview SVG in org mode. Please comment if you have suggestions for a better approach.

It works by having svg in a #+begin_src svg block and running org-format-svg on it.

I took inspiration from org-format-latex and wonder whether it should be merged with that function.

Upsides:
- The same keybinding (C-c C-x C-l) could be used.
- Less duplicated code
- More?

Downsides: 
- The name of the function would be misleading
- Other breakage
- More?

It could also be integrated with the C-c mechanisms on src_blocks. But I don’t know how to do that.

Best regards

Robert

(defun org--make-svg-preview-overlay (beg end image)
  "Build an overlay between BEG and END using the svg image data."
  (let ((ov (make-overlay beg end)))
    (overlay-put ov 'org-overlay-type 'org-svg-overlay)
    (overlay-put ov 'evaporate t)
    (overlay-put ov
		 'modification-hooks
		 (list (lambda (o _flag _beg _end &optional _l)
			 (delete-overlay o))))
    (overlay-put ov
		 'display
		 (find-image `((:type svg :data ,image :scale 1 :transform-smoothing t))))))

(defun org-format-svg (&optional beg end)
  (let ((context-regexp "#\\+begin_src +svg"))
    (goto-char (or beg (point-min)))
    (while (re-search-forward context-regexp end t)
      (let* ((context (org-element-context))
	     (type (org-element-type context)))
	(when (and (eq type 'src-block) 
		   (string= (org-element-property :language context) "svg"))
	  (let* ((value (org-element-property :value context))
		 (beg (org-element-property :begin context))
		 (end (save-excursion
			(goto-char (org-element-property :end context))
			(skip-chars-backward " \r\t\n")
			(point))))
	    (progn
	      (dolist (o (overlays-in beg end))
		(when (eq (overlay-get o 'org-overlay-type) 'org-svg-overlay)
		  (delete-overlay o))))
	    (org--make-svg-preview-overlay beg end value)
	    (goto-char end)))))))

(defun org-clear-svg-preview (&optional beg end)
  (let ((overlays (cl-remove-if-not
		   (lambda (o) (eq (overlay-get o 'org-overlay-type) 'org-svg-overlay))
		   (overlays-in (or beg (point-min)) (or end (point-max))))))
    (mapc #'delete-overlay overlays)
    overlays))

(defun org-svg-preview (&optional arg)
  "Toggle the preview of the svg fragment at point"
  (interactive)
  (cond
   ((not (display-graphic-p)) nil)  ;; noop on non-graphic displays
   ((use-region-p)
    (org-format-svg (region-beginning) (region-end)))
   ((let ((context (org-element-context)))
      (and (eq (org-element-type context) 'src-block)
	   (string= (org-element-property :language context) "svg")
	   (let ((beg (org-element-property :begin context))
		 (end (org-element-property :end context)))
	     (if (org-clear-svg-preview beg end)
		 (message "SVG preview removed")
	       (message "Creating SVG preview...")
	       (org-format-svg beg end)
	       (message "Creating SVG preview... done."))
	     t))))))
(provide 'bob-org-svg)



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: SVG Previews for org mode
  2024-03-29 22:14 SVG Previews for org mode Robert
@ 2024-03-30 10:18 ` Ihor Radchenko
  0 siblings, 0 replies; 2+ messages in thread
From: Ihor Radchenko @ 2024-03-30 10:18 UTC (permalink / raw)
  To: Robert, Timothy, Karthik Chikmagalur; +Cc: emacs-orgmode

Robert <robert+orgmode@robewald.de> writes:

> I created the attached code to be able to preview SVG in org mode. Please comment if you have suggestions for a better approach.
>
> It works by having svg in a #+begin_src svg block and running org-format-svg on it.
>
> I took inspiration from org-format-latex and wonder whether it should be merged with that function.
> ...
> It could also be integrated with the C-c mechanisms on src_blocks. But I don’t know how to do that.

Thanks for the proposal!

C-c C-c mechanisms and preview mechanisms are very different things.
C-c C-c is supposed to _run_ the code. Inserting overlays is a rather
fragile side effect of running a code.
So, utilizing preview does make more sense compared to utilizing babel.

However, I am not very sure if previewing raw svg fragments is something
many people will need. At least, I do not recall many requests to have
previews of svg images _specifically_. AFAIR, the more common requests
are (1) previewing html links and files (for example, produced by
ipython); (2) previewing base-encoded images in general, not just svgs;
with the intention to store images as plain text, right inside Org
buffers; (3) previewing pdfs.

Rather than adding a new preview command for each possible data type,
I'd prefer to see a more unified API to preview parts of Org files.
So, your idea to integrate things with the existing image latex does
make sense.

However, we are currently in the process of major rewrite of the latex
preview system [1], so making major changes in this area is temporarily
suspended.

[1] https://list.orgmode.org/87lek2up0w.fsf@tec.tecosaur.net/

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-03-30 10:19 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-29 22:14 SVG Previews for org mode Robert
2024-03-30 10:18 ` Ihor Radchenko

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).