为什么 \captiondelim 会导致 babel-french 出错?

为什么 \captiondelim 会导致 babel-french 出错?

下面的 MWE 导致错误:

./caption-err.tex:9: Argument of \reserved@a has an extra }.
<inserted text> 
                \par 
l.9 \begin{document}
                    
? q
OK, entering \batchmode...
Runaway argument?
{.\ }\ifx \reserved@a \@empty \let \check@icl \@empty \let \check@icr \ETC.
./caption-err.tex:9: Paragraph ended before \reserved@a was complete.
<to be read again> 
                   \par 
l.9 \begin{document}
                    
I suspect you've forgotten a `}', causing me to apply this
control sequence to too much text....

如何修复?

错误确实不是french如果不用作选项,则发生babel

\documentclass{memoir}
\usepackage[T1]{fontenc}
\usepackage[french,ngerman,main=english]{babel}

\captionnamefont{\sffamily}
\captiondelim{\textsf{.\ }}
\begin{document}

\begin{figure}
\centering
\framebox[15in][c]{\rule{0pt}{1in}}
\caption{A figure.}
\end{figure}

\end{document}

有关的:

在回忆录中使用 Babel French 更改标题标签分隔符,但没有标题包?

答案1

新版本的 french.ldf 包含\edef\FB@capsep{\@contdelim}。这不是一个好主意,因为它无法控制 的内容\@contdelim,因此无法确定它是否可扩展。这至少应该是\protected@edef\FB@capsep{\@contdelim}。向作者报告。

\edef定义中的会\textsf中断。因此,避免此错误的一种方法是改用\captiondelim{.\ }

答案2

直到french.ldf更新以修复故障,您才能\@contdelim在下进行增强\edef

\documentclass{memoir}
\usepackage[T1]{fontenc}
\usepackage[french,ngerman,main=english]{babel}

\captionnamefont{\sffamily}
\captiondelim{\textsf{.\ }}
\makeatletter
\protected\edef\@contdelim{\unexpanded\expandafter{\@contdelim}}
\makeatother


\begin{document}

\begin{figure}
\centering
\framebox[5in][c]{\rule{0pt}{1in}}
\caption{A figure.}
\end{figure}

\end{document}

的上一版本french.ldf(2020/04/18 v3.5h)具有

1541      \ifFBCustomiseFigTabCaptions
1542        \ifFB@koma
1543          \renewcommand*{\captionformat}{\CaptionSeparator}%
1544        \fi
1545        \@ifclassloaded{memoir}%
1546           {\captiondelim{\CaptionSeparator}}{}%
1547        \@ifclassloaded{beamer}%
1548           {\defbeamertemplate{caption label separator}{FBcustom}{%
1549                \CaptionSeparator}%
1550            \setbeamertemplate{caption label separator}[FBcustom]}{}%
1551      \else
1552        \ifFB@koma
1553          \renewcommand*{\captionformat}{{\autospace@beforeFDP : }}%
1554        \fi
1555        \@ifclassloaded{memoir}%
1556           {\captiondelim{{\autospace@beforeFDP : }}%
1557           }{}%
1558        \@ifclassloaded{beamer}%
1559           {\defbeamertemplate{caption label separator}{FBcolon}{%
1560                 {\autospace@beforeFDP : }}%
1561            \setbeamertemplate{caption label separator}[FBcolon]%
1562           }{}%
1563      \fi

新版本 2020/06/30 v3.5i 重新编写了上述代码

1551      \@ifclassloaded{memoir}%
1552         {\edef\FB@capsep{\@contdelim}\edef\FB@std@capsep{: }%
1553          \ifx\FB@capsep\FB@std@capsep
1554            \ifFBCustomiseFigTabCaptions
1555              \captiondelim{\CaptionSeparator}%
1556            \else
1557              \captiondelim{{\autospace@beforeFDP : }}%
1558            \fi
1559          \fi}{}%

这在很多方面都是有争议的。没有理由这样做

\edef\FB@std@capsep{: }

when\def已经足够了。但主要错误在于前面的声明应该是

\let\FB@capsep\@contdelim

因为代码想要比较意义符合\@contdelim标准。那么,用户可能会

\newcommand{\mycaptiondelim}{: }
\captiondelim{\mycaptiondelim}

并且执行的测试french.ldf将返回 false(使用建议的修复)。但是它应该返回 false,因为用户肯定有间接的原因(例如,他们想避免french.ldf优先考虑他们的偏好)。

正如 Ulrike Fischer 在她的回答中所述,这\edef在概念上是错误的,因为没有什么可以确定\@contdelim只包含\edef-safe 令牌。

相关内容