listings 包和 latex3 变量

listings 包和 latex3 变量

我正在尝试将自定义环境从许多可选参数更改为以;-separated 列表(使用此答案作为模板并将其主要功能写为 latex3 宏)。

宏应将列表中的每个标记放在单独的行上,并使用等宽字体格式化(这是源代码)。我以前使用过\lstinlinelistings但它似乎与 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}

相关内容