使用:
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014) (preloaded format=pdflatex)
...我编写了以下MWE:
\documentclass[10pt,twoside,openright]{book}
%\usepackage[english]{babel}
\usepackage[greek,english]{babel} %% A
\usepackage{mparhack} %% B
\usepackage{lipsum}
\begin{document}
\pagenumbering{roman} %% C
Testing
\lipsum[1]
\end{document}
...这会触发以下错误pdflatex test.tex
:
! Use of \\@lipsum doesn't match its definition.
\text@command #1->\def \reserved@a {
#1}\ifx \reserved@a \@empty \let \check@...
l.12 \end{document}
?
! Unbalanced write command.
<write> \string \mph@setcol {ii:\thepage }{
\string \mph@nr }
l.12 \end{document}
? X
有趣的是,出现此错误仅有的当 A、B 和 C 三者都存在时;如果我们用 替换 A \usepackage[danish,english]{babel}
(如果在重新编译之前先删除旧的 .aux 文件),则不会发生这种情况。(注意:在我的原始文档中,我实际上得到了! Incomplete \iffalse; all text was ignored after line ...
出现在\mph@outputpage@hook
中的;但同样,只有在添加到mparhack
之后,该错误才会首先出现greek
babel
)
babel
因此,这似乎是 Greek和interact时发生的特定错误。我该如何摆脱它mparhack
?\pagenumbering{roman}
答案1
这个问题相当微妙,lipsum
实际上并不复杂。
问题分析
该mparhack
包在文件中做了一些注释.aux
,使用
\newcommand*\mph@outputpage@hook{%
\bgroup
\advance\c@page\m@ne
\immediate\write\@auxout{%
\string\mph@setcol{ii:\thepage}{\string\mph@nr}%
}%
\egroup
}
问题就从这里开始:使用\pagenumbering{roman}
命令\thepage
意味着和,当使用希腊语时,所使用的\roman{page}
命令不再存在,因为它现在包含的命令不是完全可扩展的。\@roman
\roman
\write
\textlatin
错误涉及\\@lipsum
因为这个宏恰好存储在中\reserved@a
,但这只是症状,而不是疾病。
治愈
\documentclass[10pt,twoside,openright]{book}
\usepackage[greek,english]{babel}
\usepackage{mparhack}
\usepackage{lipsum}
\makeatletter
\renewcommand*\mph@outputpage@hook{%
\bgroup
\let\textlatin\@firstofone % make \textlatin a no-op
\advance\c@page\m@ne
\immediate\write\@auxout{%
\string\mph@setcol{ii:\thepage}{\string\mph@nr}%
}%
\egroup
}
\makeatother
\begin{document}
\pagenumbering{roman}
Testing
\lipsum[1]
\end{document}
这成功地消除了在编写注释时扩展原始内容的任何尝试\textlatin
。重新定义是按组进行的,因此\textlatin
一旦\egroup
扫描到,的含义就会恢复。在.aux
文件中,你会发现
\mph@setcol{ii:i}{\mph@nr}
这应该是正确的,因为ii:i
它仅用作唯一标签。
进一步的问题
如果twocolumn
使用了该选项,问题将以不同的形式再次出现;一个可能的解决方案是修补和\mph@setcol
,\mph@check
因为在这种情况下,实际上不可能\textlatin
从注释中删除,因此我们在执行\mph@setcol
和时将其删除\mph@check
。在它们周围添加一个组不是问题,因为无论如何两者都只执行全局分配。
\documentclass[10pt,twoside,openright,twocolumn]{book}
\usepackage[greek,english]{babel}
\usepackage{mparhack}
\usepackage{lipsum}
\usepackage{etoolbox}
\makeatletter
% this is the hack for one column output
\patchcmd\mph@outputpage@hook
{\bgroup}
{\bgroup\let\textlatin\@firstofone}
{}{}
% this is the hack for two column output
\pretocmd\mph@setcol{\bgroup\let\textlatin\@firstofone}{}{}
\apptocmd\mph@setcol{\egroup}{}{}
\pretocmd\mph@check{\bgroup\let\textlatin\@firstofone}{}{}
\apptocmd\mph@check{\egroup}{}{}
\makeatother
\begin{document}
\pagenumbering{roman}
Testing
\lipsum[1]
\end{document}
答案2
好的,我得到了一些信息,但我不确定它是否正确 - 因此,如果能得到更多博学的回答,我将不胜感激。通过使用 package ,我比较了 babel 正确选项和有问题选项的{trace}
跟踪输出。两种变体都出现在此堆栈跟踪中:[english]
[greek,english]
\mph@outputpage@hook ->\bgroup \advance \c@page \m@ne \immediate \write \@auxout {\string \mph@setcol {ii:\thepage }{\string \mph@nr }}\egroup
\thepage ->\csname @roman\endcsname \c@page
此时,\@roman
命令被调用;在[english]
-only 情况下,它是:
\@roman #1->\romannumeral #1
...但在这种[greek,english]
情况下,它是:
\@roman #1->\expandafter \textlatin \expandafter {\romannumeral #1}
...并\textlatin
调用\text@command #1->\def \reserved@a {#1}...
where #1<-i
(页码 1 的罗马数字i
);然而在这种情况下结果\reserved@a ->\\@lipsum
不知何故,所以我们会得到,我猜\@lipsum{i}
是尝试执行,但这确实是错误的。
我读了一下texdoc babel-greek
,似乎\textlatin
是为了确保切换到拉丁语言字体/编码;我猜显然\@roman
是通过简单地重新定义的,babel-greek
以确保引擎在尝试排版罗马数字之前处于“拉丁文本”模式,这是有道理的 - 但在这种情况下会产生不幸的交互。
我使用 for[greek,...]{babel}
主要是为了确保字体/编码正确显示 μsiunitx
等(相关:babel-greek、TexLive 2014 中可能存在错误);我不会使用希腊文本的部分。因此,在希腊文本模式下排版罗马数字的可能性非常低,所以我想:为什么不将命令重新定义\@roman
为原来的命令呢?以下方法texdef
有帮助:
$ texdef -t latex -s @roman
% latex.ltx, line 1850:
\def\@roman#1{\romannumeral #1}
...因此,现在起作用的固定 MWE 是:
\documentclass[10pt,twoside,openright]{book}
\usepackage{trace}
\usepackage[greek,english]{babel} %% A
\usepackage{mparhack} %% B
\usepackage{lipsum}
\begin{document}
\traceon
\pagenumbering{roman} %% C
% latex.ltx, line 1850: % fix
\makeatletter % fix
\def\@roman#1{\romannumeral #1} % fix
\makeatother % fix
Testing
\lipsum[1]
\end{document}