我有一个相当复杂的设置,用于创建一个较大的文档(> 200 页)。我想创建文档选定部分的“预览”。关于如何剪切和拼接 PDF 文件有很多问题 - 这是不是我所要求的。
我想做的是
- 标记文档源中我想要包含在摘录中的区域 - 我正在考虑某种
\startpreview
和\endpreview
命令 - 将这些命令以文本形式呈现到的页面写入某个外部文件(或者可能是 .aux 文件,如果这有帮助或更容易?),以便我获得要提取的页面范围动态地
- 汇编命令行脚本或一些提取实际预览的 .tex 文件
我应该能够完成最后一步,但我感觉应该有一个包或一些预组装的工具来实现前两个步骤。我什么也没找到。将文档中标记区域的页面范围放入某些后处理工具中的最佳方法是什么?
答案1
我添加了另一个答案,因为前一个答案几乎有效,并且它是一种完全不同的方法。
我定义了相同的两个命令;\startpreview
和\endpreview
。
他们的行为:
该\startpreview
宏定义了一个\prevpage
保存当前页码的宏。该\endpreview
宏将使用 完成此页面范围的创建start-end
。
该\startpreview
宏会将此页面范围写入文件\jobname.prev
。
编译结束时,文件\jobname.prev
将具有“预览”的页面范围。要创建预览 pdf,只需将此文件传递给 pdf 管理软件,例如pdftk
。
例如,使用pdftk
和bash
,可以使用以下命令创建预览 pdf:
pdftk main.pdf cat $(cat main.prev) output preview.pdf
代码:
\documentclass{article}
\usepackage{lipsum}
\usepackage{atbegshi}
\newcounter{globalpage}
\AtBeginDocument{\setcounter{globalpage}{1}}
\AtBeginShipout{\stepcounter{globalpage}}
\newwrite\fid
\immediate\openout\fid=\jobname.prev
\newif\ifprev\prevfalse
\newif\ifstartprev\startprevfalse
\def\removelastpage#1-#2\null{%
\xdef\prevpage{#1-}%
}
\def\startpreview{%
\ifstartprev
\errmessage{You must use \string\endpreview\space before using another \string\startpreview.}
\fi%
\startprevtrue%
\ifprev% one page range was already defined
\ifnum\lastpage=\the\value{globalpage}% if the last page of the previous range is equal to the first page of this range then they are the same
\expandafter\removelastpage\prevpage\null%
\else% otherwise, write
\immediate\write\fid{\prevpage}%
\xdef\prevpage{\the\value{globalpage}-}%
\fi%
\else%
\xdef\prevpage{\the\value{globalpage}-}%
\fi
\prevfalse
}
\def\endpreview{%
\ifstartprev\else
\errmessage{You must use \string\startpreview\space before using \string\endpreview.}
\fi%
\startprevfalse%
\xdef\prevpage{\prevpage\the\value{globalpage}}%
\xdef\lastpage{\the\value{globalpage}}%
\prevtrue%
}
\AtEndDocument{%
\ifstartprev\endpreview\fi% finish preview if necessary
\immediate\write\fid{\prevpage}%
}
\let\oldthepage\thepage
\renewcommand*\thepage{{\Huge\oldthepage}}
\begin{document}
\Huge
\startpreview
\lipsum[1]
\endpreview
\lipsum[2-5]
\startpreview
\lipsum[6]
\endpreview
\startpreview
\lipsum[7-8]
\endpreview
\end{document}
更新:
之前版本的代码保存\the\value{page}
在 .prev 文件中。我当时天真地没有意识到其中的问题,但是一旦代码要用于包含罗马数字目录的书籍,保存的数字就会出错。所以我定义了一个,globalpage
并用钩子让它增加\AtBeginShipout
,这样 .prev 文件中保存的数字就有望成为全局页码了。
答案2
就这样吧:)
我创建了两个宏:\startpreview
和\endpreview
。
他们的行为:
一切后a
\startpreview
将被写入输出 pdf。从 之后的页面开始的所有内容
\endpreview
都将被丢弃,除非\startpreview
覆盖了这一点。
工作原理:
\newif
我定义了两个计数器(由于某种原因,我无法让它与 一起工作),\thiskeep
并且\nextkeep
.\thiskeep
将告诉当前页面是否保留,并\nextkeep
告知下一个是否保留。
该\startpreview
宏将设置\thiskeep
并\nextkeep
保留当前页面以及之后的任何页面。
该\endpreview
宏将设置\nextkeep
为丢弃下一页。但它不会对 执行任何操作\thiskeep
。这是为了让\startpreview
比 更“强大” \endpreview
。
最后,在发送每个页面时都会有一个钩子检查是否\thiskeep
设置为 1。如果不是,那么钩子会丢弃该页面并使\thiskeep
为\nextkeep
。
默认行为是丢弃每一页。
代码:
\documentclass{article}
\usepackage{lipsum}
\usepackage{atbegshi}
\newcount\thiskeep\global\thiskeep=0
\newcount\nextkeep\global\nextkeep=0
\def\startpreview{%
\global\thiskeep=1%
\global\nextkeep=1%
}
\def\endpreview{%
\global\nextkeep=0%
}
\AtBeginShipout{%
\ifodd\thiskeep\else%
\AtBeginShipoutDiscard%
\fi%
\global\thiskeep=\nextkeep%
}
\let\oldthepage\thepage
\renewcommand*\thepage{{\Huge\oldthepage}}
\begin{document}
\Huge
\startpreview
\lipsum[1]
\endpreview
\lipsum[2-5]
\startpreview
\lipsum[6]
\endpreview
\startpreview
\lipsum[7-8]
\endpreview
\end{document}
输出:
添加家具使得可视化变得容易。
请注意第 2 页到第 6 页之间缺失的页面:)