我正在尝试将自定义环境从许多可选参数更改为以;
-separated 列表(使用此答案作为模板并将其主要功能写为 latex3 宏)。
宏应将列表中的每个标记放在单独的行上,并使用等宽字体格式化(这是源代码)。我以前使用过\lstinline
,listings
但它似乎与 latex3 变量不兼容。改用\texttt
即可。
我宁愿使用\lstinline
而不是\texttt
,因为我需要postbreak
它提供的功能来标记长行中的断点。
重现此问题:
\documentclass{minimal}
\usepackage{listings,xparse}
\lstset{basicstyle=\ttfamily,breaklines=true,columns=fullflexible}
\NewDocumentCommand{\code}{m}{\textbf{\texttt{#1}}} % works
% uncomment for error
%\NewDocumentCommand{\code}{m}{\lstinline{#1}} % results in "Improper
% alphabetic constant."
\ExplSyntaxOn
\NewDocumentCommand{\methods}{m}{\methods_main:n {#1}}
\seq_new:N \l_methods_body_seq
\cs_new:Npn \methods_main:n #1
{
\noindent
\seq_set_split:Nnn \l_methods_body_seq {;} { #1 }
\seq_pop_right:NN \l_methods_body_seq \l_tmpa_tl
\seq_map_inline:Nn \l_methods_body_seq { \code{##1} \\ }
\code{\tl_use:N \l_tmpa_tl} %<---- error occurs in this line
}
\ExplSyntaxOff
\begin{document}
\methods{monoSpacedLine1();int methodSignature();const int ANSWER 42}
\end{document}
我尝试的宏的每个参数都会发生错误\methods
。我还尝试过使用\tl_to_str:N
而不是\tl_use:N
,或者在其周围加上额外的括号。
\lstinline
是否有可能以接受的方式扩展变量?
答案1
您必须展开令牌列表才能\code
看到它;最便宜的方法是\exp_args:NV
:
\documentclass{article}
\usepackage{listings,xparse}
\lstset{basicstyle=\ttfamily,breaklines=true,columns=fullflexible}
\NewDocumentCommand{\code}{m}{\lstinline{#1}}
\ExplSyntaxOn
\NewDocumentCommand{\methods}{m}{\methods_main:n {#1}}
\seq_new:N \l_methods_body_seq
\tl_new:N \l_methods_last_tl
\cs_new_protected:Npn \methods_main:n #1
{
\noindent
\seq_set_split:Nnn \l_methods_body_seq {;} { #1 }
\seq_pop_right:NN \l_methods_body_seq \l_methods_last_tl
\seq_map_inline:Nn \l_methods_body_seq { \code{##1} \\ }
\exp_args:NV \code \l_methods_last_tl
}
\ExplSyntaxOff
\begin{document}
\methods{monoSpacedLine1();int methodSignature();const int ANSWER 42}
\end{document}
这将产生与
\code{<value of \l_methods_last_tl>}
这正是所期望的。
请注意,之所以\methods_main:n
定义为,\cs_new_protected:Npn
是因为它执行“不可扩展的事情”,例如设置变量。
然而,一个更好的方法是使用一个“内部”函数\code
:
\documentclass{article}
\usepackage{listings,xparse}
\lstset{basicstyle=\ttfamily,breaklines=true,columns=fullflexible}
\ExplSyntaxOn
\NewDocumentCommand{\methods}{m}{\methods_main:n {#1}}
\NewDocumentCommand{\code}{m}{\methods_code:n {#1}}
\cs_new_protected:Npn \methods_code:n #1
{ \lstinline{#1} }
\cs_generate_variant:Nn \methods_code:n { V }
\seq_new:N \l_methods_body_seq
\tl_new:N \l_methods_last_tl
\cs_new_protected:Npn \methods_main:n #1
{
\noindent
\seq_set_split:Nnn \l_methods_body_seq {;} { #1 }
\seq_pop_right:NN \l_methods_body_seq \l_methods_last_tl
\seq_map_inline:Nn \l_methods_body_seq { \methods_code:n {##1} \\ }
\methods_code:V \l_methods_last_tl
}
\ExplSyntaxOff
\begin{document}
\methods{monoSpacedLine1();int methodSignature();const int ANSWER 42}
\end{document}