草庐IT

Python功能实现:为pdf电子书籍生成书签目录

CNmelody 2023-04-12 原文

      今天搞了本pdf电子书看,奈何没有书签目录,用acrobat DC看起来很难受,所以索性写了个python脚本,配合PdfEditor软件能够较为方便地生成可跳转页码的书签目录。

注意:

1、用python3运行我提供的脚本。

2、请提前下载PdfEditor软件并了解如何用其制作书签目录。

3、脚本运行需要提供文件origin.txt文件,内容是书籍对应的原始书签目录。

4、实现思路主要使用了正则匹配,大家可以去了解下python re库的使用,正则规则最好根据origin.txt自行分析调整。

5、大家主要参考程序的实现思路,请根据实际情况进行修改。

脚本内容:

# 作者:Melody
# 功能:PDF书籍目录生成脚本,生成目标文件后需要配合PdfEditor软件使用
# 时间:2021/5/30
import re
pageOffset = 16 # 印刷链接页码与实际跳转页码偏移量
originFileName = 'origin.txt'
resultFileName = 'result.txt'

# 获得目标文件绝对路径
nameList = __file__.split('\\')
nameList.pop(-1) # 去除脚本文件名
nameList.append(originFileName)
path = "//".join(nameList)
f = open(path, 'r', encoding='utf-8')
info = f.read()
f.close()
myList = list()

# 找到无效小数点对应区间
cmd = r'[^\.]\.{2,}(\d| )'
for match in re.finditer(cmd, info):
	myList.append((match.start()+1, match.end()-2))

# 删除无效的小数点
start = 0
end = myList[0][0]
newInfo = ""
cnt = 0
for i in range(len(myList)): 
	if cnt != 0:
		end = myList[i][0]
		newInfo += info[start+1:end] + "\t"
	else:
		newInfo += info[start:end] + "\t"
	start = myList[i][1]
	cnt += 1

# 给页码加偏移
splitForPage = newInfo.split('\n') 
newInfo = ""
for item in splitForPage:
	temp = item.split('\t')
	try:
		num = int(temp[-1]) + pageOffset
		temp[-1] = "\t" + str(num)
	except(ValueError):
		pass
	item = "".join(temp)
	newInfo += item + "\n" 

# 删除目录无效章节
splitForDelete = newInfo.split('\n') 
newInfo = ""
for item in splitForDelete:
	if item != "":
		if item[0] == "测" or item[0] == "例":
			continue
		else:
			newInfo += item + "\n"
	else:
		continue

# 给章节加缩进,根据小数点个数判断章节层级
splitForCap = newInfo.split('\n') 
newInfo = ""
for item in splitForCap:
	temp = item.split(" ")
	capter = temp[0]
	numPoint = capter.count(".")
	if numPoint == 1:
		item = '\t' + item
	if numPoint == 2:
		item = "\t\t" + item
	newInfo += item + "\n"

nameList.pop(-1)
nameList.append(resultFileName)
path = "//".join(nameList)
f = open(path, 'w', encoding='utf-8')
f.write(newInfo)
f.close()

运行结果:

origin.txt内容:(自己想办法搞到这些信息,我是直接从pdf里复制粘贴的)

result.txt:

用PdfEditor打开目标pdf,将result.txt内容复制到软件里,直接保存就好了!太强了这软件!

正则表达式学习网站:

https://regex101.com/r/dmRygT/1

https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md

有关Python功能实现:为pdf电子书籍生成书签目录的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  5. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  6. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  7. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  8. ruby-on-rails - Prawn PDF : I need to generate nested tables - 2

    我需要一个表,其中行实际上是2行表,一个嵌套表是..我怎样才能在Prawn中做到这一点?也许我需要延期..但哪一个? 最佳答案 现在支持子表:Prawn::Document.generate("subtable.pdf")do|pdf|subtable=pdf.make_table([["sub"],["table"]])pdf.table([[subtable,"original"]])end 关于ruby-on-rails-PrawnPDF:Ineedtogeneratenested

  9. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  10. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

随机推荐