将每个可选参数映射到应用特定样式的函数的正确方法是什么?
在下面的示例中,可选参数以粗体显示,前面带有冒号。但我希望用户能够定义要以何种样式#2
进行排版,#3
等等:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand {\mystyle} { m } {:\textbf{#1}}
\NewDocumentCommand {\mycs} { moooooooo }
{
#1
\tl_set:Nn \l_my_tl { {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9} }
\tl_map_inline:Nn \l_my_tl {\IfValueT{##1}{\mystyle{##1}}}
}
\ExplSyntaxOff
\begin{document}
\mycs{1}[2][3][4][5][6][7][8][9]
\end{document}
答案1
以下可能是一个选项。\setstyle
宏采用逗号分隔的命令名称列表,可能以字符开头。默认情况下,列表以逗号分隔,但可选参数可以将分隔符更改为任意值。在下面的例子中,我使用了
\setstyle{:\textbf,.\emph,\textsc}
该\usestyles
宏接受两个强制参数。第一个对应于上面的强制参数,第二个是参数列表。默认情况下,列表以逗号分隔,但可以使用可选参数进行更改。n
然后将第一个样式映射到第一个n
参数。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% optional arg1 changes the separator for arg2
\NewDocumentCommand{\setstyle}{ O{,} m }{
\ss_set_my_styles:nn {#1}{#2}
}
% optional arg1 changes the separator for arg3
\NewDocumentCommand{\usestyles}{ O{,} m m }{
\ss_use_my_styles:nnn {#1}{#2}{#3}
}
% split style list at separator and store
\seq_new:N \g__ss_my_styles_seq
\cs_new:Npn \ss_set_my_styles:nn #1#2
{
\seq_set_split:Nnn \g__ss_my_styles_seq {#1}{#2}
}
\cs_new:Npn \ss_use_my_styles:nnn #1#2#3
{
#2\par
% split arg list at separator
\seq_set_split:Nnn \l_tmpa_seq {#1}{#3}
% map styles to list items in order
\seq_mapthread_function:NNN \g__ss_my_styles_seq \l_tmpa_seq \__ss_use:nn
}
\cs_new:Npn \__ss_use:nn #1#2
{
% applies arg1 to arg2
#1{#2}\par
}
\ExplSyntaxOff
\begin{document}
\setstyle{:\textbf,.\emph,\textsc}
\usestyles{first}{arg1,arg2,arg3}
\end{document}
另一个选项是使用l3regex
。这样,您可以在参数之前和之后添加字符。
\setstyle[<separator>][<string to replace>]{<style list>}
第一个可选项设置分隔符,<style list>
默认为逗号,第二个可选项设置要被参数替换的字符串,默认为thearg
。
\usestyles[<separator>]{<1st mand>}{<list of args>}
可选项再次设置第三个参数的分隔符。
\documentclass{article}
\usepackage{xparse}
\usepackage{l3regex}
\ExplSyntaxOn
\tl_new:N \c__ss_repl_symb_tl
\seq_new:N \g__ss_my_styles_seq
% optional #1 sets separator
% optional #2 sets string to replace
\NewDocumentCommand{\setstyle}{ O{,} O{thearg} m }{
\ss_set_my_styles:nn {#1}{#2}{#3}
}
% split style list at separator and store
\cs_new:Npn \ss_set_my_styles:nn #1#2#3 {
\tl_gset:Nn \c__ss_repl_symb_tl {#2}
\seq_set_split:Nnn \g__ss_my_styles_seq {#1}{#3}
}
% optional #1 sets separator to use when
% splitting #3
\NewDocumentCommand{\usestyles}{ O{,} m m }{
\ss_use_my_styles:nnn {#1}{#2}{#3}
}
\cs_new:Npn \ss_use_my_styles:nnn #1#2#3 {
#2\par
% split arg list at separator
\seq_set_split:Nnn \l_tmpa_seq {#1}{#3}
% map styles to list items in order
\seq_mapthread_function:NNN \g__ss_my_styles_seq \l_tmpa_seq \__ss_use:nn
}
\cs_generate_variant:Nn \regex_replace_all:nnN {VnN}
\cs_new:Npn \__ss_use:nn #1#2 {
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_all:VnN {\c__ss_repl_symb_tl} {#2} \l_tmpa_tl
\tl_use:N \l_tmpa_tl\par
}
\ExplSyntaxOff
\begin{document}
\setstyle{before \textbf{thearg} after,before \emph{thearg} after,before \textsc{thearg} after}
\usestyles{first}{arg1,arg2,arg3}
\end{document}