Extracting characters of two strings in a for loop
Without any packages:
\documentclass[]{article}
\makeatletter
\newcommand\printchar[2]{#1,#2}
\def\parsefoo#1#2,#3#4|{%
\ifx\relax#1\relax%
\else%
\ifx\relax#3\relax%
\else%
\printchar{#1}{#3}%
\ifx\relax#2\relax%
\else%
\ifx\relax#4\relax%
\else%
,\edef\@footmp{#2,#4|}%
\expandafter\parsefoo\@footmp%
\fi%
\fi%
\fi%
\fi%
}
\newcommand\foo[2]{% Takes in two strings
% <begin loop>
% Extracts out one character from both strings
\edef\@footmp{#1,#2|}%
\expandafter\parsefoo\@footmp%
%\printchar{#1}{#2}%
% Continue loop until strings run out of characters
% <end loop>
}
\makeatother
\begin{document}
\foo{abc}{def} % Should print a,d,b,e,f
haha
\end{document}
The loop will stop when either strings runs out of items.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\foo}{mmm}
{% #1 is the macro to use, #2 is the first string, #3 is the second string
\troy_foo:Nnn #1 { #2 } { #3 }
}
\seq_new:N \l_troy_foo_first_seq
\seq_new:N \l_troy_foo_second_seq
\cs_new_protected:Nn \troy_foo:Nnn
{
% split the first string into items
\seq_set_split:Nnn \l_troy_foo_first_seq { } { #2 }
% split the second string into items
\seq_set_split:Nnn \l_troy_foo_second_seq { } { #3 }
% map over the two string
\seq_mapthread_function:NNN \l_troy_foo_first_seq \l_troy_foo_second_seq #1
}
\ExplSyntaxOff
\newcommand{\printchars}[2]{#1#2\par}
\begin{document}
\foo{\printchars}{abc}{def}
\end{document}
A fully expandable variant:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\loopstrings}{mmm}
{
\troy_loopstrings:Nnn #1 { #2 } { #3 }
}
\cs_new:Nn \troy_loopstrings:Nnn
{
\__troy_loopstrings:Nffff #1
{ \tl_head:n { #2 } } { \tl_head:n { #3 } }
{ \tl_tail:n { #2 } } { \tl_tail:n { #3 } }
}
\cs_new:Nn \__troy_loopstrings:Nnnnn
{
\bool_lazy_or:nnF { \tl_if_empty_p:n { #2 } } { \tl_if_empty_p:n { #3 } }
{
#1{#2}{#3}
\troy_loopstrings:Nnn #1 { #4 } { #5 }
}
}
\cs_generate_variant:Nn \__troy_loopstrings:Nnnnn { Nffff }
\ExplSyntaxOff
\newcommand{\printchars}[2]{#1#2\par}
\begin{document}
\loopstrings{\printchars}{abcd}{1234}
\loopstrings{\printchars}{abc}{1234}
\loopstrings{\printchars}{abcd}{123}
\end{document}
Here's a LuaLaTeX-based solution. (Exact same output as in @egreg's answer, hence no separate screenshot.)
%% to be compiled under LuaLaTeX
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function string_pair ( u , v )
for i=1,string.len(u) do
tex.sprint ( string.sub (u,i,i) .. string.sub (v,i,i) .. "\\par" )
end
end
\end{luacode}
\newcommand\foo[2]{\directlua{string_pair(\luastring{#1},\luastring{#2})}}
\begin{document}
\foo{abc}{def}
\end{document}