为什么 babel[french] 包会破坏 \@for 循环?

为什么 babel[french] 包会破坏 \@for 循环?

为什么这个最小示例代码:

\documentclass{article}
\usepackage[francais]{babel}
\begin{document}

\def\names{Toto,Titi,Tete,Tutu}
\makeatletter
\@for\next:=\names\do{\textbf{\next} }
\makeatother

\end{document}

导致此错误信息:

Runaway argument?
\next :=\names \do {\textbf {\next } } \makeatother \par \end {docume\ETC.
! File ended while scanning use of \@for.

但如果我删除该行,同样的代码就可以完美运行

\usepackage[francais]{babel}

当然,有没有什么解决方案可以保留 [french] 选项的使用?

答案1

问题是french使其:成为一个主动角色(之后)\begin{document}

解决方案。

  1. 在序言中定义自己的列表处理器

    \makeatletter
    \newcommand{\bflist}[1]{\@for\next:=#1\do{\textbf{\next}}}
    \makeatother
    

    并使用\bflist{\names}

  2. 强制:使用正确的类别代码:

    \documentclass{article}
    \usepackage[francais]{babel}
    \begin{document}
    
    \def\names{Toto,Titi,Tete,Tutu}
    \makeatletter
    \expandafter\@for\expandafter\next\string:=\names\do{\textbf{\next} }
    \makeatother
    
    \end{document}
    

该包etoolbox定义了一些不应该存在此问题的列表处理宏。

答案2

法语 babel 使用活动字符。使用前必须禁用此功能:=

\documentclass{article}
\usepackage[francais]{babel}
\begin{document}

\def\names{Toto,Titi,Tete,Tutu}
\makeatletter
\shorthandoff{:}
\@for\next:=\names\do{\textbf{\next} }
\shorthandon{:}
\makeatother

\end{document}

答案3

你可以定义自己的循环,与 LaTeX 的循环不同\@for,它甚至是可扩展的:

\documentclass{article}
\usepackage[francais]{babel}
\usepackage{xcolor}
\def\amfor#1#2{\doam{#2}#1,\doam,}
\def\doam#1#2,{\ifx\doam#2\amend\fi#1{#2}\doam{#1}}
\def\amend#1\doam#2{\fi}

\begin{document}
% The equivalent of Cristo's original example:
\amfor{Toto,Titi,Tete,Tutu}\textbf
\par\bigskip

% More tests:
\def\dspace#1{\def\cspace{\def\cspace{\space#1\space}}}
\dspace\textbullet
\amfor{Toto,Titi,Tete,Tutu}{\cspace\textbf}
\par\bigskip

\dspace{\textcolor{red}\textasteriskcentered}
\def\do#1{\cspace\textbf{#1}}
\amfor{Toto,Titi,Tete,Tutu}\do
\par\bigskip

% Building a stack in an expandable fashion:
\newcount\nr\nr=2\relax
\def\eat#1{}
\def\do#1{%
  \let\noexpand#1%
  \expandafter\noexpand\csname\expandafter\eat\string#1/\romannumeral\nr\endcsname
}
\edef\x{\amfor{\cmda,\cmdb,\cmdc}\do}
\def\strippref#1>{}
{\tt\expandafter\strippref\meaning\x}
\end{document}

相关内容