如何找出给定 \ref 引用的节类型

如何找出给定 \ref 引用的节类型

我正在使用 KOMAscript 的类编写文档scrreprt,并且正在编写自定义宏(\xref)来格式化用于交叉引用的文本。

该宏将标签名称作为参数:\xref{mylabel}

我想根据标签是指章节/节/小节(默认编号)还是小节/段落(默认未编号)来生成不同的文本。

我该如何检查?以下两种方法均可:

  1. 检查标签是否引用章节/节/小节(或相反:检查标签是否引用小节/段落)
  2. 检查标签是否指向编号商品

答案1

unnumbered/numbered请参阅最后的更新以了解结构单元的引用和检查。

不使用任何额外的包,只\renewcommand, \let, \pdfstrcmp使用等并将写入\@namedef文件.aux

它需要两次运行(无论如何都是需要的,因为我们正在处理标签!)

使用\extractlabeltype{labelname}\checklabeltype真/假分支。

它假定没有其他包涉及\label\ref,即不支持hyperref或。cleveref

\documentclass{book}


\makeatletter
\let\latex@@refstepcounter\refstepcounter
\let\latex@@label\label%


\renewcommand{\refstepcounter}[1]{%
  \gdef\lastrefsteppedcounter{#1}%
  \latex@@refstepcounter{#1}%
}

\renewcommand{\label}[1]{%
  \immediate\write\@auxout{\string\global\string\@namedef{label#1}{\lastrefsteppedcounter}}
   \latex@@label{#1}%
}

\newcommand{\extractlabeltype}[1]{%
  \@nameuse{label#1}%
}

\makeatother

\newcommand{\checklabeltype}[4]{%
\ifnum0=\pdfstrcmp{\extractlabeltype{#1}}{#2}
#3%
\else
#4%
\fi
}


\begin{document}



\chapter{Foo} \label{foo}


\section{Foosection}\label{foosection}

\checklabeltype{foosection}{section}{Yes, it is section}{No, it is something different}

\checklabeltype{foo}{section}{Yes, it is section}{No, it is something different}


\end{document}

在此处输入图片描述

更新检查未编号/已编号的问题。

请注意,这故意依赖于这样的假设:未编号结构单元的锚点名称中包含一个*,因此玩弄\theH...宏并不是一个好主意;-)

\documentclass{book}

\usepackage{xparse}
\usepackage[hyperref,counter]{zref}% Using the counter mechanism behind `nameref`
\usepackage{hyperref}


\makeatletter
\AtBeginDocument{%
  \let\latex@@label\label%

  \renewcommand{\label}[1]{%
    \zref@label{#1}%
    \latex@@label{#1}%
  }
  % Get the underlying counter type
  \newcommand{\extractlabelcounter}[1]{%
    \zref@ifrefundefined{#1}{%
      ???????}{%
      \zref@extract{#1}{counter}%
    }%
  }
  % Get the anchor name for hyperref or nameref -> has a `*` inside if it is unnumbered
  \newcommand{\extractlabelanchor}[1]{%
    \zref@ifrefundefined{#1}{%
      ???????}{%
      \zref@extract{#1}{anchor}%
    }%
  }
}

% Check if there's a `*` inside of the anchor name
\ExplSyntaxOn
\cs_new:Npn \checkifnumbered#1#2#3{%
  \tl_set:Nx \l_tmpa_tl {\extractlabelanchor{#1}}
  \tl_if_in:NnTF \l_tmpa_tl {*} {#2} {#3}
}
\ExplSyntaxOff

\makeatother


\newcommand{\checklabeltype}[4]{%
  \ifnum0=\pdfstrcmp{\extractlabelcounter{#1}}{#2}
  #3%
  \else
  #4%
  \fi
}

\begin{document}
\chapter{Foo} \label{foo}

\section*{An unnumbered section} \label{unnumbered}

\section{Foosection}\label{foosection}

\checklabeltype{foosection}{section}{Yes, it is section}{No, it is something different}

\checklabeltype{foo}{section}{Yes, it is section}{No, it is something different}

\begin{enumerate}
\item First \label{enumfirst}
\item Second \label{enumsecond}
\end{enumerate}

\checklabeltype{enumsecond}{enumi}{It is a numbered item and has the value \ref{enumsecond}}{}

In \nameref{unnumbered} we have an \checkifnumbered{unnumbered}{unnumbered}{numbered} \extractlabelcounter{unnumbered}


In \nameref{foo} we have an \checkifnumbered{foo}{unnumbered}{numbered} \extractlabelcounter{foo} whereas
 \nameref{foosection} is a \checkifnumbered{foosection}{unnumbered}{numbered} \extractlabelcounter{foosection}.


\end{document}

在此处输入图片描述

相关内容