如何將參數傳遞給 smartef

如何將參數傳遞給 smartef

我正在嘗試編寫自己的定理包,其中包含一堆函數來訂購我的標準序言。在這樣做的過程中,我遇到了以下問題:我嘗試創建一個函數來定義一個新的類似定理的環境和相應的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

但我不明白為什麼每次都要設定該功能。

相關內容