尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Jupytext Markdown 格式精讲:从 Notebook 到带元数据与长文本的 Markdown 文档

发布时间:2026/9/29 5:31:36

资讯中心
01
ARTICLE

Jupytext Markdown 格式精讲:从 Notebook 到带元数据与长文本的 Markdown 文档

Jupytext Markdown 格式精讲:从 Notebook 到带元数据与长文本的 Markdown 文档
开发工具【免费下载链接】jupytextJupyter Notebooks as Markdown Documents, Julia, Python or R scripts项目地址https://gitcode.com/gh_mirrors/ju/jupytext点击查看免费下载本指南以 Jupytext 的 Markdown 文档格式jupytext 格式md为主题围绕一个元数据丰富且包含长文本单元的典型 NotebookNotebook with metadata and long cells.ipynb及其转换产物Notebook with metadata and long cells.md展开系统讲解 Jupytext 如何用!-- #region --/!-- #raw --HTML 注释标记还原 Markdown 与 raw 单元、如何在代码块围栏行携带单元元数据以及 Jupytext 将 Jupyter Notebook 无损映射为 Markdown 文档的完整规则。读完本文你将能熟练阅读、编写和校验这种带元数据与长文本单元的 Markdown 格式 Notebook并理解其底层实现机制。一、为什么需要带元数据与长文本单元的 Markdown NotebookJupytext 的核心能力之一是把 Jupyter Notebook.ipynb表示为纯文本的 Markdown 文档格式标识为md。但 Notebook 中的单元远比普通 Markdown 内容复杂存在两类特殊单元长文本 Markdown 单元单元内容可能包含空行、内嵌代码块、HTML 注释等。若直接以普通 Markdown 书写解析时容易被拆碎或误判为多个单元。raw 单元与单元元数据raw 单元是 Notebook 中既非代码也非 Markdown 的原始文本而单元级元数据如tags、keyvalue等需要一种确定的文本编码方式才能在纯文本中保存并在转换回 Notebook 时无损还原。Jupytext 的解决方案是用HTML 注释形式的区域标记包裹这类特殊单元并用代码块围栏行的附加选项如python .class tags[parameters]序列化单元元数据。下面的转换示例即是这一机制的完整展示其测试覆盖见 test_mirror.pytest_ipynb_to_md会对ipynb_to_md目录下的所有产物做往返一致性校验。二、转换示例一个完整的 Notebook → Markdown 产物以下是被转换的 Notebook输入侧它依次包含普通标题单元、含两个空行的长 Markdown 单元、内嵌代码块的 Markdown 单元、含空行的代码单元、raw 单元、以及三个携带元数据的单元# Part one - various cells, Here we have a markdown cell\n\n\nwith two blank lines, Now we have a markdown cell\nwith a code block inside it\n\npython\n1 1\n\n\nAfter that cell well have a code cell, code: 2 2\n\n\n3 3输出 6 markdown: Followed by a raw cell, raw: This is \nthe content\nof the raw cell, # Part two - cell metadata, markdown {key: value}, code {.class: null, tags: [parameters]}输出 20 raw {key: value}转换得到的 Markdown 文件Notebook with metadata and long cells.md完整内容如下它是本文所有讨论的基准--- jupyter: kernelspec: display_name: Python 3 language: python name: python3 --- # Part one - various cells !-- #region -- Here we have a markdown cell with two blank lines !-- #endregion -- !-- #region -- Now we have a markdown cell with a code block inside it python 1 1After that cell well have a code cell2 2 3 3Followed by a raw cellThis is the content of the raw cellPart two - cell metadataThis is a markdown cell with cell metadata{key: value}This is a code cell with metadata {tags:[parameters], .class:null}This is a raw cell with cell metadata{key: value}文件顶部的 YAML 头jupyter.kernelspec保存的是 Notebook 级元数据由 Jupytext 的标准 Markdown 头机制写入。下文分三部分讲解普通单元与长文本单元的标记规则、raw 单元的编码、单元元数据的两种文本表示。 ## 三、Markdown 单元的区域标记!-- #region -- 与 !-- #endregion -- ### 3.1 何时需要区域标记 观察上面的转换结果有两个 Markdown 单元被 !-- #region -- … !-- #endregion -- 包裹 - 内容 Here we have a markdown cell\n\n\nwith two blank lines含两个空行 - 内容 Now we have a markdown cell\nwith a code block inside it\n\npython\n1 1\n\n\nAfter that cell well have a code cell内嵌 Markdown 代码块。 而普通的标题单元 # Part one - various cells 则直接以裸文本输出没有区域标记。原因在导出器源码中有明确说明[cell_to_text.py](https://link.gitcode.com/i/170794a8b2083c6cb7e7590ddc0076ea) python # Is an explicit region required? if self.metadata: protect True else: # Would the text be parsed to a shorter cell/a cell with a different type? cell, pos self.cell_reader(self.fmt).read(self.source) protect pos len(self.source) or cell.cell_type ! self.cell_type if protect: return self.html_comment(self.metadata, self.metadata.pop(region_name, region)) return self.source即只要单元携带元数据或者裸写会导致解析结果与原始单元不一致被截短、或单元类型改变就必须加区域标记。这正是长文本单元场景的判定逻辑——含空行的 Markdown 若不加标记反解析时可能被截断为多个单元内嵌 代码块的 Markdown 若不标记反解析时可能被误判为代码单元。3.2 区域标记的生成实现区域标记由MarkdownCellExporter.html_comment生成cell_to_text.pydef html_comment(self, metadata, coderegion): Protect a Markdown or Raw cell with HTML comments if metadata: region_start [ !-- # code, metadata_to_text(metadata, plain_jsonself.cell_metadata_json), --, ] region_start .join(region_start) else: region_start f!-- #{code} -- return [region_start] self.source [f!-- #end{code} --]可见标记格式为!-- #region --无元数据或!-- #region 元数据 --有元数据结束标记统一为!-- #endregion --。3.3 解析侧区域如何被还原为单元读取侧在 cell_reader.py 中实现start_region_re re.compile(r^!--\s*#(region|markdown|md|raw)(.*)--\s*$)区域开始标记支持四种名称region、markdown、md、raw。匹配后进入in_region状态并依据区域名构造对应的结束标记正则^!--\s*#end{region_name}\s*--\s*$。其中区域名为raw时该区域内的内容按 raw 单元处理#raw标记见下一节区域名为markdown或md时会把区域名写入metadata[region_name]供写出时复用同名标记解析器支持嵌套区域——代码中注释We want to parse inner most regions as cellscell_reader.py因此长文本单元内部即便出现区域标记也能被正确还原。3.4 额外注意点!-- #region keyvalue --这类带元数据的开始标记会由metadata_to_textcell_metadata.py序列化格式为keydumps(value)例如keyvalue、tags[parameters]、.classnull。反解析时区域内的全部行包括空行、内嵌代码块都归入该单元从而保证长文本单元的完整性。四、raw 单元的编码!-- #raw --与!-- #endraw --raw 单元在 Markdown 中同样使用 HTML 注释区域标记只是区域名换成了raw。转换示例中有两个 raw 单元Followed by a raw cell !-- #raw -- This is the content of the raw cell !-- #endraw --以及带元数据的版本!-- #raw keyvalue -- This is a raw cell with cell metadata {key: value} !-- #endraw --导出侧的逻辑在 cell_to_text.pyif self.cell_type raw and not is_active(self.ext, self.metadata, False): return self.html_comment(self.metadata, raw)即raw 单元默认以!-- #raw --…!-- #endraw --包裹输出元数据照常序列化进开始标记。阅读侧则在cell_reader.py的start_region_re分支中识别raw区域名并创建 raw 单元cell_reader.py。注意raw 单元只会在非活跃is_active判定为 False时使用#raw标记R Markdown.Rmd等格式对 raw 单元另有处理路径evalFalse等选项本格式下统一为#raw区域标记。五、代码单元的元数据围栏行选项与class键5.1 带元数据代码单元的输出Markdown 格式下代码单元以围栏代码块表示。当单元携带元数据时元数据会以选项字符串形式追加到围栏行语言名之后。例如python .class tags[parameters] This is a code cell with metadata {tags:[parameters], .class:null}对应 Notebook 侧该代码单元的元数据为 {.class: null, tags: [parameters]}。注意其中的**特殊键 .class**当元数据值为 null 时metadata_to_text 只输出键名本身而不输出值[cell_metadata.py](https://link.gitcode.com/i/a6e86451351c65bb384d12d5f0a36a85)于是得到围栏行 python .class tags[parameters]。阅读侧解析时tags[parameters] 被还原为标签列表裸 .class 被还原为 .class: null往返后元数据完全一致。 ### 5.2 生成规则源码 代码单元的写出逻辑在 [cell_to_text.py](https://link.gitcode.com/i/eec63fdd08b9399a6671a1f054db3a1f) python def code_to_text(self): source copy(self.source) comment_magic(source, self.language, self.comment_magics) ... options metadata_to_text(self.language, self.metadata) code_cell_delimiter three_backticks_or_more(self.source) return [code_cell_delimiter options] source [code_cell_delimiter]其中metadata_to_text(self.language, self.metadata)将语言名与元数据合并为一行选项文本规则是语言名在前其后按keyjson值拼接值为None的键只写键名。three_backticks_or_more保证当单元源码本身包含 时围栏会自动加长到三个以上反引号避免与内嵌代码块冲突。5.3 空行与执行计数示例中代码单元2 2\n\n\n3 3在 Markdown 中保留了三个换行两个空行因为长代码单元的反解析同样依赖围栏结构空行不会导致单元被拆散。同时注意输出outputs与执行计数execution_count默认不会写入 Markdown 文本这是 Markdown 格式的固有取舍——文本形态保留代码与元数据运行结果留在配对/转换回的 Notebook 中。六、格式往返校验如何验证你的 Markdown Notebook 无损Jupytext 对ipynb_to_md目录下的所有转换产物执行镜像一致性测试。核心测试位于 test_mirror.pydef test_ipynb_to_md(ipynb_file, no_jupytext_version_number): assert_conversion_same_as_mirror(ipynb_file, md, ipynb_to_md)该测试对tests/data/notebooks/inputs/ipynb_py/下的每个 Notebook 执行.ipynb → .md → .ipynb的往返转换再对比元数据与单元内容是否一致。本文讨论的示例文件即通过此类校验证明!-- #region --/!-- #endregion --包裹的长 Markdown 单元往返后内容与类型不变!-- #raw --/!-- #endraw --包裹的 raw 单元往返后无损围栏行选项中的keyvalue、keynull、tags[...]等元数据往返后与原 Notebook 完全等价。你可以用同样方式验证自己的文件安装 jupytext 后在仓库根目录执行jupytext --to md 输入.ipynb生成 Markdown再执行jupytext --from md --to ipynb 输出.md转回并对比或直接运行pytest tests/functional/round_trip/test_mirror.py观察全量往返结果。七、实战要点速查场景Markdown 表示往返还原普通 Markdown 单元裸文本直接还原含空行 / 内嵌代码块的长 Markdown 单元!-- #region --…!-- #endregion --完整还原为单个单元携带元数据的 Markdown 单元!-- #region keyvalue --…!-- #endregion --元数据并入单元raw 单元!-- #raw --…!-- #endraw --还原为 raw 单元携带元数据的 raw 单元!-- #raw keyvalue --…!-- #endraw --元数据并入单元普通代码单元python\n…\n还原为代码单元携带元数据的代码单元python .class tags[parameters]\n…\n元数据并入单元其他注意事项Notebook 级元数据如kernelspec写在文件顶部 YAML 头--- ... ---中region_name支持region/markdown/md三种名称写出时可通过元数据指定值为null的元数据键只写键名布尔值写true/false字符串与列表写 JSON如keyvalue、tags[parameters]Markdown 文本不承载单元输出与执行计数需要保留运行结果的场景请使用配对 Notebook 或.ipynb主文件。八、延伸阅读导出器完整实现cell_to_text.pyMarkdownCellExporter及html_comment/code_to_text解析器完整实现cell_reader.pystart_region_re、嵌套区域解析元数据序列化与反序列化cell_metadata.pymetadata_to_text、_IGNORE_CELL_METADATA过滤规则往返一致性测试test_mirror.py输入 NotebookNotebook with metadata and long cells.ipynb转换产物本文基准文档Notebook with metadata and long cells.md通过本文的标记规则与源码佐证你已经能完整读懂并手工编写带元数据与长文本单元的 Jupytext Markdown Notebook并能利用仓库自带的往返测试验证自己的转换结果。赞分享开发工具【免费下载链接】jupytextJupyter Notebooks as Markdown Documents, Julia, Python or R scripts项目地址https://gitcode.com/gh_mirrors/ju/jupytext点击查看免费下载相关推荐Flipper Zero Unleashed Firmware 调试指南使用 PyCortexMDebug 在 GDB 中解析 SVD 外设寄存器Flipper Zero Unleashed Firmware 调试指南使用 PyCortexMDebug 在 GDB 中解析 SVD 外设寄存器 PyCor开发工具Fleet 写作规范与文档协作指南从文章元数据到 Markdown 写作风格Fleet 写作规范与文档协作指南从文章元数据到 Markdown 写作风格 Fleet 是一个开源的设备管理device management平台其仓后端前端企业应用运维网络安全Koog Markdown支持prompt-markdown文档格式化Koog Markdown支持prompt markdown文档格式化 痛点AI应用中的文档生成难题 在构建AI应用时开发者经常面临一个挑战如何以编程方AI AgentAgent 框架人工智能大模型MCP 服务RAG后端上一篇终极对话AI新标杆Yi-1.5-6B-Chat模型深度解析与核心优势揭秘下一篇gh_mirrors/de/developer生物科技开发生命科学新突破创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。