Cómo pasar argumentos a Cleveref

Cómo pasar argumentos a Cleveref

Estoy intentando escribir mi propio paquete de teoremas que incluya un montón de funciones para ordenar mi preámbulo estándar. Al hacerlo, me encontré con el siguiente problema: intento crear una función para definir un nuevo entorno similar a un teorema y los cleverefnombres correspondientes, ambos en un solo método mediante una sola llamada. Sin embargo, por alguna razón no puedo hacer que esto funcione.

A continuación se muestra un ejemplo mínimo con dos enfoques, el primero es lo que naturalmente haría, en el segundo trato de usar la sintaxis latex3 en la que actualmente estoy escribiendo el paquete más amplio (es decir: supongo que para este problema esto parece un un poco exagerado, todavía lo incluí porque se acerca más a mi 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}

En ambos casos me sale el mensaje de error:

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

respectivamente lo mismo para \defB.

¿Alguno de ustedes sabe lo que está pasando aquí y, respectivamente, qué estoy haciendo mal aquí?

Respuesta1

Ambos comandos funcionan siempre que estén definidos y llamados en el preámbulo del 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}

salida de código

Respuesta2

El código para definir entornos similares a teoremas debería ir en el preámbulo, porque es un entorno "global".

El expl3código que estás usando es incorrecto en varios lugares. Aquí hay una versión limpia.

\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

Sin embargo, no entiendo por qué configurar la función cada vez.

información relacionada