50 如何 print down hyperref 的 href 的 border?

发布于 2024-09-23 15:54:01

在用 hyperref 宏包的时候,对于 colored boxes / border 有没有类似 ocgcolorlinks 的相反作用的命令?
就是我想它既显示彩框,又打印彩框(这里的打印是指打印成纸质材料)
比如
image.png

我想它既显示那个红框和绿框,也打印这个红框和绿框,但是打印视图里没有(实际也不会打印)
image.png

这是一个 MWE,使用 TeXLive 2024 发行版 + pdflatex 编译 + Acrobat 阅读器

\documentclass{article}
\usepackage{hyperref}
\title{Test}
\begin{document}
\maketitle
\tableofcontents
\section{Test Title}
This is a test.\cite{meow}
\begin{thebibliography}{1}
\bibitem{meow} Meow, Cat. \emph{Meow}. 2021.
\end{thebibliography}
\end{document}

查询该宏包文档后,找到的OCG(Optional Content Groups)的相关选项,并没有帮助到我
image.png

查看更多

关注者
0
被浏览
3.2k
Eureka
Eureka 2024-09-28
这家伙很懒,什么也没写!

前言

其实在 TSE 上已经有人问过一样的问题了,如下: printing colored borders of hyperref package (latex)

但是下面的回答是叫他每次都手动添加. 这肯定不是你想要的:
image.png

1. ocgcolorlinks

首先解答关于最后那个 ocgcolorlinks 的问题, 这个东西其实是有用的,只不过你没有使用正确。这个 ocgcolorlinks 只能够控制 linkcolor, 并不能够控制 linkborder。下面就是把此 option 分别置为 falsetrue 的打印预览图:

  • 置为 false:

image.png

  • 置为 true:

image.png

所以现在想要在打印的时候保留这个 border,你需要的也许是 ocgbordercolors 而不是 ocglinkcolors , 但是遗憾的是,目前 hyperref 没有这个选项. 而且它还采用了一个比较 邪恶 的的做法,直接在宏包中写入 pdf 源码. hyperref 中的这部分代码如下:

\def\Hy@setpdfborder{%
  \ifx\@pdfborder\@empty
  \else
    /Border[\@pdfborder]%
  \fi
  \ifx\@pdfborderstyle\@empty
  \else
    /BS<<\@pdfborderstyle>>%
  \fi
}

你猜猜这个 /BS<< ... >> 以及 /Border[...] 是啥东西?这个就是手写pdf,其实在 pdf specification 中你可以找到这两个命令的用法的, 如下:
image.png

所以你如果会手写 pdf 的话,你可以做出来一些比较 interesting 的 border style. 比如下面这样的:
image.png

但是由于目前,我也不会手写 pdf, 所以我采用的方法是就是重定义这部分命令. 具体操作细节见下面说明.

2. 思路分析

下面我们就看看这个 ocglinkcolors 选项怎么起作用的? hyperref 宏包中跟这部分有关的代码 snippets 如下:

% line: 4501
\Hy@AtBeginDocument{%
  \ifHy@ocgcolorlinks
    \kvsetkeys{Hyp}{colorlinks}%
    \ifHy@pdfa
      \Hy@Warning{%
        PDF/A: Optional Content Groups are prohibited,\MessageBreak
        using `colorlinks' instead of `ocgcolorlinks'%
      }%
      \Hy@ocgcolorlinksfalse
    \fi
  \fi
  \ifHy@ocgcolorlinks
  \else
    \Hy@DisableOption{ocgcolorlinks}%
  \fi
  \ifHy@colorlinks
    \def\@pdfborder{0 0 0}%
    \let\@pdfborderstyle\@empty
    \Hy@CatcodeWrapper{%
      \RequirePackage{color}%
     }%
    \def\Hy@colorlink#1{%
      \begingroup
      \HyColor@UseColor#1%
    }%
    \def\Hy@endcolorlink{\endgroup}%
    \Hy@Info{Link coloring ON}%
  \else
    \ifHy@frenchlinks
      \def\Hy@colorlink#1{\begingroup\fontshape{\scdefault}\selectfont}%
      \def\Hy@endcolorlink{\endgroup}%
      \Hy@Info{French linking ON}%
    \else
      \def\Hy@colorlink#1{\begingroup}%
      \def\Hy@endcolorlink{\endgroup}%
      \Hy@Info{Link coloring OFF}%
    \fi
  \fi
  % line: 4538
  ...
 
 }

这个 ocglinkcolors 默认为 false, 所以默认情况下会直接走到判断 \ifHy@colorlinks. 如果此时 colorlinks 这个选项为 true,那么 hyperref 会取消这个 border, 对应的语句为: def\@pdfborder{0 0 0}. 然后把这个 \Hy@colorlink1 放到对应的 hyper-text 前面,把 \Hy@endcolorlink 放到 这个 hyper-text 后面,可以想象成下面这个样子:

\Hy@colorlink <hyper-text> \Hy@endcolorlink

这个就是 ocglinkcolors 的运行过程. 想要把这个 box 输出出来也就很简单了:只要把这个 <hyper-text> 放到一个 \fbox 命令中就行了. 但是因为这里是以前以后的两个命令,时候我就用了一个 box 来截取这个 <hyper-text>, 然后把这个 box 放到 \fbox 中. 具体可编译的的代码如下:

\documentclass{article}
\usepackage{xcolor}
\usepackage[colorlinks=true]{hyperref}
\newsavebox{\mybox}
\NewDocumentEnvironment{hyperbox}{}
  {\begin{lrbox}{\mybox}}
  {\end{lrbox}\fbox{\usebox{\mybox}}}

\begin{document}
\makeatletter
\def\Hy@colorlink#1{%
  \begingroup%
  \HyColor@UseColor#1%
  \begin{hyperbox}
}%
\def\Hy@endcolorlink{\end{hyperbox}\endgroup}%
\makeatother


\tableofcontents
\section{Test Title}
Href Test: \href{www.google.com}{GOOGLE}


\subsection{Bib Test}
This is a test.\cite{meow}
\begin{thebibliography}{1}
\setcounter{enumiv}{15}
\bibitem{meow} Meow, Cat. \emph{Meow}. 2021.
\end{thebibliography}
\end{document}

打印预览结果:
image.png

3. 备注

  • 如果你想要在 colorlinks=false 的情况下输入这个 \fbox 的话,你可以定义 colorlinks=false 那个分支的两个命令.
  • 盒子的样式你也可以自定义,把那个 \fbox 换成你喜欢的任何的盒子命令就可以了,比如 \tcbbox{}.
  • 个人觉得这个方法目前还不好,如果有更复杂的需求,请继续提问,我就可能会改用其它更好的方法

Happy Hyperref !!

1 个回答

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览