1

Consider the following example:

\documentclass{scrbook}

\usepackage{blindtext} \usepackage{pgfornament}

\title{Some Book} \subtitle{A novel} \author{Some Author}

\begin{document}

\chapter{Chapter One} \blindtext{} \begin{center} \begin{tikzpicture}[alt=Separator,hclass=separator] \node {\pgfornament[height=1cm]{79}}; \end{tikzpicture} \end{center} \blindtext{} \begin{center} \begin{tikzpicture}[alt=Endmarker,hclass=endmarker] \node {\pgfornament[height=1cm]{75}}; \end{tikzpicture} \end{center}

\end{document}

As indicated in the extra arguments to tikzpicture above (but not working), I'd like to specify the alt text for accessibility and the class for the img element for markup in the resulting HTML for tikzpictures. The .tex should be parseable both by pdflatex and htlatex via make4ht.

I currently get:

<img alt=' ' src='book0x.svg' />

A solution wrapping the images in an additional tag (e.g. a div) and setting the class there is of course also fine, while the alt tag needs to be set on the image. If the solution also affects \includegraphics commands, that is also fine.

Note this question has similarity to htlatex: img with alt tag and custom class but is about tikzpictures, which provides another level of indirection and I'd like to have the possibility to specify the class by picture, since some pictures / images will be separators and others may be content.

michal.h21
  • 50,697

1 Answers1

1

Let's say that you save the alt and hclass keys to custom macros:

\documentclass{scrbook}

\usepackage{blindtext} \usepackage{pgfornament} \tikzset{ alt/.store in=\myalt, hclass/.store in=\myclass } \title{Some Book} \subtitle{A novel} \author{Some Author}

\begin{document}

\chapter{Chapter One} \blindtext{} \begin{center} \begin{tikzpicture}[alt=Separator,hclass=separator] \node {\pgfornament[height=1cm]{79}}; \end{tikzpicture} \end{center}

\blindtext{} \begin{center} \begin{tikzpicture}[alt=Endmarker,hclass=endmarker] \node {\pgfornament[height=1cm]{75}}; \end{tikzpicture} \end{center}

\end{document}

Important code is this:

\tikzset{
  alt/.store in=\myalt,
  hclass/.store in=\myclass
}

The keys are now available in \myalt and \myclass macros, but the problem is that keys are set after we start pictures in TeX4ht driver, so start tag for image is already in the document. We can fix it with the following configuration file:

\Preamble{xhtml}
\begin{document}
\makeatletter
\ConfigureEnv{tikzpicture}{}{}{}{}{}
\def\texfourht@tikz@begin{}
\def\texfourht@tikz@end{}
\AddToHook{env/tikzpicture/begin}{\ifdefined\myalt\ifvmode\Picture*[\myalt]{ class="\myclass"}\else\Picture+[\myalt]{ class="\myclass"}\fi\def\inside@pict@cmd{}\fi}
\AddToHook{env/tikzpicture/end}{\ifdefined\EndPicture\EndPicture\fi}

\makeatother \EndPreamble

First we reset configuration for the tikzpicture, then we need to reset also other macros that start images. Then, we use the LaTeX environment hooks to insert picture starting code after keys were set:

\AddToHook{env/tikzpicture/begin}{\ifdefined\myalt\ifvmode\Picture*[\myalt]{ class="\myclass"}\else\Picture+[\myalt]{ class="\myclass"}\fi\def\inside@pict@cmd{}\fi}

For some reason, this hook is executed twice with tikzpicture. When it is executed for the first time, \myalt is not defined yet. Thus we need to use the \ifdefined command, and start pictures only once it is defined.

\Picture* and \Picture+ are different versions of the command that starts conversion to picture, one inside a paragraph, other outside.

This is the result:

enter image description here

<p class='noindent'>           <img alt='Separator' class='separator' src='sample0x.svg' />
</p></div>
<!-- l. 23 --><p class='indent'>  Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam lobortis facilisis sem.
Nullam nec mi et neque pharetra sollicitudin. Praesent imperdiet mi nec ante. Donec
ullamcorper, felis non sodales commodo, lectus velit ultrices augue, a dignissim nibh lectus
placerat pede. Vivamus nunc nunc, molestie ut, ultricies vel, semper in, velit. Ut porttitor.
Praesent in sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis fringilla
tristique neque. Sed interdum libero ut metus. Pellentesque placerat. Nam rutrum augue
a leo. Morbi sed elit sit amet ante lobortis sollicitudin. Praesent blandit blandit
mauris. Praesent lectus tellus, aliquet aliquam, luctus a, egestas a, turpis. Mauris
lacinia lorem sit amet ipsum. Nunc quis urna dictum turpis accumsan semper. 
</p>
<div class='center'>
<!-- l. 24 --><p class='noindent'>
</p><!-- l. 27 --><p class='noindent'>              <img alt='Endmarker' class='endmarker' src='sample1x.svg' />

Edit:

it seems that there is a problem with this configuration. Try this version of pgfsys-dvisvgm4ht.def instead:

% Copyright 2021 by Michal Hoftich
% 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{pgfsys-dvisvgm4ht.def}

% Driver commands for tex4ht

% % Load common pdf commands: %

% we load the dvips driver by default. it doesn't support patterns and some other stuff, % but it handles better nested images and some formatting. if you use patterns or if you % have other issues with the default method, pass the "tikz-dvisvgm" option to make4ht. \ifdefined\ifOption \ifOption{tikz+}{\input pgfsys-dvisvgm.def}{\input pgfsys-dvips.def} \else % load the dvips driver by default \input pgfsys-dvips.def \fi

\def\texfourht@tikz@begin{% \bgroup% \def\run@pict@cmd{}% insert the \Picture hooks only in the top nesting level \def\end@pict@cmd{}% \ifdefined\EndPicture\else% We are already inside command that uses \Picture \ifdefined\inside@pict@cmd\else% handle nested uses \ifdefined\tikzexternalize\else% Support externalize library \def\run@pict@cmd{\Picture*[\ifdefined\myalt\myalt\else\csname a:Picture-alt\endcsname\fi]{ \ifdefined\myclass class="\myclass"\fi}}% \def\end@pict@cmd{\EndPicture}% \fi\fi\fi% % command used to detect nesting \def\inside@pict@cmd{}% \csname a:tikzpicture\endcsname% }

\def\texfourht@tikz@end{% \csname b:tikzpicture\endcsname% \egroup% }

\AtBeginDocument{% \NewConfigure{tikzpicture}{2}% \catcode\:=11% \Configure{tikzpicture}{% \protect\csname nested:math\endcsname% support display math \run@pict@cmd{}% }{\end@pict@cmd} % configure the output picture format to svg, as it will require dvisvgm % post processing. \Configure{Picture}{.svg}% \def\pgfsys@typesetpicturebox#1{% \def\@tempa{#1}% % I've found that inserting picture instructions here leads to % errors when \pic feature of pgf is used. \if\@tempa\pgfpic% \orig@pgfsys@typesetpicturebox{#1}% \else% \texfourht@tikz@begin% \orig@pgfsys@typesetpicturebox{#1}% \texfourht@tikz@end% \fi% } % % insert tex4ht hooks around TikZ picture box \ConfigureEnv{tikzpicture}{\texfourht@tikz@begin}{\texfourht@tikz@end}{}{}% \ConfigureEnv{pgfpicture}{\texfourht@tikz@begin}{\texfourht@tikz@end}{}{}% \catcode:=12% }

% Make the code inserted by tex4ht configurable %

\let\orig@pgfsys@typesetpicturebox\pgfsys@typesetpicturebox %\def\pgf@sys@postscript@header#1{{\special{! #1}}}

\endinput

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

It uses \myalt and \myclass when they are available.

michal.h21
  • 50,697
  • Thanks! Sadly, with TeXlive 2021 on my end, it seems to explode this way --- the domfilter get's an "Unbalanced Tag (/div)", and the HTML contains broken parts like ` <img src="book1x.svg" alt="

    " /> " /> ` However, I can confirm that this works like a charm using a "live" TeXlive version from Arpil 2022, so I will accept this answer and wait for my distro to upgrade TeXlive :-).

    Many thanks for the elaborate explanation, as usual! :-)

    – Oliver Freyermuth Apr 20 '22 at 00:55
  • I'm coming back to this with TeXlive 2023/2024, and dvisvgm 3.2. Trying the very same example, the second picture goes bad (large, cut off content) if translated with --format html5+dvisvgm_hashes. Is this a bug in dvisvgm, or is there anything I can do about it? – Oliver Freyermuth Mar 31 '24 at 13:01
  • 1
    @OliverFreyermuth I see it as well. It seems like a bug in dvisvgm. – michal.h21 Mar 31 '24 at 13:45
  • Thanks for confirming! Sadly, I could not track the issue down (to report a bug), since downgrading dvisvgm below 3.1 seems not cleanly possible on systems with up-to-date Ghostscript and GCC. Since dvisvgm_hashes still works fine when tikzpicture is not redefined, I'll keep using that for now. Thanks! – Oliver Freyermuth Mar 31 '24 at 16:03
  • 1
    @OliverFreyermuth I will report it, but first I need to update to TeX Live 2024 to test the current output. – michal.h21 Mar 31 '24 at 19:48