
這prettyref
包的工作原理是檢查表單的標籤\label{format:name}
並僅基於format:
.文件說:
除了將[原文如此] 格式與名稱分開之外,請勿
:
在標籤內的任何位置使用該字元。
遺憾的是,我有一個用例,其中使用三部分標籤自動產生 .tex 檔案\label{first:second:name}
。下面是 MWE。的實作prettyref
非常簡單,所以我想知道是否可以調整它以容忍三部分標籤。
\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}
編輯:為了完整起見,我應該補充一點也仍然希望保留使用舊的單冒號標籤的能力。自動匯出的 .tex 檔案實際上兩者都有(例如\label{datatype:integer}
,將使用 格式化)。\newrefformat{datatype}{\textit{\ref{#1}}}
並不是說目前的答案與此不符,但對於未來的讀者來說了解是有好處的。
我還應該提到,作為作者,我嚴重依賴自動完成來使用這些導出的標籤(它們很多,而且很長)。對於某些格式的修改需要記住一些事情。
答案1
11
\def\prettyref#1{\@prettyref#1:}
\@prettyref
內部巨集\@prettyref
完成所有工作。它需要兩個由 分隔的參數:
。第一個參數是格式名稱。如果格式尚未定義,則會發出警告並\ref
使用。否則,引用將被格式化。\@prettyref
使用 LaTeX 巨集\ref
並\pageref
存取\newlabel
資料結構。希望這使得該包足夠強大,可以與各種其他包一起使用。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}
因此,\prettyref
在內部使用兩個:
- 分隔的參數來分割表示格式的參數部分。
LaTeX 去掉了圍繞整個參數的大括號。
它也透過分隔參數來實現這一點。
因此,包圍整個定界參數的大括號可用來隱藏定界參數內部出現的定界符實例,這樣 TeX 取得定界參數的機制就不會應用於定界符的這些實例。
這意味著:您
可以\prettyref{Formatting:RemainderOfLabelName}
執行or或。
\prettyref{{Formatting}:RemainderOfLabelName}
\prettyref{Formatting:{RemainderOfLabelName}}
\prettyref{{Formatting}:{RemainderOfLabelName}}
因此,在您的情況下,為了隱藏:
TeX 的抓取 - 分隔參數的機制:
/讓事情順利進行,只需將\prettyref
s 參數的整個部分包裝到表示格式的大括號中,即,而不是
\prettyref{diag:seq:FirstExportedDiagram}
do
\prettyref{{diag:seq}:FirstExportedDiagram}
或
\prettyref{{diag:seq}:{FirstExportedDiagram}}
。
氣象局
\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}
產量:
解釋:
\prettyref{{diag:seq}:FirstExportedDiagram}
產生:
\@prettyref{diag:seq}:FirstExportedDiagram:
,進而產生:
\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
所以看起來你其實不需要重新定義任何東西。 With\prettyref
的參數只需在各處使用額外的花括號來隱藏:
TeX 機制的實例,以獲得:
- 分隔的參數。
如果您不想手動將大括號插入自動生成的程式碼中,並且存在多個未嵌套在大括號中的冒號始終意味著僅/恰好前兩個:
分隔的組件代表格式規範,那麼您可以做這樣的事情,它在未嵌套在大括號中的冒號處分割,並且不刪除/剝離大括號:
\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}
答案2
目前尚不清楚為什麼 Prettyref 用冒號分隔結尾。這裡的正常分隔符號是\@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}