4

I have been using the list parsing functionality from etoolbox and I have a weird use case in which I want a space separated list.

\usepackage{etoolbox}
\DeclareListParser*{\symbolListParser}{<symbol for space character>}
\newcommand{\processSymbolList}[1]{
    \symbolListParser{}{#1}
}

I am unsure where to even start looking. I have poked around for a while looking at documentation about lists, documentation about space, and documentation about ascii characters to no avail.

so if someone could either tell me how to do it, where to look or that it isn't possible I would really appreciate it.

UPDATE: I did find this but I was looking for something a bit cleaner like what the OP wanted

UPDATE2: Thanks to Tobi for the answer. I've accepted it. below is a more general version of spacelist that behaves more like the list parser

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{ \spacelist }{ mm }{
    \seq_set_split:Nnn \l_tmpa_seq { ~ } { #2 }
    \seq_map_inline:Nn \l_tmpa_seq {
        #1{##1}
    }
}

\ExplSyntaxOff

% to use you would write it like:
\spacelist{\fbox}{Boxes and Spaces in a List}
  • I don't think etoolbox lists can be space separated. It probably depends on the implementation, where probably both delimited and undelimited arguments are used; when TeX is looking for an undelimited argument, it ignores spaces as it goes, and this may explain the infinite loop it enters if you use { } as the delimiter argument. – egreg Feb 16 '15 at 21:25
  • @egreg that is correct. that is what Tobi pointed out. so I posted code that does not use etoolbox and instead uses xparse and expl3 – Daniel Fallon Feb 17 '15 at 1:54
3

Here’s an approach using expl3

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{ \spacelist }{ m }{
   \seq_set_split:Nnn \l_tmpa_seq { ~ } { #1 }
   \seq_map_inline:Nn \l_tmpa_seq {
      \fbox { ##1 }
   }
}

\ExplSyntaxOff

\begin{document}
List: \spacelist{Boxes and Spaces in a List}
\end{document}

The code uses so called sequences which is generated by splitting the Argument #1of \spacelist at spaces, which are ~ in the new syntax*, while normal spaces are ignored. The sequins ist stored in a local, temporarily variable named \l_tempa_seq and with \seq_map_inline we can iterate through all items of the sequence. The current item is given as argument code #1, here it is ##1 because the mapping is nested inside a definition.

You may replace the \fbox part to fit your needs …


* new syntax means the syntax introduced with LaTeX3 which is currently available as the expl3packed, which is loaded by xparse. To find out more look at the manual of expl3 or source3.

1

The listofitems package can provide it, in either rendered or detokenized form:

\documentclass{article}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage{listofitems}
\newcommand\spacelist[2][]{
  \setsepchar{ }%
  \readlist\mylist{#2}%
  \showitems#1\mylist%
}
\begin{document}
List: \spacelist{Boxes and \textbf{Spaces} in a List}

Tokens: \spacelist[*]{Boxes and \textbf{Spaces} in a List}
\end{document}

enter image description here

1

You can write in two lines of TeX macros a no-package approach for your goal.

\documentclass{article}

\catcode`z 3
\makeatletter
\newcommand\spacelist[1]{\spacelist@boxit #1 {z} }%
\long\def\spacelist@boxit #1 {\ifx z#1\relax\else
         \fbox{#1}\expandafter\spacelist@boxit\fi}
\catcode`z 11
\makeatother

\begin{document}
List: \spacelist{Boxes and Spaces in a List}
\end{document}

Admission of guilt: the method is fragile if the parsed list contains \else or \fi tokens.

enter image description here

Here is more robust way still with simple means. But argument should not contain catcode 3 letter Z...

\documentclass{article}
\usepackage[T1]{fontenc}

\catcode`Z 3
\makeatletter
\newcommand\spacelist[1]{\spacelist@getone{}#1 Z }%
\long\def\spacelist@getone #1 {\spacelist@check #1.Z\spacelist@check{#1}}%
\long\def\spacelist@check  #1Z#2\spacelist@check#3%
        {\if\relax\detokenize{#1}\relax
         \expandafter\@gobbletwo % abort parse
         \else
%
% #3 contains the searched for item, but with an empty brace pair
% added, which serves to prevent brace removal in processing
% so I am showing here how to remove it with \expandafter/\@gobble
% initial braces are not lost.
% 
         \fbox{\detokenize\expandafter{\@gobble#3}}%
         \fi
         \spacelist@getone{}}%
\catcode`Z 11
\makeatother

\begin{document}
List: \spacelist{Boxes {and Spaces} in a {List with \if, \else, \end tokens}}

\end{document}

enter image description here

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.