如何将参数传递给 cleveref

如何将参数传递给 cleveref

我正在尝试编写自己的定理包,该包包装了一堆函数来对我的标准序言进行排序。在这样做的过程中,我遇到了以下问题:我尝试创建一个函数来定义一个新的定理类环境和相应的cleveref名称——两者都在单个方法中通过单个调用完成。但是,出于某种原因,我无法完成这项工作。

下面是一个包含两种方法的最小示例,前者是我自然会做的,在后者中,我尝试使用我目前正在编写更广泛的包的 latex3 语法(也就是说:我猜对于这个问题来说,这似乎有点夸张,我仍然将它包括在内,因为这更接近我的实际用例)。

\documentclass{article}

\usepackage{cleveref}

\begin{document}

% Version A
\NewDocumentCommand{\myfooA}{m m m m}{
    \newtheorem{#1}{#2}
    \Crefname{#1}{#3}{#4}
}

% Version B
\ExplSyntaxOn
\NewDocumentCommand{\myfooB}{m m m m}{
    \newtheorem{#1}{#2}
    \tl_set:Nn \l_crefname_tl {#1}
    \tl_set:Nn \l_name_tl {#3}
    \tl_set:Nn \l_names_tl {#4}
    \cs_set:Npn \l_mycrefname_cs ##1##2##3 {\Crefname{##1}{##2}{##3}}
    \exp_args:Nooo \l_mycrefname_cs \l_crefname_tl \l_name_tl \l_names_tl
}
\ExplSyntaxOff

% Test Version A
\myfooA{defA}{Definition}{Definition A}{Definitions A}
\begin{defA}\label{defA}
    Some Definition A
\end{defA}
\Cref{defA}


% Test Version B
\myfooB{defB}{Definition}{Definition B}{Definitions B}
\begin{defB}\label{defB}
    Some Definition B
\end{defB}
\Cref{defB}

\end{document}

在这两种情况下我都会收到错误消息:

LaTeX: Cref reference format for label type `defA' undefined.

分别为 相同\defB

你们有谁知道这里发生了什么,或者我在这里做错了什么?

答案1

只要在文档的序言中定义和调用这两个命令,它们就可以起作用。

\documentclass{article}
\usepackage{cleveref}
\NewDocumentCommand{\myfooA}{m m m m}{
    \newtheorem{#1}{#2}
    \Crefname{#1}{#3}{#4}
}

% Version B
\ExplSyntaxOn
\NewDocumentCommand{\myfooB}{m m m m}{
    \newtheorem{#1}{#2}
    \tl_set:Nn \l_crefname_tl {#1}
    \tl_set:Nn \l_name_tl {#3}
    \tl_set:Nn \l_names_tl {#4}
    \cs_set:Npn \l_mycrefname_cs ##1##2##3 {\Crefname{##1}{##2}{##3}}
    \exp_args:Nooo \l_mycrefname_cs \l_crefname_tl \l_name_tl \l_names_tl
}
\ExplSyntaxOff
\myfooA{defA}{Definition}{Definition A}{Definitions A}
\myfooB{defB}{Definition}{Definition B}{Definitions B}


\begin{document}
% Version A


% Test Version A

\begin{defA}\label{defA}
    Some Definition A
\end{defA}
\Cref{defA}


% Test Version B

\begin{defB}\label{defB}
    Some Definition B
\end{defB}
\Cref{defB}

\end{document}

代码输出

答案2

定义类似定理的环境的代码应该放在序言中,因为它是一个“全局”设置。

您使用的代码expl3在多个地方都存在问题。这是经过清理的版本。

\ExplSyntaxOn
\NewDocumentCommand{\definetheorem}{m m m m}
  {
    \newtheorem{#1}{#2}
    \uzername_crefname:nnn { #1 } { #3 } { #4 }
  }

\tl_new:N \l_uzername_crefname_tl
\tl_new:N \l_uzername_name_tl
\tl_new:N \l_uzername_names_tl

\cs_new_protected:Npn \uzername_crefname_make:nnn {} % initialize
\cs_generate_variant:Nn \uzername_crefname_make:nnn { VVV }

\cs_new_protected:Npn \uzername_crefname:nnn #1#2#3
% alternative, using signature instead of parameter text:
% \cs_new_protected:Nn \uzername_crefname:nnn 
  {
    \tl_set:Nn \l_uzername_crefname_tl {#1}
    \tl_set:Nn \l_uzername_name_tl {#2}
    \tl_set:Nn \l_uzername_names_tl {#3}
    \cs_set_protected:Npn \uzername_crefname_make:nnn ##1##2##3 {\Crefname{##1}{##2}{##3}}
    \uzername_crefname_make:VVV \l_uzername_crefname_tl \l_uzername_name_tl \l_uzername_names_tl
  }
\ExplSyntaxOff

但我不明白为什么每次都要设置该功能。

相关内容