2012-10-16 15 views
8

Chciałbym eksportować etykiety stron przechowywane w niektórych dokumentach PDF, aby ułatwić ich parsowanie. Wiem, że mógłbym zagłębić się w dokument PDF po przekonwertowaniu go na qpdf, ale wydaje się to przesadą.Eksportuj etykiety stron PDF w wierszu polecenia

Czy istnieje żadne narzędzie wiersza poleceń, które po prostu wydrukować etykietę stronę dla każdej strony (lub wraz z innymi meta-danych)? Wiem, że PDFSpy wyeksportuje etykietę, ale 300 USD nie jest opcją, najlepiej rozwiązanie powinno być bezpłatne.

Odpowiedz

10

Krótka odpowiedź:
nie jestem świadomy każdej (za darmo) narzędzie, które można „po prostu wydrukować” etykietę stronę dla każdej strony.

Ponadto nie będzie można obejść obiektów skompresowanych i strumieni obiektów rozszerzonych za pomocą narzędzia takiego jak qpdf lub o równoważnych możliwościach.

Długa odpowiedź:
Nie ma takich narzędzi, ponieważ są to tylko kilka rzeczy, które można bezpiecznie polegać, jeśli chodzi o etykiety stronie. Są to:

  1. Każdy dokument PDF musi zawierać obiekt główny.
  2. To obiekt główny koniecznością być /Type /Catalog.
  3. Zwiastun dokumentu pokaże, gdzie znaleźć obiekt za pomocą klucza /Root, po którym następuje referencja numeru obiektu pośredniego.
  4. IF dokument PDF używa niestandardowych etykiet strony, a następnie głównego dokumentu obiekt moszczu mieć wpis o nazwie /PageLabels.

Tu jest miejsce, gdzie zatrzymuje się być stosunkowo łatwe. Ponieważ obiekt, do którego odnosi się klucz /PageLabels, może być zawarty w skompresowanym obiekcie . Oznacza to, że musisz rozszerzyć ten strumień obiektów.

Jeśli naprawdę udało się uzyskać opis etykiet stronie jak ASCII, dowiesz się, że to nie jest łatwe parsowalnym lista płaski (jak dictionary jest): jest to liczba drzewo.

Nie będę wchodził w szczegóły tych zawiłości, ponieważ zajęłoby bardzo długi artykuł, aby opisać wszystkie możliwe warianty. Lepiej przeczytaj go bezpośrednio w numerze official ISO PDF-1.7 specification.

Ale zamiast dam wam przykład w kodzie ASCII PDF:

213 0 obj 
    << /Type /Catalog 
    /PageLabels 
     << 
      /Nums 
       [ 
        0 <<   % start labeling from page no. 1 
         /S /r  % label with lowercase roman numbers 
        >> 
        7 <<   % start new labeling from page no. 8 
         /S /D  % label with standard decimal numbers 
        >> 
        11 <<   % start labeling page no. 12 
         /S /D  % label with decimal numbers... 
         /P (ABCD-) % ...but using label prefix 'ABCD-'... 
         /St 3  % ...followed by '3' as the start decimal. 
        >> 
        ] 
     >> 
    %%........................... 
    %%...more root object keys... 
    %%........................... 
    >> 
endobj 

Powyższy przykład etykiecie liczba stron 1, 2, 3, ... (ostatni) tak:

i 
ii 
iii 
iv 
v 
vi 
1 
2 
3 
4 
ABCD-3 
ABCD-4 
ABCD-5 
ABCD-6 
...and so on until last page... 

Jak widać, metoda etykietowania stron w pliku PDF (odwzorowywanie numerów stron na nazwy stron) jest całkowicie nieintuicyjna.Możesz to zrozumieć jedynie poprzez analizę specyfikacji PDF.

+0

Dzięki za to wspaniałe podsumowanie sytuacji. Dowiedziałem się o tym wcześniej. Zdałem sobie sprawę, że to będzie mój własny mini-parser lub ktoś inny wcześniej go napisał (co miałem nadzieję). Byłbym szczęśliwy, gdyby sam je obliczyć z informacji zawartych w obiekcie głównym, ale niestety obiekt główny nie zawsze jest łatwy do znalezienia w prostej implementacji jscript (której chciałem użyć). QPDF daje mi łatwy dostęp do obiektów stronicowania, ale nie ma możliwości, aby poprosić o zwrócenie przyczepy lub obiektu głównego bezpośrednio, a więc nie ma sposobu, aby dowiedzieć się, gdzie szukać katalogu – grovel

+1

Ok, po dalszym kopaniu, mam faktycznie znalazłem raczej proste rozwiązanie: PDFtk (które wcześniej oglądałem, ale ta funkcja jest słabo udokumentowana). – grovel

+8

'pdftk.exe document.pdf dump_data output report.txt' spowoduje utworzenie pliku txt zawierającego nie tylko meta-dane, takie jak zakładki, ale także etykiety stron. Będzie to wyglądać tak: 'PageLabelNewIndex: 1 PageLabelStart: 1 PageLabelPrefix: C PageLabelNumStyle: DecimalArabicNumberals PageLabelNewIndex: 3 PageLabelStart: 1 PageLabelNumStyle: LowercaseRomanNumerals PageLabelNewIndex: 15 PageLabelStart: 1 PageLabelNumStyle: DecimalArabicNumerals' tj C1, C2, i, ii, ..., xiii, 1,2, ... Łatwo sparsować, dokładnie to, czego potrzebuję. @Kurt, dzięki, bardzo doceniane! – grovel

Powiązane problemy