13

Problem

This question is related to How can I specify a long list of math operators? – but with a twist: I want to allow spaces in in the comma-separated list, like so:

\newacronyms{acm, ams, cpu, nih}

For each of these, the macro \newacronym (note missing suffix “s”) should be invoked, which is defined as follows:

\newcommand*\newacronym[1]{
  \expandafter\newcommand\csname#1\endcsname[1][]{{\acronymstyle#1}##1\xspace}}

Then I can use the acronyms in a text as follows:

The \nih is the National Institute of Health.
Modern computers have several \cpu[s].

– But how does the \newacronyms macro look like?

Partial solution

I got it working without spaces – that is, it only works as \newacronyms{foo,bar}:

\newcommand*\newacronyms[1]{
  \@for\@i:=#1\do{\expandafter\newacronym\expandafter{\@i}}}

My approach (not working …)

Now I need a way to gobble the leading spaces inside the \@i macro but I’ve come up dry. My initial thought was that something along the following lines should work, but to no avail.

\def\gobble@spaces{\@ifnextchar\space{\@gobble\gobble@spaces}{}}

\newcommand*\newacronyms[1]{
  \@for\@i:=#1\do{%
    \edef\@ii{\expandafter\gobble@spaces\@i}%
    \expandafter\newacronym\expandafter{\@ii}}}

It should be noted that \gobble@spaces works in similar circumstances (although I’m not sure why … shouldn’t there be an \expandafter before the \@gobble?), just not in the above:

% This WORKS:
\def\mylst{1, 2, 3, 4}
\@for\i:=\mylst\do{print ``\expandafter\gobble@spaces\i''\\}

Incidentally, does an equivalent command already exist somewhere in the kernel? I can’t imagine that I’m the first to need it.

5 Answers 5

10

Here a solution that uses the etoolbox package:

\usepackage{etoolbox}
\newcommand*{\newacronym}[1]{\typeout{New acronym: [#1]}}
\newcommand*{\newacronyms}{%
  \let\do\newacronym
  \docsvlist
}
\newacronyms{acm, ams, cpu, nih}
7

In ConTeXt, you have a \processcommalist macro for processing comma lists. So your example could be written as

\def\newacronyms#1{\processcommalist[#1]\donewacronyms}

\def\donewacronyms#1%
  {\setvalue{#1}{\newacronym{#1}}}

I am pretty sure that there will be a LaTeX package that does the same thing. If not, you can always copy the definition of \processcommalist

5

To answer your smaller question: to gobble spaces inside a macro or even around a string of tokens, check out the trimspaces package:

\usepackage{trimspaces}
...
\newcommand*\newacronyms[1]{%
  \@for\@ii:=#1\do{%
    \trim@spaces@in\@ii
    \expandafter\newacronym\expandafter{\@ii}}}
3

A solution with the clist module of LaTeX3, which directly takes care of trimming white space:

\documentclass{article}
\usepackage{xparse,xspace}
\ExplSyntaxOn
\NewDocumentCommand{\newacronyms}{ m }
  {
   \clist_map_inline:nn { #1 }
     {
      \cs_new:cpn { ##1 } { \acroprint {##1} }
     }
  }
\NewDocumentCommand{\acroprint}{ m O{} }
  {
   { \acronymstyle #1 } #2 \xspace
  }
\ExplSyntaxOff

\newcommand\acronymstyle{\scshape}

\newacronyms{acm, ams, cpu , nih }

\begin{document}
The \nih is the National Institute of Health.
Modern computers have several \cpu[s].
\end{document}

Item foo of the comma separated list defines \foo to expand to \acroprint{foo} and \acroprint has also an optional argument following the mandatory one, so \foo[s] expands to \acroprint{foo}[s] which typesets the optional argument outside the braces delimiting the action of \acronymstyle.

The command \acroprint can be used by itself: \acroprint{bar}[s].

0

You can put everything together. Your definition of \gobble@spaces leaves much to be desired.

\documentclass{article}
\usepackage{catoptions}
\usepackage{xcolor,xspace}
\makeatletter
% \docommalist trims leading and trailing spaces in the elements of the list:
\robust@def*\newacronyms#1{%
  \docommalist{#1}{%
    \ifcsndefinable{##1}\relax
    \csn@def{##1}{\aftercsname\cpt@testopt{##1@aux}{}}%
    \csn@def{##1@aux}[####1]{{\acronymstyle##1}####1\xspace}%
  }%
}
\makeatother

\newacronyms{acm , ams , cpu, nih}

\begin{document}
\def\acronymstyle{\color{red}}
\acm, \ams, \acm[s], \ams[s]
\end{document} 

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .