expl3 keyvalue 命令中的 & 符号

expl3 keyvalue 命令中的 & 符号

动机

我正在尝试制作一个自定义paragraph命令。我希望它有几个参数,一些是可选的,一些是必需的。以前的版本有一个不便之处,就是可以通过位置访问可选参数,例如

\Paragraph[][remember to specify default value here][][is this the right one?]{body of text}

为了避免这种情况,我想实现键值参数,例如。tikz我还想在定义中的可选参数中指定默认值。

我目前拥有的

笔记

我期望完成的命令的顶行看起来像这样:

\NewDocumentCommand{\Paragraph}{O{before={&}, after={\\}} m}{

我已经得到了这个可选语法,可以在没有&符号的情况下工作,或者在有&符号但没有第二个键值对的情况下工作,但是在下面的代码中,出于解释目的,使用第二个强制参数而不是可选参数很有用。

注释结束

我已经拆开了@egreg的回答问题产生以下。我有expl3 指导打开了,但是还没有深入研究过。

\documentclass{article}
\usepackage{xparse,amsmath}

\ExplSyntaxOn

% define the keys
\keys_define:nn { Paragraph }{
    before  .tl_set:N = \l__Paragraph_before_tl,
    after .tl_set:N = \l__Paragraph_after_tl,
}

% formatting
\NewDocumentCommand{\Paragraph}{m m}{
    \keys_set:nn { Paragraph } { #1 } % populate the keys
    % format the paragraph
    \Paragraph_before:V \l__Paragraph_before_tl
    #2
    \Paragraph_after:V \l__Paragraph_after_tl
}

\cs_new_protected:Nn \Paragraph_before:n{
    #1
}
\cs_new_protected:Nn \Paragraph_after:n{
    #1
}
\cs_generate_variant:Nn \Paragraph_before:n {V}
\cs_generate_variant:Nn \Paragraph_after:n {V}

\ExplSyntaxOff

\begin{document}
    \begin{align*}
        & above \\
        \Paragraph{before={&}}{text 1} \\ % before works singly
        & \Paragraph{after={\\}}{text 2} % after works singly
        & \Paragraph{before=hi~, after={\\}}{text 3} % before and after together, without ampersand, works
        \Paragraph{before={&}, after={~hey}}{text 4} \\ % before and after together, with ampersand, doesn't work
        & below
    \end{align*}
\end{document}

问题

该命令旨在用于align-type 环境内。如代码注释所示,& 符号似乎破坏了某些东西。

答案1

问题是,它l__Paragraph_after_tl是用普通(本地)赋值设置的,因此赋值只适用于当前组结束。但是 TeX 在对齐时会结束一个组并开始一个新组,因此值会丢失。您可以通过在执行任何用户代码之前&进行扩展来避免这种情况:\l__Paragraph_after_tl

例如,我在这里添加了一个,它获取和\__Paragraph_line:VVn的值作为参数。由于它的参数在执行之前被扩展,因此扩展发生在执行之前,因此在正确的组中。beforeafter&

\documentclass{article}
\usepackage{xparse,amsmath}

\ExplSyntaxOn

% define the keys
\keys_define:nn { Paragraph }{
    before  .tl_set:N = \l__Paragraph_before_tl,
    after .tl_set:N = \l__Paragraph_after_tl,
}

% formatting
\NewDocumentCommand{\Paragraph}{m m}{
    \keys_set:nn { Paragraph } { #1 } % populate the keys
    % format the paragraph
    \__Paragraph_line:VVn \l__Paragraph_before_tl \l__Paragraph_after_tl { #2 }
}

\cs_new_protected:Nn \__Paragraph_line:nnn {
    \Paragraph_before:n { #1 }
    #3
    \Paragraph_after:n { #2 }
}
\cs_new_protected:Nn \Paragraph_before:n{
    #1
}
\cs_new_protected:Nn \Paragraph_after:n{
    #1
}
\cs_generate_variant:Nn \__Paragraph_line:nnn {VVn}

\ExplSyntaxOff

\begin{document}
    \begin{align*}
        & above \\
        \Paragraph{before={&}}{text 1} \\ % before works singly
        & \Paragraph{after={\\}}{text 2} % after works singly
        & \Paragraph{before=hi~, after={\\}}{text 3} % before and after together, without ampersand, works
        \Paragraph{before={&}, after={~hey}}{text 4} \\ % before and after together, with ampersand, doesn't work
        & below
    \end{align*}
\end{document}

相关内容