# Split a string with hyphens into separate words

I want to write a macro in which I can split a string with a linking character (like a hyphen) into different words. So, I have something like \macro{one-two-three} which I would like to split into three different words. Similarly, \macro{four-five} should print "four five" (please note the space).

A restriction is that I don't want to load any package to keep the tex-file as small as possible. So I don't want to use xstring or substr or anything else.

How do I write a macro which returns me the separate words?

I'm new here, so my apologies if I didn't explain my problem clearly.

-
Welcome to TeX.SX! With "return" you mean that writing \macro{four-five} LaTeX should print "four five"? – egreg Oct 29 '12 at 14:44
Welcome to TeX.sx! A tip: You can use backticks  to mark your inline code. – Corentin Oct 29 '12 at 14:44
Yes indeed. The space inbetween is mandatory for me. – Peter Oct 29 '12 at 14:45
If you want to keep your tex-file small loading a suitable package is the way to go. I doubt that a handmade definition can be shorter than \usepackage{...}. – Ulrike Fischer Oct 29 '12 at 14:46

This will work without any package; but it would be much easier with xstring or xparse:

\documentclass{article}
\makeatletter
\newcommand{\splitlist}[1]{\@splitlist#1\@nil}
\def\@splitlist#1\@nil{%
\if\relax\detokenize{#1}\relax
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
{\@spl@tlist#1-\@nil}%
}
\def\@spl@tlist#1-#2\@nil{%
#1\space
\if\relax\detokenize{#2}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\unskip}%
{\@spl@tlist#2\@nil}%
}
\makeatother

\begin{document}

X\splitlist{}X

X\splitlist{A}X

X\splitlist{A-B}X

X\splitlist{A-B-C}X

\end{document}


Version with xstring:

\usepackage{xstring}
\newcommand{\splitlist}[1]{\StrSubstitute{#1}{-}{ }}


Version with xparse:

\usepackage{xparse}
\NewDocumentCommand{\splitlist}{>{\SplitList{-}}m}


Advanced version with xparse:

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\splitlist}{ m }
{
\tl_set:Nn \l_tmpa_tl { #1 }
\tl_replace_all:Nnn \l_tmpa_tl { - } { ~ }
\l_tmpa_tl
}
\ExplSyntaxOff


## Alternative way suggested by Herbert:

\newcommand{\splitlist}{%
\begingroup\lccode~=-
\lowercase{\def~}{ }%
\catcode-=\active
\splitlistaux}
\newcommand{\splitlistaux}[1]{%
#1\endgroup}


However this definition disallows \splitlist being in the argument to another command.

-
if we make - active and then let-\space maybe another idea – Herbert Oct 29 '12 at 16:06
@Herbert It indeed can be. – egreg Oct 29 '12 at 16:09
Wow, thanks for this elaborate answer, it works perfectly! – Peter Oct 29 '12 at 16:29

\documentclass{article}

\makeatletter
\newcommand\macro[1]{\@macro[#1-]}
\def\@macro[#1-#2]{#1%
\if\relax\detokenize{#2}\relax
\else%
\space\@macro[#2]%
\fi}
\makeatother

\begin{document}

\macro{one-two-three}

\macro{four-five}

\macro{six}

\end{document}

-
This is also a nice solution, and easier to understand for me as a newbee. Thanks a lot! – Peter Oct 29 '12 at 16:30