Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
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
add comment

3 Answers

up vote 11 down vote accepted

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.

share|improve this answer
add comment

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}
share|improve this answer
add comment

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}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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