12

Why does this minimal example code:

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

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

\end{document}

lead to this error message:

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

but the same code works perfectly if I delete the line

\usepackage[francais]{babel}

and of course, is there any solution that preserves the use of the [french] option?

  • 1
    I would add to the answers below that if you use \@for at a document level, you're probably doing something wrong. It should presumably be wrapped inside macros with a better semantic. Then just define that macro before \usepackage[francais]{babel}. – Bruno Le Floch Jul 18 '12 at 19:12
11

The problem is that french makes : into an active character (after \begin{document}.

Solutions.

  1. Define your own list processor in the preamble

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

    and use \bflist{\names}

  2. Force : to have the correct category code:

    \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}
    

The package etoolbox defines some list processing macros that shouldn't have this problem.

6

French babel uses active characters. You must disable this before use :=:

\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}
1

You can define your own loop, which, unlike LaTeX's \@for, is even expandable:

\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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.