Как передать аргументы в 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

Хотя я не понимаю, зачем каждый раз настраивать функцию.

Связанный контент