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