How can I split the string Hello World!
- stored into a macro \def\mystring{Hello Word!}
- into a comma-separated list of characters (including spaces) which can be used as argument of a \foreach
loop (\foreach \char in {\myCSlist}
) in order to loop over each character (as with \foreach \char in {H,e,l,l,o,\space,W,o,r,l,d,!})
?
EDIT 1 (Mar 21): Why I want that?
At first, I didn't explain why I want the solution generates a comma-separated list of characters (e.g. \myCSlist
) which can be used as argument of a \foreach
. It's because I want to create a Tikz \node
for each character using a pic
. Something like this (from here):
\newcommand{\hsp}{.5}
\tikzset{symbols/.pic={%
\foreach \s[count=\n from 0] in {\myCSlist}{%
\pgfmathsetmacro{\myangle}{360*rnd}%
\node[rotate=\myangle] at (\hsp*\n,0){\s};%
}}}%
First attempt
I tried with the \markletters
macro of egreg (using xparse and expl3) but the results seems to be not suitable for looping with foreach
.
I changed the result print - of the \markletters
macro - from (##1)
to ##1,
, in order to obtain a comma-separated list, but this also results in a unwanted comma ,
at the end of the comma-separated list.
Here a M(Non)WE:
\documentclass{article}
\usepackage{tikz}% For the \foreach loop
\usepackage{xparse}
% egreg's \markletters macro : https://tex.stackexchange.com/a/359204/262081
\ExplSyntaxOn
\NewDocumentCommand{\markletters}{om}
{
\IfNoValueTF{#1}
{
\kessels_markletters:nn { #2 } { \tl_use:N \l_kessels_marked_letters_tl }
}
{
\kessels_markletters:nn { #2 } { \tl_set_eq:NN #1 \l_kessels_marked_letters_tl }
}
}
\tl_new:N \l_kessels_unmarked_letters_tl
\tl_new:N \l_kessels_marked_letters_tl
\cs_new_protected:Nn \kessels_markletters:nn
{
\tl_set:Nn \l_kessels_unmarked_letters_tl { #1 }
\tl_replace_all:Nnn \l_kessels_unmarked_letters_tl { ~ } { \textvisiblespace }
\tl_clear:N \l_kessels_marked_letters_tl
\tl_map_inline:Nn \l_kessels_unmarked_letters_tl
{
\tl_put_right:Nn \l_kessels_marked_letters_tl { ##1, }
}
#2
}
\ExplSyntaxOff
\def\mystring{Hello World!}
\begin{document}
\markletters[\foo]{\mystring}%
\foreach \char in {\foo}{%
<\char>%
}%
\end{document}
This gives the following result:
But I would prefer this result (note the presence of the space between 'Hello' and 'World'):
lua
to do this, instead of all this weird\tl_new:N #
unreadable stuff :)