Doppelter Doppelpunkt im Prettyref-Label

Doppelter Doppelpunkt im Prettyref-Label

DerprettyrefDas Paket funktioniert, indem es die Beschriftungen des Formulars überprüft \label{format:name}und eine Referenz nur auf Grundlage der erstellt format:. In der Dokumentation heißt es:

Verwenden Sie das Zeichen nicht :an einer beliebigen Stelle innerhalb des Etiketts, außer um das Format vom Namen zu trennen.

Leider habe ich einen Anwendungsfall, bei dem automatisch eine .tex-Datei mit dreiteiligen Beschriftungen generiert wird \label{first:second:name}. Ein MWE finden Sie weiter unten. Die Implementierung prettyrefist bemerkenswert einfach, daher frage ich mich, ob sie angepasst werden kann, um dreiteilige Beschriftungen zu tolerieren.

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

Bearbeiten:Der Vollständigkeit halber möchte ich hinzufügen, dass ichAuchmöchte immer noch die Möglichkeit behalten, alte Beschriftungen mit einem Doppelpunkt zu verwenden. Die automatisch exportierte .tex-Datei hat tatsächlich beides (z. B. \label{datatype:integer}, das beispielsweise mit formatiert wäre \newrefformat{datatype}{\textit{\ref{#1}}}). Ich sage nicht, dass die aktuellen Antworten nicht damit übereinstimmen, aber es ist gut für zukünftige Leser, das zu wissen.

Ich sollte auch erwähnen, dass ich als Autor stark auf die automatische Vervollständigung angewiesen bin, um diese exportierten Beschriftungen zu verwenden (es gibt viele davon und sie sind lang). Das sollte man bei bestimmten Format-Hacks im Hinterkopf behalten.

Antwort1

DerHandbuch des Pakets prettyrefsagt:

11\def\prettyref#1{\@prettyref#1:}

\@prettyrefDas interne Makro \@prettyreferledigt die ganze Arbeit. Es benötigt zwei Argumente, die durch getrennt sind :. Das erste Argument ist der Formatname. Wenn das Format nicht definiert wurde, wird eine Warnung ausgegeben und \refverwendet. Andernfalls wird die Referenz formatiert. \@prettyrefverwendet die LaTeX-Makros \refund , \pagerefum auf die \newlabelDatenstruktur zuzugreifen. Dies macht das Paket hoffentlich robust genug, um es mit verschiedenen anderen Paketen verwenden zu können.

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}

Verwendet also \prettyrefintern zwei :durch - getrennte Argumente, um den Teil des Arguments aufzuteilen, der die Formatierung bezeichnet.
LaTeX entfernt geschweifte Klammern, die ein ganzes Argument umgeben.
Dies geschieht auch bei abgegrenzten Argumenten.
Geschweifte Klammern, die ein ganzes abgegrenztes Argument umgeben, können also verwendet werden, um Instanzen eines Trennzeichens zu verbergen, die innerhalb des abgegrenzten Arguments vorkommen, sodass der TeX-Mechanismus zum Erfassen des abgegrenzten Arguments nicht auf diese Instanzen des Trennzeichens angewendet wird.

Dies bedeutet:
Statt „ \prettyref{Formatting:RemainderOfLabelName}können Sie auch „ oder „ tun . “
\prettyref{{Formatting}:RemainderOfLabelName}
\prettyref{Formatting:{RemainderOfLabelName}}
\prettyref{{Formatting}:{RemainderOfLabelName}}

Um also in Ihrem Fall den :TeX-Mechanismus zum Erfassen von :-getrennten Argumenten zu verbergen/damit die Dinge funktionieren, schließen Sie einfach den gesamten Teil des \prettyrefArguments in geschweifte Klammern ein, die die Formatierung kennzeichnen, d. h. anstelle von
\prettyref{diag:seq:FirstExportedDiagram}
do
\prettyref{{diag:seq}:FirstExportedDiagram}
oder
\prettyref{{diag:seq}:{FirstExportedDiagram}}.

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

ergibt:

Bildbeschreibung hier eingeben

Erläuterung:

\prettyref{{diag:seq}:FirstExportedDiagram}ergibt:
\@prettyref{diag:seq}:FirstExportedDiagram:, was wiederum ergibt:

  \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

Es scheint also, dass Sie tatsächlich nichts neu definieren müssen. \prettyrefVerwenden Sie mit dem Argument einfach hier und da zusätzliche geschweifte Klammern, um Instanzen von :vor dem TeX-Mechanismus zum Erfassen :von -getrennten Argumenten zu verbergen.



Wenn Sie in Ihren automatisch generierten Code keine geschweiften Klammern manuell einfügen möchten und das Vorhandensein von mehr als einem nicht in geschweiften Klammern verschachtelten Doppelpunkt immer bedeutet, dass nur/genau die ersten beiden :durch - getrennten Komponenten die Formatierungsspezifikation darstellen, können Sie Folgendes tun, wobei an nicht in geschweiften Klammern verschachtelten Doppelpunkten geteilt wird und die geschweiften Klammern nicht entfernt/entfernt werden:

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

Bildbeschreibung hier eingeben

Antwort2

Es ist nicht ganz klar, warum prettyref das Ende mit einem Doppelpunkt abgrenzt. Das normale Trennzeichen hier ist \@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}

verwandte Informationen