├── .gitignore ├── refer.txt ├── pdf_utils.pyc ├── AddPDFBookmarks.zip ├── info.conf ├── .vscode └── launch.json ├── add_bookmark.py ├── handle_pdf.py ├── getbookmarks.py ├── bookmarks.txt ├── pdf_utils.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | files/* 3 | __pycache__/ 4 | -------------------------------------------------------------------------------- /refer.txt: -------------------------------------------------------------------------------- 1 | pypdf2在线文档:http://pythonhosted.org/PyPDF2/ -------------------------------------------------------------------------------- /pdf_utils.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syaoo/pdfbookmark/HEAD/pdf_utils.pyc -------------------------------------------------------------------------------- /AddPDFBookmarks.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syaoo/pdfbookmark/HEAD/AddPDFBookmarks.zip -------------------------------------------------------------------------------- /info.conf: -------------------------------------------------------------------------------- 1 | [info] 2 | pdf_path = ./test.pdf 3 | bookmark_file_path = ./test.txt 4 | page_offset = 17 5 | new_pdf_file_name = ./test.pdf -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: Current File", 9 | "type": "python", 10 | "request": "launch", 11 | "program": "${file}", 12 | "console": "integratedTerminal" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /add_bookmark.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # 往pdf文件中添加书签 3 | from PyPDF2 import PdfFileReader as reader,PdfFileWriter as writer 4 | 5 | import sys 6 | reload(sys) 7 | sys.setdefaultencoding('utf-8') 8 | 9 | def main(): 10 | # 读取PDF文件,创建PdfFileReader对象 11 | book = reader('./book.pdf') 12 | 13 | # 创建PdfFileWriter对象,并用reader对象进行初始化 14 | pdf = writer() 15 | pdf.cloneDocumentFromReader(book) 16 | 17 | # 添加书签 18 | # 注意:页数是从0开始的,中文要用unicode字符串,否则会出现乱码 19 | # 如果这里的页码超过文档的最大页数,会报IndexError异常 20 | # 3表示书签链接到的页码数为第3页 21 | pdf.addBookmark(u'Hello World! 你好,世界!',3) 22 | 23 | # 保存修改后的PDF文件内容到文件中 24 | with open('./book-with-bookmark.pdf','wb') as fout: 25 | pdf.write(fout) 26 | 27 | if __name__ == '__main__': 28 | main() -------------------------------------------------------------------------------- /handle_pdf.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # 添加PDF书签 3 | from pdf_utils import MyPDFHandler,PDFHandleMode as mode 4 | import configparser 5 | import sys 6 | import codecs 7 | # reload(sys) 8 | # sys.setdefaultencoding('utf-8') 9 | 10 | def main(): 11 | # 从配置文件中读取配置信息 12 | cf = configparser.ConfigParser() 13 | cf.readfp(codecs.open('./info.conf','r','utf-8')) 14 | # cf.read('./info.conf') 15 | print('a:{0}'.format(cf.sections)) 16 | pdf_path = cf.get('info','pdf_path') 17 | bookmark_file_path = cf.get('info','bookmark_file_path') 18 | page_offset = cf.getint('info','page_offset') 19 | new_pdf_file_name = cf.get('info','new_pdf_file_name') 20 | 21 | pdf_handler = MyPDFHandler(pdf_path,mode = mode.NEWLY) 22 | pdf_handler.add_bookmarks_by_read_txt(bookmark_file_path,page_offset = page_offset) 23 | pdf_handler.save2file(new_pdf_file_name) 24 | 25 | if __name__ == '__main__': 26 | main() -------------------------------------------------------------------------------- /getbookmarks.py: -------------------------------------------------------------------------------- 1 | from PyPDF2 import PdfFileReader as reader 2 | def getbookmark(fullfile:str, outfile:str=None)->list: 3 | ''' 4 | 提取PDF文件中的bookmarks,存储到content元组列表中 5 | :param fullfile:PDF文件路径字符串 6 | :param outfile:可选参数,将提取的PDF书签输出outfile指定路径 7 | : return: list 8 | ''' 9 | pdffile = reader(fullfile) 10 | outlins = pdffile.getOutlines() 11 | content = [] 12 | for bm in outlins: 13 | if type(bm) == list: 14 | for sub in bm: 15 | thistitl = sub.title 16 | thispage = pdffile.getDestinationPageNumber(sub) 17 | content.append(('\t'+thistitl,thispage)) 18 | # if bm.index(sub) == 0: 19 | # content.append(('\t'+thistitl,thispage)) 20 | # else: 21 | # content.append((thistitl,thispage)) 22 | else: 23 | thistitl = bm.title 24 | thispage = pdffile.getDestinationPageNumber(bm) 25 | content.append((thistitl,thispage)) 26 | # outfile存在则将bookmarks存储到outfie中 27 | if outfile != None: 28 | f = open(outfile,'w') 29 | for s in content: 30 | f.write('{}@{}\n'.format(s[0],s[1])) 31 | f.close() 32 | return content 33 | 34 | # lis = getbookmark('.test.pdf','./files/tt') 35 | # lis = getbookmark('test.pdf') 36 | # for t,n in lis: 37 | # print(t,n) -------------------------------------------------------------------------------- /bookmarks.txt: -------------------------------------------------------------------------------- 1 | [meta] 2 | page_offset = 15 3 | 4 | 目录@-4 5 | 第1章:函数与极限@1 6 | 1.1 映射与函数@1 7 | 1.2 数列的极限@18 8 | 1.3 函数的极限@27 9 | 1.4 无穷大与无穷小@34 10 | 1.5 极限运算法则@38 11 | 1.6 极限存在准则@45 12 | 1.7 无穷小的比较@52 13 | 1.8 函数的连续性与间断点@56 14 | 1.9 连续函数的运算与初等函数的连续性@62 15 | 1.10 闭区间上连续函数的性质@66 16 | 总习题1@70 17 | 第2章:导数与微分@73 18 | 2.1 导数的概念@73 19 | 2.2 函数的求导法则@84 20 | 2.3 高阶导数@96 21 | 2.4 隐函数、参数方程函数的导数@101 22 | 2.5 函数的微分@110 23 | 总习题2@122 24 | 第3章:微分中值定理与导数的应用@125 25 | 3.1 微分中值定理@125 26 | 3.2 洛必达法则@132 27 | 3.3 泰勒公式@137 28 | 3.4 函数的单调性与凹凸性@144 29 | 3.5 函数的极值与最大值、最小值@152 30 | 3.6 函数图形的描绘@163 31 | 3.7 曲率@168 32 | 3.8 方程的近似解@177 33 | 总习题3@181 34 | 第4章:不定积分@184 35 | 4.1 不定积分的概念与性质@184 36 | 4.2 换元积分法@193 37 | 4.3 分部积分法@208 38 | 4.4 有理函数的积分@213 39 | 4.5 积分表的使用@219 40 | 总习题4@222 41 | 第5章:定积分@224 42 | 5.1 定积分的概念与性质@224 43 | 5.2 微积分基本公式@237 44 | 5.3 定积分的换元法和分部积分法@246 45 | 5.4 反常积分@256 46 | 5.5 反常积分的审敛法@262 47 | 总习题5@270 48 | 附录1:二阶和三阶行列式简洁@363 49 | 附录4:积分表@374 50 | 习题答案与提示@385 51 | 第一章@385 52 | 习题1-1@385 53 | 习题1-2@386 54 | 习题1-3@387 55 | 习题1-4@387 56 | 习题1-5@387 57 | 习题1-6@388 58 | 习题1-7@389 59 | 习题1-8@389 60 | 习题1-9@389 61 | 习题1-10@390 62 | 总习题1@390 63 | 第二章@391 64 | 习题2-1@391 65 | 习题2-2@392 66 | 习题2-3@394 67 | 习题2-4@395 68 | 习题2-5@395 69 | 总习题2@396 70 | 第三章@397 71 | 习题3-1@397 72 | 习题3-2@398 73 | 习题3-3@398 74 | 习题3-4@399 75 | 习题3-5@400 76 | 习题3-6@401 77 | 习题3-7@402 78 | 习题3-8@403 79 | 总习题3@403 80 | 第四章@404 81 | 习题4-1@404 82 | 习题4-2@405 83 | 习题4-3@406 84 | 习题4-4@407 85 | 习题4-5@409 86 | 总习题4@410 87 | 第五章@413 88 | 习题5-1@413 89 | 习题5-2@413 90 | 习题5-3@414 91 | 习题5-5@415 92 | 总习题5@416 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /pdf_utils.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # 封装的PDF文档处理工具 3 | from PyPDF2 import PdfFileReader as reader,PdfFileWriter as writer 4 | import os 5 | 6 | import sys 7 | # reload(sys) 8 | # sys.setdefaultencoding('utf-8') 9 | 10 | class PDFHandleMode(object): 11 | ''' 12 | 处理PDF文件的模式 13 | ''' 14 | # 保留源PDF文件的所有内容和信息,在此基础上修改 15 | COPY = 'copy' 16 | # 仅保留源PDF文件的页面内容,在此基础上修改 17 | NEWLY = 'newly' 18 | 19 | class MyPDFHandler(object): 20 | ''' 21 | 封装的PDF文件处理类 22 | ''' 23 | def __init__(self,pdf_file_path,mode = PDFHandleMode.COPY): 24 | ''' 25 | 用一个PDF文件初始化 26 | :param pdf_file_path: PDF文件路径 27 | :param mode: 处理PDF文件的模式,默认为PDFHandleMode.COPY模式 28 | ''' 29 | # 只读的PDF对象 30 | self.__pdf = reader(pdf_file_path) 31 | 32 | # 获取PDF文件名(不带路径) 33 | self.file_name = os.path.basename(pdf_file_path) 34 | # 35 | self.metadata = self.__pdf.getXmpMetadata() 36 | # 37 | self.doc_info = self.__pdf.getDocumentInfo() 38 | # 39 | self.pages_num = self.__pdf.getNumPages() 40 | # 数据父级对象 41 | self.parent = None 42 | # 可写的PDF对象,根据不同的模式进行初始化 43 | self.__writeable_pdf = writer() 44 | if mode == PDFHandleMode.COPY: 45 | self.__writeable_pdf.cloneDocumentFromReader(self.__pdf) 46 | elif mode == PDFHandleMode.NEWLY: 47 | for idx in range(self.pages_num): 48 | page = self.__pdf.getPage(idx) 49 | self.__writeable_pdf.insertPage(page, idx) 50 | 51 | def save2file(self,new_file_name): 52 | ''' 53 | 将修改后的PDF保存成文件 54 | :param new_file_name: 新文件名,不要和原文件名相同 55 | :return: None 56 | ''' 57 | # 保存修改后的PDF文件内容到文件中 58 | with open(new_file_name, 'wb') as fout: 59 | self.__writeable_pdf.write(fout) 60 | print('save2file success! new file is:{0}'.format(new_file_name)) 61 | 62 | def add_one_bookmark(self,title,page,parent = None, color = None,fit = '/Fit'): 63 | ''' 64 | 往PDF文件中添加单条书签,并且保存为一个新的PDF文件 65 | :param str title: 书签标题 66 | :param int page: 书签跳转到的页码,表示的是PDF中的绝对页码,值为1表示第一页 67 | :paran parent: A reference to a parent bookmark to create nested bookmarks. 68 | :param tuple color: Color of the bookmark as a red, green, blue tuple from 0.0 to 1.0 69 | :param list bookmarks: 是一个'(书签标题,页码)'二元组列表,举例:[(u'tag1',1),(u'tag2',5)],页码为1代表第一页 70 | :param str fit: 跳转到书签页后的缩放方式 71 | :return: None 72 | ''' 73 | # 为了防止乱码,这里对title进行utf-8编码 74 | self.parent = self.__writeable_pdf.addBookmark(title,page - 1,parent = parent,color = color,fit = fit) 75 | print('add_one_bookmark success! bookmark title is: {0}'.format(title)) 76 | return self.parent 77 | 78 | def add_bookmarks(self,bookmarks): 79 | ''' 80 | 批量添加书签 81 | :param bookmarks: 书签元组列表,其中的页码表示的是PDF中的绝对页码,值为1表示第一页 82 | :return: None 83 | ''' 84 | ptlt = None 85 | for title,page in bookmarks: 86 | if title[0]!= ' ' and title[0]!='\t': 87 | ptlt = self.add_one_bookmark(title,page) 88 | else: 89 | self.add_one_bookmark(title.lstrip(' \t'),page,parent=ptlt) 90 | 91 | print('add_bookmarks success! add {0} pieces of bookmarks to PDF file'.format(len(bookmarks))) 92 | 93 | def read_bookmarks_from_txt(self,txt_file_path,page_offset = 0): 94 | ''' 95 | 从文本文件中读取书签列表 96 | 文本文件有若干行,每行一个书签,内容格式为: 97 | 书签标题 页码 98 | 注:中间用空格隔开,页码为1表示第1页 99 | :param txt_file_path: 书签信息文本文件路径 100 | :param page_offset: 页码偏移量,为0或正数,即由于封面、目录等页面的存在,在PDF中实际的绝对页码比在目录中写的页码多出的差值 101 | :return: 书签列表 102 | ''' 103 | bookmarks = [] 104 | with open(txt_file_path,encoding='utf8') as fin: 105 | for line in fin: 106 | line = line.rstrip() 107 | if not line: 108 | continue 109 | # 以'@'作为标题、页码分隔符 110 | print('read line is: {0}'.format(line)) 111 | try: 112 | title = line.split('@')[0].rstrip() 113 | page = line.split('@')[1].strip() 114 | except IndexError as msg: 115 | print(msg) 116 | continue 117 | # title和page都不为空才添加书签,否则不添加 118 | if title and page: 119 | try: 120 | page = int(page) + page_offset 121 | bookmarks.append((title, page)) 122 | except ValueError as msg: 123 | print(msg) 124 | 125 | return bookmarks 126 | 127 | def add_bookmarks_by_read_txt(self,txt_file_path,page_offset = 0): 128 | ''' 129 | 通过读取书签列表信息文本文件,将书签批量添加到PDF文件中 130 | :param txt_file_path: 书签列表信息文本文件 131 | :param page_offset: 页码便宜量,为0或正数,即由于封面、目录等页面的存在,在PDF中实际的绝对页码比在目录中写的页码多出的差值 132 | :return: None 133 | ''' 134 | bookmarks = self.read_bookmarks_from_txt(txt_file_path,page_offset) 135 | self.add_bookmarks(bookmarks) 136 | print('add_bookmarks_by_read_txt success!') 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [原作者](https://github.com/dnxbjyj/py-project/tree/master/AddPDFBookmarks),我对`add_bookmarks`做了修改使其能够讲缩进添加成为二级书签。并增加了`getbookmarks`函数可以导出PDF文件的书签。 2 | 3 | # 用Python为PDF文件批量添加书签 4 | 5 | > 本文讲述的核心库:`PyPDF2` 6 | > 官方文档:http://pythonhosted.org/PyPDF2/ 7 | 8 | 平时看一些大部头的技术书籍,大多数都是PDF版的,而且有一些书籍是影印扫描版的,几百上千页的书,没有任何书签,想要找到一个章节的位置非常费劲。那么就想,能不能搞一个工具,来自动地为这些大部头的PDF书籍添加书签便于自己阅读呢?下面就是这样一个工具的开发过程。 9 | 10 | # 为PDF文件添加一个最简单的书签 11 | 学习使用一个技术,我们都从最简单的开始入手。比如我现在想为一个名为`book.pdf`的PDF文件添加一个`Hello World`书签,该怎么做呢?show code: 12 | ```python 13 | # coding:utf-8 14 | # 往pdf文件中添加书签 15 | from PyPDF2 import PdfFileReader as reader,PdfFileWriter as writer 16 | 17 | import sys 18 | reload(sys) 19 | sys.setdefaultencoding('utf-8') 20 | 21 | def main(): 22 | # 读取PDF文件,创建PdfFileReader对象 23 | book = reader('./book.pdf') 24 | 25 | # 创建PdfFileWriter对象,并用拷贝reader对象进行初始化 26 | pdf = writer() 27 | pdf.cloneDocumentFromReader(book) 28 | 29 | # 添加书签 30 | # 注意:页数是从0开始的,中文要用unicode字符串,否则会出现乱码 31 | # 如果这里的页码超过文档的最大页数,会报IndexError异常 32 | pdf.addBookmark(u'Hello World! 你好,世界!',2) 33 | 34 | # 保存修改后的PDF文件内容到文件中 35 | with open('./book-with-bookmark.pdf','wb') as fout: 36 | pdf.write(fout) 37 | 38 | if __name__ == '__main__': 39 | main() 40 | ``` 41 | 运行上述代码,发现当前目录下生成了一个名为`book-with-bookmark.pdf`的文件,打开这个文件,看到成功添加了一个书签: 42 | ![](http://upload-images.jianshu.io/upload_images/8819542-2b7e97382c072042.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 43 | 点击这个书签,会自动跳转到第3页。 44 | 45 | # PDF处理工具类 46 | 下面先编写一个功能更为丰富的PDF处理工具类,代码如下: 47 | ```python 48 | # coding:utf-8 49 | # 封装的PDF文档处理工具 50 | from PyPDF2 import PdfFileReader as reader,PdfFileWriter as writer 51 | import os 52 | 53 | import sys 54 | reload(sys) 55 | sys.setdefaultencoding('utf-8') 56 | 57 | class PDFHandleMode(object): 58 | ''' 59 | 处理PDF文件的模式 60 | ''' 61 | # 保留源PDF文件的所有内容和信息,在此基础上修改 62 | COPY = 'copy' 63 | # 仅保留源PDF文件的页面内容,在此基础上修改 64 | NEWLY = 'newly' 65 | 66 | class MyPDFHandler(object): 67 | ''' 68 | 封装的PDF文件处理类 69 | ''' 70 | def __init__(self,pdf_file_path,mode = PDFHandleMode.COPY): 71 | ''' 72 | 用一个PDF文件初始化 73 | :param pdf_file_path: PDF文件路径 74 | :param mode: 处理PDF文件的模式,默认为PDFHandleMode.COPY模式 75 | ''' 76 | # 只读的PDF对象 77 | self.__pdf = reader(pdf_file_path) 78 | 79 | # 获取PDF文件名(不带路径) 80 | self.file_name = os.path.basename(pdf_file_path) 81 | # 82 | self.metadata = self.__pdf.getXmpMetadata() 83 | # 84 | self.doc_info = self.__pdf.getDocumentInfo() 85 | # 86 | self.pages_num = self.__pdf.getNumPages() 87 | 88 | # 可写的PDF对象,根据不同的模式进行初始化 89 | self.__writeable_pdf = writer() 90 | if mode == PDFHandleMode.COPY: 91 | self.__writeable_pdf.cloneDocumentFromReader(self.__pdf) 92 | elif mode == PDFHandleMode.NEWLY: 93 | for idx in range(self.pages_num): 94 | page = self.__pdf.getPage(idx) 95 | self.__writeable_pdf.insertPage(page, idx) 96 | 97 | def save2file(self,new_file_name): 98 | ''' 99 | 将修改后的PDF保存成文件 100 | :param new_file_name: 新文件名,不要和原文件名相同 101 | :return: None 102 | ''' 103 | # 保存修改后的PDF文件内容到文件中 104 | with open(new_file_name, 'wb') as fout: 105 | self.__writeable_pdf.write(fout) 106 | print 'save2file success! new file is: {0}'.format(new_file_name) 107 | 108 | def add_one_bookmark(self,title,page,parent = None, color = None,fit = '/Fit'): 109 | ''' 110 | 往PDF文件中添加单条书签,并且保存为一个新的PDF文件 111 | :param str title: 书签标题 112 | :param int page: 书签跳转到的页码,表示的是PDF中的绝对页码,值为1表示第一页 113 | :paran parent: A reference to a parent bookmark to create nested bookmarks. 114 | :param tuple color: Color of the bookmark as a red, green, blue tuple from 0.0 to 1.0 115 | :param list bookmarks: 是一个'(书签标题,页码)'二元组列表,举例:[(u'tag1',1),(u'tag2',5)],页码为1代表第一页 116 | :param str fit: 跳转到书签页后的缩放方式 117 | :return: None 118 | ''' 119 | # 为了防止乱码,这里对title进行utf-8编码 120 | self.__writeable_pdf.addBookmark(title.decode('utf-8'),page - 1,parent = parent,color = color,fit = fit) 121 | print 'add_one_bookmark success! bookmark title is: {0}'.format(title) 122 | 123 | def add_bookmarks(self,bookmarks): 124 | ''' 125 | 批量添加书签 126 | :param bookmarks: 书签元组列表,其中的页码表示的是PDF中的绝对页码,值为1表示第一页 127 | :return: None 128 | ''' 129 | for title,page in bookmarks: 130 | self.add_one_bookmark(title,page) 131 | print 'add_bookmarks success! add {0} pieces of bookmarks to PDF file'.format(len(bookmarks)) 132 | 133 | def read_bookmarks_from_txt(self,txt_file_path,page_offset = 0): 134 | ''' 135 | 从文本文件中读取书签列表 136 | 文本文件有若干行,每行一个书签,内容格式为: 137 | 书签标题 页码 138 | 注:中间用空格隔开,页码为1表示第1页 139 | :param txt_file_path: 书签信息文本文件路径 140 | :param page_offset: 页码便宜量,为0或正数,即由于封面、目录等页面的存在,在PDF中实际的绝对页码比在目录中写的页码多出的差值 141 | :return: 书签列表 142 | ''' 143 | bookmarks = [] 144 | with open(txt_file_path,'r') as fin: 145 | for line in fin: 146 | line = line.rstrip() 147 | if not line: 148 | continue 149 | # 以'@'作为标题、页码分隔符 150 | print 'read line is: {0}'.format(line) 151 | try: 152 | title = line.split('@')[0].rstrip() 153 | page = line.split('@')[1].strip() 154 | except IndexError as msg: 155 | print msg 156 | continue 157 | # title和page都不为空才添加书签,否则不添加 158 | if title and page: 159 | try: 160 | page = int(page) + page_offset 161 | bookmarks.append((title, page)) 162 | except ValueError as msg: 163 | print msg 164 | 165 | return bookmarks 166 | 167 | def add_bookmarks_by_read_txt(self,txt_file_path,page_offset = 0): 168 | ''' 169 | 通过读取书签列表信息文本文件,将书签批量添加到PDF文件中 170 | :param txt_file_path: 书签列表信息文本文件 171 | :param page_offset: 页码便宜量,为0或正数,即由于封面、目录等页面的存在,在PDF中实际的绝对页码比在目录中写的页码多出的差值 172 | :return: None 173 | ''' 174 | bookmarks = self.read_bookmarks_from_txt(txt_file_path,page_offset) 175 | self.add_bookmarks(bookmarks) 176 | print 'add_bookmarks_by_read_txt success!' 177 | 178 | ``` 179 | `MyPDFHandler`类可以用一个PDF对象进行初始化,支持从一个txt文件中读取要添加的书签列表,然后根据这个书签列表自动为PDF添加书签,书签列表txt文件是类似这样格式的文件,书签标题和页码(一个整数,代表书签的相对页码数,可以为负数)用`@`作为分隔符隔开: 180 | ``` 181 | 目录@-5 182 | 【第一篇 开发基础】@1 183 | 第1章 Eclipse平台简介@1 184 | 1.1 Eclipse集成开发环境(IDE)介绍@2 185 | 1.2 什么是Eclipse@9 186 | 1.3 SWT/JFace技术@11 187 | 1.4 插件技术和OSGi@12 188 | 1.5 RCP技术@15 189 | 1.6 EMF技术@16 190 | 1.7 GEF技术@17 191 | ``` 192 | 193 | # 编写书签列表txt文件 194 | 从网上找到一本大部头的书籍`Eclipse插件开发学习笔记.pdf`,这是一本非常好的Eclipse插件开发入门书籍,但是是扫描版的,没有任何书签,看起来比较费劲。 195 | 196 | 这是这本书的目录: 197 | ![](http://upload-images.jianshu.io/upload_images/8819542-c4491ce0c7b13e17.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 198 | 199 | 下面手工将目录内容和页码信息录入添加书签所需的书签列表文本文件中(`bookmarks-eclipse_plutin.txt`): 200 | ``` 201 | [meta] 202 | page_offset = 11 203 | 204 | 目录@-5 205 | 【第一篇 开发基础】@1 206 | 第1章 Eclipse平台简介@1 207 | 1.1 Eclipse集成开发环境(IDE)介绍@2 208 | 1.2 什么是Eclipse@9 209 | 1.3 SWT/JFace技术@11 210 | 1.4 插件技术和OSGi@12 211 | 1.5 RCP技术@15 212 | 1.6 EMF技术@16 213 | 1.7 GEF技术@17 214 | 215 | 第2章 SWT/JFace概述@19 216 | 217 | 第3章 SWT编程基础@39 218 | 219 | 第4章 使用基本控件与对话框@64 220 | 221 | 第5章 容器与布局管理器@92 222 | 223 | 第6章 界面开发工具@121 224 | 225 | 第7章 高级控件使用@135 226 | 227 | 第8章 SWT/JFace的事件处理@166 228 | 229 | 【第二篇 核心技术】@183 230 | 第9章 Eclipse插件体系结构@183 231 | 9.1 Eclipse体系结构@184 232 | 9.2 插件的加载过程@187 233 | 9.3 插件的扩展模式@191 234 | 235 | 第10章 开发第一个插件项目@196 236 | 10.1 创建插件工程@197 237 | 10.2 "插件开发"透视图@200 238 | 10.3 插件工程结构@203 239 | 10.4 插件文件@204 240 | 10.5 插件类@207 241 | 10.6 运行插件程序@208 242 | 10.7 调试插件@210 243 | 10.8 发布插件@211 244 | 245 | 第11章 操作(Actions)@213 246 | 11.1 Eclipse中的操作概览@214 247 | 11.2 添加工作台窗口操作@214 248 | 11.3 IAction与IActionDelegate接口@222 249 | 11.4 对象操作@224 250 | 11.5 视图操作@230 251 | 11.6 编辑器操作@234 252 | 11.7 快捷键映射@237 253 | 254 | 第12章 视图(Views)@241 255 | 12.1 Eclipse视图体系结构概览@242 256 | 12.2 Eclipse工作环境中的视图@243 257 | 12.3 创建一个视图@248 258 | 12.4 视图类@250 259 | 12.5 为视图添加操作@260 260 | 12.6 视图间通信@265 261 | 12.7 添加状态栏支持@272 262 | 12.8 视图状态@273 263 | 12.9 加载和卸载图标@279 264 | 265 | 第13章 编辑器(Editors)@282 266 | 13.1 Eclipse编辑器体系结构概览@283 267 | 13.2 Eclipse工作环境中的编辑器@284 268 | 13.3 为例子增加一个编辑器@289 269 | 13.4 编辑器使用的数据模型@294 270 | 13.5 编辑器页面@301 271 | 13.6 响应编辑器更改@313 272 | 13.7 保存编辑器模型@318 273 | 13.8 编辑器生命周期@322 274 | 13.9 为编辑器添加操作@326 275 | 276 | 第14章 透视图(Perspectives)@334 277 | 14.1 什么是透视图@335 278 | 14.2 创建一个透视图@336 279 | 14.3 IPageLayout@339 280 | 14.4 填充透视图@341 281 | 14.5 扩展现有透视图@344 282 | 283 | 第15章 对话框和向导@349 284 | 15.1 对话框和向导概述@350 285 | 15.2 对话框类别@350 286 | 15.3 为例子增加SWT对话框@354 287 | 15.4 创建JFace对话框@355 288 | 15.5 向导介绍@362 289 | 15.6 添加向导@364 290 | 291 | 第16章 首选项(Preferences)@379 292 | 16.1 首选项页面结构@381 293 | 16.2 添加首选项页面@382 294 | 16.3 示例首选项@383 295 | 16.4 为例子创建首选项页面@387 296 | 297 | 第17章 帮助内容(Help Contents)@397 298 | 299 | 第18章 备忘单(CheatSheet)@410 300 | 301 | 【第三篇 高级进阶】@426 302 | 第19章 插件开发高级内容@426 303 | 304 | 第20章 富客户端平台(RCP)技术@473 305 | 306 | 第21章 Draw2d@509 307 | 308 | 第22章 GEF介绍与实现@526 309 | 310 | 【第四篇 综合实例】@586 311 | 第23章 插件开发实例@586 312 | 313 | 第24章 GEF实例@630 314 | ``` 315 | 注:一开始的`page_offset `的值表示书签页码的偏移量,即某一页所在的实际页码与PDF目录中所写的页码值的差值,这是考虑到在PDF的目录页之前还会有其他的一些封面、前言等页面,实际页码会和目录中所写的页码不一致。 316 | 317 | # 为PDF批量添加书签 318 | 上面的准备工作就做好了,下面来开始为`Eclipse插件开发学习笔记.pdf`这本书添加目录: 319 | ```python 320 | # coding:utf-8 321 | # 添加PDF书签 322 | from pdf_utils import MyPDFHandler,PDFHandleMode as mode 323 | import sys 324 | reload(sys) 325 | sys.setdefaultencoding('utf-8') 326 | 327 | def main(): 328 | pdf_handler = MyPDFHandler(u'Eclipse插件开发学习笔记.pdf',mode = mode.NEWLY) 329 | pdf_handler.add_bookmarks_by_read_txt('./bookmarks-eclipse_plutin.txt',page_offset = 11) 330 | pdf_handler.save2file(u'Eclipse插件开发学习笔记-目录书签版.pdf') 331 | 332 | if __name__ == '__main__': 333 | main() 334 | ``` 335 | 运行上面代码,发现在当前目录生成了一个名为`'Eclipse插件开发学习笔记-目录书签版.pdf`的文件,打开它,看到书签已经全部完美地添加了进去,并且点击各个书签页面跳转的位置也是正确的,大大地方便了平时的阅读: 336 | ![](http://upload-images.jianshu.io/upload_images/8819542-33d2ffaac6d5e3ab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 337 | 338 | 339 | # 本文代码GitHub地址 340 | 本文涉及到的代码都放在了[本人的GitHub](https://github.com/dnxbjyj/py-project/tree/master/AddPDFBookmarks) --------------------------------------------------------------------------------