使用希腊语 babel、mparhack 和 \pagenumbering{roman} 时出错

使用希腊语 babel、mparhack 和 \pagenumbering{roman} 时出错

使用:

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之后,该错误才会首先出现greekbabel

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}

相关内容