我正在使用 tcolorbox 包通过 xelatex 生成定义和其他类似定理的环境,现在我的目标是使用 make4ht 将我的 latex 文件转换为 html 文件。在这里我必须感谢所有为这个出色的工具做出贡献的人(特别感谢 Michal Hoftich!)。
现在我的问题是:在我的 cfg 文件中,我该如何配置我的环境“定义”,它需要 2 个参数,如下面的 mwe 所示:
\documentclass{article}
\usepackage[theorems]{tcolorbox}
\newtcbtheorem%
{definition}%
{Définition}%
{}
{def}
\begin{document}
\begin{definition}{Arg1}{Arg2}%
Text
\end{definition}
\end{document}
让 tex4ht 将其转换为
<div class="definition">
<a id="def:Arg2"></a>
<div class="EnteteDef">
Arg1
</div>
<div class="CorpsDef">
Text
</div>
</div>
为了更清楚起见,我只想知道如何处理 2 个参数 Arg1 和 Arg2,以及环境中的文本,并将它们放在 HTML 输出中我想要的位置。
我提前感谢那些愿意关注我的问题的耐心人们……
答案1
编辑:
我刚刚为 TeX4ht 添加了对该包的全面支持tcolorbox
。它支持所有使用底层tcolorbox
机制的环境,例如您的definition
环境。
这是完整的配置文件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;}}
我稍后会描述细节,下面是一个例子:
\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}
这是浏览器中的结果:
更多信息:
tcolorbox
将标题和内容保存在框中。然后它用于pgf
在这些框周围绘制框架和装饰。我们需要禁用此功能,而是希望将标题和内容输出到 HTML 文件并使用 CSS 来设置特定框的样式。
所有这些都是在重新定义的\tcb@drawcolorbox
命令中完成的:
\get:xcolorcss{tcbcolbacktitle}\:tcbcolbacktitle%
\get:xcolorcss{tcbcoltitle}\:tcbcoltitle%
\get:xcolorcss{tcbcolback}\:tcbcolback%
\get:xcolorcss{tcbcolframe}\:tcbcolframe%
\get:xcolorcss{tcbcolupper}\:tcbcolupper%
这些命令将所使用的背景和文本颜色保存到tcolorbox
可以在 CSS 声明中使用的命令中。
\a:tcolorbox%
% save label, if it is set
\ifdefined\tcolorbox:label:key%
\label{\tcolorbox:label:key}%
\fi%
% open title
\b:tcolorbox%
...
这是重新定义的命令的一部分,用于插入 HTML 标签。命令(如\a:tcolorbox
和)\b:tcolorbox
包含使用命令定义的 HTML 标签\Configure{tcolorbox}
。它们使用声明\NewConfigure{tcolorbox}{4}
。我们使用四个命令来包含标签,因为我们需要一个用于打开框,另一个用于标签和标题之间,第三个用于标题和内容之间,最后一个用于结尾。使用创建的框\tcblower
由单独的配置配置,tcolorlowerbox
以使代码更具可读性和可维护性,因为此框仅偶尔使用。
我们需要修复此文件中的一些其他问题。例如,保存以下\label
命令的密钥:
% 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}
\SaveEndP
和\EndP
是\RecallEndP
TeX4ht 提供的处理段落的命令。重新定义的命令处理正文周围的框。原始内容不幸产生了一些虚假的段落,因此此代码在启动框之前重置了段落处理代码,并在关闭框时恢复它。
我们最终可以配置盒子了:
\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
用于正确处理段落。我们希望在<div>
元素之前关闭当前段落,以保持 HTML 有效。因此,有必要根据需要使用此构造,基本上每次我们打开或关闭元素时都是如此<div>
。
\Css{\#\:tcbcolid\space .EnteteDef{color: \:tcbcoltitle; background-color: \:tcbcolframe;}}
这会将有关使用的颜色的信息保存到 CSS 文件中,这要归功于之前定义的宏。
生成的 HTML 如下所示:
<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>
CSS 如下:
#tcolobox-1 .EnteteDef{color: #FFFFFF; background-color: #404040;}
#tcolobox-1 .CorpsDef{color: #000000; background-color: #F2F2F2; border: 1px solid #404040;}
原始帖子:
TeX4ht 中尚不支持该tcolorbox
软件包。但我正在努力解决这个问题,完成后会更新此答案。
与此同时,您可以仅针对您的自定义环境使用修复。尝试以下配置文件:
\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
它重新定义了definition
环境。它使用自定义计数器来启用交叉引用。环境的第二个参数用作标签。 、\IgnorePar
和\EndP
命令\par
用于段落处理。\Hnewline
在 HTML 中插入换行符,\HCode
插入 HTML 标签。
以下是示例文件:
\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}
结果如下:
HTML 代码如下:
<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>