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.

I have a big text referring to 500+ scientific epynoms like e.g. "Maxwell's equations". These eponyms should go into the main index and they should also show up in footnotes - but only once-per-chapter. I have written a macro that so far does 90% of the job. I can for instance write

\eponym{le Chatelier}
\eponym{Le Chatelier}
\eponym{L e C h a t e l i e r}
\eponym{Le Chat'elier}
\eponym{Le Chat\'elier}

and have the command sequence \@eChatelier defined such that it keeps the current chapter number. The first line does then produce a footnote - the others do not - as long as \thechapter does not change. This is fine. The problem I am facing is connected to the use of foreign accents. E.g.

\eponym{Le Chat{\'e}lier}

produces the error:

! Missing = inserted for \ifnum.
<to be read again> 
                   e
l.70  \eponym{Le Chat{\'e}lier}

I hope the question is reasonably well formulated. The MWE is here:

\documentclass{report} 

\makeatletter

% Convert first letter in string to uppercase. 
% Then call \@tail on remaining string.

\def\@head#1{%
 \ifx\relax#1
 \else
  \ifnum \the\catcode`#1 = 11
%    \uppercase{#1}%          *** this line gives an error - I am not 100% sure why
%    #1%                     *** OK but makes eg "van der" different from "Van der"
   @%    *** removes the semantics problem above at the cost of introducing a hack!
  \else
  \fi
  \expandafter\@tail
 \fi
}

% Keep a-z, A-Z. 
% Ignore all other characters.

\def\@tail#1{%
 \ifx\relax#1
 \else
  \ifnum \the\catcode`#1 = 11
   #1%
  \else
  \fi
  \expandafter\@tail
 \fi
}

% To each eponym define a command sequence holding the chapter number.
% Print footonote.
% Do once-per-chapter only.
% Start over again when (if) the chapter counter is changed.

\newcommand{\eponym}[1]{%
 \edef\@@az{\@az{#1}}%                                           *** shortcut
 \ifcsname\@@az\endcsname%                              *** chapter 2, 3, etc
  \ifnum \thechapter > \csname\@@az\endcsname%        *** counter has changed
   \expandafter\edef\csname\@@az\endcsname{\thechapter}%
   {\sc #1}\expandafter\footnote{CSname: \@@az}%
  \else
   {\sc #1}%                                    *** same chapter as last time
  \fi
 \else%                                                    *** chapter 1 only
  \expandafter\edef\csname\@@az\endcsname{\thechapter}%
  {\sc #1}\expandafter\footnote{CSname: \@@az}%
 \fi
}

% Filter everything except a-z, A-Z from argument.
\def\@az#1{\@head #1\relax}

\makeatother

\begin{document} 

\section*{Chapter~\thechapter}

\eponym{le Chatelier}\\
\eponym{Le Chatelier}\\
\eponym{L e C h a t e l i e r}\\
\eponym{Le Chat'elier}\\
\eponym{Le Chat\'elier}\\
\eponym{Le Chat\' elier}\\
\eponym{Le Chat{\'e}lier}%                 *** this line gives an error - why?

\end{document}
share|improve this question
add comment

4 Answers

Using a safer catcode test of

  \ifcat a\noexpand#1%

makes your document run without error although {\'e} is not considered equal to the others. It is in any case a bad markup style to use braces like that as it prevents any kerns ligatures that should be between the letters. If however all brace groups should be stripped that could be added.

If you want to lose the brace groups, so get just one footnote marker on the test file, then change

\def\@tail#1{%

to

\def\@tail#1{\@@tail#1}

\def\@@tail#1{%

where you use one macro expansion level to strip off one level of brace group.

share|improve this answer
    
Hmmm, seems like I have to change my LaTeX input style. I am using {\'e}, {\o}, {\aa} etc all the time since they (to me) appear more "markup oriented". I was not aware of the ligature issue. Thanks for notifying me. On the other hand, stripping braces (not their contents) are nevertheless of interest. –  Tore H-W Mar 26 '13 at 17:09
    
Brace group stripping line added –  David Carlisle Mar 26 '13 at 17:15
    
In other words: \@tail reads one (maybe braced) token and \@@tail rip it apart. Right? –  Tore H-W Mar 26 '13 at 17:31
    
yes \@tail a would be \@@tail a which is the code you had , but \@tail {abc}xyz would be \@@tail abcxyz which is the code you had, after the group is gone. –  David Carlisle Mar 26 '13 at 17:43
    
For the time being I've implemented @DavidCarlisle's suggestion(s) and it all works. In the future I will also give @StevenBSegletes 's stringstrings approach atry. However, the question is not only to achieve a solution but also to learn something new. Right now I am in the mood of learning a little TeX... Thanks! –  Tore H-W Mar 27 '13 at 13:17
add comment

Leaving the footnote stuff aside, and concentrating on the string manipulation, the stringstrings package can do this simply:

\documentclass{report} 

\usepackage{stringstrings}

\begin{document} 

\section*{Chapter~\thechapter}

\newcommand\eponym[1]{%
  \noblanks[e]{#1}%
  \capitalize[e]{\thestring}%
  \alphabetic{\thestring}%
}

\eponym{le Chatelier}\\
\eponym{Le Chatelier}\\
\eponym{L e C h a t e l i e r}\\
\eponym{Le Chat'elier}\\
\eponym{Le Chat\'elier}\\
\eponym{Le Chat\' elier}\\
\eponym{Le Chat{\'e}lier}

\end{document}
share|improve this answer
    
Truely beautiful! I was not aware of the stringstrings package. –  Tore H-W Mar 26 '13 at 17:33
    
@ToreHaug-Warberg Thanks. The approach of leaving intermediate results in \thestring allows one to string together complex string manipulations, each taking \thestring to the next level. –  Steven B. Segletes Mar 26 '13 at 17:51
add comment

I'd do it in a very different way:

\documentclass{report}
\usepackage[utf8]{inputenc}
\usepackage{xparse,l3regex}
\ExplSyntaxOn
\makeatletter
\NewDocumentCommand{\eponym}{m}
 {
  \tore_eponym:n { #1 }
 }
\cs_new_protected:Npn \tore_eponym:n #1
 {
  % A bit of LaTeX2: resolve commands into the LICR
  \protected@edef \l_tore_eponym_tl { #1 }
  %
  % Remove all non letters from the token list
  \regex_replace_all:nnN { [^A-Za-z]+ } { } \l_tore_eponym_tl
  % change the first letter with @
  \tl_set:Nx \l_tore_eponym_tl { @ \tl_tail:V \l_tore_eponym_tl }
  % print the argument
  \textsc{#1}
  % if the control sequence is not defined, define it and add a footnote
  \cs_if_exist:cF { \l_tore_eponym_tl }
   {
    \cs_set:cpx { \l_tore_eponym_tl } { \thechapter }
    \footnote{CSname:~\cs_to_str:c { \l_tore_eponym_tl } }
   }
 }
% A variant we need for printing the control sequence name
\cs_generate_variant:Nn \cs_to_str:N { c }
% The needed variable
\tl_new:N \l_tore_eponym_tl

\makeatother
\ExplSyntaxOff

\begin{document} 

\chapter{Abc}

\eponym{le Chatelier}\\
\eponym{Le Chatelier}\\
\eponym{L e C h a t e l i e r}\\
\eponym{Le Chat'elier}\\
\eponym{Le Chat\'elier}\\
\eponym{Le Chat\' elier}\\
\eponym{Le Chat{\'e}lier}\\
\eponym{Le Chatélier}

What chapter? Number \csname @eChatelier\endcsname
\end{document}

With \protected@edef the accented characters, even if given directly with the help of inputenc, will be translated into the "expanded form", precisely the LICR. However, letters such as \ae or \o would be stripped. It would be possible to add them to an exception list, with a proper translation into letters.

enter image description here

share|improve this answer
    
Impressive! I've heard about the regex package in LaTeX but I have never given it a try. Is it stable? I have year-long experience with regex in Ruby, Python (and Perl) but when it comes to LaTeX I am hesitating. There are so many projects "out there" that I most of all want to stay portable. Secondly, I want to start learning TeX as well. What about LuaTeX? Would that be an alternative? –  Tore H-W Mar 26 '13 at 17:18
    
The l3regex should be quite stable. LuaTeX is a "superset" of TeX: it understands all TeX and adds a Lua interface to the internals of TeX. –  egreg Mar 26 '13 at 17:25
    
OK. I must read up on l3regex as well. –  Tore H-W Mar 26 '13 at 17:37
add comment

My answer to Can one define an expandable command that removes control sequences from its argument? solved basically this problem for basically the same purpose. You could take a look at it, though it is less polished than one of the other, package-based answers.

share|improve this answer
    
Without actually trying out your code I am quite sure it will work. I do not have the time right now but I will keep it in the back of my head. –  Tore H-W Mar 27 '13 at 13:22
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.