本地绕过 hyperref

本地绕过 hyperref

我想让 hyperref 包跳过\ref我的 TeX 文件中的某些命令,而不是使它们成为生成的 pdf 文档中的超链接。

有没有简单的方法可以实现这一点?


下面是一个我想绕过 hyperref 的示例:

\documentclass[12pt,twoside]{article}

\usepackage{ifthen}
\usepackage{hyperref}

\makeatletter
\newcommand{\writeval}[2]{%
\@bsphack%
\protected@write\@auxout{}%
{\string\newlabel{#1}{{#2}{\thepage}}}%
\protected@write\@auxout{}%
\@esphack%
}
\makeatother

\newcounter{counter}


\begin{document}

\writeval{mylabel}{6}
mylabel = \protect\ref{mylabel}\\

\begin{tabular}{c}%
  \setcounter{counter}{1}%
  \whiledo{\thecounter<\ref{mylabel}}{%
    {\thecounter}\\ % 
    \stepcounter{counter}%
  }%
\end{tabular}%

\end{document}

答案1

是:使用\ref*而不是\ref创建不是超链接的交叉引用。

一个简单的例子:

在此处输入图片描述

\documentclass{article}
\usepackage[colorlinks=true]{hyperref}
\begin{document}
\section{First section}\label{sec:1}
abc    
\section{Next section}\label{sec:2}
def    
\section{Final section}\label{sec:3}    
A hyperlinked cross-reference to Section \ref{sec:1}, 
and an ordinary cross-reference to Section \ref*{sec:2}.
\end{document}

答案2

默认\label-\ref系统存储/检索与标签相关的事物。第一个是计数器,第二个是页码。从技术上讲,标签是使用(来自latex.ltx):

\def\label#1{\@bsphack
  \protected@write\@auxout{}%
         {\string\newlabel{#1}{{\@currentlabel}{\thepage}}}%
  \@esphack}

您将只看到\@currentlabel\thepage被写入使用.aux\protected@writehyperref加载后,它存储的不仅仅是两个东西。事实上,它存储(从nameref.dtx):

\def\label#1{%
  \@bsphack
  \begingroup
    \def\label@name{#1}%
    \label@hook
    \protected@write\@auxout{}{%
      \string\newlabel{#1}{%
        {\@currentlabel}%
        {\thepage}%
        {\@currentlabelname}%
        {\@currentHref}{}%
      }%
    }%
  \endgroup
  \@esphack
}%

为了应对这种重新定义\label(现在存储条目),\ref也更新为预计 事物,而不是你可能认为的两件事。

下面我提供了你的 MWE 的更新版本,它似乎可以满足你的要求,使用refcount作为\getrefnumber中介可扩展的反计算:

在此处输入图片描述

\documentclass{article}
\usepackage{xifthen,refcount,hyperref}% http://ctan.org/pkg/{xifthen,refcount,hyperref}

\makeatletter
\newcommand{\writeval}[2]{%
  \@bsphack%
  \setcounter{mycntr}{\numexpr\number#2-1}\refstepcounter{mycntr}%
  \label{#1}% Mark current label
  \@esphack%
}
\makeatother

\newcounter{mycntr}

\begin{document}

\writeval{mylabel}{6}
mylabel = \ref{mylabel}

\begin{tabular}{c}%
  \setcounter{mycntr}{1}%
  \whiledo{\value{mycntr}<\getrefnumber{mylabel}}{%
    {\themycntr}\\ % 
    \stepcounter{mycntr}%
  }%
\end{tabular}%

\end{document}

为了便于使用,我使用了一个计数器,并使用 标记了引用\refstepcounter。还有其他方法可以做到这一点(例如,将 中的内容复制\label到 的定义中\writeval,只使用重要的部分),但在这种情况下很方便(假设您只标记数字)。

答案3

该解决方案包括提供一个\hyperbypass宏,用于本地修补 hyperref 驱动程序(如果您不想用 s 替换相关的\refs \ref*)和一个\hyperrestore宏来恢复以前的设置:

\documentclass{article}
\usepackage{hyperref}

\makeatletter
%Store the hyperref driver setup
\let\HR@hyper@@anchor\hyper@@anchor
\let\HR@hyper@link\hyper@link%
\let\HR@hyper@linkurl\hyper@linkurl%
\let\HR@hyper@linkfile\hyper@linkfile%
\let\HR@hyper@anchorstart\hyper@anchorstart
\let\HR@hyper@anchorend\hyper@anchorend
\let\HR@hyper@linkstart\hyper@linkstart
\let\HR@hyper@linkend\hyper@linkend
%Bypass macro
\newcommand\hyperbypass{%
\let\hyper@@anchor\@gobble
\gdef\hyper@link##1##2##3{##3}%
\def\hyper@linkurl##1##2{##1}%
\def\hyper@linkfile##1##2##3{##1}%
\let\hyper@anchorstart\@gobble
\let\hyper@anchorend\@empty
\let\hyper@linkstart\@gobbletwo
\let\hyper@linkend\@empty
}
%Restore macro
\newcommand\hyperrestore{%
\let\hyper@@anchor\HR@hyper@@anchor
\let\hyper@link\HR@hyper@link%
\let\hyper@linkurl\HR@hyper@linkurl%
\let\hyper@linkfile\HR@hyper@linkfile%
\let\hyper@anchorstart\HR@hyper@anchorstart
\let\hyper@anchorend\HR@hyper@anchorend
\let\hyper@linkstart\HR@hyper@linkstart
\let\hyper@linkend\HR@hyper@linkend
}
\makeatother

\begin{document}
\section{Introduction}
\label{sec:intro}
This \verb+\ref+ will be linked regularly \ref{sec:intro}.\\
\hyperbypass
This one won't \ref{sec:intro}.\\
\hyperrestore
But, this one again \ref{sec:intro}.
\end{document}

相关内容