
Elprettyref
El paquete funciona inspeccionando las etiquetas del formulario \label{format:name}
y creando una referencia basada solo en el archivo format:
. La documentación dice:
No utilice el carácter
:
en ningún lugar dentro de la etiqueta excepto para separar el formato del nombre.
Lamentablemente tengo un caso de uso en el que se genera automáticamente un archivo .tex con etiquetas de tres partes \label{first:second:name}
. Un MWE está debajo. La implementación de prettyref
es notablemente simple, por lo que me pregunto si se puede ajustar para tolerar etiquetas de tres partes.
\documentclass[a4paper]{article}
\usepackage{graphicx}
\usepackage{prettyref}
\newrefformat{diag:cla}{Class Diagram \ref{#1}}
\newrefformat{diag:seq}{Sequence Diagram \ref{#1}}
\begin{document}
Behold: \prettyref{diag:seq:FirstExportedDiagram}.
\begin{figure}[h]
\includegraphics[scale=0.5]{sequencediagram1.pdf}
\caption{The first sequence diagram.}
\label{diag:seq:FirstExportedDiagram}
\end{figure}
\end{document}
Editar:Para completar, debo agregar quetambiénTodavía quiero conservar la capacidad de utilizar etiquetas antiguas de dos puntos. El archivo .tex exportado automáticamente en realidad tiene ambos (por ejemplo \label{datatype:integer}
, que tendría el formato \newrefformat{datatype}{\textit{\ref{#1}}}
, por ejemplo). No digo que las respuestas actuales no coincidan con esto, pero es bueno que los futuros lectores lo sepan.
También debo mencionar que, como escritor, dependo en gran medida del autocompletado para usar estas etiquetas exportadas (hay muchas y son largas). Algo a tener en cuenta para ciertos hacks de formato.
Respuesta1
Elmanual del paquete Prettyrefdice:
11
\def\prettyref#1{\@prettyref#1:}
\@prettyref
La macro interna\@prettyref
hace todo el trabajo. Se necesitan dos argumentos delimitados por:
. El primer argumento es el nombre del formato. Si el formato no se ha definido, se emite y\ref
se utiliza una advertencia. De lo contrario, se formatea la referencia.\@prettyref
utiliza las macros LaTeX\ref
y\pageref
para acceder a la\newlabel
estructura de datos. Con suerte, esto hará que el paquete sea lo suficientemente robusto como para usarlo con otros paquetes.12
\def\@prettyref#1:#2:{%
13\expandafter\ifx\csname pr@#1\endcsname\relax%
14\PackageWarning{prettyref}{Reference format #1\space undefined}%
15\ref{#1:#2}%
16\else%
17\csname pr@#1\endcsname{#1:#2}%
18\fi%
19}
Por lo tanto, \prettyref
utiliza internamente dos :
argumentos delimitados para dividir la parte del argumento que denota el formato.
LaTeX elimina las llaves que rodean un argumento completo.
Lo hace además con argumentos acotados.
Por lo tanto, las llaves que rodean un argumento delimitado completo se pueden usar para ocultar instancias de un delimitador que ocurren dentro del argumento delimitado, de modo que el mecanismo de TeX para capturar el argumento delimitado no se aplicará a estas instancias del delimitador.
Esto implica:
En lugar de \prettyref{Formatting:RemainderOfLabelName}
you can do or or .
\prettyref{{Formatting}:RemainderOfLabelName}
\prettyref{Formatting:{RemainderOfLabelName}}
\prettyref{{Formatting}:{RemainderOfLabelName}}
Por lo tanto, en su caso de esconderse :
del mecanismo de TeX para capturar :
argumentos delimitados/para que las cosas funcionen, simplemente envuelva toda esa parte del \prettyref
argumento entre llaves que denotan el formato, es decir, en lugar de
\prettyref{diag:seq:FirstExportedDiagram}
do
\prettyref{{diag:seq}:FirstExportedDiagram}
o
\prettyref{{diag:seq}:{FirstExportedDiagram}}
.
El MWE
\documentclass[a4paper]{article}
\usepackage{graphicx}
\usepackage{prettyref}
\newrefformat{diag:cla}{Class Diagram \ref{#1}}
\newrefformat{diag:seq}{Sequence Diagram \ref{#1}}
\begin{document}
Behold: \prettyref{{diag:seq}:FirstExportedDiagram}.
\begin{figure}[h]
%\includegraphics[scale=0.5]{sequencediagram1.pdf}
\includegraphics[scale=0.5]{example-image.pdf}
\caption{The first sequence diagram.}
\label{diag:seq:FirstExportedDiagram}
\end{figure}
\end{document}
rendimientos:
Explicación:
\prettyref{{diag:seq}:FirstExportedDiagram}
produce:
\@prettyref{diag:seq}:FirstExportedDiagram:
, que a su vez produce:
\expandafter\ifx\csname pr@diag:seq\endcsname\relax
\PackageWarning{prettyref}{Reference format diag:seq\space undefined}%`
\ref{diag:seq:FirstExportedDiagram}%`
\else
\csname pr@diag:seq\endcsname{diag:seq:FirstExportedDiagram}%`
\fi
Entonces parece que en realidad no es necesario redefinir nada. Con \prettyref
el argumento simplemente use llaves adicionales aquí y allá para ocultar instancias de :
del mecanismo de TeX para capturar :
argumentos delimitados.
Si no desea insertar llaves en su código generado automáticamente manualmente, y la presencia de más de dos puntos no anidados entre llaves siempre significa que solo/exactamente los dos primeros :
componentes separados representan la especificación de formato, entonces Puede hacer algo como esto que se divide en los dos puntos que no están anidados entre llaves y que no elimina/quita las llaves:
\documentclass[a4paper]{article}
\usepackage{prettyref}
\usepackage{hyperref}
\makeatletter
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
\newcommand\UD@firstofone[1]{#1}%
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
%%=============================================================================
%% Check whether argument is empty:
%%=============================================================================
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
\expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%=============================================================================
%% Extract first inner undelimited argument:
%%
%% \UD@ExtractFirstArg{ABCDE} yields {A}
%%
%% \UD@ExtractFirstArg{{AB}CDE} yields {AB}
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps/after "hitting" \UD@ExtractFirstArg with \expandafter
%% twice.
%%
%% \UD@ExtractFirstArg's argument must not be blank.
%% This case can be cranked out via \UD@CheckWhetherBlank before calling
%% \UD@ExtractFirstArg.
%%
%% Use frozen-\relax as delimiter for speeding things up.
%% I chose frozen-\relax because David Carlisle pointed out in
%% <https://tex.stackexchange.com/a/578877>
%% that frozen-\relax cannot be (re)defined in terms of \outer and cannot be
%% affected by \uppercase/\lowercase.
%%
%% \UD@ExtractFirstArg's argument may contain frozen-\relax:
%% The only effect is that internally more iterations are needed for
%% obtaining the result.
%%
%%.............................................................................
\@ifdefinable\UD@RemoveTillFrozenrelax{%
\expandafter\expandafter\expandafter\UD@Exchange
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\ifnum0=0\fi}%
{\long\def\UD@RemoveTillFrozenrelax#1#2}{{#1}}%
}%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral\expandafter
\UD@PassFirstToSecond\expandafter{\romannumeral
\expandafter\expandafter\expandafter\UD@Exchange
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\ifnum0=0\fi}{\UD@stopromannumeral#1}%
}{%
\UD@stopromannumeral\romannumeral\UD@ExtractFirstArgLoop
}%
}{%
\newcommand\UD@ExtractFirstArg[1]%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}%
{\UD@stopromannumeral#1}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillFrozenrelax#1}}%
}%
\@ifdefinable\UD@GobbleToColon{\long\def\UD@GobbleToColon#1:{}}%
\@ifdefinable\UD@KeepToColon{\long\def\UD@KeepToColon#1:{{#1}}}%
\newcommand\UD@SplitColon[4]{%
% #1 Tokens to prepend to {<Already splitted stuff>{<stuff splitted in this iteration>}}{<New remainder to split>}
% if <Remainder to split> does contain colon.
% #2 Tokens to prepend to <Already splitted stuff>{<Remainder to split>}
% if <Remainder to split> does not contain colon.
% #3 Already splitted stuff.
% #4 Remainder to split.
\expandafter\UD@CheckWhetherNull\expandafter{\UD@GobbleToColon#4:}%
{#2#3{#4}}{%
\expandafter\UD@PassFirstToSecond\expandafter{\UD@GobbleToColon#4}{%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral
\expandafter\UD@Exchange\expandafter{%
\romannumeral
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\UD@stopromannumeral
\expandafter\UD@ExtractFirstArg\expandafter{\UD@KeepToColon#4}%
}{\UD@stopromannumeral#3}%
}{#1}%
}%
}%
}%
\renewcommand\prettyref[1]{%
\UD@SplitColon{%
\UD@SplitColon{% Here you could nest more \UD@SplitColon.
\expandafter\UD@prettyref@morethanonecolon\UD@firstofone
}{%
\UD@prettyref@onecolon
}%
}{%
\PackageWarning{prettyref}{No referencing format specified}\ref
}{}{#1}%
}%
\newcommand\UD@prettyref@onecolon[2]{%
\expandafter\ifx\csname pr@#1\endcsname\relax
\PackageWarning{prettyref}{Reference format #1\space undefined}%
\ref{#1:#2}%
\else
\csname pr@#1\endcsname{#1:#2}%
\fi
}%
\newcommand\UD@prettyref@morethanonecolon[3]{%
\expandafter\ifx\csname pr@#1:#2\endcsname\relax
\PackageWarning{prettyref}{Reference format #1:#2\space undefined}%
\ref{#1:#2:#3}%
\else
\csname pr@#1:#2\endcsname{#1:#2:#3}%
\fi
}%
\makeatother
% In order to create hyperlinks, you can use
%
% \hyperref[{<referencing label>}]{<textual phrase which shall be a hyperlink>}
%
% As components of <textual phrase which shall be a hyperlink> you can use starred
% referencing-commands \ref*/\pageref* which themselves don't produce hyperlinks.
% This avoids errors due to nesting hyperlinks within hyperlinks.
\newrefformat{diag}{\hyperref[{#1}]{Diagram \ref*{#1}}}
\newrefformat{diag:cla}{\hyperref[{#1}]{Class Diagram \ref*{#1}}}
\newrefformat{diag:seq}{\hyperref[{#1}]{Sequence Diagram \ref*{#1}}}
\newcounter{democounter}
\begin{document}
You should get: Sequence Diagram 1\par
You actually get: \prettyref{diag:seq:FirstExportedDiagram:x:Y}
\medskip
You should get: Sequence Diagram 2\par
You actually get: \prettyref{diag:seq:FirstExportedDiagram}
\medskip
You should get: Class Diagram 3\par
You actually get: \prettyref{diag:cla:FirstExportedDiagram}
\medskip
You should get: Diagram 4\par
You actually get: \prettyref{diag:FirstExportedDiagram}
\medskip
% You should get: 5 plus a warning "No referencing format specified" \par
% You actually get: \prettyref{FirstExportedDiagram}
% \medskip
You should get: 5\par
You actually get: \ref{FirstExportedDiagram}.
\medskip
Here the democounter is stepped. It has the value \refstepcounter{democounter}\thedemocounter.
\label{diag:seq:FirstExportedDiagram:x:Y}%
\bigskip
Here the democounter is stepped. It has the value \refstepcounter{democounter}\thedemocounter.
\label{diag:seq:FirstExportedDiagram}%
\bigskip
Here the democounter is stepped. It has the value \refstepcounter{democounter}\thedemocounter.
\label{diag:cla:FirstExportedDiagram}%
\bigskip
Here the democounter is stepped. It has the value \refstepcounter{democounter}\thedemocounter.
\label{diag:FirstExportedDiagram}%
\bigskip
Here the democounter is stepped. It has the value \refstepcounter{democounter}\thedemocounter.
\label{FirstExportedDiagram}%
\bigskip
\end{document}
Respuesta2
No está del todo claro por qué Prettyref delimita el final con dos puntos. El delimitador normal aquí es \@nil
:
\documentclass[a4paper]{article}
\usepackage{graphicx}
\usepackage{prettyref}
\newrefformat{diag:cla}{Class Diagram \ref{#1}}
\newrefformat{diag:seq}{Sequence Diagram \ref{#1}}
\makeatletter
\def\prettyref#1{\@prettyref#1\@nil}
\def\@prettyref#1:#2\@nil{%
\expandafter\ifx\csname pr@#1\endcsname\relax%
\PackageWarning{prettyref}{Reference format #1\space undefined}%
\ref{#1:#2}%
\else%
\csname pr@#1\endcsname{#1:#2}%
\fi%
}
\makeatother
\begin{document}
Behold: \prettyref{diag:seq:FirstExportedDiagram}.
\begin{figure}[h]
\includegraphics[scale=0.5]{example-image.pdf}
\caption{The first sequence diagram.}
\label{diag:seq:FirstExportedDiagram}
\end{figure}
\end{document}