# Expl3 seq with macros

I use it TeXLive with XeLaTex I had an Expl3 function to insert a character between the characters of each word.

My code:

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn
\seq_new:N \l_mycustom
\seq_new:N \l_mycustom_out
\seq_new:N \l_mycustom_tmp
\newcommand{\mycustom}[1] {
\seq_set_split:Nnn \l_mycustom {~} { #1 }
\seq_map_inline:Nn \l_mycustom {
\seq_set_split:Nnn \l_mycustom_tmp {} {##1}
\seq_put_right:Nx \l_mycustom_out {
\seq_use:Nn \l_mycustom_tmp {-}
}
}
\seq_use:Nn \l_mycustom_out {~}
}
\ExplSyntaxOff

\setlength\parindent{0pt}
\begin{document}
a-b-c \textbf{d-\underline{e-f}} g-h-i \\
\mycustom{abc \textbf{d\underline{ef}} ghi}
\end{document}


I get this:

As you can see in the first line it shows what I want to get. But when I use \myCustom the macro inside that make a different result.

• Easy to explain what you get, difficult to implement what you want. Your second \seq_set_split:Nnn generates a sequence of two items: \textbf and d\underline{ef} because of the semantic of \seq_set_split:Nnn (spaces removed on both sides of each item, then one set of outer braces removed). Then your macro inserts a - separator between them, which becomes the argument of \textbf. The output is thus \textbf-d\underline{ef}, which corresponds to your screenshot. – frougon Apr 10 at 22:09

You can get sensible results from \seq_set_split:Nnn \l_tmpa_seq {} {<tokens>} only if you don't have control sequences in <tokens>.

For instance, the second word would be split as

{\textbf}
{{d\underline{ef}}}


(in the usual representation of sequences, which you can check with \seq_show:N) which explains what you get.

For your application you need more powerful methods, namely regular expressions.

I change every letter in the word by the letter followed by a hyphen, then remove the last one, which is not followed by any letter up to the end.

\documentclass{article}
\usepackage{expl3,xparse}

\ExplSyntaxOn
\NewDocumentCommand{\mycustom}{m}
{
\mycustom_main:n { #1 }
}

\seq_new:N \l__mycustom_in_seq
\seq_new:N \l__mycustom_out_seq
\tl_new:N \l__mycustom_word_tl

\cs_new_protected:Nn \mycustom_main:n
{
\seq_clear:N \l__mycustom_out_seq
\seq_set_split:Nnn \l__mycustom_in_seq {~} { #1 }
\seq_map_variable:NNn \l__mycustom_in_seq \l__mycustom_word_tl
{
\__mycustom_word:N \l__mycustom_word_tl
}
\seq_use:Nn \l__mycustom_out_seq {~}
}

\cs_new_protected:Nn \__mycustom_word:N
{
\regex_replace_all:nnN { ([[:alpha:]]) } { \1\- } #1
\regex_replace_once:nnN { \- ([^[:alpha:]]*) \Z } { \1 } #1
\seq_put_right:NV \l__mycustom_out_seq #1
}
\ExplSyntaxOff

\begin{document}

a-b-c \textbf{d-\underline{e-f}} g-h-i

\mycustom{abc \textbf{d\underline{ef}} ghi}

\end{document}


I changed the names to conform to the naming guidelines.

• Thanks, I had a question if I want the special and unicode characters like a string: "hello, 감. [best]" transform in: "h-e-l-l-o 감-. [-b-e-s-t-]" if I try with regex like \s\S don't work as expected – jtwalters Apr 11 at 16:39
• @jtwalters With what engine? – egreg Apr 11 at 17:06
• The same, TeXLive with XeLaTex – jtwalters Apr 11 at 17:07