2

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:

Result

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
4

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.

enter image description here

  • 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

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.