지정된 대상을 PDF로 나열

지정된 대상을 PDF로 나열

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)

관련 정보