6

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.

6
  • 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. Commented Jan 5, 2012 at 13:48
  • Is it possible to generate pngs from tikz pictures?
    – Skarab
    Commented Jan 5, 2012 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. Commented Jan 5, 2012 at 14:04
  • Do you mean that I should move TikZ pictures to separated tex files and apply this method?
    – Skarab
    Commented Jan 5, 2012 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}} Commented Jan 5, 2012 at 14:28

3 Answers 3

7

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
\@ifpackageloaded{tex4ht}{
\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
7
  • 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
    Commented Jan 6, 2012 at 9:31
  • When I remove /pgf/images/external info from style, I keep getting only the Package tikz Error.
    – Skarab
    Commented Jan 6, 2012 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
    Commented Jan 6, 2012 at 9:46
  • there was error in the shell command, it generated wrong filenames for the png files
    – michal.h21
    Commented Jan 6, 2012 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
    Commented Jan 6, 2012 at 10:06
5

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

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

\makeatletter
\@ifpackageloaded{tex4ht}{
\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/.

1
  • Since PDF export is the default for tikz, there should not be a need to define pdf export style.
    – devendra
    Commented Dec 16, 2012 at 3:18
2

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
\@ifpackageloaded{tex4ht}{
\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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .