找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 3919|回复: 4

【完结】epub文档目录以及正文的修正+100元

  [复制链接]
发表于 2025-7-22 12:27:00 | 显示全部楼层 |阅读模式
本帖最后由 lxh623 于 2025-7-24 18:43 编辑

通过网盘分享的文件:20250722
链接: https://pan.baidu.com/s/1NG7njma8UHUEVNFy33vIGg?pwd=4sxt 提取码: 4sxt

"J:\大藏经修改\epub解包后\"下面很多个解包epub文件夹,合并001_split_00*.xhtml到一个文件,改名为001.xhtml (不只是001,很多带有split的文件,文件名001开头的合并到001,002开头的合并到002),最后删除哪些合并前的文件。附件是sigil合并之后的文件,合并办法参考它的处理。
toc.ncx文件内,把<content src="juans/替换为<content src="Text/ 。
最后,最好打包后 ,microsoft edge打开,能够看到书签(目录)。或者calibre的ebook-edit-portable打开,编辑目录,不显示一个红色(链接有问题)。

谢谢!
发表于 2025-7-23 14:30:25 | 显示全部楼层
本帖最后由 flashercs 于 2025-7-23 18:54 编辑
  1. <#*,:
  2. @echo off
  3. cd /d "%~dp0"
  4. set "batchfile=%~f0"
  5. Powershell -ExecutionPolicy Bypass -C "Set-Location -LiteralPath ([Environment]::CurrentDirectory);. ([ScriptBlock]::Create([IO.File]::ReadAllText($env:batchfile,[Text.Encoding]::GetEncoding(0) )) )"
  6. pause
  7. exit /b
  8. #>
  9. # 合并xhtml
  10. $utf8 = New-Object System.Text.UTF8Encoding -ArgumentList $false

  11. Add-Type -AssemblyName System.Xml.Linq
  12. if (-not $?) { return }
  13. [System.Xml.Linq.XNamespace]$ns_opf = "http://www.idpf.org/2007/opf"
  14. $dic_item = New-Object 'System.Collections.Generic.Dictionary[string,object]' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase)
  15. $dic_fileName = New-Object 'System.Collections.Generic.Dictionary[string,object]' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase)
  16. $strb = New-Object System.Text.StringBuilder -ArgumentList 4kb
  17. $re_body = [regex]'(?s)(<body[^>]*>)(.*)(</body>)'
  18. $re_src = [regex]'(src=")([^"]+)'
  19. foreach ($di0 in Get-ChildItem -Path '.\epub解包后\*' | Where-Object { $_ -is [IO.DirectoryInfo] }) {
  20.   $di0.Name

  21.   $opf = Get-ChildItem -LiteralPath $di0.FullName -Filter content.opf -Recurse | Where-Object { $_ -is [IO.FileInfo] } | Select-Object -First 1
  22.   if ($null -eq $opf) { "找不到文件: content.opf"; continue }
  23.   $ncx = Get-ChildItem -LiteralPath $di0.FullName -Filter toc.ncx -Recurse | Where-Object { $_ -is [IO.FileInfo] } | Select-Object -First 1
  24.   if ($null -eq $ncx) { "找不到文件: toc.ncx"; continue }
  25.   # $diText = Get-ChildItem -LiteralPath $di0.FullName -Filter Text -Recurse | Where-Object { $_ -is [IO.DirectoryInfo] } | Select-Object -First 1
  26.   # if ($null -eq $diText) { "找不到文件夹: Text"; continue }
  27.   # 修改 opf
  28.   "修改 opf:$($opf.FullName)"
  29.   try {
  30.     $dic_item.Clear()
  31.     $dic_fileName.Clear()
  32.     $xdoc_opf = [System.Xml.Linq.XDocument]::Load($opf.FullName)
  33.     $dir_opf = [IO.Path]::GetDirectoryName($opf.FullName)
  34.     $xel_spine = $xdoc_opf.Root.Element($ns_opf + 'spine')
  35.     foreach ($xel_item in $xdoc_opf.Root.Element($ns_opf + 'manifest').Elements($ns_opf + 'item')) {
  36.       $xattr_href = $xel_item.Attribute('href')
  37.       if ($xattr_href) {
  38.         $baseName = [IO.Path]::GetFileNameWithoutExtension($xattr_href.Value)
  39.         if ($baseName -match '^(.+)_split_(.+)$') {
  40.           $prefix = $Matches[1]
  41.           if (-not $dic_item.ContainsKey($prefix)) {
  42.             $dic_item[$prefix] = New-Object 'System.Collections.Generic.List[System.Xml.Linq.XElement]'
  43.           }
  44.           $dic_item[$prefix].Add($xel_item)
  45.         }
  46.       }
  47.     }
  48.     if ($dic_item.Count -gt 0) {
  49.       foreach ($prefix in $dic_item.Keys) {
  50.         $strb.Length = 0
  51.         for ($i = 0; $i -lt $dic_item[$prefix].Count; ++$i) {
  52.           $xel_item = $dic_item[$prefix][$i]
  53.           $html_path = [IO.Path]::GetFullPath([IO.Path]::Combine($dir_opf, $xel_item.Attribute('href').Value))
  54.           $html_text = [IO.File]::ReadAllText($html_path)
  55.           if ($i -eq 0) {
  56.             $xel_item0 = $xel_item
  57.             $html_path0 = $html_path
  58.             $html_text0 = $html_text
  59.             $ext0 = [IO.Path]::GetExtension($html_path0)
  60.           } else {
  61.             # 删除 spine/itemref
  62.             $item_id = $xel_item.Attribute('id').Value
  63.             foreach ($xel_itemref in @($xel_spine.Elements($ns_opf + 'itemref'))) {
  64.               if ($xel_itemref.Attribute('idref').Value -ceq $item_id) {
  65.                 $xel_itemref.Remove()
  66.               }
  67.             }
  68.             # 删除 manifest/item
  69.             $xel_item.Remove()
  70.             # 删除 xhtml
  71.             [IO.File]::Delete($html_path)
  72.           }
  73.           $m = $re_body.Match($html_text)
  74.           if ($m.Success) {
  75.             $null = $strb.Append($m.Groups[2].Value)
  76.           }
  77.          
  78.         }
  79.         $html_text_new = $re_body.Replace($html_text0, {
  80.             param($m)
  81.             $m.Groups[1].Value + $strb.ToString() + $m.Groups[3].Value
  82.           })
  83.         # 保存001.xhtml
  84.         $html_path_new = [IO.Path]::Combine([IO.Path]::GetDirectoryName($html_path0), $prefix + $ext0)
  85.         [IO.File]::WriteAllText($html_path_new, $html_text_new)
  86.         [IO.File]::Delete($html_path0)
  87.         # 更改 $xel_item0 属性 href
  88.         $xel_item0.Attribute('href').Value = $html_path_new.Substring($dir_opf.Length).TrimStart('\').Replace('\', '/')
  89.       }
  90.       $sw = New-Object System.IO.StreamWriter -ArgumentList ($opf.FullName, $false, $utf8)
  91.       $xdoc_opf.Save($sw, 'OmitDuplicateNamespaces')
  92.       $sw.Close()
  93.     }
  94.     # 获取文件列表
  95.     foreach ($xel_item in $xdoc_opf.Root.Element($ns_opf + 'manifest').Elements($ns_opf + 'item')) {
  96.       $xattr_href = $xel_item.Attribute('href')
  97.       if ($xattr_href) {
  98.         $fileName = [IO.Path]::GetFileName($xattr_href.Value)
  99.         $dic_fileName.$fileName = [IO.Path]::GetFullPath([IO.Path]::Combine($dir_opf, $xattr_href.Value))
  100.       }
  101.     }
  102.   } finally {}
  103.   # 修改 ncx
  104.   "修改 ncx:$($ncx.FullName)"
  105.   try {
  106.     $dir_ncx = [IO.Path]::GetDirectoryName($ncx.FullName)
  107.     $str_ncx = [IO.File]::ReadAllText($ncx.FullName)
  108.     $str_ncx = $re_src.Replace($str_ncx, {
  109.         param($m)
  110.         $gp1 = $m.Groups[1].Value
  111.         $gp2 = $m.Groups[2].Value
  112.         $fileName = ($gp2 -split '/')[-1]
  113.         $fileName0 = ($fileName -split '#')[0]
  114.         if ($dic_fileName.ContainsKey($fileName0)) {
  115.           $relpath = [IO.Path]::Combine([IO.Path]::GetDirectoryName($dic_fileName.$fileName0.Substring($dir_ncx.Length).TrimStart('\')), $fileName).Replace('\', '/')
  116.         } else {
  117.           $relpath = $gp2
  118.         }
  119.         $gp1 + $relpath
  120.       })
  121.     [IO.File]::WriteAllText($ncx.FullName, $str_ncx)
  122.   } finally {
  123.    
  124.   }
  125.   
  126.   trap {}
  127. }
复制代码

评分

参与人数 1技术 +1 收起 理由
lxh623 + 1 乐于助人

查看全部评分

 楼主| 发表于 2025-7-23 15:27:17 | 显示全部楼层
回复 2# flashercs
谢谢!请查收!
 楼主| 发表于 2025-7-23 16:06:41 | 显示全部楼层
本帖最后由 lxh623 于 2025-7-23 16:11 编辑

回复 2# flashercs


文件很多,搞了不少次,结果,有多种文件样式。比如,路径是:J:\大藏经修改\epub解包后\N29n0017--譬喻经(第1卷-第39卷)--悟醒译\OEBPS\juans。
我上传了两个示例文件夹。
能不能稍微修改,增加兼容性。
这种好像不用修改toc.ncx,只是合并文件。
谢谢!
发表于 2025-7-23 18:55:15 | 显示全部楼层
楼上已经修改了;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 19:15 , Processed in 0.021162 second(s), 10 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表