使用父环境枚举项的扩展参考

使用父环境枚举项的扩展参考

如果我们仍在同一个枚举中,我想通过其正常标签引用枚举列表中的一项;parent.item如果我们在文档中的其他地方,则通过语法引用枚举列表中的一项。例如:

\documentclass{scrartcl}

\usepackage[colorlinks]{hyperref}

\makeatletter
\newcounter{entity}
\def\theentity{\Roman{entity}}
\newenvironment{entity}[1]{\refstepcounter{entity}\@startsection{entity}{4}{-1em}{\baselineskip}{.1\baselineskip}{\bfseries}{\theentity. Entity: #1}}{}
\newcommand\entitymark{\@gobble}
\newcommand\toclevel@entity{3}
\newcommand\l@entity{\@gobbletwo}
\newcommand\entityautorefname{Entity}
\newcommand\entityname{Entity}
\makeatother

\begin{document}

\begin{entity}{Test1}
    \begin{enumerate}
        \item Some text \label{label}!
        \item Some more text, oh and \autoref{label}.
    \end{enumerate}
\end{entity}

Even more text and here: \autoref{label}.

\begin{entity}{Test2}
    Referencing \ref{label} again.
\end{entity}

\end{document}

现在引用是item 1item 11。但我希望将它们打印为item 1entity 1 item 11.1

aux文件包含如下一行:

\newlabel{label}{{1}{1}{\theentity . Entity: Test1\relax }{Item.1}{}}

\r@label如果我理解的话我可以通过它访问埃格尔正确。但目前它不包含有关entity其定义在何处的任何信息。我​​能以某种方式添加它吗?

答案1

这是我的建议。我只使用了非常强大的zref-package,它可以存储比标准 -command 多得多的(标签)信息label。此外,还有在环境中使用的新命令(\entityLabel和) 。我不想解释给定代码的所有行,因为我认为并行使用 -package 文档和注释行可以很容易地理解代码。\entityRefentityzref

实体环境

\documentclass{scrartcl}
\usepackage{zref-user}
\usepackage[colorlinks]{hyperref}

\makeatletter
% new properties in zref
\zref@newprop{EntityName}{}
\zref@newprop{EntityTag}{}
\zref@newprop{EntityCounter}{}
\zref@newprop{ItemCounter}{}

% add the new properties to the main list
\zref@addprop{main}{EntityName}
\zref@addprop{main}{EntityTag}
\zref@addprop{main}{EntityCounter}
\zref@addprop{main}{ItemCounter}

% define some hyper references
\def\entityRef@EntityName#1{%
    \def\tag{\zref@extractdefault{\zprefix#1}{EntityTag}{}}%
    \def\name{\zref@extractdefault{\zprefix#1}{EntityName}{}}%
    \hyperref[\zprefix\tag]{\name}}

\def\entityRef@EntityCounter#1{%
    \def\tag{\zref@extractdefault{\zprefix#1}{EntityTag}{}}%
    \def\count{\zref@extractdefault{\zprefix#1}{EntityCounter}{0}}%
    \hyperref[\zprefix\tag]{\count}}

\def\entityRef@ItemCounter#1{%
    \def\icount{\zref@extractdefault{\zprefix#1}{ItemCounter}{0}}%
    \hyperref[\zprefix#1]{\icount}}

\def\entityRef@EntityPage#1{%
    \def\pagenum{\zref@extractdefault{\zprefix#1}{page}{0}}%
    \hyperpage{\pagenum}}

% counter for the entities
\newcounter{EntityCounter}

% prefix for all labels and references
\def\zprefix{entity:}

% boolean to check if we work inside an entity environment
\newif\ifIsInEntity

% the new entity environment
\newenvironment{entity}[1]{%
    \IsInEntitytrue
    \refstepcounter{EntityCounter}%
    \def\entityName{#1}
    \def\entityTag{Entity\theEntityCounter}
    \addcontentsline{toc}{section}{\theEntityCounter. Entity: #1}
    \noindent\textbf{\label{\zprefix\entityTag}\theEntityCounter. Entity: #1}%
    \begin{enumerate}
}{%
    \IsInEntityfalse
    \end{enumerate}
}%

% a new label
\def\entityLabel#1{%
    \zref@setcurrent{EntityName}{\entityName}%
    \zref@setcurrent{EntityTag}{\entityTag}%
    \zref@setcurrent{EntityCounter}{\the\value{EntityCounter}}%
    \zref@setcurrent{ItemCounter}{\theenumi}%
    \zlabel{\zprefix#1}\label{\zprefix#1}}

% a new ref
% the output depends on the place where the reference is used
\def\entityRef#1{%
    \ifIsInEntity
        % reference is inside an entity
        % compare the saved EntityCounter with the current EntityCounter
        \ifnum\zref@extractdefault{\zprefix#1}{EntityCounter}{-1}=\theEntityCounter
            % reference is inside the same entity
            see Item \entityRef@ItemCounter{#1}%
        \else
            % reference is in an other entity
            see \entityRef@EntityCounter{#1}.\entityRef@ItemCounter{#1}%
        \fi
    \else
        % reference is outside of an entity
        see Entity "\entityRef@EntityName{#1}" (Nr. \entityRef@EntityCounter{#1}) Item \entityRef@ItemCounter{#1} on page \entityRef@EntityPage{#1}%
    \fi
}


\makeatother

\begin{document}
\tableofcontents
\newpage
\begin{entity}{First Test}
    \item Some text with label \entityLabel{Entity1Item1}
    \item Some more text, oh and \entityLabel{Entity1Item2}
    \item More text \entityRef{Entity1Item1}
\end{entity}
\noindent
Refernce in text: \entityRef{Entity1Item1}\\
Refernce in text: \entityRef{Entity2Item2}\\
Refernce in text: \entityRef{Entity3Item2}\\

\begin{entity}{Second Test}
    \item Referencing \entityRef{Entity2Item2}
    \item Referencing \entityLabel{Entity2Item2}\entityRef{Entity1Item2}
    \item Referencing \entityRef{Entity1Item2}
\end{entity}
\newpage
\begin{entity}{Third Test}
    \item Referencing \entityRef{Entity1Item1}
    \item Referencing \entityLabel{Entity3Item2}\entityRef{Entity2Item2}
    \item Referencing \entityRef{Entity1Item2}
\end{entity}
\end{document}

答案2

我认为,如果你有多个entity实例,每个实例都包含多个实例enumerate,你的读者很快就会感到困惑,因为有些项目仅通过其编号进行交叉引用(如果在当前环境中entity或在环境之外entity但在下一个entity实例启动之前),而其他项目则通过(罗马)实体编号进行交叉引用项目编号(如果在不同的环境中)。假设在同一个 中有两个交叉引用,第一个指向编号为 的项目,第二个指向编号为 的项目,entity您认为会发生什么情况?entity1II.1

因此,无论您希望达到什么样的优雅程度——仅当所讨论的条目属于与当前条目不同的条目(或当前在实体之间时,紧接在前一个条目)时,才将entity数字加到数字前面……——都很可能被混淆和困惑所抵消,因为究竟哪些条目被交叉引用。交叉引用标注可能是超目标这一事实几乎没有帮助;事实上,它甚至可能损害文档的整体可读性,因为它可能会邀请读者单击标注,只是为了确定哪些条目被交叉引用。itemitementity

如果您不想entity\theentity.\theenumi样式中对环境中的项目进行编号,可以发出命令

\renewcommand\p@enumi{\theentity.}

(当然是在\makeatletter...\makeatother对内)。这将指示 LaTeX 在构建交叉引用的“编号”时,自动将实体的(罗马)数字加到编号前面enumi

答案3

根据 Holle 的回答,我构建了以下内容,它包含类似于\autoref和的功能\nameref(实际上是我所说的\doubleref;另见仅当有名称时才使用 \nameref)。此外,hyperref链接延伸到整个参考资料,仅直接指向该项目。以下是 MWE 版本:

\documentclass{scrartcl}
\usepackage{zref-user}
\usepackage[english]{babel}
\RequirePackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}

\makeatletter
% new properties in zref
\zref@newprop{EntityTitle}{}
\zref@newprop{EntityType}{}
\zref@newprop{EntityNr}{}
\zref@newprop{ItemNr}{}

% add the new properties to the main list
\zref@addprop{main}{EntityTitle}
\zref@addprop{main}{EntityType}
\zref@addprop{main}{EntityNr}
\zref@addprop{main}{ItemNr}

% counter for the entities
\newcounter{entity}

% prefix for all labels and references
\def\zprefix{entity:}

% boolean to check if we work inside an entity environment
\newif\ifIsInEntity

% the new entity environment
\newcommand\entitymark{\@gobble}
\newcommand\toclevel@entity{3}
\newcommand\l@entity{\@gobbletwo}
\newcommand\entityautorefname{Entity}
\newcommand\entityname{Entity}
\newenvironment{entity}[1]{%
    \IsInEntitytrue
    \refstepcounter{entity}%
    \def\entityTitle{#1}
    \def\entityType{entity}
    \@startsection{entity}{4}{-1em}{\baselineskip}{.1\baselineskip}{\bfseries}{\theentity. Entity: #1}
    \begin{enumerate}
}{%
    \IsInEntityfalse
    \end{enumerate}
}%

% a new label
\newcommand\ilabel[1]{%
    \zref@setcurrent{EntityTitle}{\entityTitle}%
    \zref@setcurrent{EntityType}{\entityType}%
    \zref@setcurrent{EntityNr}{\the\value{entity}}%
    \zref@setcurrent{ItemNr}{\theenumi}%
    \zlabel{\zprefix#1}\label{\zprefix#1}}

% a new ref
% the output depends on the place where the reference is used
\newcommand\iref[1]{%
    %my zref version is too old for:
    %\zref@def@extractdefault{\z@inr}{\zprefix#1}{ItemNr}{0}
    %\zref@def@extractdefault{\z@entitynr}{\zprefix#1}{EntityNr}{0}
    %use instead:
    \def\z@inr{\zref@extractdefault{\zprefix#1}{ItemNr}{0}}%
    \def\z@entitynr{\zref@extractdefault{\zprefix#1}{EntityNr}{-1}}%
    \hyperref[\zprefix#1]{%
        \ifIsInEntity
            % reference is inside an entity
            % compare the saved EntityNr with the current EntityNr
            \ifnum\z@entitynr=\theentity
                % reference is inside the same entity
                (\z@inr)%
            \else
                % reference is in an different entity
                \z@entitynr(\z@inr)%
            \fi
        \else
            % reference is outside of an entity
            \z@entitynr(\z@inr)%
        \fi
    }%
}
\newcommand\iautoref[1]{%
    \def\z@inr{\zref@extractdefault{\zprefix#1}{ItemNr}{0}}%
    \def\z@entitynr{\zref@extractdefault{\zprefix#1}{EntityNr}{-1}}%
    \def\z@entitytype{\zref@extractdefault{\zprefix#1}{EntityType}{entity}}%
    \hyperref[\zprefix#1]{%
        \ifIsInEntity
            % reference is inside an entity
            % compare the saved EntityNr with the current EntityNr
            \ifnum\z@entitynr=\the\value{entity}
                % reference is inside the same entity
                \itemautorefname~(\z@inr)%
            \else
                % reference is in an different entity
                \csname\z@entitytype name\endcsname~\z@entitynr\-~\itemautorefname~\z@inr%
            \fi
        \else
            % reference is outside of an entity
            \csname\z@entitytype name\endcsname~\z@entitynr\-~\itemautorefname~\z@inr%
        \fi
    }%
}
\newcommand\idoubleref[1]{%
    \def\z@inr{\zref@extractdefault{\zprefix#1}{ItemNr}{0}}%
    \def\z@entitynr{\zref@extractdefault{\zprefix#1}{EntityNr}{-1}}%
    \def\z@entitytype{\zref@extractdefault{\zprefix#1}{EntityType}{entity}}%
    \def\z@entityname{\zref@extractdefault{\zprefix#1}{EntityTitle}{}}%
    \hyperref[\zprefix#1]{%
        \ifIsInEntity
            % reference is inside an entity
            % compare the saved EntityNr with the current EntityNr
            \ifnum\z@entitynr=\theentity
                % reference is inside the same entity
                \itemautorefname~(\z@inr)%
            \else
                % reference is in an different entity
                \csname\z@entitytype name\endcsname~\z@entitynr\-~\itemautorefname~\z@inr%
                \ifx\empty\z@entityname\relax\else
                    ~(\z@entityname)%
                \fi
            \fi
        \else
            % reference is outside of an entity
            \csname\z@entitytype name\endcsname~\z@entitynr\-~\itemautorefname~\z@inr%
            \ifx\empty\z@entityname\relax\else
                ~(\z@entityname)%
            \fi
        \fi
    }%
}

\renewcommand\theenumi{\roman{enumi}} \renewcommand\labelenumi{(\theenumi)}

\makeatother

\begin{document}
\begin{entity}{First Test}
    \item Some text with label \ilabel{Entity1Item1}
        \item Some more text; oh and \ilabel{Entity1Item2}
    \item More text \iref{Entity1Item1}
\end{entity}
\noindent
Reference in text: \iref{Entity1Item1}\\
Reference in text: \iautoref{Entity2Item2}\\
Reference in text: \idoubleref{Entity3Item2}

\begin{entity}{Second Test}
    \item Referencing \iref{Entity2Item2}
    \item Referencing \ilabel{Entity2Item2}\iautoref{Entity1Item2}
    \item Referencing \iautoref{Entity1Item2}
\end{entity}
\newpage
\begin{entity}{Third Test}
    \item Referencing \iref{Entity1Item1}
    \item Referencing \ilabel{Entity3Item2}\iautoref{Entity2Item2}
    \item Referencing \iautoref{Entity1Item2}
\end{entity}
\end{document}

相关内容