Listar destinos nomeados em um PDF

5

Como posso listar os destinos nomeados em um arquivo PDF?

Destinos nomeados são o nome formal para o que você pode chamar de âncoras. Os principais navegadores pulam para o destino nomeado foo quando você segue um link para http://example.com/some.pdf#foo .

Tenho documentos em que posso ver âncoras funcionando, mas não consigo encontrar uma maneira de listar as âncoras. Evince, okular e xpdf vão pular para eles quando instruídos, mas não parecem ter uma interface que os liste. pdftk dump_data lista os favoritos, mas isso não é a mesma coisa (essa é a tabela de entradas de conteúdo, que pode estar na mesma posição dos destinos nomeados, mas não pode ser usada como âncoras).

Estou procurando uma solução de linha de comando (adequada, por exemplo, para uso em uma função de conclusão após os gostos de evince -n ). Na medida em que isso é significativo, gostaria de listar os destinos na ordem em que aparecem no documento. Bônus: mostre o número da página de destino e outras informações que ajudam a descobrir onde o destino está.

Consulte também Exibir âncoras em um documento PDF sobre Recomendações de software para um visualizador de GUI.

    
por Gilles 01.12.2015 / 15:13

3 respostas

7

A biblioteca pyPDF pode listar âncoras:

#!/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]))

Isso é bom o suficiente para o caso de uso de conclusão, mas as âncoras são listadas em ordem aleatória. Com apenas as interfaces estáveis do pyPdf 1.13, não consigo encontrar uma maneira de listar as âncoras em ordem. Eu não tentei pyPdf2 ainda.

    
por 01.12.2015 / 17:34
5

Poppler's pdfinfo fornecerá o número da página, a posição e o nome de todos os destinos nomeados em um PDF. Você precisa de pelo menos a versão 0.58 do Poppler.

$ 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"
(...)
    
por 12.04.2018 / 00:29
1

Isso os imprime (duas vezes), classificados por nome e, em seguida, pela posição da página no PDF. Um pdf de amostra grande contendo destinos nomeados

#!/usr/bin/env python
import sys
from pyPdf import PdfFileReader
def pdf_get_anchors(fh):
    reader = PdfFileReader(fh)
    destinations = reader.getNamedDestinations()                #completely unsorted order, does not include pagenums
    L=list();
    for PageNum in range(1,reader.numPages+1) :
        ThisPage = reader.getPage(PageNum-1)
        PageTop = ThisPage['/MediaBox'][3]
        for name in destinations:
            ThisDest = destinations[name]
            ThisDestPage = ThisDest.page.getObject()
            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), reader.getNumPages()

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
        #print ThisDest.title, "       ",  PageNum,  round(Position*100)/100

HeaderLine="\n Page   Name\n"                     
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 HeaderLine
print "Number of NamedDestinations: ", NumDests, "NumPages: ", NumPages
    
por 30.07.2016 / 10:39

Tags