我有一个宏,它使用内部宏来处理参数对。基本部分可以分解为
\mymacro{\inside{A}{1};\inside{B}{2},\inside{C}{3}}
。
最初,我处理了所有对,然后打印出来,用逗号分隔,使用序列来获得输出,例如“1A,2B,3C”,“1A,2B”或“1A”,分别代表三个,两个和一个参数。
现在要求已经改变,我需要输出为:“1,A 2,B 3.C”,“1,A 2.B”或“1.A”。
我想,这可以通过序列来完成,并提出了这个解决方案:
\documentclass{article}
\usepackage{xparse,expl3} % expl3 loaded explicitly - not necessary because it is already loaded by xparse
\ExplSyntaxOn
\tl_new:N \l__map_current_tl
\tl_new:N \l__map_tl
\tl_new:N \l__inside_tl
\seq_new:N \l__my_seq
\seq_new:N \l__second_seq
\NewDocumentCommand \mymacro {>{\SplitList{;}} m}
{
\mymacro_process_func:n {#1}
\mymacro_output_func:n
\\
}
\NewDocumentCommand \inside {m m}
{
\inside_process_func:nn {#1} {#2}
}
\cs_new_protected:Npn \inside_process_func:nn #1 #2
{
\tl_if_empty:NTF \l__inside_tl
{ \tl_put_right:Nn \l__inside_tl {#2 !! #1} }
{ \tl_put_right:Nn \l__inside_tl {~ #2 !! #1} }
}
\cs_new_protected:Npn \mymacro_process_func:n #1
{
% make sure token lists and sequences are empty
\tl_clear:N \l__map_current_tl
\tl_clear:N \l__map_tl
\tl_clear:N \l__inside_tl
\seq_clear:N \l__my_seq
\seq_clear:N \l__second_seq
\tl_map_function:nN {#1} \mymacro_map_func:n
\tl_show:N {\l__map_tl}
\seq_set_split:NnV \l__my_seq {;} \l__map_tl
% \seq_show:N \l__my_seq
\seq_use:Nnnn \l__my_seq {} {} {}
}
\cs_new_protected:Npn \mymacro_map_func:n #1
{
\tl_set:Nn \l__map_current_tl {#1}
\tl_if_empty:NTF \l__map_tl
{ \tl_set_eq:NN \l__map_tl \l__map_current_tl }
{
\tl_put_right:Nn \l__map_tl {;}
\tl_put_right:NV \l__map_tl \l__map_current_tl
}
\tl_set:Nn \l__map_current_tl {#1}
}
\cs_new_protected:Npn \mymacro_output_func:n
{
\seq_set_split:NnV \l__second_seq {!!} \l__inside_tl
% \seq_show:N \l__second_seq
\seq_use:Nnnn \l__second_seq {.} {,} {.}
}
\ExplSyntaxOff
\begin{document}
Achieved:\\
\mymacro{\inside{A}{1}}
\mymacro{\inside{A}{1};\inside{B}{2}}
\mymacro{\inside{A}{1};\inside{B}{2};\inside{C}{3}}
Desired:\\
1.A \\ 1,A 2.B \\ 1,A 2,B 3.C
\end{document}
如您所见,代码完成了应有的工作:
但是,我担心它效率不高,而且对我来说看起来很可疑。例如,我在以前的版本中使用了带空格的\l__my_seq
in :\mymacro_process_func:n
\seq_set_split:NnV \l__my_seq {;} \l__map_tl
\seq_use:Nnnn \l__my_seq {~} {~} {~}
但空格没有出现在输出中。(实际上,用 all 替换会~
在?
输出前分别打印无问号、一个问号或两个问号。)
- 有没有更好(更短)的方法来而无需改变
\mymacro
和的使用\inside
?(我无法更改文档中的所有宏) - 总的来说,有没有更好的方法来解决此问题?
顺便说一句:我不确定我的解决方案(命名等)是否符合所有规则和惯例,因此对此的任何评论也值得赞赏。
答案1
如果我理解了这个要求,似乎你不需要循环输入,你可以简单地执行列表,并在进行时排版每个项目。
\documentclass{article}
\def\mymacro#1{#1\relax}
\def\inside#1#2#3{\ifx\relax#3#2.#1\else#2,#1 \fi}
\begin{document}
Achieved:\\
\mymacro{\inside{A}{1}}\\
\mymacro{\inside{A}{1};\inside{B}{2}}\\
\mymacro{\inside{A}{1};\inside{B}{2};\inside{C}{3}}
Desired:\\
1.A \\ 1,A 2.B \\ 1,A 2,B 3.C
\end{document}