# Htlatex and Tikz creates sometimes incorrect svgs

I have a document with a large number of Tikz pictures and I need to generate a html page from it. I have declared a driver to have TikZ pictures as SVGs (after this question) and run htlatex main.tex:

\ifx\HCode\UnDef\else\def\pgfsysdriver{pgfsys-tex4ht.def}\fi


However, for some pictures SVGs are correctly generated for some they are not (e.g., TikZ pictures from answers to this question). For most of them, I got XML Parsing Error: mismatched tag error with </text> mentioned, e.g.:

alt="ExAAel "  class="pic-halign" ></text>


Is there any website that would help me to understand which kind of TikZ pictures are supported by htlatex?

UPDATE:

Because of problems with SVG generation, I decided to try to generate pngs. I use tikzexternalize as Andrew Stacey suggested. I am on MacOs so I also needed to install (with macports) poppler to have pdftoppm and pnmtopng. Here is my example document:

\documentclass[11pt,a4paper]{article}
\usepackage{pgf}
\usepackage{tikz}
\usepackage{pgf}
\usetikzlibrary{external}
\tikzexternalize[prefix=figures_external/]

\begin{document}

\tikzset{external/system call={pdflatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource" && pdftoppm "\image.pdf" | pnmtopng > "\image.png"}}

\tikzset{external/figure name={tikz-figure}}

\begin{tikzpicture}
% Picture code
\end{tikzpicture}

\end{document}


Unfortunately I got the following error:

> Package tikz Error: Sorry, the system call 'pdflatex -halt-on-error
> -interact ion=batchmode -jobname "figures_external/braids-figure0" "\def\tikzexternalreal
> job{example_tikz_external}\input{example_tikz_external}" && pdftoppm
> "figures_e xternal/braids-figure0.pdf" | pnmtopng >
> "figures_external/braids-figure0.png"' did NOT result in a usable
> output file 'figures_external/braids-figure0' (expe cted one of
> .pdf:.jpg:.jpeg:.png:). Please verify that you have enabled system
> calls. For pdflatex, this is 'pdflatex -shell-escape'. Sometimes it is
> also nam ed 'write 18' or something like that. Or maybe the command
> simply failed? Error messages can be found in
> 'figures_external/braids-figure0.log'. If you continu e now, I'll try
> to typeset the picture. See the tikz package documentation for
> explanation. Type H <return> for immediate help.


I wonder what could be a reason that the externalize call fails.

-
My general principle when using TikZ to generate SVGs is that it works fine on pictures without text but is unreliable for pictures with text. –  Loop Space Jan 5 '12 at 13:48
Is it possible to generate pngs from tikz pictures? –  Skarab Jan 5 '12 at 13:56
Take a look at: tex.stackexchange.com/q/11866/86 It is also possible to modify the system command used in the externalisation library to generate PNGs directly. –  Loop Space Jan 5 '12 at 14:04
Do you mean that I should move TikZ pictures to separated tex files and apply this method? –  Skarab Jan 5 '12 at 14:20
I think I'd go for the externalisation method. Here's what I use: \usetikzlibrary{external} \tikzexternalize \tikzset{external/system call={pdflatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource" && pdftoppm "\image.pdf" | pnmtopng > "\image.png"}} \tikzset{external/figure name={braids-figure}}  –  Loop Space Jan 5 '12 at 14:28

In order to use the tikz externalize library, you need to call latex with --shell-escape option, so it can run the external commands. in tex4ht running of the external commands is not allowed.

My solution is to run first pdflatex file -shell-escape to get the pdf figures, then comvert pdf files to png using imagemagick and finally run htlatex to insert the generated png.

\documentclass{article}
\usepackage{tikz,graphicx}
\usetikzlibrary{external}
\makeatletter
\tikzexternalize[mode=only graphics]
}{
\tikzexternalize
}
\makeatother

\tikzset{
png export/.style={
/pgf/images/external info,
/pgf/images/include external/.code={%
\includegraphics
[width=\pgfexternalwidth,height=\pgfexternalheight]
{##1.png}%
}
}
}

\tikzset{png export}

\begin{document}
\begin{tikzpicture}
\path (0,0) node[draw] (A) {A};
\path (2,0) node[draw] (B) {B};
\draw (A) -- (B) node[midway,above = 0 em] {via};
\end{tikzpicture}
\end{document}


command sequence:

pdflatex myfile -shell-escape
for i in example-figure*.pdf; do convert -density 300 $i echo$i | sed -e 's/\.pdf/\.png/g'; done
htlatex myfile

-
After running pdflatex example.tex -shell-escape, I get the following error on the line with \tikzset{png export}: Package pgfkeys Error: I do not know the key '/tikz/pgf/images/external info' –  Skarab Jan 6 '12 at 9:31
When I remove /pgf/images/external info from style, I keep getting only the Package tikz Error. –  Skarab Jan 6 '12 at 9:34
I have changed {##1.png}% to {##1.pdf}% and it works fine. Thank you for your help. I need to find a better condition than @ifpackageloaded[tex4h], because it does not work as expected. –  Skarab Jan 6 '12 at 9:46
there was error in the shell command, it generated wrong filenames for the png files –  michal.h21 Jan 6 '12 at 10:02
The error is in tex file. Both the \tikzset should be executed only if tex4th is loaded. Moving both just after \tikzexternalize[mode=only graphics] solves my problem. –  Skarab Jan 6 '12 at 10:06

A modified version of the michal.h21 example, which works for me is (MacOS, MacTex 2011):

\documentclass{article}
\usepackage{tikz,graphicx}
\usetikzlibrary{external}

\makeatletter
\tikzexternalize[mode=only graphics]
\tikzset{png export/.style={/pgf/images/external info,/pgf/images/include external/.code={%
\includegraphics[width=\pgfexternalwidth,height=\pgfexternalheight]{##1.png}%
}
}
}
\tikzset{png export}%
}{%
\tikzexternalize%
\tikzset{pdf export/.style={/pgf/images/external info,/pgf/images/include external/.code={%
\includegraphics[width=\pgfexternalwidth,height=\pgfexternalheight]{##1.pdf}%
}
}
}
\tikzset{pdf export}%
}
\makeatother

\begin{document}
\begin{tikzpicture}
\path (0,0) node[draw] (A) {A};
\path (2,0) node[draw] (B) {B};
\draw (A) -- (B) node[midway,above = 0 em] {via};
\end{tikzpicture}
\end{document}


The command sequence is the same as michal.h21 suggested. It is still not perfect solution, because for some pictures I got ! Undefined control sequence \Gin@ewidth ->\pgfexternalwidth error.

Regarding the error, I got it for picture that uses remember picture, such as an example from http://www.texample.net/tikz/examples/beamer-arrows/.

-
Since PDF export is the default for tikz, there should not be a need to define pdf export style. –  devendra Dec 16 '12 at 3:18

With the following solution (slightly modified from Skarab's one) you don't need the intermediate step of pdf->png conversion "by hand": it is performed automatically (you still need imagemagick installed in your system though). It works for me with TeXLive under Ubuntu:

\documentclass{article}
\usepackage{tikz,graphicx}
\usetikzlibrary{external}

\tikzset{
png copy/.style={
external/system call={
pdflatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource";
convert -density 300 -transparent white "\image.pdf" "\image.png"
}
}
}
\tikzset{png copy}

\makeatletter
\tikzexternalize[mode=only graphics]
\tikzset{png export/.style={/pgf/images/external info,/pgf/images/include external/.code={\includegraphics[width=\pgfexternalwidth,height=\pgfexternalheight]{##1.png}}}}
\tikzset{png export}
}{
\tikzexternalize
\tikzset{pdf export/.style={/pgf/images/external info,/pgf/images/include external/.code={\includegraphics[width=\pgfexternalwidth,height=\pgfexternalheight]{##1.pdf}}}}
\tikzset{pdf export}
}
\makeatother

\begin{document}
\begin{tikzpicture}
\path (0,0) node[draw] (A) {A};
\path (2,0) node[draw] (B) {B};
\draw (A) -- (B) node[midway,above = 0 em] {via};
\end{tikzpicture}
\end{document}


Therefore with this solution you need just 2 steps to obtain the final tex4ht output:

pdflatex -shell-escape mytexfile
htlatex mytexfile


Faster, cleaner and you don't have to worry about OS batch conversion command. I got the clue from here.

-