Estou tentando escrever meu próprio pacote de teoremas que envolve várias funções para ordenar meu preâmbulo padrão. Ao fazer isso, fiquei com o seguinte problema: tento criar uma função para definir um novo ambiente semelhante a um teorema e os cleveref
nomes correspondentes - ambos em um único método por uma única chamada. No entanto, por algum motivo, não consigo fazer esse trabalho.
Abaixo de um exemplo mínimo com duas abordagens, a primeira é o que eu faria naturalmente, na segunda tento usar a sintaxe latex3 na qual estou escrevendo atualmente o pacote mais amplo (ou seja: acho que para este problema isso parece um um pouco exagerado, ainda o incluí porque está mais próximo do meu caso de uso real).
\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}
Em ambos os casos, recebo a mensagem de erro:
LaTeX: Cref reference format for label type `defA' undefined.
respectivamente o mesmo para \defB
.
Algum de vocês sabe o que está acontecendo aqui, respectivamente, o que estou fazendo de errado aqui?
Responder1
Ambos os comandos funcionam desde que sejam definidos e chamados no preâmbulo do documento.
\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}
Responder2
O código para definir ambientes semelhantes a teoremas deve estar no preâmbulo, porque é uma configuração “global”.
O expl3
código que você está usando é ruim em vários lugares. Aqui está uma versão limpa.
\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
Não entendo por que definir a função sempre.