Создание закладок в PDF-файл с помощью командной строки
Я ищу инструмент командной строки для добавления закладок в файл PDF.
у меня есть page number
и label
. Хотелось бы создать закладку под названием label
ссылка на страницу page number
.
кто-нибудь знает инструмент командной строки (предпочтительно OSX) для этого?
у меня есть около 4000 страниц PDF-файлов и около 150 закладок, и я хотел бы автоматизировать его.
мой план заключается в использовании системного вызова в Р-сценарий.
редактировать
Я создаю около 4000 отдельных PDF-файлов с графиками, и я использую системную команду OSX /System/Library/Automator/Combine PDF Pages.action/Contents/Resources/join.py
для объединения PDF-файлов вместе. Ранее я использовал pdfjoin
С pdfjam
пакета, но это было слишком медленно. В конце концов, именно так я получаю свой PDF, где я добавляю закладки вручную с помощью Adobe Acrobat Professional на данный момент.
4 ответов
вы также можете использовать pdftk
. Он также доступен для OS X.
Я не буду обсуждать все детали здесь и сейчас, потому что это уже было сделано в другом месте. Только коротко:
- создайте образец PDF из исходных файлов (без закладок).
- добавить некоторые закладки с Adobe Acrobat (к которым у вас, похоже, есть доступ).
-
запустить один из этих команд:
pdftk my.pdf dump_data output - pdftk my.pdf dump_data output bookmarks+otherdata.txt
изучите формат вывода.
- изменить выход .txt файл, добавив все записи, которые вы хотите.
-
запустите PDFTK еще раз:
pdftk my.pdf update_info bookmarks.txt output bookmarked.pdf
Дополнительная Информация
это формат закладки, который я заметил после проверки на шаге 4 выше.
BookmarkBegin
BookmarkTitle: -- Your Title 1 --
BookmarkLevel: 1
BookmarkPageNumber: 1
BookmarkBegin
BookmarkTitle: -- Your Title 2 --
BookmarkLevel: 1
BookmarkPageNumber: 2
BookmarkBegin
BookmarkTitle: -- Your Title 3 --
...
...
and so on...
и заменить выше.. в нужном месте.
хорошо, вот быстрый способ сделать три работы сразу:
- объединить 400 одностраничных PDF-файлов.
- создайте документ верхнего уровня ToC (Оглавление).
- создайте закладку PDF для каждой страницы.
он включает в себя использование установки LaTeX.
вы начинаете с пустого шаблона LaTeX, как следующий:
\documentclass[]{article}
\usepackage{pdfpages}
\usepackage{hyperref}
\hypersetup{breaklinks=true,
bookmarks=true,
pdfauthor={},
pdftitle={},
colorlinks=true,
citecolor=blue,
urlcolor=blue,
linkcolor=magenta,
pdfborder={0 0 0}}
\begin{document}
{
\hypersetup{linkcolor=black}
\setcounter{tocdepth}{3}
% Comment next line in or out if you want a ToC or not:
\tableofcontents
}
%% Here goes your additional code:
%% 1 line per included PDF!
\end{document}
теперь перед последней строкой этого шаблона вы вставляете один строка на внешний PDF-файл, который вы хотите включить.
-
если вы хотите создать ToC, он должен быть отформатирован следующим образом:
\includepdf[pages={<pagenumber>},addtotoc{<pagenumber>,<section>,<level>,\ <heading>,<label>}]{pdffilename.pdf}
-
в случае, если вы уверены, что каждый включенный PDF является 1-страничным документом, он упрощает это:
\includepdf[addtotoc{<pagenumber>,<section>,<level>,\ <heading>,<label>}]]{pdffilename.pdf}
здесь все из следующих пяти параметров для addtotoc
требуются в порядке, указанном для файлов, чтобы отображаются в закладках и в ToC. См. ниже конкретный пример:
-
<pagenumber>
: номер страницы вставленного документа, с которым необходимо связать. (В вашем случае всегда "1", потому что вы вставляете только 1-страничные документы; вы можете вставить 5-страничный документ и ссылку на страницу 3 вставленного PDF). -
<section>
: имя секционирования латекса. Может бытьsection
,subsection
,subsubsection
... В вашем случае "раздел." -
<level>
: уровень раздела LaTeX. В вашем случае "1". -
<heading>
: это строка. Используется для текста закладки -
<label>
: это должно быть уникальным для каждой закладки. Используется в PDF внутренне, чтобы перейти к правильной странице при нажатии закладки.
чтобы проверить это быстро, я использовал Ghostscript для создания 20 1-страничного PDF документы:
for i in {1..20}; do
gs -o p${i}.pdf -sDEVICE=pdfwrite \
-c "/Helvetica findfont 30 scalefont setfont \
100 600 moveto \
(Page ${i}) show \
showpage";
done
С помощью этих тестовых файлов я мог бы сделать строки для вставки в шаблон выглядеть так:
\includepdf[addtotoc={1,section,1,Page 1 (First),p1}]{p1.pdf}
\includepdf[addtotoc={1,section,1,Page 2,p2}]{p2.pdf}
\includepdf[addtotoc={1,section,1,Page 3,p3}]{p3.pdf}
[...]
\includepdf[addtotoc={1,section,1,Page 11 (In the Middle),p11}]{p11.pdf}
[...]
\includepdf[addtotoc={1,section,1,Page 20 (Last),p20}]{p20.pdf}
сохраните шаблон с вставленными строками, затем выполните следующую команду два раза:
pdflatex template.tex
pdflatex template.tex
полученный файл будет иметь закладки, выглядящие так в предварительном просмотре.app:
Примечание: латекс доступно для OSX двумя способами:
я добавлю один или два других метода для вставки закладок в командной строке, позже или в ближайшие несколько дней, если у меня будет больше времени.
пока это нужно сделать, потому что я никогда не показывал его здесь на SO, AFAICR.
но я думал, потому что вы дали фон " я объединяю 1-страничные PDF-файлы, и это медленно; теперь я хочу добавить закладки тоже...- Я мог бы показать, как это делается одним-единственным способом.
подсказка : один из других методов можно будет использовать pdftk
, который IS доступно для Mac OS X!
вот еще один ответ. Этот использует Ghostscript для обработки PDF-to-PDF и pdfmark
оператор PostScript для вставки закладок.
для некоторого введения в тему pdfmark см. Также:
- Томаса Мерца PDFmark Праймер.
этот метод включает в себя два шага:
- создайте текстовый файл (Файл PostScript, действительно) с ограниченным набором из
pdfmark
команды, по одной на строку и закладку, которую вы хотите добавить. - запустите команду Ghostscript, которая обрабатывает текущий PDF-файл вместе с текстовым файлом.
1.
содержимое текстового файла должно выглядеть примерно так:
[/Page 1 /View [/XYZ null null null] /Title (This is page 1) /OUT pdfmark
[/Page 2 /View [/XYZ null null null] /Title (Dunno which page this is....) /OUT pdfmark
[/Page 3 /View [/XYZ null null null] /Title (Some other name) /OUT pdfmark
[/Page 4 /View [/XYZ null null null] /Title (File 4) /OUT pdfmark
[/Page 5 /View [/XYZ null null null] /Title (File 5) /OUT pdfmark
[/Page 6 /View [/XYZ null null null] /Title (File 6) /OUT pdfmark
[/Page 7 /View [/XYZ null null null] /Title (File 7) /OUT pdfmark
% more lines for more pages to bookmark...
[/Page 13 /View [/XYZ null null null] /Title (File 13) /OUT pdfmark
[/Page 14 /View [/XYZ null null null] /Title (Bookmark for page 14) /OUT pdfmark
% more lines for more pages to bookmark...
назовите этот файл, например:addmybookmarks.txt
2.
теперь выполните следующую команду:
gs -o bookmarked.pdf \
-sDEVICE=pdfwrite \
addmybookmarks.txt \
-f original.pdf
полученный PDF,bookmarked.pdf
теперь содержит закладки. Видеть этот скриншот:
вот метод python для добавления закладок в оглавление. Работает на MacOS без каких-либо других установок.
#!/usr/bin/python
from Foundation import NSURL, NSString
import Quartz as Quartz
import sys
# You will need to change these filepaths to a local test pdf and an output file.
infile = "/path/to/file.pdf"
outfile = "/path/to/output.pdf"
def getOutline(page, label):
# Create Destination
myPage = myPDF.pageAtIndex_(page)
pageSize = myPage.boundsForBox_(Quartz.kCGPDFMediaBox)
x = 0
y = Quartz.CGRectGetMaxY(pageSize)
pagePoint = Quartz.CGPointMake(x,y)
myDestination = Quartz.PDFDestination.alloc().initWithPage_atPoint_(myPage, pagePoint)
myLabel = NSString.stringWithString_(label)
myOutline = Quartz.PDFOutline.alloc().init()
myOutline.setLabel_(myLabel)
myOutline.setDestination_(myDestination)
return myOutline
pdfURL = NSURL.fileURLWithPath_(infile)
myPDF = Quartz.PDFDocument.alloc().initWithURL_(pdfURL)
if myPDF:
# Here's where you list your page index (starts at 0) and label.
outline1 = getOutline(0, 'Page 1')
outline2 = getOutline(1, 'Page 2')
outline3 = getOutline(2, 'Page 3')
# Create a root Outline and add each outline. (Needs a loop.)
rootOutline = Quartz.PDFOutline.alloc().init()
rootOutline.insertChild_atIndex_(outline1, 0)
rootOutline.insertChild_atIndex_(outline2, 1)
rootOutline.insertChild_atIndex_(outline3, 2)
myPDF.setOutlineRoot_(rootOutline)
myPDF.writeToFile_(outfile)