PDF Dir Generator,PDF 目录生成器, 是基于 wxpython 和 PyPDF2 开发的一个简易的 GUI 程序,主要功能是给未添加书签的 PDF 添加目录书签。
可使用 pip 安装 PyPDF2 和 wxpython.
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.py
的 get_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,例如我这儿搜索的是《合成孔径雷达成像算法与实现》,打开版权页 / 前言页 / 目录页,复制它的SS码到书签获取软件,点击获取即可得到 PDF 的目录信息。
(法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 以及 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