在某些罕见情况下会出现错误:babel 在列表后带有法语选项、移动参数中的活动字符、跨页面列表中的代码

在某些罕见情况下会出现错误:babel 在列表后带有法语选项、移动参数中的活动字符、跨页面列表中的代码

编辑:我已经编辑了我的问题,该问题最初错误地集中在标签上。

这个问题与\lstlisting 中的代码破坏了文档(编译错误)让我们考虑以下 MWE:

\documentclass{article}
\usepackage{lipsum}
\usepackage{listings}
\usepackage[french]{babel}
%
\begin{document}
%
\begin{figure}
  \caption{Foo ; bar}
\end{figure}
%
\lipsum[1-4]%
%
\begin{lstlisting}
Foo 1
Foo 2
Foo 3
Foo 4
Foo 5
Foo 6
Foo 7
Foo 8
Foo 9
\end{lstlisting}
%
\end{document}

当用 编译时pdflatex,会出现错误:

! Incomplete \iffalse; all text was ignored after line 15.
<inserted text> 
                \fi 
l.23 Foo 
         9
?

奇怪的是,错误不会在以下任一情况下立即出现:

  • 列表不跨页(例如通过删除Foo 9),
  • babel与另一种语言一起使用french
  • ;在 caption 参数(我猜是一个移动参数)中被替换为非活动字符frenchb(任何不同于 的字符;:!?),
  • listings包在之后加载babel

因此,有几种解决方法,但我想了解发生了什么,并知道是否有办法始终如一地摆脱这个错误。

答案1

简而言之,这里发生了什么。

冒号定义为\active@prefix :\active@char:。此定义使得在某些条件下(例如在 protected@write 中,或者当\if@safe@actives为真时(即 中的情况\@newl@bel))会:扩展为标签中的“安全”内容。

但是在您的示例中,:随着 listings 的介入,这个安全定义不再存在。listings 重新定义了:

 \def :{\lst@ProcessOther :}

因此在输出例程中(当标签写入辅助时),没有:“安全”定义和中断。

如果您在 babel 之后加载列表,它就会起作用,因为列表在每一行之后重置定义,所以现在 babel 定义在输出中处于活动状态。

但您应该意识到,任何重新定义:都可能破坏标签:

\documentclass{article}
\usepackage[frenchb]{babel}%
\begin{document}
\rule{0.4pt}{.805\textheight}\par
\section{Listing}
\tracingmacros=1
\label{secccc:listing}
%
Foo
Foo 1
Foo 2
Foo 3\def:{~}
Foo 4
\end{document}

因此标签中的活性字符本质上是不安全的。

相关内容