1

(My first question ever on SO)

Goal: to generate an svg out of a tikz block in orgmode with a minimal working example.

I have tried everything within my limited knowledge and I've broken down a supposedly minimal example to this.

#+name: circle
#+begin_src latex :imagemagick yes :file circle.svg
  \begin{tikzpicture}
    \fill[yellow] (0,0) circle (3cm);
  \end{tikzpicture}
#+end_src

However, instead of producing a yellow circle, my snippet creates an svg version of the body of the source block (see below):

svg generated by tikz block when C-c C-c 'ing over the block

I've changed the header arguments, changed the extension, I even installed Emacs (Doom Emacs) and Orgmode again and still can't get this to work. I don't know what else to try.

I've used as guide:

If someone could just paste a simple example that works on their machine I would really appreciate it so I could be sure that this thing actually works.

About: I've seen countless examples of how to manipulate output and other things related to svg and orgmode: the resonant by-backend macro so depending on the export you leave the tikz as is or transform it to svg (my next goal) - -- I can't get that macro to work either, but that's for the future me ---.

However, I can't manage to create a simple working example to create an svg from a tikz source code block in the first place. I need help please.

I did as much research as possible before posting this question, however I am aware that it may not be enough so I will edit accordingly if necessary.

4 Answers 4

1

[Not a complete answer: it does PNG, not SVG]

Here's a minimal example that works for PNG:

#+name: circle
#+header: :results file drawer
#+header: :file circle.png
#+header: :imagemagick yes
#+header: :headers '("\\usepackage{tikz}")
#+begin_src latex
  \begin{tikzpicture}
      \fill[yellow] (0,0) circle (3cm);
    \end{tikzpicture}
#+end_src

Unfortunately it does not work for SVG: apparently that requires more setup than what I have available on my machine right now.

But even though the above is not a complete solution, it is a step in the right direction. Hope it helps.

The two most important additions is the :results file header which is now necessary with recent versions of Org mode, and the \usepackage{tikz} header, which is absolutely necessary any time that you want to process a LaTeX src block that involves tikz.

1

I finally found a way to make following example work :

#+HEADER: :file test1.svg
#+HEADER: :exports results
#+HEADER: :results output silent graphics file
#+HEADER: :headers '("\\usepackage{tikz}")
#+begin_src latex
\begin{tikzpicture}
\draw[->] (-3,0) -- (-2,0) arc[radius=0.5cm,start angle=-180,end angle=0] (-1,0) -- (1,0) arc[radius=0.5cm,start angle=180,end angle=0] (2,0) -- (3,0);
\filldraw (-1.5,0) circle[radius=1mm];
\filldraw (1.5,0) circle[radius=3mm];
\end{tikzpicture}
#+end_src

by modifying file ~/.emacs.d/elpa/org-9.5.2/ob-latex.el :

  1. I commented out the code dealing with the svg extension :

          ;; ((string= "svg" extension)
          ;;  (with-temp-file tex-file
          ;;    (insert (concat (funcall org-babel-latex-preamble params)
          ;;             (mapconcat #'identity headers "\n")
          ;;             (funcall org-babel-latex-begin-env params)
          ;;             body
          ;;             (funcall org-babel-latex-end-env params))))
          ;;  (let ((tmp-pdf (org-babel-latex-tex-to-pdf tex-file)))
          ;;    (let* ((log-buf (get-buffer-create "*Org Babel LaTeX Output*"))
          ;;           (err-msg "org babel latex failed")
          ;;           (img-out (org-compile-file
          ;;                     tmp-pdf
          ;;                     (list org-babel-latex-pdf-svg-process)
          ;;                     extension err-msg log-buf)))
          ;;      (shell-command (format "mv %s %s" img-out out-file)))))
    

    This piece of code was responsible for the svg generation to fail. The trouble lies in the latex preamble inserted which was making (as for me) pdflatex fail to generate a valid pdf file.

  2. Then I changed :

      ((and (string= "html" extension))
            (executable-find org-babel-latex-htlatex))
    

    into

      ((and (or (string= "html" extension) (string= "svg" extension))
            (executable-find org-babel-latex-htlatex))
    

    which means I let htlatex compile the latex src block code, instead of pdflatex. The former produces an html file and a svg one corresponding to the tikz block.

As far as I understand, there are several ways to compile a tikz src block into a svg file :

  • pdflatex + inkscape (the default way, with commented out elisp code)
  • latex + dvisvgm
  • pdflatex + pdf2svg
  • htlatex

I guess one method my be better than another one, depending on the image content. As said, "pdflatex + inkscape" could be made to work again by modifying the inserted latex preamble. For now, I keep up with htlatex as long as it renders well.

Regards

1
  • This works with 9.6.
    – 147pm
    Dec 18, 2022 at 17:18
0

I have exactly the same concern.

I posted a question a few months ago to the orgmode mailing list.

You can access the thread here.

In short, I had success by manually compiling the latex code snippet generated by orgmode with htlatex.

By default, latex code snippet are compiled with pdflatex. But when you specify the output to be svg, the latex header is changed, but still compiled with pdflatex, which fails but succeeds with htlatex.

Unfortunately, I am not skilled enough (yet !) to modify orgmode's code and curiously, this question did not draw much attention.

However, one of the thread answer was kind enough to give me a workaround and to point where in the code some changes could be performed.

I will post here any successful modifications.

Hopes this helps.

Regards

0

Okay, none of the above solutions worked across the board, i.e., put just anything from the wild in babel latex blocks and evaluate the block. But this is my kludge workaround. YMMV.

Basically, just plug in whatever TikZ you've found in the wild. I started a blank org file with this

* Introduction

\usepackage[utf8]{inputenc}
\usepackage{tikz, pgfplots}
\usetikzlibrary{positioning}


\vspace{1in}

\begin{tikzpicture}[
youngnode/.style={rectangle, draw=red!60, fill=red!5, very thick, minimum size=40},
oldnode/.style={rectangle, draw=blue!60, fill=blue!5, very thick, minimum size=40},
]
%Nodes
\node[oldnode]        (SusO)                            { $S_O(t)$};
\node[oldnode]        (InfO)       [below=of SusO]      { $I_O(t)$};
\node[oldnode]        (RecO)       [below=of InfO]      { $R_O(t)$};

\node[youngnode]      (SusY)        [left=of SusO]      { $S_Y(t)$};
\node[youngnode]      (InfY)        [left=of InfO]      { $I_Y(t)$};
\node[youngnode]      (RecY)        [left=of RecO]      { $R_Y(t)$};

%Lines
\draw[->, very thick] (SusO.south east)  to node[right] {$a_{OO}$} (InfO.north east);
\draw[->, very thick] (InfO.south)  to node[right] {$b_O$} (RecO.north);
\draw[->, very thick] (RecO.east)  .. controls  +(right:17mm) and +(right:17mm)   .. (SusO.east);

\draw[->, very thick] (SusY.south west)  to node[left] {$a_{YY}$} (InfY.north west);
\draw[->, very thick] (InfY.south)  to node[left] {$b_Y$} (RecY.north);
\draw[->, very thick] (RecY.west) .. controls  +(left:17mm) and +(left:17mm)   .. (SusY.west);

\draw[dashed,->, very thick] (InfO.north west)  to  (SusY.south east);
\draw[->, very thick] (SusY.south east)  to node[left] {$a_{OY}$} (InfY.north east);

\draw[->, very thick] (SusO.south west)  to node[right] {$a_{YO}$} (InfO.north west);
\draw[dashed,->, very thick] (InfY.north east)  to  (SusO.south west);
\end{tikzpicture}

which I got from here from this video.

Then I did an export to latex C-c C-e l o. Then I opened the pdf in LibreOffice Draw, stretched a box with the mouse around the image to select the image. Then chose File Export... Then ticked the Selection box in the bottom left corner, chose svg from the dropdown and saved it. Works. One caveat is some tikz from the wild can be problematic. This didn't fly so well from an org-mode export. So I just created a tex file and let latex create the pdf. Then into Draw. Worked. Yes, it would be nice to have org-mode babel blocks exporting tikz to latex and html, but in the meantime....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.