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

그런데 왜 매번 기능을 설정하는지 이해가 되지 않습니다.

관련 정보