TransWikia.com

Work around for bug in pgf when used with htlatex?

TeX - LaTeX Asked by user30471 on June 28, 2021

EDIT The PGF team reported that this bug was fixed on 2018-12-29

There is a bug in pgf that stops it playing nicely with tikz/pgf. As discovered by michal.h21, the solution is a simple a one line change to pgfsys-tex4ht.def. This bug was reported to the pgf team in 2014, together with a patch, but it remains unfixed as of TeXLive 2017.

Question
Is there a way that I can patch the pgf file pgfsys-tex4ht.def from within LaTeX?

It is possible to fix the problem by editing/replacing the system version of pgfsys-tex4ht.def. What I would like, however, is a way of patching this from inside LaTeX because I want to be able to work around this problem in a package. (In an ideal world, the pgf team would just apply Michael’s patch, and so fix the problem once and for all, but they just don’t seem to be interested in doing this…)

The actual error that occurs is:

! Undefined control sequence.
pgfsys@svg@newline ->Hnewline

l.190   pgfusepathqfill}

and the fix is to replace the line defpgfsys@svg@newline{Hnewline} in
pgfsys-tex4ht.def with

defpgfsys@svg@newline{^^J} %% corrected

I have tried patching this line in many ways, in latex files, my class file, in cfg files and mk4 files. Sadly, nothing that I have tried fixes the problem. For reasons I don’t understand, once the pgfsys-tex4ht.def file has been read it is really hard to convince htlatex to use any other definition of pgfsys@svg@newline or Hnewline.

To see the bug in action, compile the following really simple MWE with htlatex:

documentclass{article}
usepackage{tikz}

begin{document}

begin{tikzpicture}
  draw(0,0)--(10,0);
end{tikzpicture}

end{document}

The problem only occurs with htlatex and friends — the MWE compiles without issue using (pdf)latex.

One Answer

This situation is quite unfortunate. The pgfsys-tex4ht.def driver is selected automatically by TikZ when the document is compiled with tex4ht. You can create alternative driver, like pgfsys-tex4ht-alt.def:

input pgfsys-tex4ht.def
defpgfsys@svg@newline{^^J}

but the problem is that the alternative driver cannot be defined in the .cfg file, because it is interpreted after the document preamble was executed. You must put it either to the TeX file:

documentclass{article}
defpgfsysdriver{pgfsys-tex4ht-alt.def}
usepackage{tikz}

begin{document}

 begin{tikzpicture}
   draw(0,0)--(10,0);
 end{tikzpicture}

end{document}

Or use one trick in the .mk4 file:

settings.packages = settings.packages ..'defpgfsysdriver{pgfsys-tex4ht-alt.def}'

You can load additional packages or define custom commands in the settings.packages variables in the mk4 build file.

Edit 2017/11/11:

Another possibility is to use dvisvgm to generate the SVG file. We can use the built-in feature of tex4ht to convert any piece of TeX code inside a Picture* ... EndPicture environment to picture and the fact that TikZ has support for dvips commands, which are supported by dvisvgm.

The alternative pgfsys-tex4ht.def:

% Copyright 2006 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Public License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.

ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-tex4ht.def,v 1.25 2013/08/06 17:46:08 tantau Exp $



% Driver commands for tex4ht

%
% Load common pdf commands:
%
  %input pgfsys-dvisvgm.def
  input pgfsys-dvips.def

%
% tex4ht-specific stuff:
%

newcountpgf@sys@svg@picnum

% configure the output picture format to svg
AtBeginDocument{
  Configure{Picture}{.svg}
}


% Make the code inserted by tex4ht configurable

NewConfigure{tikzpicture}{2}
Configure{tikzpicture}{%
  % ifvmodeIgnoreParfiEndP%HtmlParOff
  Picture*{}
}{EndPicture}

letorig@pgfsys@beginpgfsys@beginpicture
letorig@pgfsys@endpgfsys@endpicture
defpgf@sys@postscript@header#1{{special{! #1}}}
defpgfsys@beginpicture{%
  bgroup
  csname a:tikzpictureendcsname
  pgf@sys@postscript@header{
    /pgfsc{}bind def% stroke color is empty by default
    /pgffc{}bind def% fill color is empty by default
    /pgfstr{stroke}bind def%
    /pgffill{fill}bind def%
    /pgfeofill{eofill}bind def%
    /pgfe{a dup 0 rlineto exch 0 exch rlineto neg 0 rlineto closepath}bind def% rectangle
    /pgfw{setlinewidth}bind def% setlinewidth
    /pgfs{save pgfpd 72 Resolution div 72 VResolution div neg scale 
      magscale{1 DVImag div dup scale}if 
      pgfx neg pgfy neg translate pgffoa .setopacityalpha}bind def% save
    /pgfr{pgfsd restore}bind def %restore
    userdict begin%
    /pgfo{pgfsd /pgfx currentpoint /pgfy exch def def @beginspecial}bind def %open
    /pgfc{newpath @endspecial pgfpd}bind def %close
    /pgfsd{globaldict /pgfdelta /delta where {pop delta} {0} ifelse put}bind def% save delta
    /pgfpd{/delta globaldict /pgfdelta get def}bind def % put delta
    /.setopacityalpha where {pop} {/.setopacityalpha{pop}def} ifelse % install .setopacityalpha 
    /.pgfsetfillopacityalpha{/pgffoa exch def
      /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha newpath fill grestore newpath}bind def
      /pgfeofill{gsave pgffoa .setopacityalpha eofill 1 .setopacityalpha newpath eofill grestore newpath}bind def}bind def
    /.pgfsetstrokeopacityalpha{/pgfsoa exch def /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore newpath}bind def}bind def
    /pgffoa 1 def
    /pgfsoa 1 def
    end
  }%
  orig@pgfsys@begin%
}%


defpgfsys@endpicture{%
  % Save the bounding box
  %printdim%
  orig@pgfsys@end%
  csname b:tikzpictureendcsname%
  egroup
  par% FIXME : was 'Par' but that seems to be undefined!?
}%


endinput


%%% Local Variables: 
%%% mode: latex
%%% End: 

Correct answer by michal.h21 on June 28, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP