PDFファイルで指定された宛先を一覧表示するには?
名前付き宛先は、アンカーポイントと呼ばれるものの公式名です。foo
リンクをクリックすると、メインブラウザが指定された宛先に移動しますhttp://example.com/some.pdf#foo
。
アンカーが機能していることを確認できるドキュメントがありますが、リストする方法が見つからないようです。 Evince、okular、およびxpdfは、指示があるときにその項目に移動しますが、リストされたインターフェースはないようです。pdftk dump_data
ブックマークを一覧表示しますが、これは同じではありません(指定されたターゲットと同じ場所にある可能性が最も高いがアンカーとして使用できないコンテンツアイテムテーブルです)。
私はコマンドラインソリューションを探しています(例:などの完成後に使用するのに適していますevince -n
)。これは意味があるので、文書に表示される順序でターゲットを一覧表示したいと思います。ボーナス:ターゲットページ番号とターゲットの場所を決定するのに役立つその他の情報を表示します。
また、見ることができますソフトウェア推奨事項のPDF文書のアンカーを表示するGUIビューア用。
答え1
ポプラの PDFについてコマンドラインユーティリティは、PDFで指定されているすべての宛先のページ番号、場所、名前を提供します。 Popplerバージョン0.58以降が必要です。
$ pdfinfo -dests input.pdf
Page Destination Name
1 [ XYZ null null null ] "F1"
1 [ XYZ 122 458 null ] "G1.1500945"
1 [ XYZ 79 107 null ] "G1.1500953"
1 [ XYZ 79 81 null ] "G1.1500954"
1 [ XYZ null null null ] "P.1"
2 [ XYZ null null null ] "L1"
2 [ XYZ null null null ] "P.2"
(...)
答え2
これpyPDFライブラリはアンカーポイントを一覧表示できます。
#!/usr/bin/env python
import sys
from pyPdf import PdfFileReader
def pdf_list_anchors(fh):
reader = PdfFileReader(fh)
destinations = reader.getNamedDestinations()
for name in destinations:
print name
pdf_list_anchors(open(sys.argv[1]))
これはユースケースを完了するのに十分ですが、アンカーはランダムな順序でリストされています。 pyPdf 1.13には安定したインターフェイスしかありません。アンカーを順番にリストする方法はありません。まだpyPdf2を試していません。
答え3
(ここにも答えがあります:PDF文書の基準点を見る)
私は同じ問題があり、ついに次のように素晴らしい答えを見つけました。PDF構造を視覚的に調べてリバースエンジニアリングするには?
答えはPythonパッケージを使用することですpdfminer.six
。均一ドキュメントの例の一つです!次のコードを切り取り、端末に貼り付けます。
pip install pdfminer.six
cat >extract.py <<EOF
import sys
import pdfminer.pdfparser, pdfminer.pdfdocument
with open(sys.argv[1], "rb") as f:
parser = pdfminer.pdfparser.PDFParser(f)
document = pdfminer.pdfdocument.PDFDocument(parser)
for (level, title, dest, a, se) in document.get_outlines():
print(' ' * level, title, dest or a, se)
EOF
python extract.py myInputFile.pdf
私の特定のPDFでは、出力は次のようになります。
$ python extract.py ~/Desktop/p2786r3.pdf | head
Abstract {'S': /'GoTo', 'D': b'section.1'} None
Revision History {'S': /'GoTo', 'D': b'section.2'} None
R3: October 2023 (midterm mailing)r3-october-2023-midterm-mailing {'S': /'GoTo', 'D': b'section*.2'} None
R2: June 2023 (Varna meeting)r2-june-2023-varna-meeting {'S': /'GoTo', 'D': b'section*.3'} None
R1: May 2023 (pre-Varna mailing)r1-may-2023-pre-varna-mailing {'S': /'GoTo', 'D': b'section*.4'} None
R0: Issaquah 2023r0-issaquah-2023 {'S': /'GoTo', 'D': b'section*.5'} None
Introduction {'S': /'GoTo', 'D': b'section.3'} None
Motivating Use Cases {'S': /'GoTo', 'D': b'section.4'} None
Efficient vector growth {'S': /'GoTo', 'D': b'subsection.4.1'} None
Moving types without empty states {'S': /'GoTo', 'D': b'subsection.4.2'} None
実際にp2786r3.pdf#subsection.4.2
ブラウザからその特定のセクションに移動すると、PDFが開きます。
答え4
pypdfライブラリにいくつかの変更があります。ここでバージョンを見つけることができますオリジナルスクリプトそして変更されたスクリプトpython3とpypdfを使う:
#!/usr/bin/env python3
import sys
from pypdf import PdfReader
def pdf_get_anchors(fh):
reader = PdfReader(fh)
destinations = reader.named_destinations #completely unsorted order, does not include pagenums
L=list();
np = len(reader.pages)
for PageNum in range(1,np+1) :
ThisPage = reader.pages[PageNum-1]
PageTop = ThisPage['/MediaBox'][3]
for name in destinations:
ThisDest = destinations[name]
ThisDestPage = ThisDest.page.get_object()
if ThisDestPage == ThisPage: #have to do this to identify the pagenum
DownPage = (PageTop - ThisDest.top) / PageTop # calc fraction of page down
Position = PageNum + DownPage # a sortable number down the whole pdf
L.append((name, PageNum, Position)); # put everything in a sortable list
return L, len (destinations), np
def pdf_print_anchors ( L ) :
for dest in L :
name=dest[0]
PageNum=dest[1]
Position= round(dest[2]*100)/100
print ("%8.2f % %s" % Position % name) #ThisDest.title
HeaderLine="\n Page Name"
pdf_get_anchors(open(sys.argv[1],'rb'))
L, NumDests, NumPages =pdf_get_anchors(open(sys.argv[1],'rb'))
print (HeaderLine)
L.sort(key=lambda dest: dest[0]) #sort name order
pdf_print_anchors(L);
print (HeaderLine)
L.sort(key=lambda dest: dest[2]) #sort in order down the pdf
pdf_print_anchors(L);
print ("Number of NamedDestinations: ", NumDests, "NumPages: ", NumPages)