美文网首页程序员
用编程的方法根据PDF内容自动生成书签

用编程的方法根据PDF内容自动生成书签

作者: Jelif | 来源:发表于2018-08-19 12:05 被阅读174次

    前言

    这篇文章介绍了一个给PDF加书签的案例,重在把多种工具综合使用以解决问题,凡是代码中能体现的信息,不会再作解释,读者如有一定的Linux基础,阅读起来会比较顺畅。

    提取PDF文件中的文本

    java -jar pdfbox-app-2.0.11.jar ExtractText onenote.pdf onenote.txt
    tac onenote.txt > reverse.txt
    

    PDFBox是一个Java平台的PDF处理类库,它的jar包提供了一些命令行接口。

    生成原始书签素材

    生成二级书签:awk -f script1.awk onenote.txt > bookmark1.txt

    script1.awk

    /的第 [0-9]+ 页/ {
       if(NF == 3)
           pagenumber = $2
       if(NF == 5)
           pagenumber = $4
    }
    /[0-9]+年[0-9]+月[0-9]+日 [0-9]+:[0-9]+/ {
       datelinemet = 1
       datelinenumber = NR
    }
    datelinemet == 1 && NR == datelinenumber + 1 {
       datelinemet = 0
       print "BookmarkPageNumber: " pagenumber
       print "BookmarkLevel: " 2
       print "BookmarkTitle: " $0
       print "BookmarkBegin"
    }
    

    生成一级书签:awk -f script2.awk reverse.txt > bookmark2.txt

    script2.awk

    BEGIN {
        prevpartitionname = "NULL"
        partitionname = "NULL"
    }
    /的第 [0-9]+ 页/ {
        if(NF == 3) {
            pagenumber = $2
            gsub("分区", "", $1)
            gsub("的第", "", $1)
            partitionname = $1
        }
        if(NF == 5) {
            pagenumber = $4
            partitionname = $2
        }
    }
    partitionname != prevpartitionname {
        prevpartitionname = partitionname
        print "BookmarkBegin"
        print "BookmarkTitle: " partitionname
        print "BookmarkLevel: " 1
        print "BookmarkPageNumber: " pagenumber
    }
    

    得到一级书签应该放在bookmark1.txt中的位置:

    n=`wc -l bookmark2.txt | awk '{print $1}'`
    grep -n -E -e "`sed -n \"1,$(($n-1))s/\$/\$|/g;s/^/^/g;/BookmarkPageNumber/H;\\$s/$/$/g;\\$g;\\$p\" bookmark2.txt | tr -d "\n"`" bookmark1.txt > bookmark3.txt
    

    bookmark2.txt相比于bookmark3.txt缺少一些书签,需要人工比对后按照格式增加到里面。

    生成最终书签文件

    为后续sed命令的执行准备脚本:sh script.sh > bookmark4.sed

    script.sh

    IFS=$'\n'
    lns=(`cat bookmark3.txt | cut -d: -f1`)
    i=0
    for l in `cat bookmark2.txt`; do
        if (($i%4 == 0)); then
            echo $((${lns[$i/4]}-3))i\\
            echo $l\\
        else 
            if (($i%4 == 3)); then
                echo $l
            else
                echo $l\\
            fi
        fi
        i=$(($i+1))
    done
    

    执行sed命令 ,修改bookmark1.txt为最终版:sed -f bookmark4.sed -i bookmark1.txt

    将书签信息导入PDF文件中

    pdftk onenote.pdf update_info_utf8 bookmark1.txt output onenote_new.pdf
    

    注意必须使用update_info_utf8这个选项,而不是类似的update_info,后者不支持中文书签。

    相关文章

      网友评论

        本文标题:用编程的方法根据PDF内容自动生成书签

        本文链接:https://www.haomeiwen.com/subject/qlkgbftx.html