Primera solución

Primera solución

Es un poco artificial, pero asume lo siguiente como contexto:

Primero, quiero agregar etiquetas para tablas como tab:label, para figuras como fig:label, etc. En segundo lugar, quiero crear algunos comandos para incluir figuras, tablas, etc.

%{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}
}

Y tengo un comando que inserta un título y una etiqueta, que tiene el siguiente aspecto:

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

La pregunta es si de alguna manera es posible llamar \captionlabeldesde \includetabley pasar el tab:prefijo (algo así \captionlabel {#1.1}[tab:]{#1.2}).

Sé que podría eliminar el argumento opcional \captionlabely llamar siempre \includetablecon tab:label, o podría cambiar el orden de los argumentos de \captionlabela {O{} m m}o {m m O{}}, o insertar el comando. Básicamente es sólo un ejemplo.

Respuesta1

\NewDocumentCommandes para definir comandos orientados al usuario, pero las cosas son más fáciles y limpias cuando expl3define una API a nivel de código en la que se basan los comandos a nivel de usuario. Una de las razones es que es muy fácil generar variantes de funciones a nivel de código con \cs_generate_variant:Nn, mientras que los comandos definidos con \NewDocumentCommandno lo admiten. Aquí hay dos formas de resolver su problema que mantienen \captionlabelintacta la interfaz de su comando.

Primera solución

Esta solución utiliza una función a nivel de código \fabian_insert_caption_and_label:nnndonde los dos argumentos proporcionados vía \SplitArgumentocupan posiciones adyacentes (es decir, las posiciones 2 y 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}

Segunda solución

Esta solución utiliza una función a nivel de código \fabian_insert_caption_and_label:nnndiferente a la de la primera solución: acepta los argumentos en el mismo orden que su archivo \captionlabel. Para gestionar los dos “argumentos no adyacentes”, los pasamos manualmente después de dividir nosotros mismos el primer argumento de \includetable. Tenga en cuenta que podría, y probablemente debería, crear una función a nivel de código correspondiente a this \includetable. De esta manera, reutilizar el código es más fácil (no lo hice para no mezclar todos los problemas, pero estoy hablando de un simple contenedor: ver más abajo).

\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}

Si la velocidad es una preocupación, usaría \seq_pop:NNdos veces en lugar de \seq_item:Nndos veces, porque esta última itera sobre toda la secuencia cada vez, mientras que \seq_pop:NNsolo almacena y elimina el primer elemento, lo cual es muy rápido (el resultado es \q_no_valuecuando ya no hay ningún elemento para mostrar). ).

Envoltorio sugerido para\includetable

Cuando dije anteriormente que sugeriría que agregara una función simple a nivel de código correspondiente a su \includetable, lo que quise decir fue simplemente algo como esto:

\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}
  }

De esta manera, puedes definir muy fácilmente variantes de \fabian_include_table:nnnuso \cs_generate_variant:Nn. También puede cambiar su interfaz si es necesario (suponiendo que no sea parte de un paquete público) sin cambiar la interfaz del comando de nivel de usuario \includetable.

Salida de ambos ejemplos.

Captura de pantalla

Respuesta2

No puedo recomendar tal sintaxis. Sólo por interés académico, así es como puede hacerlo:

\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}

ingrese la descripción de la imagen aquí

información relacionada