我记得很久以前,我看到 PDF 文档(例如报纸的在线 PDF 版本)的段落周围都有超文本框,这样当你点击这些框内时,被包围的段落就会放大精确到 Acrobat Reader 窗口中的那个段落。我不确定使用什么工具创建这些 PDF,不幸的是,我目前找不到一个例子。
是否可以使用一些 pdflatex 代码重现这种点击放大功能?重复一遍:请求的功能是在段落或图形周围创建超文本框,单击时 PDF 查看器会放大该区域。
此功能对于给定页面中具有大量结构的 PDF 非常有用,例如分散在页面各处的小段落或图形或图形标题。
(Beamer 具有“放大”功能(\framezoom
),但这并不是一回事,因为放大后会创建一个包含放大区域的新页面,而我只想强制 PDF 阅读器通过缩放来封闭同一页面中的区域。我也知道 Acrobat 中的选框缩放功能,但这不是我想要的,因为它无法识别内容。)
答案1
以下代码(用于 pdfLaTeX)定义了命令\zoombox[box line width]{contents}
。它创建一个点击缩放框,用于将第二个参数“内容”放入 AdobeReader 窗口。如果可选的“框线宽度”大于 0,则会在框周围绘制一条虚线。
编辑:代码已针对演示 PDF(例如beamer
生成的 PDF)进行了优化,全屏模式。单击时,缩放框现在位于屏幕中央,正如@alfC 所要求的那样。
\documentclass{beamer}
\usepackage{graphicx}
\usepackage{mwe}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \zoombox[box line width]{contents}
%
% optimized version for beamer: in full screen, zoom boxes are centred
% in the viewer; useable with any documenclass
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatletter
\newsavebox\zb@x
\newcounter{z@@m}
\usepackage{calc}
\newdimen\B@r\newdimen\P@r
\newdimen\@zw\newdimen\@zh\newdimen\@zd
\newcommand{\zoombox}[2][0]{%
\leavevmode%
\sbox\zb@x{#2}%
\setlength\B@r{1pt*\ratio{\wd\zb@x}{\ht\zb@x+\dp\zb@x}}%
\setlength\P@r{1pt*\ratio{\paperwidth}{\paperheight}}%
\ifdim\B@r>\P@r\relax%
\setlength\@zw{\wd\zb@x}\setlength\@zh{\@zw*\ratio{\paperheight}{\paperwidth}}%
\setlength\@zd{(\@zh-\ht\zb@x-\dp\zb@x)*\real{0.5}+\dp\zb@x}%
\setlength\@zh{\@zh-\@zd}%
\else%
\setlength\@zh{\ht\zb@x+\dp\zb@x}%
\setlength\@zw{\@zh*\ratio{\paperwidth}{\paperheight}}%
\setlength\@zh{\ht\zb@x}\setlength\@zd{\dp\zb@x}%
\fi%
\makebox[0pt][l]{\makebox[\wd\zb@x][c]{\makebox[\@zw][l]{%
\pdfdest name {zbfs\thez@@m} fitr
width \@zw\space
height \@zh\space
depth \@zd\space
}}}%
\pdfdest name {zb\thez@@m} fitr
width \wd\zb@x\space
height \ht\zb@x\space
depth \dp\zb@x\space
\immediate\pdfannot
width \wd\zb@x\space
height \ht\zb@x\space
depth \dp\zb@x\space
{%
/Subtype/Link/H/N
/Border [0 0 #1 [1 2]]
/A <<
/S/JavaScript
/JS (
if(typeof(zoomed)=='undefined'||!zoomed){
var lastView=this.viewState;
if(app.fs.isFullScreen) this.gotoNamedDest('zbfs\thez@@m');
else this.gotoNamedDest('zb\thez@@m');
zoomed=true;
}else{
this.viewState=lastView;
zoomed=false;
}
)
>>
}%
\usebox{\zb@x}%
\stepcounter{z@@m}%
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{frame}
\zoombox{\includegraphics[width=1cm]{example-image-a}}
\zoombox{\includegraphics[width=1cm]{example-image-b}}
\zoombox{\includegraphics[width=1cm]{example-image-c}}
\zoombox{\includegraphics[height=1cm]{example-image-golden}}
\zoombox{\includegraphics[width=1cm]{example-image-golden-upright}}
\end{frame}
\end{document}
第二个示例定义了用于标记缩放框对角(左下角和右上角,或左上角和右下角)的命令对,以及用于标记文本序列/整个段落的命令。
\documentclass{article}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatletter
\InputIfFileExists{\jobname.zom}{}{}
\newwrite\zoomdat
\immediate\openout\zoomdat=\jobname.zom
\newcommand{\startzoombox}[2][0]{%
\leavevmode%
\pdfsavepos%
\protected@write\zoomdat{}{%
\string\expandafter\string\def\string\csname\space zb#2.ulx\string\endcsname{%
\noexpand\number\pdflastxpos}%
\string\expandafter\string\def\string\csname\space zb#2.uly\string\endcsname{%
\noexpand\number\pdflastypos}%
}%
\ifcsname zb#2.ulx\endcsname\ifcsname zb#2.lrx\endcsname%
\edef\zoomwd{\dimexpr \csname zb#2.lrx\endcsname sp- \csname zb#2.ulx\endcsname sp\relax}%
\edef\zoomdp{\dimexpr \csname zb#2.uly\endcsname sp- \csname zb#2.lry\endcsname sp\relax}%
\pdfdest name {zb#2.in} fitr
width \zoomwd
height 0pt
depth \zoomdp
\immediate\pdfannot
width \zoomwd
height 0pt
depth \zoomdp
{%
/Subtype/Link/H/N
/Border [0 0 1 [1 2]]
/A <<
/S/JavaScript
/JS (
if(typeof(zoomed)=='undefined'||!zoomed){
var lastView=this.viewState;
zoomed=true;
this.gotoNamedDest('zb#2.in');
}else{
this.viewState=lastView;
zoomed=false;
}
)
>>
}%
\fi\fi%
}
\def\stopzoombox#1{%\leavevmode%
\leavevmode%
\pdfsavepos%
\protected@write\zoomdat{}{%
\string\expandafter\string\def\string\csname\space zb#1.lrx\string\endcsname{%
\noexpand\number\pdflastxpos}%
\string\expandafter\string\def\string\csname\space zb#1.lry\string\endcsname{%
\noexpand\number\pdflastypos}%
}%
}
\def\startzoom{%
\stepcounter{@zb@id}%
\xdef\@lblStack{\the@zb@id.\@lblStack}%
\@ifstar\@startzoomstar\@startzoom%
}
\newcommand{\@startzoom}[1][0]{%
\raisebox{\baselineskip}[0pt][0pt]{\startzoombox[#1]{.\the@zb@id}}%
}
\newcommand{\@startzoomstar}[1][0]{%
\makebox[0pt][r]{\raisebox{\baselineskip}[0pt][0pt]{\startzoombox[#1]{.\the@zb@id}}%
\hspace{\parindent}}%
}
\def\stopzoom{%
\@ifstar\@stopzoomstar\@stopzoom%
}
\def\@stopzoom{%
\@popStack\@lblStack%
\raisebox{-1ex}[0pt][0pt]{\stopzoombox{.\@lblCur}}%
\xspace%
}
\def\@stopzoomstar{%
\@popStack\@lblStack%
\hfill\raisebox{-1ex}[0pt][0pt]{\stopzoombox{.\@lblCur}}%
\xspace%
}
\newcounter{@zb@id}
\def\@lblStack{}
\def\@popStack#1{\expandafter\@@popStack#1\nil}
\def\@@popStack#1.#2\nil{\gdef\@lblCur{#1}\gdef\@lblStack{#2}}
\RequirePackage{xspace}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\section{Paragraph zooming}
\startzoom[1]First paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first \startzoom[1]\emph{Do not miss this one.}\stopzoom First paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph first paragraph.\stopzoom*
\startzoom*[1]Second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph second paragraph.\stopzoom*
\end{document}
标记缩放区域角落的两个命令是
\startzoombox[line width]{label}
和
\stopzoombox{label}
它们旨在用于图片制作环境,例如pspicture
或tikzpicture
。相关命令对必须由唯一的标签标识。
为了标记文本和段落,提供了以下命令:
\startzoom[lwidth]
\startzoom*[lwidth]
\stopzoom
\stopzoom*
带星号的版本插入水平空格(\parindent
第一行负片,\hfill
段落末尾)。
缩放区域可以嵌套。但是,较小的区域应放在较大的区域之上(即在代码中稍后出现),以免被遮挡。
请注意,至少pdflatex
需要运行两次。
编辑:
该宏的 dvipdfmx/XeLaTeX 版本\zoombox
如下:如何在非投影仪文档中包含可点击缩放的缩略图?
答案2
据我所知,没有预定义的宏或包可以完成所有这些工作,但您需要的元素是存在的:您可以使用包放置带有缩放窗口的超链接hyperref
。您可以使用包获取所需的坐标zref
,尤其是zref-abspos
。这些包来自同一作者,可以很好地协同工作。
您需要将段落放在其自己的框中。zref
分别在段落的左侧和右侧位置放置一个标记,以获取其坐标。然后将整个框放入使用坐标作为目标的宏中。有关更多详细信息,尤其是(矩形缩放) \href
,请参阅手册。hyperref
\href
FitR
答案3
我猜你正在考虑 PDF 的“文章线索”功能。此功能对于报纸等文本流复杂(多列且页面分为多篇文章,甚至“(第 3 页继续)”等内容尤其有用。使用 Adobe Reader,当你将鼠标悬停在线索上时,手形图标会变为带有箭头的手形图标,单击后会缩放到文章的宽度,并且每次单击都会遵循文章的流程,无论文章的流程多么非线性和复杂。
PDFtex 确实具有支持文章线程的原语:\pdfthread
,,,。但据我所知,唯一的 latex 支持相当有限,通过\pdfstartthread
,因此仅在您用于某些复杂的拼版时才有用。\pdfendthread
\pdfthreadmargin
pdfpages
pdfpages