编辑:我已经编辑了我的问题,该问题最初错误地集中在标签上。
这个问题与\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}
因此标签中的活性字符本质上是不安全的。