2

I'm using the tcolorbox package to produce definition and other theorems-like environments with xelatex, and I'm aiming now to convert my latex files to html files with make4ht. Here I must thank all contributors to that fantastic tool (with special greetings to Michal Hoftich !).

Now my question : how would I configure, in my cfg file, my environment "definition", that takes 2 arguments like in the mwe below :

\documentclass{article}

\usepackage[theorems]{tcolorbox}
\newtcbtheorem%
{definition}%
{Définition}%
{}
{def}

\begin{document}

\begin{definition}{Arg1}{Arg2}%
  Text
\end{definition}

\end{document}

for tex4ht to transform it to

<div class="definition">
    <a id="def:Arg2"></a>
    <div class="EnteteDef">
        Arg1
    </div>
    <div class="CorpsDef">
        Text
    </div>
</div>

To be clearer, I only want to know how to handle the 2 arguments Arg1 and Arg2, and the Text within the environment, to place them where I want in the HTML output.

I thank in advance patient people who will want to pay attention to my problem...

8
  • 1
    We will need to see the definition of your environment. It will most likely be necessary to redefine it with configurable hooks.
    – michal.h21
    Dec 1 '20 at 10:24
  • Always please post a full MWE, i.e., from \documentclass to \end{document} to get better suggestion.....
    – MadyYuvi
    Dec 1 '20 at 13:14
  • Thank you for your answers, I modified my question intending to be clearer... Dec 1 '20 at 13:40
  • this situation is a lot harder than just simple environment, because tcolorbox does lot of stuff internally. I have a solution that more or less works, but there are still some issues.
    – michal.h21
    Dec 1 '20 at 23:04
  • I don't know if I'm not clear or if my question is a lot harder than I think. I will change my question a little bit (still hard in english...) : what advice should you give me if I only want a new latex environment, say "mydefinition", with two arguments that would be transformed by tex4ht in the HTML code I asked yesterday ? Perhaps it's not possible ?... Thank you in advance Michal ! Dec 2 '20 at 7:39
4

Edit:

I've just added a full support for the tcolorbox package to TeX4ht. It supports all environments that use the underlying tcolorbox mechanism, like your definition environment.

Here is the full configuration file, tcolorbox.4ht:

% use custom counter that increments for every \tcolorbox
\newcounter{:tcbcolcount}

\def\tcb@drawcolorbox{%
  \stepcounter{:tcbcolcount}%
  % save text and background colors for use in CSS
  \get:xcolorcss{tcbcolbacktitle}\:tcbcolbacktitle%
  \get:xcolorcss{tcbcoltitle}\:tcbcoltitle%
  \get:xcolorcss{tcbcolback}\:tcbcolback%
  \get:xcolorcss{tcbcolframe}\:tcbcolframe%
  \get:xcolorcss{tcbcolupper}\:tcbcolupper%
  % make unique ID for this box
  \def\:tcbcolid{tcolobox-\arabic{:tcbcolcount}}
  % Open box
  \a:tcolorbox%
  % save label, if it is set
  \ifdefined\tcolorbox:label:key%
    \label{\tcolorbox:label:key}%
  \fi%
  % open title
  \b:tcolorbox%
  \kvtcb@before@title\kvtcb@title\kvtcb@after@title%
  % close title and open main box
  \c:tcolorbox%
  \box\tcb@upperbox%
  % deal with lower box, if it is set
  \iftcb@hasLower%
    \a:tcolorlowerbox%
    \box\tcb@lowerbox%
    \b:tcolorlowerbox%
  \fi%
  % close box
  \d:tcolorbox%
}

% overwrite other versions of box drawing macros
\let\tcb@drawcolorbox@standalone\tcb@drawcolorbox

\NewConfigure{tcolorbox}{4}
\NewConfigure{tcolorlowerbox}{2}

% we need to save label for a later use
\def\:tempa#1{%
  \xdef\tcolorbox:label:key{#1}%
  \o:tcb@set@label:{#1}%
}
\HLet\tcb@set@label\:tempa


% this is a trick to fix issues with paragraphs
% spurious end </p> tags were inserted
\def\tcb@minipage#1{\SaveEndP\vbox\bgroup\par}
\def\endtcb@savebox{\EndP\egroup\RecallEndP}


\Configure{tcolorbox}
{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="tcolorbox \@currenvir" id="\:tcbcolid">}
  \Css{\#\:tcbcolid\space .EnteteDef{color: \:tcbcoltitle; background-color: \:tcbcolframe;}}
  \Css{\#\:tcbcolid\space .CorpsDef{color: \:tcbcolupper; background-color: \:tcbcolback; border: 1px solid \:tcbcolframe;}}
}
{\HCode{\Hnewline<div class="EnteteDef">}\par}
{\ifvmode\IgnorePar\fi\EndP\HCode{</div>\Hnewline<div class="CorpsDef">}}
{\ifvmode\IgnorePar\fi\EndP\HCode{\Hnewline</div>\Hnewline</div>}\par}

\Css{.tcolorbox{margin-top:0.5em;margin-bottom: 0.5em;}}


\Configure{tcolorlowerbox}{\ifvmode\IgnorePar\fi\EndP\HCode{\Hnewline<div class="lowerbox">}
  \Css{\#\:tcbcolid\space .lowerbox{border-top: 1px dashed \:tcbcolframe;}}
}
{\ifvmode\IgnorePar\fi\EndP\HCode{\Hnewline</div>}}

\Css{.tcolorbox .lowerbox{margin-top:0pt;}}

I will describe the details later, here is an example:

\documentclass{article}
\usepackage{lipsum}

\usepackage[theorems]{tcolorbox}
\newtcbtheorem%
{definition}%
{Définition}%
{}
{def}

\begin{document}

\begin{definition}{Arg1}{Arg2}%
  Text
\end{definition}

Now, we can try some more \texttt{tcolorbox} environments:


\begin{tcolorbox}
This is a \textbf{tcolorbox}.
\end{tcolorbox}

\begin{tcolorbox}
This is another \textbf{tcolorbox}.
\tcblower
Here, you see the lower part of the box.
\end{tcolorbox}

\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black,title=My nice heading]
This is another \textbf{tcolorbox}.
\tcblower
Here, you see the lower part of the box.
\end{tcolorbox}

\begin{definition}{Another definition}{def2}%
  \lipsum[1-3]
\end{definition}
\end{document}

This is the result in browser:

enter image description here

Some more info:

tcolorbox saves the title and content in boxes. It then uses pgf to draw frames and ornaments around these boxes. We need to disable this functionality, instead we want to output title and content to the HTML file and use CSS to style particular boxes.

All of this is done in the redefined \tcb@drawcolorbox command:

  \get:xcolorcss{tcbcolbacktitle}\:tcbcolbacktitle%
  \get:xcolorcss{tcbcoltitle}\:tcbcoltitle%
  \get:xcolorcss{tcbcolback}\:tcbcolback%
  \get:xcolorcss{tcbcolframe}\:tcbcolframe%
  \get:xcolorcss{tcbcolupper}\:tcbcolupper%

These commands save background and text colors used by tcolorbox to commands that can be used in the CSS declarations.

  \a:tcolorbox%
  % save label, if it is set
  \ifdefined\tcolorbox:label:key%
    \label{\tcolorbox:label:key}%
  \fi%
  % open title
  \b:tcolorbox%
  ...

This is the part of the redefined command that is used to insert the HTML tags. Commands like \a:tcolorbox and \b:tcolorbox contain HTML tags defined using the \Configure{tcolorbox} command. They are declared using \NewConfigure{tcolorbox}{4}. We use four commands for tags inclusion because we need one for opening of the box, another between label and title, third between title and content and the last at the end. The box that is created using \tcblower is configured by a separate configuration, tcolorlowerbox, to make the code bit more readable and maintainable, as this box is used only occasionally.

We need to fix some other issues in this file. For example save key for the \label command:

% we need to save label for a later use
\def\:tempa#1{%
  \xdef\tcolorbox:label:key{#1}%
  \o:tcb@set@label:{#1}%
}
\HLet\tcb@set@label\:tempa

And fix issues with paragraphs:

% this is a trick to fix issues with paragraphs
% spurious end </p> tags were inserted
\def\tcb@minipage#1{\SaveEndP\vbox\bgroup\par}
\def\endtcb@savebox{\EndP\egroup\RecallEndP}

\SaveEndP, \EndP and \RecallEndP are commands provided by TeX4ht that handle with paragraphs. The redefined commands handle box around the main text. The original content unfortunatelly produced some spurious paragraphs, so this code resetes the paragraph handling code before the box is started and restores it when the box is closed.

We can finally configure the boxes:

\Configure{tcolorbox}
{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="tcolorbox \@currenvir" id="\:tcbcolid">}
  \Css{\#\:tcbcolid\space .EnteteDef{color: \:tcbcoltitle; background-color: \:tcbcolframe;}}
  \Css{\#\:tcbcolid\space .CorpsDef{color: \:tcbcolupper; background-color: \:tcbcolback; border: 1px solid \:tcbcolframe;}}
}
{\HCode{\Hnewline<div class="EnteteDef">}\par}
{\ifvmode\IgnorePar\fi\EndP\HCode{</div>\Hnewline<div class="CorpsDef">}}
{\ifvmode\IgnorePar\fi\EndP\HCode{\Hnewline</div>\Hnewline</div>}\par}

\ifvmode\IgnorePar\fi\EndP is used to correctly handle paragraphs. We want to close current paragraph before <div> element, in order to keep the HTML valid. So it is necessary to use this construct as needed, basically every time we open or close a <div> element.

\Css{\#\:tcbcolid\space .EnteteDef{color: \:tcbcoltitle; background-color: \:tcbcolframe;}}

This saves the information about used colors to the CSS file, thanks to the macros that were defined earlier.

The generated HTML looks like this:

 <div class='tcolorbox definition' id='tcolobox-1'>   <a id='x1-1doc'></a> 
<div class='EnteteDef'>
<!-- l. 15 --><p class='indent'>   Définition 1: Arg1</p></div> 
<div class='CorpsDef'><!-- l. 14 --><p class='noindent'>Text</p>                                                                                                  
</div> 
</div>

And CSS like this:

#tcolobox-1 .EnteteDef{color: #FFFFFF; background-color: #404040;}
#tcolobox-1 .CorpsDef{color: #000000; background-color: #F2F2F2; border: 1px solid #404040;}

Original post:

There is no support for the tcolorbox package in TeX4ht yet. But I am working on that and will update this answer when I am done.

In the meantime, you can use fix just for your custom environment. Try the following configuration file:

\Preamble{xhtml}
% counter for the label
\newcounter{mydefinition}
\renewenvironment{definition}[2]{%
\ifvmode\IgnorePar\fi\EndP\HCode{<div class="definition">}%
\refstepcounter{mydefinition}\label{def:#2}%
\HCode{<div class="EnteteDef">}#1\HCode{</div>\Hnewline<div class="CorpsDef">}\par
}{\ifvmode\IgnorePar\fi\EndP\HCode{</div>\Hnewline</div>}
}
\begin{document}
\EndPreamble

It redefines the definition environment. It uses a custom counter to enable cross-referencing. The second argument to the environment is used as label. The \IgnorePar, \EndP and \par commands are used for paragraph handling. \Hnewline inserts line break in the HTML, \HCode inserts HTML tags.

Here is a sample file:

\documentclass{article}

\usepackage[theorems]{tcolorbox}
\newtcbtheorem%
{definition}%
{Définition}%
{}
{def}

\begin{document}

\begin{definition}{Arg1}{Arg2}%
  Text
\end{definition}

See definition~\ref{def:Arg2}.


\end{document}

This is the result:

enter image description here

And HTML code:

<body>
   <div class='definition'><a id='x1-2r1'></a><div class='EnteteDef'>Arg1</div> 
<div class='CorpsDef'>
<!-- l. 13 --><p class='indent'>   Text </p></div> 
</div>
<!-- l. 16 --><p class='noindent'>See definition <a href='#x1-2r1'>1<!-- tex4ht:ref: def:Arg2  --></a>.
</p>
    
</body> 
6
  • Thanks a lot for having lost a bit of your time for me Michal ! I will test your solution as soon as I can ! Dec 2 '20 at 17:52
  • Well thank you so much, that was exactly what I wanted ! I didn't realise that I could define new environments "à la TeX" with \renewenvironement, I was dealing with \ConfigureEnv without success... Dec 2 '20 at 21:11
  • @AlexLaGrandeJaurasse you are welcome. \ConfigureEnv is good for adding tags to existing environments, but when you need to more complicated stuff, and especially when you need to suppress behavior of the original evnironment, \renewenvironment is the way.
    – michal.h21
    Dec 2 '20 at 21:42
  • @AlexLaGrandeJaurasse I've updated my answer with a solution for all tcolorbox environments. I've also updated TeX4ht sources, so tcolorbox support should be included in TeX Live soon.
    – michal.h21
    Dec 3 '20 at 22:48
  • Wow ! Michal ! It's a great job ! Thank you very much for sharing ! Dec 8 '20 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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