
그만큼prettyref
패키지는 양식의 레이블을 검사 \label{format:name}
하고 format:
. 문서에는 다음과 같이 나와 있습니다.
:
이름과 별도의 [sic] 형식을 제외하고 레이블 내 어느 곳에도 문자를 사용하지 마십시오 .
안타깝게도 .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
그만큼Prettyref 패키지 매뉴얼말한다:
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}
수행할 수 있습니다 .
\prettyref{{Formatting}:RemainderOfLabelName}
\prettyref{Formatting:{RemainderOfLabelName}}
\prettyref{{Formatting}:{RemainderOfLabelName}}
따라서 -구분된 인수를 잡기 위해/작업을 수행하기 위해 :
TeX의 메커니즘을 숨기는 경우에는 의 인수 전체 부분을 형식을 나타내는 중괄호로 묶습니다(예: do 또는 대신) .:
\prettyref
\prettyref{diag:seq:FirstExportedDiagram}
\prettyref{{diag:seq}:FirstExportedDiagram}
\prettyref{{diag:seq}:{FirstExportedDiagram}}
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}
수익률:
설명:
\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
따라서 실제로 아무것도 재정의할 필요가 없는 것 같습니다. 의 인수를 사용 하면 -구분된 인수를 잡기 위한 TeX 메커니즘의 \prettyref
인스턴스를 숨기기 위해 여기저기에 추가 중괄호를 사용하면 됩니다 .:
:
자동 생성된 코드에 중괄호를 수동으로 삽입하고 싶지 않고 중괄호 안에 중첩되지 않은 콜론이 두 개 이상 존재한다는 것은 항상 처음 두 개의 :
-구분된 구성 요소만이 형식 지정 사양을 나타냄을 의미하는 경우 중괄호에 중첩되지 않은 콜론에서 분할되고 중괄호를 제거/제거하지 않는 다음과 같은 작업을 수행할 수 있습니다.
\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}