向现有 \ExplSyntaxOn 代码添加新参数时未定义控制序列

向现有 \ExplSyntaxOn 代码添加新参数时未定义控制序列

我正在修复我的命令\fullref,该命令内部使用\nameref并且不支持同时使用多个标签。然而,在这个问题上如何同时引用多个标签?,提出了一个\nameref支持同时支持多个标签的固定版本。

这个问题的答案提供了 2 种变体\nameref,但对于我的\fullref命令,我需要一种新的变体,使我可以省略参考标签名称,FigureFigure My Caption

编辑问题的答案如何同时引用多个标签?,我设法创建了这个新变体,超出了答案中已有的 2 个变体。 导致\nameref命令的以下 3 个变体:

% “Start in lower case” variant. With star: disable hyperlinks.
% Does put the label name, i.e., Figure My Figure. #2: comma list of refs
\NewDocumentCommand \namerefs { s m }
  {
    \__user_name_refs:NNnn \c_true_bool \c_false_bool {#1} {#2}
  }

% “Start in upper case” variant. With star: disable hyperlinks.
% Does put the label name, i.e., Figure My Figure. #2: comma list of refs
\NewDocumentCommand \Namerefs { s m }
  {
    \__user_name_refs:NNnn \c_true_bool \c_true_bool {#1} {#2}
  }

% “Start in lower case” variant. With star: disable hyperlinks.
% Does NOT put the label name, i.e., My Figure. #2: comma list of refs
\NewDocumentCommand \nameRefs { s m }
  {
    \__user_name_refs:NNnn \c_false_bool \c_false_bool {#1} {#2}
  }

我所做的更改只是在函数中添加一个新的布尔参数作为第一个参数\__user_name_refs:NNnn,并将此参数传递给函数\user_name_refs:nnxn,并在函数内部使用它\user_name_refs:nnxn来不将\nameref标签名称打印为Figure

如果该函数的第一个参数\user_name_refs:nnxntrue,则将打印/输出引用标签Figure。如果是false,则不会打印任何内容,即没有Figure标签。

    \bool_if:nTF {#1}
    {
      % (section, Section, sections or Sections) or (theorem, Theorem, ...) or...
      \user_name_cref:xV
        { \bool_if:nTF {#2} { C } { c }
          ref
         \int_compare:nNnTF { \l__user_name_refs_nbrefs_int } > { 1 } { s } { } }
       \l__user_name_refs_firstref_tl
      \nobreakspace
    }{}

到目前为止,我已经编辑了所有代码,这些代码应该足以使上述 3 个\nameref变体正常工作。但我无法编译它,因为 latex 会抛出此错误:

(D:\User\Documents\latex\texmfs\install\tex\latex\base\omscmr.fd)
! Undefined control sequence.
\__user_name_refs:NNnn ...4->\user_name_refs:nnxn
                                                  {#1}{#2}{\IfBooleanTF {#3}...
l.114 ...reference and hyperlink: \nameRefs{first}
                                                   (we'll disable

我不太了解新的扩展语法,可能遗漏了一些非常简单的东西。你能找到我在更改中忘记添加的内容吗?

% The code below automatically adapts to the selected language.
\documentclass[english]{memoir}
\usepackage{babel}
\usepackage{xparse}

\usepackage[colorlinks=true]{hyperref}
\usepackage{cleveref}
\OnehalfSpacing

\ExplSyntaxOn

% #1: variant (cref, Cref, crefs or Crefs)
% #2: reference name (label)
\cs_new_protected:Npn \user_name_cref:nn #1#2
  { \use:c { name #1 } {#2} }

\cs_generate_variant:Nn \user_name_cref:nn { xV }

% #1: boolean expression (true: disable hyperlink)
% #2: reference name (label)
\cs_new_protected:Npn \user_name_ref:nn #1#2
  { \bool_if:nTF {#1} { \nameref* } { \nameref } {#2} }

\cs_generate_variant:Nn \user_name_ref:nn { nV }

\seq_new:N \l__user_name_refs_tmpa_seq
\seq_new:N \l__user_name_refs_tmpb_seq
\int_new:N \l__user_name_refs_nbrefs_int
\tl_new:N \l__user_name_refs_firstref_tl

% #1: boolean expression (true: Does put the label name, i.e., Figure My Figure)
% #2: boolean expression (true: start with capitalized letter, as in \Cref)
% #3: boolean expression (true: disable hyperlinks)
% #4: comma list of refs
\cs_new_protected:Npn \user_name_refs:nnnn #1#2#3#4
  {
    \seq_set_from_clist:Nn \l__user_name_refs_tmpa_seq {#4}
    \int_set:Nn \l__user_name_refs_nbrefs_int
                { \seq_count:N \l__user_name_refs_tmpa_seq }
    \seq_get_left:NN \l__user_name_refs_tmpa_seq \l__user_name_refs_firstref_tl

    \bool_if:nTF {#1}
    {
      % (section, Section, sections or Sections) or (theorem, Theorem, ...) or...
      \user_name_cref:xV
        { \bool_if:nTF {#2} { C } { c }
          ref
         \int_compare:nNnTF { \l__user_name_refs_nbrefs_int } > { 1 } { s } { } }
       \l__user_name_refs_firstref_tl
      \nobreakspace
    }{}

    % Now print the references.
    \seq_clear:N \l__user_name_refs_tmpb_seq
    \seq_map_inline:Nn \l__user_name_refs_tmpa_seq
      {
        \seq_put_right:Nn \l__user_name_refs_tmpb_seq
                          { \user_name_ref:nn {#3} {##2} }
      }
    \seq_use:Nnnn \l__user_name_refs_tmpb_seq { \crefpairconjunction }
                  { \crefmiddleconjunction } { \creflastconjunction }
  }

\cs_generate_variant:Nn \user_name_refs:nnnn { nx }

\cs_new_protected:Npn \__user_name_refs:NNnn #1#2#3#4
  {
    \user_name_refs:nnxn {#1}
      {#2}
      { \IfBooleanTF {#3} { \c_true_bool } { \c_false_bool } }
      {#4}
  }

% “Start in lower case” variant.
% Does put the label name, i.e., Figure My Figure.
% With star: disable hyperlinks.
% #2: comma list of refs
\NewDocumentCommand \namerefs { s m }
  {
    \__user_name_refs:NNnn \c_true_bool \c_false_bool {#1} {#2}
  }

% “Start in upper case” variant.
% Does put the label name, i.e., Figure My Figure.
% With star: disable hyperlinks.
% #2: comma list of refs
\NewDocumentCommand \Namerefs { s m }
  {
    \__user_name_refs:NNnn \c_true_bool \c_true_bool {#1} {#2}
  }

% “Start in lower case” variant.
% Does NOT put the label name, i.e., My Figure.
% With star: disable hyperlinks.
% #2: comma list of refs
\NewDocumentCommand \nameRefs { s m }
  {
    \__user_name_refs:NNnn \c_false_bool \c_false_bool {#1} {#2}
  }

\ExplSyntaxOff

\newcommand*{\fullref}[1]{\Cref{#1}: \nameRefs{#1}}

\begin{document}

\fullref{first,second,third,fourth}.

\namerefs{first,second,third,fourth}.

\Namerefs{first,second,third,fourth}.

\nameRefs{first,second,third,fourth}.

\section{First section}
\label{first}

\section{Second section}
\label{second}

\section{Third section}
\label{third}

\section{Fourth section}
\label{fourth}

\end{document}

参考:

  1. `\cs_new_protected` 和 `\cs_generate_variant` 起什么作用?
  2. ExplSyntaxOn 和 ExplSyntaxOff 起什么作用?
  3. https://github.com/textmate/latex.tmbundle/issues/79expl3 语法高亮
  4. http://mirror.las.iastate.edu/tex-archive/macros/latex/contrib/l3kernel/expl3.pdf

答案1

可以通过生成适当的函数变体来解决该问题以便能够使用\user_name_refs:nnxn

\cs_generate_variant:Nn \user_name_refs:nnnn { nnxn }

并在定义中使用正确的内联函数参数(##1而不是) :##2\user_name_refs:nnnn

\seq_map_inline:Nn \l__user_name_refs_tmpa_seq
  {
    \seq_put_right:Nn \l__user_name_refs_tmpb_seq
                      { \user_name_ref:nn {#3} {##1} }
  }

生成的 PDF:

完整编译文档的 PDF 结果

相关内容