PDF目录书签生成器 PDG

PDF Dir Generator

PDF Dir Generator,PDF 目录生成器, 是基于 wxpython 和 PyPDF2 开发的一个简易的 GUI 程序,主要功能是给未添加书签的 PDF 添加目录书签。

安装 PyPDF2 和 wxPython

可使用 pip 安装 PyPDF2wxpython.

pip install PyPDF2
pip install wxPython

我使用的版本号为: Python 3.9.12, wxpython 4.2.0, PyPDF2 2.11.0

如果 PDF 经过其他软件修改(如删除书签)可能会有如下报错:

File "C:\Users\q2799\.conda\envs\py36\lib\site-packages\PyPDF2\_writer.py", line 1195, in addBookmark
    title, pagenum, parent, color, bold, italic, fit, *args
  File "C:\Users\q2799\.conda\envs\py36\lib\site-packages\PyPDF2\_writer.py", line 1174, in add_bookmark
    parent = self.get_outline_root()
  File "C:\Users\q2799\.conda\envs\py36\lib\site-packages\PyPDF2\_writer.py", line 1008, in get_outline_root
    idnum = self._objects.index(outline) + 1
ValueError: {'/Type': '/Outlines', '/First': IndirectObject(1006, 0, 3019818315728), '/Count': 493, '/Last': IndirectObject(1498, 0, 3019818315728)} is not in list

安装完成 PyPDF2 后需要对 _writer.pyget_outline_roor() 函数进行修改,这个函数的路径可以在报错信息上找到:

def get_outline_root(self) -> TreeObject:
    if CO.OUTLINES in self._root_object:
        # TABLE 3.25 Entries in the catalog dictionary
        outline = cast(TreeObject, self._root_object[CO.OUTLINES])
        try:
            idnum = self._objects.index(outline) + 1
        except ValueError:
            if not isinstance(outline, TreeObject):
                def _walk(node):
                    node.__class__  = TreeObject
                    for child in node.children():
                        _walk(child)
                _walk(outline)
            outline_ref = self._add_object(outline)
            self._add_object(outline_ref.get_object())
            self._root_object[NameObject('/Outlines')] = outline_ref       
            idnum = self._objects.index(outline) + 1    
        outline_ref = IndirectObject(idnum, 0, self)
        assert outline_ref.get_object() == outline
    else:
        outline = TreeObject()
        outline.update({})
        outline_ref = self._add_object(outline)
        self._root_object[NameObject(CO.OUTLINES)] = outline_ref

    return outline

在这里插入图片描述

获取 PDF 目录信息

这一步比较繁琐,需要手动来获取 PDF 目录信息,主要有两种方式:

  1. (推荐)使用书签获取软件(见源码下载)

    全国图书馆参考咨询联盟 上搜索你的 PDF,例如我这儿搜索的是《合成孔径雷达成像算法与实现》,打开版权页 / 前言页 / 目录页,复制它的SS码到书签获取软件,点击获取即可得到 PDF 的目录信息。

    在这里插入图片描述

    在这里插入图片描述

  2. (法1没找到时)使用一些OCR文字识别工具,或者直接原PDF的目录页提取出来,然后再转为word

最后,我们需要将目录信息保存为一个 txt 文件,类似下面这种:

第一部分  合成孔径雷达基础	2
第1章  概论	2
1.1合成孔径雷达背景简介	2
1.2遥感中的雷达	3
1.3  SAR基础	3
1.4星载合成孔径雷达传感器	7
1.5内容概要	9
1.5.1星载合成孔径雷达图像示例	10
参考文献	11
第2章  信号处理基础	14
2.1简介	14
2.2线性卷积	14
2.2.1连续时间卷积	14
2.2.2离散时间卷积	16
2.3傅里叶变换	18
2.3.1连续时间傅里叶变换	18
2.3.2离散傅里叶变换	18
2.3.3傅里叶变换性质	19
2.3.4傅里叶变换示例	22
2.4卷积的DFT计算	24
2.5信号采样	25
2.5.1采样信号的频谱	25
2.5.2信号类型	26
2.5.3奈奎斯特采样率和混叠	28
2.6小结	42
2.6.1金星坑的麦哲伦图像	42
参考文献	43
附录A  RADARSAT数据光盘	393
缩略语对照表	395
符号表	398
参考书目	401
索引	415

每一行包含两项:标题 title + 页码 page。

其中标题中的符号 . 可以帮助我们判断书签的级别,例如:

第一部分  合成孔径雷达基础	2
第1章  概论	2

标题符号 . 个数为0,我们认为这些是一级书签,像:

2.1简介	14
2.2线性卷积	14

标题符号 . 个数为1,我们认为这些是二级书签。当然也有例外

1.5.1星载合成孔径雷达图像示例	10
参考文献	11
第2章  信号处理基础	14

这里的“参考文献 ”应该和“1.5.1星载合成孔径雷达图像示例 ”同属于二级书签,但是由于没有符号 . 会被误判断为一级书签。

注意到这些标题名往往是固定的,因此可以预定义这些标题的级别,当书签的标题与预定义的标题一致时,直接判定为预定义级别,无需统计符号 . 的个数。

格式化书签

为提高目录文件的可读性,根据书签的级别在每一行添加 n-1 个\t前缀(n为书签级别)。
后续的“生成书签”也是根据前缀数来判断书签级别的,因此这一步往往是必须的。

点击 Run > Format Dir, 最终代码格式化为:

第一部分  合成孔径雷达基础	2
第1章  概论	2
	1.1合成孔径雷达背景简介	2
	1.2遥感中的雷达	3
	1.3  SAR基础	3
	1.4星载合成孔径雷达传感器	7
	1.5内容概要	9
		1.5.1星载合成孔径雷达图像示例	10
	参考文献	11
第2章  信号处理基础	14
	2.1简介	14
	2.2线性卷积	14
		2.2.1连续时间卷积	14
		2.2.2离散时间卷积	16
	2.3傅里叶变换	18
		2.3.1连续时间傅里叶变换	18
		2.3.2离散傅里叶变换	18
		2.3.3傅里叶变换性质	19
		2.3.4傅里叶变换示例	22
	2.4卷积的DFT计算	24
	2.5信号采样	25
		2.5.1采样信号的频谱	25
		2.5.2信号类型	26
		2.5.3奈奎斯特采样率和混叠	28
	2.6小结	42
		2.6.1金星坑的麦哲伦图像	42
	参考文献	43
附录A  RADARSAT数据光盘	393
缩略语对照表	395
符号表	398
参考书目	401
索引	415

生成书签

再完成 format dir 后点击 Run > Generate Dir ,一切正常的话即可完成书签的添加。

使用说明

基本流程

注意:选择 PDF 时记得先清空里面原先的书签。

在这里插入图片描述

参数设置

在这里插入图片描述

参数说明

  • Offset 页码偏移量,书签对应的页数 = 目录文件的page + offset, 一般这个值等于目录页最后一页所在的页码;
  • Prefix 目录文件每行的前缀, 生成书签时用于判断书签的级别
  • DELIMITER 单词分隔符, 通常是空格, 不建议修改
  • LEVEL_MARKER 级别标志符, 格式化书签时用于判断书签的级别
  • Pre-level 预定义级别
  • Pre-title 预定义标题, 注意使用“;”隔开,不要有多余的空格
  • PDF Output Path PDF输出目录, 留空会根据输入PDF名自动生成
  • Dir-Log Path 格式化目录文件的输出日志存放文件夹目录,留空则与原目录在同一文件夹
  • Dir-format Path 格式化目录的输出文件夹,留空则与原目录在同一文件夹

这里通常需要设置的是 Offset 以及 Pre-title,设置完成后记得点击 Finish

除了这种设置方式外,还支持直接导入配置文件(文件后缀名为 .conf):

在这里插入图片描述

###########################################################################
#
# 这是一个配置文件, 以行为基本单元, 可以分为注释行, 赋值行和空行.
# 
# 注释行以字符 '#' 开头, 程序会忽略以'#'开头的行; 行首直接回车,则是空行; 注释行
# 和空行可以提高配置文件的可读性.
#
# 赋值行的格式为: 字段名 = 值:
# 1. "值"可以修改, 但不要修改"字段名";
# 2. "="两边的空格可有可无, 数量没有限制;
# 
###########################################################################

# str, 待添加书签的PDF路径
PDF_INPUT_PATH = "test\pdg_test.pdf"

# str, 目录文件的路径
DIR_INPUT_PATH = "test\pdg_normal_dir.txt"

# int, 页码偏移量, 通常是PDF目录页最后一页的页码
OFFSET = 5

# char, 目录文件每行的前缀, 生成书签时用于判断书签的级别
PREFIX = "\t"

# char, 单词分隔符, 通常是空格, 不建议修改
DELIMITER = " "

# char, 级别标志符, 格式化书签时用于判断书签的级别
LEVEL_MARKER = "."

# int, 预定义级别
PRE_LEVEL = 2

# str, 预定义标题, 使用';'隔开
PRE_TITLE = "本章小结;习题"

# str, 格式化目录文件的输出日志存放文件夹,留空则与原目录在同一文件夹
DIR_LOG_PATH = ""

# str, 格式化目录的输出文件夹,留空则与原目录在同一文件夹
DIR_FORMAT_PATH = ""

# PDF输出目录, 留空会根据输入PDF名自动生成
PDF_OUTPUT_PATH = ""

# int, 是否只显示目录日志
IS_PRINT_ACTICE_ONLY = 0

# int, 生成日志前默认先进行格式化
IS_FORMAT_DIR_FIRST = 1

# int, 是否打印生成书签过程中的信息
IS_PRINT_PROCESS = 1

最终效果

在这里插入图片描述

在这里插入图片描述

源码下载

参考

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wreng我是002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值