拓冰建站拓冰建站
首页 / 资讯中心 / 正文

calibre 电子书编辑工具 API 深度指南:Container 容器模型与 Polish 模块实战

calibre 电子书编辑工具 API 深度指南Container 容器模型与 Polish 模块实战【免费下载链接】calibreThe official source code repository for the calibre ebook manager项目地址: https://gitcode.com/GitHub_Trending/ca/calibre本指南以 calibre 官方仓库 manual/polish.rst 的 API 文档为骨架系统讲解电子书编辑工具E-book editing tools / Edit Book的核心架构Container容器对象如何把一本书表示为“HTML 资源文件”的集合以及calibre.ebooks.oeb.polish.*各模块提供的文件管理、HTML 修复、封面处理、CSS 清理、目录ToC生成、文件拆分合并等可编程能力。读完本文你将掌握如何用几行 Python 代码对 EPUB/AZW3 书执行批量编辑并能在 E-book editor 插件中直接操作当前打开的书籍。概述编辑工具的两大组成calibre 的电子书编辑工具由两部分构成见 manual/polish.rstContainer容器对象定义于calibre.ebooks.oeb.polish.container将一本书表示为一个文件夹里的 HTML 与资源文件集合是所有编辑操作的数据中枢一组模块级函数工具分布在calibre.ebooks.oeb.polish.*的各个子模块中例如replace、pretty、jacket、split、cover、css、toc、fonts用于在容器上执行具体操作。两者配合即可对书籍做无副作用的程序化编辑所有操作都作用于容器最后统一commit回磁盘。获取 Container 对象命令行 / 脚本场景对一个位于某路径的书文件EPUB、AZW3、MOBI 等获取容器from calibre.ebooks.oeb.polish.container import get_container container get_container(Path to book file, tweak_modeTrue)get_container的原型见 container.pydef get_container(path, logNone, tdirNone, tweak_modeFalse, ebook_clsNone) - Container:其行为要点根据文件扩展名自动选择容器实现.azw3、.mobi、.original_azw3、.original_mobi使用AZW3Container.kepub、.original_kepub使用KEPUBContainer其余含目录默认使用EpubContainerEPUB 会被解压到临时目录PersistentTemporaryDirectory(_epub_container)再解析is_dir为 True 时按目录方式复制tweak_mode是解析模式开关True表示“编辑模式”HTML/CSS 解析更宽容保留原始格式细节供编辑器使用False表示“打磨模式”polish可对解析做预处理。源码中ContainerBase明确注释tweak_mode Falsepolishing 使用编辑器则使用tweak_modeTrue见 container.py。插件场景获取正在编辑的书如果你正在为E-book editorEdit Book编写插件可用模块级函数获取当前编辑中的容器from calibre.gui2.tweak_book import current_container container current_container() if container is None: report_error # No book has been opened yet该函数的实现位于 src/calibre/gui2/tweak_book/init.py内部就是一个模块级全局变量_current_container由set_current_container()在打开书籍时设置。因此在编辑器未打开任何书时current_container()返回None插件代码必须做判空处理。此外在插件Tool子类内部self.current_container属性直接封装了上面的调用见 plugin.py。Container 对象电子书的统一视图Container类完整定义于 src/calibre/ebooks/oeb/polish/container.py。其文档字符串定义了三个核心概念根目录root folder电子书的基准目录书内所有文件都在该目录或其子目录下Names相对于根目录的文件路径永远使用 POSIX 分隔符/、不带 URL 引号、且处于 NFC Unicode 规范化形式。Names 是容器内文件的“规范标识符”容器的大部分方法都以 name 为参数Clones容器支持高效的磁盘克隆clone_data/data_for_clone这是 E-book editor 实现检查点checkpoint/ 撤销功能的基础。正因如此永远不要直接访问文件系统应通过raw_data()或open()读写书内文件。各容器子类通过类属性区分能力book_typeepub/azw3、is_dir、SUPPORTS_TITLEPAGES、SUPPORTS_FILENAMES、MAX_HTML_FILE_SIZEEPUB 容器为 260 KiB。关键方法速览方法作用raw_data(name)/open(name, mode)读取/写入书内文件推荐兼容克隆机制parsed(name)返回文件的解析树HTML/CSS/XMLreplace(name, obj)用新解析对象替换某文件内容并标记 dirtydirty(name)标记文件已修改等待提交commit(outpathNone, keep_parsedFalse)把所有 dirty 文件写回磁盘/写出书文件add_file(...)添加文件自动登记 OPF manifest 与 spinerename(current_name, new_name)重命名文件并处理 OPFremove_item(name)从容器删除文件含 manifest/guideadd_name_to_manifest(name)为文件创建 manifest 条目返回 item idmanifest_has_name(name)/make_name_unique(name)manifest 检查与重名处理opf()/mi()/opf_version()访问 OPF 解析树、元数据对象与版本spine_items/spine_names()/set_spine(...)阅读与重排 spinehref_to_name(href, base)/name_to_href(name, base)href带引号与 name 互转iterlinks(name)遍历文件中的链接含行号compare_to(other)对比两个容器差异测试用所有写操作如add_file、dirty最终由commit()汇总commit()遍历self.dirtied集合逐个调用commit_item()见 container.py。修改过的文件只有调用commit()才会真正落盘。管理容器中的组件文件replace 模块模块calibre.ebooks.oeb.polish.replace提供三类文件级操作源码见 replace.py。replace_links —— 批量替换链接def replace_links(container, link_map, frag_maplambda name, frag: frag, replace_in_opfFalse):遍历容器内所有文件把指向旧文件名的链接改为新文件名link_map{旧规范名: 新规范名}映射例如{images/old.png: images/new.png}frag_map可调用对象接收(name, anchor)返回新锚点用于同时改写 HTML 内锚点如#chapter2replace_in_opf为False默认时跳过 OPF 文件为True时连 OPF 里的 href 一并替换。实现上由LinkReplacer类配合container.replace_links(name, repl)逐文件执行。rename_files —— 重命名并自动修复链接def rename_files(container, file_map):file_map{旧规范名: 新规范名}例如{text/chapter1.html: chapter1.html}自动调用container.rename()并随后replace_links(container, link_map, replace_in_opfTrue)因此所有指向旧文件名的链接会被同步更新安全性检查拒绝循环重命名目标同时也是源、目标已存在、以及目标名重复大小写变化在大小写不敏感文件系统上会被特殊处理。get_recommended_folders —— 推荐文件夹def get_recommended_folders(container, names):根据容器内同类文件多数所在位置为给定文件名推荐存放目录若某种类型不存在则推荐 OPF 所在文件夹。内部按 MIME 类型归类text / style / font / opf / toc 等见mt_to_category同名工具被 Edit Book 的“Rationalize Folders”整理文件夹功能使用。同模块还提供replace_ids(container, id_map)批量改写 id 及指向它们的 idref、smarten_punctuation(container, report)智能标点转换、replace_file(...)用外部文件替换书内文件、remove_links_to(container, predicate)按谓词删除链接等函数。美化打印与自动修复解析错误pretty 模块模块calibre.ebooks.oeb.polish.pretty提供对 HTML/CSS/XML 的美化与修复能力源码见 pretty.py函数行为fix_html(container, raw)用HTML5 解析算法修复raw字符串中的解析错误返回序列化后的 HTMLfix_all_html(container)对容器内所有 HTML 文档执行修复标记 dirty 触发重写pretty_html(container, name, raw)美化单个 HTML 字符串pretty_css(container, name, raw)美化单个 CSS 字符串pretty_xml(container, name, raw)美化单个 XML 字符串若name是 OPF还会执行 OPF 专属美化pretty_opfpretty_all(container)美化容器内全部 HTML/CSS/XML 文件内部实现要点pretty_html先经parse_xhtml解析成树再通过pretty_html_tree对块级元素重新缩进pretty_script_or_style专门处理script/style内的内容pretty_css用parse_css解析后序列化实现 CSS 规则的统一缩进fix_all_html并不逐个比较新旧内容而是直接对每个 OEB 文档调用parsed(name)dirty(name)让 HTML5 解析器在重写时自动纠正错误。这两个函数集正是 Edit Book 中Fix HTML与Pretty Print工具的后端GUI 菜单Tools → Fix HTML/Tools → Pretty Print见Boss.fix_html与Boss.pretty_printboss.py。管理书籍封套jacket 模块模块calibre.ebooks.oeb.polish.jacket用于管理 EPUB 的封套页jacket书籍开头的装饰页源码见 jacket.pyremove_jacket(container)删除书中已存在的封套页及其图片资源remove_jacket_imagesadd_or_replace_jacket(container)为书添加封套页若已存在旧式/现式封套则先替换。实现细节find_existing_jacket在 spine 中定位封套文档is_legacy_jacket/is_current_jacket用于识别不同版本的封套结构render_jacket根据书籍元数据渲染封套 HTMLreplace_jacket完成内容替换并处理 OPF 条目。文件的拆分与合并split 模块模块calibre.ebooks.oeb.polish.split提供对 HTML 文档的拆分与合并源码见 split.py。split —— 单点拆分def split(container, name, loc_or_xpath, beforeTrue, totalsNone):把name指定的文件在loc_or_xpath处一分为二自动迁移所有受影响的链接与引用loc_or_xpathXPath 表达式如//h:div[idsplit_here]也可传内部使用的loc预览面板拆分时使用beforeTrue表示在命中元素之前拆分否则在之后失败保护若定位节点在table内或为body标签则抛出AbortError若 HTML 解析计数不一致会强制用 HTML5 解析器重试并提示“Try running the Fix HTML tool before splitting”。multisplit —— 多点拆分def multisplit(container, name, xpath, beforeTrue):按 XPath 命中的所有元素将文件拆成多份逻辑基于split的循环调用。merge —— 合并文件def merge(container, category, names, master):把同类别category的一组文件合并进masterHTML 合并由merge_html实现insert_page_breaksFalse时按顺序拼接各文件 body 内容并把锚点改名以保证唯一性unique_anchor、remove_name_attributesCSS 合并由merge_css实现把各样式表规则并入主样式表合并后调用remove_names_from_toc等清理工作确保 ToC 不再指向被合并掉的旧文件。管理封面cover 模块模块calibre.ebooks.oeb.polish.cover负责书籍封面的设置与识别源码见 cover.py函数行为set_cover(container, cover_path, reportNone, optionsNone)把外部图片设为书籍封面写入封面图、生成/替换封面页EPUB 走set_epub_coverAZW3 走set_azw3_cover并清理旧封面残留mark_as_cover(container, name)把容器内已有文件标记为封面EPUB 走mark_as_cover_epubAZW3 走mark_as_cover_azw3mark_as_titlepage(container, name, move_to_startTrue)把指定文件标记为书名页titlepage默认移到 spine 开头find_cover_image(container, strictFalse)智能探测书籍封面图has_epub_cover(container)判断 EPUB 是否已有封面EPUB 封面处理会同时维护三处状态OPF 的metadatameta namecover、manifest中封面图条目、以及 spine 中的封面页create_epub_cover负责生成包含封面图的书名页 HTMLremove_cover_image_in_page在更换封面时清理旧图。处理 CSScss 模块与 fonts 模块remove_unused_css —— 清理无用样式def remove_unused_css( container, reportNone, remove_unused_classesFalse, merge_rulesFalse, merge_rules_with_identical_propertiesFalse, remove_unreferenced_sheetsFalse, ):删除书中所有不匹配任何实际内容的 CSS 规则源码见 css.pyremove_unused_classesTrue同时移除 HTML 中不匹配任何 CSS 规则的class属性merge_rulesTrue合并选择器相同的规则merge_identical_selectorsmerge_rules_with_identical_propertiesTrue合并属性完全相同的规则remove_unreferenced_sheetsTrue移除未被任何内容引用的样式表文件内部通过mark_used_selectors用 CSS 选择器引擎select对全部文档做使用标记get_imported_sheets处理import链默认递归深度 10未命中的选择器与规则进入removal_stats被删除。filter_css —— 过滤 CSS 属性def filter_css(container, properties, names()):从样式表中删除指定 CSS 属性如filter_css(container, {color})可限定只处理names列出的文件transform_css是更通用的“CSS 变换”入口可传入transform_sheet/transform_style回调支持把font-size转成pt/em这类整体重写二者实现均在 css.py。change_font —— 全局更换字体def change_font(container, old_name, new_nameNone):把字体族old_name全局替换为new_name源码见 fonts.py作用于样式表、style标签与内联style属性三处若old_name是内嵌字体替换时会被一并移除new_nameNone表示只移除该字体族而非替换底层由font_family_data汇总所有字体声明change_font_in_sheet/change_font_in_declaration分别处理样式表与声明。处理目录 ToCtoc 模块模块calibre.ebooks.oeb.polish.toc提供目录的生成与提交能力源码见 toc.py。从 XPath 生成 ToCdef from_xpaths(container, xpaths, prefer_titleFalse):用一组 XPath 表达式生成目录每个表达式对应一级[//h:h1, //h:h2, //h:h3]会从h1/h2/h3生成三级目录。实现会自动剔除在所有 spine 文档中均无匹配的“空层级”并用node_level_map维护父子关系prefer_titleTrue时优先取title属性作为条目文本。从链接与文件生成 ToCfrom_links(container)把 spine 文档中已有的a链接结构转换为目录适用于从 HTML 链接推断章节结构from_files(container)把每个 spine 文件作为目录的一个条目文件级目录。提交与内联目录commit_toc(container, toc, langNone, uidNone)根据 EPUB 版本写入 NCX 或 EPUB3nav文档——commit_ncx_toc负责 EPUB2 的toc.ncxcommit_nav_toc负责 EPUB3 的nav.xhtml并同步ensure_container_has_nav/set_landmarkslandmarks 导航create_inline_toc(container, titleNone)生成内联目录页toc_to_html把当前 ToC 渲染成书内一个 HTML 页面并插入 spine。Edit Book 插件工具类Tool为 E-book editor 编写插件时工具类继承class Tool: # calibre.gui2.tweak_book.plugin.Tool定义于 plugin.py常用成员self.plugin所属calibre.customize.Plugin对象self.boss全局Boss对象用于控制用户界面get_boss()self.gui编辑器主窗口self.current_container当前编辑书籍的Container即current_container()self.name工具的唯一名称作 key 使用allowed_in_toolbar/allowed_in_menu用户是否可把该工具放入插件工具栏/插件菜单必须覆写的方法create_action、register_shortcut。register_shortcut(qaction, unique_name, default_keys(), ...)用于注册快捷键例如default_keys(CtrlJ, F9)注册后用户可在编辑器的快捷键偏好设置中自定义若与内置快捷键或用户配置冲突则自动忽略。控制编辑器用户界面Boss编辑器的用户界面由一个全局Boss对象统一控制calibre.gui2.tweak_book.boss.Boss见 boss.py插件代码可通过get_boss()获取它来执行常见任务常用方法包括方法用途currently_editing()当前是否处于编辑状态open_book(path, ...)/new_book()/import_book(path)打开/新建/导入书籍book_opened(job)书籍打开完成的回调可在此刷新插件 UIadd_file()/add_files()/add_cover()添加文件/封面edit_toc()/insert_inline_toc()编辑 ToC / 插入内联目录polish(action, name, parentNone)调用 polish 工具Editor Polish 菜单入口transform_html()/transform_styles()打开 HTML/CSS 变换对话框manage_fonts()/manage_fonts_embed()/manage_fonts_subset()字体管理内嵌/子集化rationalize_folders()整理文件夹结构rename_requested(...)/bulk_rename_requested(...)文件重命名/批量重命名do_global_undo()/do_global_redo()全局撤销/重做add_savepoint(msg)/rewind_savepoint()保存点管理撤销层级show_current_diff(...)/compare_book()显示当前改动差异 / 对比书籍set_modified()标记书籍已修改fix_html(current)/pretty_print(current)修复 HTML / 美化打印完整示例脚本化打磨一本书把上述 API 串起来一个典型的“打磨流程”脚本大致如下脚本式使用需在 calibre 的 Python 环境运行例如calibre-debug -e script.py入口见 develop/calibre-debugfrom calibre.ebooks.oeb.polish.container import get_container from calibre.ebooks.oeb.polish.pretty import fix_all_html, pretty_all from calibre.ebooks.oeb.polish.css import remove_unused_css from calibre.ebooks.oeb.polish.toc import from_xpaths, commit_toc # 1. 以打磨模式打开书籍tweak_modeFalse即 polish 模式 container get_container(/path/to/book.epub) # 2. 修复所有 HTML 解析错误并美化 fix_all_html(container) pretty_all(container) # 3. 清理无用 CSS合并重复规则 remove_unused_css(container, remove_unused_classesTrue, merge_rulesTrue, remove_unreferenced_sheetsTrue) # 4. 按 h1/h2 重新生成三级目录 toc from_xpaths(container, [//h:h1, //h:h2, //h:h3]) commit_toc(container, toc) # 5. 写回磁盘 container.commit()若是在E-book editor 插件里则第 1 步改为from calibre.gui2.tweak_book import current_container第 5 步改为依赖编辑器的“保存”流程插件只需对容器做修改即可编辑器通过克隆容器实现撤销/恢复。参考资源API 文档原文manual/polish.rst容器核心实现src/calibre/ebooks/oeb/polish/container.py各工具模块replace.py、pretty.py、jacket.py、split.py、cover.py、css.py、toc.py、fonts.py编辑器 GUI 集成src/calibre/gui2/tweak_book/init.py 中的current_container、plugin.py 中的Tool、boss.py 中的Boss插件编写综合指南manual/creating_plugins.rst含 manual/plugin_examples/editor_demo/main.py 可运行的编辑器插件示例单元测试src/calibre/ebooks/oeb/polish/tests/container、split、cascade、structure 等测试覆盖了上述多数 API【免费下载链接】calibreThe official source code repository for the calibre ebook manager项目地址: https://gitcode.com/GitHub_Trending/ca/calibre创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门