첫 번째 솔루션

첫 번째 솔루션

다소 인위적이지만 다음과 같은 맥락을 가정합니다.

tab:label먼저 테이블에 , 그림 등의 fig:label레이블 을 추가하고 싶습니다 . 둘째, 그림, 표 등을 포함하는 몇 가지 명령을 만들고 싶습니다.

%{caption; label} %table def %table content
\NewDocumentCommand{\includetable}{> { \SplitArgument { 1 } { ; } } m m m}{
  \begin{table}[htb!]
    \captionlabel#1 % the Question is about this line; how do I pass the prefix?
    \begin{tabular}{#2}
        #3
    \end{tabular}
  \end{table}
}

그리고 다음과 같은 캡션과 레이블을 삽입하는 명령이 있습니다.

%caption %label prefix %label
\NewDocumentCommand{\captionlabel}{m O{} m}{
    \caption{#1}\label{#2#3} 
}

문제는 접두사(예: ) \captionlabel에서 호출 \includetable하고 전달하는 것이 어떻게든 가능한지 여부입니다 .tab:\captionlabel {#1.1}[tab:]{#1.2}

에서 선택적 인수를 제거 \captionlabel하고 항상 \includetable로 호출할 수 tab:label있거나 인수의 순서를 또는 \captionlabel로 전환하거나 명령을 인라인할 수 있다는 것을 알고 있습니다. 이는 기본적으로 단지 예일 뿐입니다.{O{} m m}{m m O{}}

답변1

\NewDocumentCommand은 사용자 지향 명령을 정의하기 위한 것이지만 expl3사용자 수준 명령의 기반이 되는 코드 수준 API를 정의하면 작업이 더 쉽고 깔끔해집니다. 그 이유 중 하나는 를 사용하면 코드 수준 함수의 변형을 생성하는 것이 매우 쉬운 \cs_generate_variant:Nn반면 로 정의된 명령은 \NewDocumentCommand이를 지원하지 않기 때문입니다. 명령 인터페이스를 \captionlabel그대로 유지하면서 문제를 해결하는 두 가지 방법이 있습니다.

첫 번째 솔루션

\fabian_insert_caption_and_label:nnn이 솔루션은 를 통해 제공된 두 인수가 \SplitArgument인접한 위치(즉, 위치 2와 3)를 차지하는 코드 수준 함수를 사용합니다 .

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Npn \fabian_insert_caption_and_label:nnn #1#2#3
  { \caption {#2} \label {#1#3} }

\NewDocumentCommand { \includetable } { > { \SplitArgument { 1 } { ; } } m m m }
  {
    \begin{table}[htb!]
    \centering
    \fabian_insert_caption_and_label:nnn { tab: } #1

    \begin{tabular}{#2}
      #3
    \end{tabular}
    \end{table}
  }

% Useless here, but maybe you want it for other code of yours.
\NewDocumentCommand { \captionlabel } { m O{} m }
  {
    \fabian_insert_caption_and_label:nnn {#2} {#1} {#3}
  }

\ExplSyntaxOff

\begin{document}
  \includetable{Caption text; the label}{ll}{This & is\\ a & table}

  See table~\ref{tab:the label} on page~\pageref{tab:the label}.
\end{document}

두 번째 해결책

이 솔루션은 첫 번째 솔루션과 다른 코드 수준 함수를 사용합니다 \fabian_insert_caption_and_label:nnn. 즉, \captionlabel. 두 개의 "인접하지 않은 인수"를 관리하기 위해 의 첫 번째 인수를 분할한 후 수동으로 전달합니다 \includetable. this 에 해당하는 코드 수준 함수를 생성할 수 있고 생성해야 할 수도 있습니다 \includetable. 이렇게 하면 코드를 재사용하는 것이 더 쉽습니다(모든 문제를 혼합하지 않기 위해 이 작업을 수행한 것은 아니지만 이는 단지 간단한 래퍼에 대해 이야기하고 있는 것입니다. 아래 참조).

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Npn \fabian_insert_caption_and_label:nnn #1#2#3
  { \caption {#1} \label {#2#3} }

\cs_generate_variant:Nn \fabian_insert_caption_and_label:nnn { xnx }

\seq_new:N \l_fabian_tmp_seq

\NewDocumentCommand { \includetable } { m m m }
  {
    \seq_set_split:Nnn \l_fabian_tmp_seq { ; } {#1}

    \begin{table}[htb!]
    \centering
    \fabian_insert_caption_and_label:xnx
      { \seq_item:Nn \l_fabian_tmp_seq { 1 } }
      { tab: }
      { \seq_item:Nn \l_fabian_tmp_seq { 2 } }

    \begin{tabular}{#2}
      #3
    \end{tabular}
    \end{table}
  }

\NewDocumentCommand { \captionlabel } { m O{} m }
  {
    \fabian_insert_caption_and_label:nnn {#1} {#2} {#3}
  }

\ExplSyntaxOff

\begin{document}
  \includetable{Caption text; the label}{ll}{This & is\\ a & table}

  See table~\ref{tab:the label} on page~\pageref{tab:the label}.
\end{document}

속도가 문제라면 \seq_pop:NN두 번 대신 \seq_item:Nn두 번을 사용하겠습니다. 후자는 매번 전체 시퀀스를 반복하는 반면 \seq_pop:NN첫 번째 항목만 저장하고 제거하기 때문에 매우 빠릅니다(결과는 \q_no_value더 이상 팝업할 항목이 없을 때입니다). ).

다음에 대한 제안 래퍼\includetable

위에서 에 해당하는 간단한 코드 수준 함수를 추가할 것을 제안한다고 말했을 때 \includetable제가 의미하는 바는 다음과 같습니다.

\cs_new_protected:Npn \fabian_include_table:nnn #1#2#3
  {
    \seq_set_split:Nnn \l_fabian_tmp_seq { ; } {#1}

    \begin{table}[htb!]
    \centering
    \fabian_insert_caption_and_label:xnx
      { \seq_item:Nn \l_fabian_tmp_seq { 1 } }
      { tab: }
      { \seq_item:Nn \l_fabian_tmp_seq { 2 } }

    \begin{tabular}{#2}
      #3
    \end{tabular}
    \end{table}
  }

\NewDocumentCommand { \includetable } { m m m }
  {
    \fabian_include_table:nnn {#1} {#2} {#3}
  }

\fabian_include_table:nnn이 방법을 사용하면 사용 변형을 매우 쉽게 정의할 수 있습니다 \cs_generate_variant:Nn. 사용자 수준 명령의 인터페이스를 변경하지 않고 필요한 경우 해당 인터페이스를 변경할 수도 있습니다(공개 패키지의 일부가 아니라고 가정) \includetable.

두 예제의 출력

스크린샷

답변2

나는 그러한 구문을 추천할 수 없습니다. 학문적 관심을 위해 다음을 수행할 수 있습니다.

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\includetable}{> { \SplitArgument { 2 } { ; } } m m m}{%
  \begin{table}[htb!]
    \centering
    \addcaptionlabel#1
    \begin{tabular}{#2}
        #3
    \end{tabular}
  \end{table}
}
\NewDocumentCommand{\captionlabel}{m O{} m}{%
  \caption{#1}\label{#2#3} 
}
\NewDocumentCommand{\addcaptionlabel}{mmm}{%
  \IfNoValueTF{#3}{%
    \captionlabel{#1}{#2}%
  }{%
    \captionlabel{#1}[#2]{#3}%
  }%
}

\begin{document}

\ref{DEF} and \ref{prefixDEF}

\includetable{ABC;DEF}{cc}{11 & 22 \\ 333 & 4}

\includetable{ABC;prefix;DEF}{cc}{11 & 22 \\ 333 & 4}

\end{document}

여기에 이미지 설명을 입력하세요

관련 정보