TeX4ht:如何使用参数配置新环境?

TeX4ht:如何使用参数配置新环境?

我正在使用 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\RecallEndPTeX4ht 提供的处理段落的命令。重新定义的命令处理正文周围的框。原始内容不幸产生了一些虚假的段落,因此此代码在启动框之前重置了段落处理代码,并在关闭框时恢复它。

我们最终可以配置盒子了:

\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> 

相关内容