我使用 TeXLive 和 XeLaTex 我有一个 Expl3 函数在每个单词的字符之间插入一个字符。
我的代码:
\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}
我明白了:
正如您在第一行中看到的,它显示了我想要得到的结果。但是当我使用 \myCustom 时,里面的宏会产生不同的结果。
答案1
\seq_set_split:Nnn \l_tmpa_seq {} {<tokens>}
仅当您没有控制序列时,您才能获得合理的结果<tokens>
。
例如,第二个单词将被拆分为
{\textbf}
{{d\underline{ef}}}
(以序列的通常表示形式,您可以用来进行检查\seq_show:N
)这解释了您所得到的内容。
对于您的应用程序,您需要更强大的方法,即正则表达式。
我将单词中的每个字母都改为后面跟有连字符的字母,然后删除最后一个字母,该字母后面直到最后都没有任何字母。
\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}
我更改了名称以符合命名指南。