我试图了解是否可以在equation*
-environments 中允许标签,只要它们未被引用。这在 中是允许的pdflatex
,但在使用tex4ebook
(使用默认参数) 进行编译时会产生错误。这是一个 MWE:
\documentclass{amsart}
\begin{document}
\section{Introduction}
\begin{equation*}\label{py}
a^2+b^2=c^2
\end{equation*}
\end{document}
错误信息如下tex4ebook
:
[ERROR] htlatex: Compilation errors in the htlatex run
[ERROR] htlatex: Filename Line Message
[ERROR] htlatex: ./test.tex 2 Extra \endcsname.
[ERROR] htlatex: ./test.4ct 2 Missing \endcsname inserted.
[ERROR] htlatex: ./test.4ct 2 Missing \endcsname inserted.
[ERROR] htlatex: ? 8 Missing \endcsname inserted.
[ERROR] htlatex: ? 8 Missing \endcsname inserted.
[ERROR] htlatex: ? 8 Missing \endcsname inserted.
[ERROR] htlatex: ? 8 Missing \endcsname inserted.
[ERROR] htlatex: ? 8 Missing \endcsname inserted.
[ERROR] htlatex: Compilation errors in the htlatex run
评论:如果删除该行\section{Introduction}
,则错误就会消失。
答案1
首先,\label
无编号方程式有什么用处?它不能用于引用该方程式。当您放置任何可以引用的对象时,就像\section
您的情况一样,它将\label
指向该对象,而不是方程式。因此它无法按预期工作。
但是,即使它没有提供有用的功能,它产生错误也确实令人遗憾。tex4ebook
需要跟踪所有 HTML 文件及其顺序。所有部分或章节都会生成单独的文件,并tex4ebook
读取特殊的 TOC 文件以查找它们的顺序。该文件具有.4tc
扩展名,它看起来像这样:
\doTocEntry\tocsection{1}{\csname a:TocLink\endcsname{2}{x2-10001}{QQ2-2-1}{Introduction}}{1}\relax
该a:TocLink
宏有很多参数,但对于我们的用例来说重要的是x2-10001
。它包含部分 ID。然后我们需要解析此部分的 HTML 文件名。TeX4ht 会跟踪文件中的所有 ID 和文件.xref
:
...
\:CrossWord{)F2F-}{samplese1.html}{1}%
...
\:CrossWord{)Qx2-10001}{2}{1}%
\:CrossWord{)Qx2-10001}{2}{1}%
TeX4ht 为每个可引用项添加一些前缀,因此文件被 包围)F<file number>F-
,而\label
IDS 有)Q<ID>
。如您所见,部分 ID 有重复的条目。它由\label
内部生成equation*
。如果您\label
直接放在 后面\section
,则不会发生此问题。为什么这是个问题?您可以\:CrossWord
使用\Ref
命令读取 的值。\Ref{)Qx2-10001}
应该生成2
,即包含此部分的 HTML 文件的数量。但是如果有重复的 IDS,它将生成用逗号分隔的列表,因此2, 2
在我们的例子中它会生成。
tex4ebook
使用嵌套\Ref
命令来查找部分 HTML 文件名:
\Ref{)F\Ref{)Q#1}F-}
正常情况下,它会产生samplese1.html
,但由于 ID 重复,它不会返回文件名,而是产生一条错误消息。
为了解决这个问题,我们可以只获取返回的第一个项目\Ref{)Qx2-10001}
,并使用它来查找文件名。这需要在tex4ebook
源代码中进行相当多的更改,但您可以使用以下配置文件来模拟它:
\Preamble{xhtml}
\begin{document}
\ExplSyntaxOn
% get filename for the section label
% sometimes, TeX4ht returns list of file numbers for label. we must use just
% the first number. we use the LaTeX 3 sequence functions to achieve that
\tl_new:N\ncx:hfilename
\def\ncx:newhfile#1{
% cw:)Q#1 is csname of tag from the xref file
\seq_set_from_clist:Nc\l_tmpa_seq{cw:)Q#1}
\seq_get_left:NN \l_tmpa_seq \l_tmpa_tl
%\tl_to_str:N \l_tmpa_tl
% \RefFileNumber returns file name for the given file number
\tl_set:Nx \ncx:hfilename {\RefFileNumber{\l_tmpa_tl}}
}
\ExplSyntaxOff
\catcode`\:=11
\def\ncxtable{%
\EndP
\HtmlParOff
\setcounter{tocdepth}{3}
\special{t4ht>\jobname.ncx}
% We don't want crosslinks in xml
% Basic sctructure of the ncx file
\NoFonts
{\HCode{<?xml version="1.0" encoding="utf-8"?>\Hnewline}}
{\a:NcxDoctype}
{\Tg<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">}{}
% To print document map, we customize the tableofcontents. We don't want TOC title,
% so:
\let\contentsname=\empty
\Configure{tableofcontents}{\boolfalse{tocnoempty}\Tg<navMap>}{%
\usetoclevels{part,appendix,chapter,likechapter,appendixsec,section,likesection,subsection,appendixsubsec,likesubsection,subsubsection,likesubsubsection,appendixsubsubsec,subsubsubsection,paragraph}%
\ifbool{tocnoempty}{}%
{\HCode{<navPoint id="mainentry" playOrder="1">
<navLabel><text>Document</text></navLabel>
<content src="\jobname.\:html" />
</navPoint>}}%
\Tg</navMap>}{}{}{}
% We need to configure TocLink
% in navmapsrc is link to the file and anchor, where chapter or section is located
\def\navmapsrc{}
\Configure{TocLink}{%
\ncx:newhfile{##2}
\def\navmapsrc{\ncx:hfilename\:sharp ##2}
\opf:registerfilename{\ncx:hfilename}
##4
}
% Configuraion of entries
\expandafter\resettoclevels\expandafter{\a:resettoclevels}%
\confnavsections%
\HtmlParOff%
\Configure{toTocLink}{}{}%
\Configure{NavSection}{\booltrue{tocnoempty}\HCode{\Hnewline<navPoint id="navPoint-}%
\stepnavpoint\HCode{" playOrder="}%
\the\navpoint\HCode{">\Hnewline<navLabel>\Hnewline<text><navmark type="\curr:sect:type">}%
}{\HCode{</text>\Hnewline%
</navLabel>\Hnewline}%
\HCode{<content src="\navmapsrc" />}%
}{\HCode{</navmark>}}{\HCode{</navPoint>\Hnewline}}
% Meta inf
\ncx:head
% Book title
\ncx:title
\tableofcontents[part,appendix,chapter,likechapter,appendixsec,section,likesection,appendixsubsec,subsection,likesubsection]%
%Hack to get close tag working
\HCode{</ncx>}
\EndNoFonts
\special{t4ht<\jobname.ncx}
\HtmlParOn
}
\catcode`\:=12
\EndPreamble
重要的代码是这样的:
\tl_new:N\ncx:hfilename
\def\ncx:newhfile#1{
% cw:)Q#1 is csname of tag from the xref file
\seq_set_from_clist:Nc\l_tmpa_seq{cw:)Q#1}
\seq_get_left:NN \l_tmpa_seq \l_tmpa_tl
%\tl_to_str:N \l_tmpa_tl
% \RefFileNumber returns file name for the given file number
\tl_set:Nx \ncx:hfilename {\RefFileNumber{\l_tmpa_tl}}
}
它使用 LaTeX 3 序列列表来解析逗号分隔的列表并返回第一项。\seq_set_from_clist:Nc\l_tmpa_seq{cw:)Q#1}
使用内部使用的控制序列来保留引用。\RefFileNumber
可以代替使用\Ref{)F<number>F-}
。\ncx:hfilename
然后定义标记列表。它可用于在中注册文件名\ncxtable
:
\Configure{TocLink}{%
\ncx:newhfile{##2}
\def\navmapsrc{\ncx:hfilename\:sharp ##2}
\opf:registerfilename{\ncx:hfilename}
##4
}
这会插入到 Epub TOC 的正确链接,并注册 HTML 文件。
使用编译
tex4ebook -c config.cfg filename.tex