在交叉引用中打印章节编号时仅提供相关上下文

在交叉引用中打印章节编号时仅提供相关上下文

我插入了一些指向本书不同部分的交叉引用。目前,我只需调用一个自定义宏即可实现这一点:

\newcommand\secref[1]{See \ref{#1}, \nameref{#1}.}

这将打印如下的参考:

参见§ 3:III.C.2.a),历史和机构

因此, 打印的数字引用\ref包括chapter数字、数字、数字section、数字和数字。请注意,我使用 定义了自己的编号方案。subsectionsubsubsectionparagraphalnumsec

我现在想要实现的是让用户\secref知道它相对于所引用标签的相对位置。\secref例如,如果在章节“§ 3”中调用“历史和机构”段落的宏,则\ref或替换命令应仅打印“III.C.2.a)”。如果\secref在章节“§ 3”的“III”部分中调用宏,则它应仅打印“C.2.a)”,依此类推。

但是如果在“§ 4”章的“III”节中调用该宏,它应该打印“3:III.C.2.a)”实际上,我想重新创建一个可以在 Microsoft Word 中找到的行为,其中对编号段落的交叉引用将仅打印在当前上下文中使引用明确所需的信息。

因此,除非提供chaptersection等数字,否则读者可以假定该引用是对同一、等中的不同、等的section引用。subsectionchaptersection

根据@JohnKormylo 的以下评论以及他的回答这个问题,我准备了一个 MWE,它尝试通过使用\secrefnumber解析内容的自定义宏来实现我想要的效果\getrefnumber,但我仍然卡住了,因为编译 MWE 会导致错误“缺少插入的 {”。 (至于 MWE 中的方法:我知道总是\if\thechapter\temptask会产生错误,因为\temptask不包含冒号;一旦 MWE 开始工作,我就会去处理它)。

\documentclass{book}

\usepackage{xstring}
\usepackage{alnumsec}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[hidelinks]{hyperref}

\addto\captionsenglish{%
\renewcommand\chaptername{}}

\alnumsectionlevels{1}{chapter,section} 
\otherseparators{2}
\alnumsecstyle{aR}
\surroundarabic[][]{§ }{:}
\surroundRoman{}{.}

\makeatletter

\newcommand\secref[1]{\secrefnumber{#1}, \nameref{#1}.}

\newcommand{\secrefnumber}[1]{% #1 = label name for subtasks
\@ifundefined{r@#1}{??}{%
\begingroup%
  \edef\temp{\expandafter\detokenize\getrefnumber{#1}}%
  \StrCut{\temp}{:}\temptask\tempsub%
  \edef\templink{\getrefbykeydefault{#1}{anchor}{}}%
  \if\thechapter\temptask%
    \hyperlink{\templink}{\tempsub)}%
  \else%
    \hyperlink{\templink}{\temptask\,\tempsub)}%
  \fi
\endgroup%
}}

\makeatother

\begin{document}

\chapter{My Very First Chapter}

\section{Introduction}
\label{sec:introduction}

\section{Once Upon a Time}

I am referencing \secref{sec:introduction}

\chapter{The Second Chapter}

I am referencing \secref{sec:introduction} again.

\end{document}

答案1

我在解析 \thechapter 时遇到了麻烦,因此我创建了 \seclabel 来生成简化的章节标签。

显然这里不需要 \detokenize 步骤(我最初是从其他地方复制来的)。

\documentclass{book}

\usepackage{xstring}
\usepackage{alnumsec}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[hidelinks]{hyperref}

\addto\captionsenglish{%
\renewcommand\chaptername{}}

\alnumsectionlevels{1}{chapter,section} 
\otherseparators{2}
\alnumsecstyle{aR}
\surroundarabic[][]{§ }{:}
\surroundRoman{}{.}

\newcommand\secref[1]{\secrefnumber{#1}, \nameref{#1}.}

\makeatletter
\newcommand{\seclabel}[1]{% #1 = label name
  \protected@edef\@currentlabel{\arabic{chapter}.\Roman{section}}%
  \label{#1}%
}

\newcommand{\secrefnumber}[1]{% #1 = label name
\@ifundefined{r@#1}{??}{%
\begingroup% use local definitions
  \edef\temp{\getrefnumber{#1}}% string containing \ref
  \StrCut{\temp}{.}\tempchap\temp% separate chapter
  \edef\templink{\getrefbykeydefault{#1}{anchor}{}}% \hyperlink anchor
  \if\arabic{chapter}\tempchap% same chapter
    \hyperlink{\templink}{\temp}%
  \else%
    \hyperlink{\templink}{§ \tempchap:\temp}%
  \fi
\endgroup%
}}

\makeatother

\begin{document}

\chapter{My Very First Chapter}

\section{Introduction}
\seclabel{sec:introduction}

\section{Once Upon a Time}

I am referencing \secref{sec:introduction}

\chapter{The Second Chapter}

I am referencing \secref{sec:introduction} again.

\end{document}

答案2

正如我所说,John Kormylo 回答了这个问题。我将包括我对他的答案的修改,该修改将方案一直应用到子段落级别,以供参考。我注意到两件事:测试etoolbox工作更可靠,这就是我使用它而不是简单的测试的原因\if;其次,xstring似乎对字符串做了一些奇怪的事情,所以我不得不对所有当前部分值进行 xstringify。

\documentclass{book}

\usepackage{xstring}
\usepackage{alnumsec}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage{etoolbox}
\usepackage{varioref}
\usepackage{csquotes}
\usepackage[hidelinks]{hyperref}

\addto\captionsenglish{%
\renewcommand\chaptername{}}

\makeatletter

\alnumsectionlevels{1}{chapter,section,subsection,subsubsection,paragraph,subparagraph} 
\otherseparators{2}
\alnumsecstyle{aRLald}
\surroundarabic[][.]{§ }{:}
\surroundLetter{}{.}
\surroundRoman{}{.}
\surroundletter{}{)}
\surrounddoubleletter{(}{)}
\surroundgreek{(}{)}

\newcommand\secref[1]{\secrefnumber{#1}\thinspace\enquote{\nameref{#1}}\thinspace\vpageref{#1}}

\@addtoreset{section}{chapter}

\@addtoreset{subsection}{chapter}
\@addtoreset{subsection}{section}

\@addtoreset{subsubsection}{chapter}
\@addtoreset{subsubsection}{section}
\@addtoreset{subsubsection}{subsection}

\@addtoreset{paragraph}{chapter}
\@addtoreset{paragraph}{section}
\@addtoreset{paragraph}{subsection}
\@addtoreset{paragraph}{subsubsection}

\@addtoreset{subparagraph}{chapter}
\@addtoreset{subparagraph}{section}
\@addtoreset{subparagraph}{subsection}
\@addtoreset{subparagraph}{subsubsection}
\@addtoreset{subparagraph}{paragraph}

\newcommand{\seclabel}[1]{%
  \protected@edef\@currentlabel{%
    \ifnumgreater{\value{chapter}}{0}{\arabic{chapter}}{}%
    \ifnumgreater{\value{section}}{0}{.\Roman{section}}{}%
    \ifnumgreater{\value{subsection}}{0}{.\Alph{subsection}}{}%
    \ifnumgreater{\value{subsubsection}}{0}{.\arabic{subsubsection}}{}%
    \ifnumgreater{\value{paragraph}}{0}{.\alph{paragraph}}{}%
    \ifnumgreater{\value{subparagraph}}{0}{.\alph{subparagraph}\alph{subparagraph}}{}%
   }%
  \label{#1}%
}

\newcommand{\secref@finaldelim}{:}
\newcommand{\secref@chapname}{§\thinspace }
\newcommand{\secref@secname}{section }
\newcommand{\secref@subname}{subsection }
\newcommand{\secref@subsname}{sub-subsection }
\newcommand{\secref@parname}{paragraph }
\newcommand{\secref@subparname}{subparagraph }

\newcommand{\secrefnumber}[1]{%
\@ifundefined{r@#1}{??}{%
\begingroup% use local definitions
  \edef\secref@name{\relax}%
  \edef\secref@text{\relax}%
  \edef\secref@rest{\getrefnumber{#1}}% string containing \ref
  \StrCut{\arabic{chapter}}{.}\secref@currchap\secref@trash% xstringify chapter number
  \StrCut{\Roman{section}}{.}\secref@currsec\secref@trash% xstringify section number
  \StrCut{\Alph{subsection}}{.}\secref@currsub\secref@trash% xstringify subsection number
  \StrCut{\arabic{subsubsection}}{.}\secref@currsubs\secref@trash% xstringify sub-subsection number
  \StrCut{\alph{paragraph}}{.}\secref@currpar\secref@trash% xstringify paragraph number
  \StrCut{\alph{subparagraph}\alph{subparagraph}}{.}\secref@currsubpar\secref@trash% xstringify subparagraph number
  \StrCut{\secref@rest}{.}\secref@chap\secref@rest% extract chapter number
  \StrCut{\secref@rest}{.}\secref@sec\secref@rest% extract section number
  \StrCut{\secref@rest}{.}\secref@sub\secref@rest% extract subsection number
  \StrCut{\secref@rest}{.}\secref@subs\secref@rest% extract subsubsection number
  \StrCut{\secref@rest}{.}\secref@par\secref@rest% extract parapraph number
  \StrCut{\secref@rest}{.}\secref@subpar\secref@rest% extract subparagraph number
  \edef\secref@restlink{\getrefbykeydefault{#1}{anchor}{}}% \hyperlink anchor
  \ifdefstrequal{\secref@currchap}{\secref@chap}% target in same chapter?
    {\ifdefstrequal{\secref@currsec}{\secref@sec}% target in same chapter (+); target in same section?
      {\ifdefstrequal{\secref@currsub}{\secref@sub}% target in same section (+), target in same subsection?
         {\ifdefstrequal{\secref@currsubs}{\secref@subs}% target in same subsection (+), target in same subsubsection?
           {\ifdefstrequal{\secref@currpar}{\secref@par}%target in same subsubsection (+), target in same paragraph?
             {\edef\secref@text{\secref@subpar}% target in same paragraph (+)
              \let\secref@name\secref@subparname}%
             {\edef\secref@text{\secref@par% target in same paragraph ()-)
                \ifdefvoid{\secref@subpar}%
                  {}%
                  {.\secref@subpar}}%
               \let\secref@name\secref@parname}% 
            }%
           {\edef\secref@text{\secref@subs% target in same subsubsection (-)
              \ifdefvoid{\secref@par}%
                {}%
                {.\secref@par%
                 \ifdefvoid{\secref@subpar}%
                   {}%
                   {.\secref@subpar}}%
                 }%  
             \let\secref@name\secref@subsname}% 
          }% 
         {\edef\secref@text{% target in same subsection (-)
          \secref@sub%
          \ifdefvoid{\secref@subs}%
            {}%
            {.\secref@subs%
             \ifdefvoid{\secref@par}%
              {}%
              {.\secref@par%
               \ifdefvoid{\secref@subpar}%
                 {}%
                 {.\secref@subpar}}%
               }%
             }%
           \let\secref@name\secref@subname}%
        }%
      {\edef\secref@text{% target in same section (-)
       \secref@sec%
       \ifdefvoid{\secref@sub}%
         {}%
         {.\secref@sub%
          \ifdefvoid{\secref@subs}%
           {}%
           {.\secref@subs%
             \ifdefvoid{\secref@par}%
              {}%
              {.\secref@par%
               \ifdefvoid{\secref@subpar}%
                 {}%
                 {.\secref@subpar}}%
               }%
             }%
           }%
         \let\secref@name\secref@secname}%
       }%
    {\edef\secref@text{% target in different chapter (+)
      \secref@chap%
      \ifdefvoid{\secref@sec}%
        {}%
        {:\secref@sec%
         \ifdefvoid{\secref@sub}%
           {}%
           {.\secref@sub%
            \ifdefvoid{\secref@subs}%
              {}%
              {.\secref@subs%
                \ifdefvoid{\secref@par}%
                  {}%
                  {.\secref@par%
                   \ifdefvoid{\secref@subpar}%
                     {}%
                     {.\secref@subpar}}%
                 }%
               }%
             }%
           }%
         \let\secref@name\secref@chapname}%
\hyperlink{\secref@restlink}{\secref@name\secref@text}%
\endgroup%
}%
\secref@finaldelim\relax}

\makeatother

\begin{document}

\chapter{My Very First Chapter}


\section{Introduction}
\seclabel{sec:introduction}

\subsection{First Subsection of the Introduction}
\seclabel{sec:first_sub_section}

I am referencing \secref{sec:second_chapter}.

\subsubsection{First Sub-Subsection}

\paragraph{First Paragraph}
\seclabel{sec:first_paragraph}

\subparagraph{First Subparagraph}
\seclabel{sec:first_subparagraph}

\subparagraph{Second Subparagraph}

This is a reference to \secref{sec:first_subparagraph}.

\paragraph{Second Paragraph}

This is a reference to \secref{sec:first_paragraph}. And here is one to \secref{sec:first_subparagraph}.

\subsubsection{Second Sub-Subsection}

This is another reference to \secref{sec:first_subparagraph}.

\subsection{Second Subsection of the Introduction}

I am referencing \secref{sec:first_sub_section}.

\section{Once Upon a Time}

I am referencing \secref{sec:introduction}. Now I am referencing \secref{sec:first_sub_section} again.

\chapter{The Second Chapter}
\seclabel{sec:second_chapter}

I am referencing \secref{sec:first_sub_section} again.

\end{document}

相关内容