
开发工具【免费下载链接】jupytextJupyter Notebooks as Markdown Documents, Julia, Python or R scripts项目地址https://gitcode.com/gh_mirrors/ju/jupytext点击查看免费下载本指南以 Jupytext 仓库中的真实示例 sas.md 为主线完整讲解 Jupyter 生态中 SAS 内核笔记本.ipynb如何被表示为 MyST Markdown 文档、两种形态之间如何无损互转以及 jupytext 在底层如何识别与处理 SAS 语言。读完本文你将能读懂 MyST 格式的 SAS 文本笔记本结构、理解{code-cell}指令与 YAML front matter 的作用并能用 jupytext 在自己项目中完成.ipynb与.md的转换与镜像同步。一、从一份 SAS Notebook 到 MyST 文档示例全景仓库测试数据中tests/data/notebooks/inputs/ipynb_sas/sas.ipynb是一个包含 SAS 内核元数据、1 个 Markdown 单元和 4 个代码单元的笔记本其内容围绕 SAS 基础操作设计proc sql查询sashelp.cars数据集、宏变量%let/%put的定义与引用、以及一个完整的%macro宏定义与调用。它被 jupytext 转换后的 MyST 表示保存在 sas.md 中全文如下--- kernelspec: display_name: SAS language: sas name: sas --- # SAS Notebooks with jupytext {code-cell} proc sql; select * from sashelp.cars (obs10) ; quit; {code-cell} %let name Jupytext; {code-cell} %put name; {code-cell} /* Note when defining macros %macro cannot be the first line of text in the cell */ %macro test; data temp; set sashelp.cars; name testx; run; proc print data temp (obs10); run; %mend test; %test 这份文件本身就是一篇自洽的“文本笔记本”它既可以被任何 Markdown 渲染器正常阅读又可以被 jupytext 反向解析回与原始.ipynb完全等价的 notebook 对象。这正是 MyST 格式myst的定位——在可读性与机器可解析性之间取得平衡。二、MyST 文本笔记本的结构拆解2.1 YAML front matter笔记本级元数据文件开头的---包裹块是文档级元数据front matter。对照源码 myst.py 中的myst_to_notebook实现解析器基于markdown-it-py的 front matter 插件会将该 YAML 块整体提取出来作为 notebook 的顶层metadata写入。本例中的三个字段字段值含义kernelspec.display_nameSASJupyterLab 界面中显示的内核名称kernelspec.languagesas内核对应的语言标识kernelspec.namesas内核注册名用于定位sas内核启动器这三个字段与原始 ipynb 的metadata.kernelspec一一对应可对照 sas.ipynb。当 MyST 文档被反向读回并交给 Jupyter 运行时这些信息决定了 notebook 会绑定哪个内核。值得注意在该示例的 MyST 版本中front matter 直接以kernelspec为顶层键而在 R Markdown.Rmd等格式中同一份元数据会被包进jupyter:命名空间参见 sas.Rmd 的写法。这是不同文本格式对 notebook 元数据的组织约定差异语义完全等价。2.2{code-cell}指令代码单元MyST 使用带指令标注的围栏代码块表示代码单元。{code-cell}正是 myst.py 中定义的CODE_DIRECTIVE常量。解析逻辑myst.py按如下方式工作解析器扫描顶层 token凡是fence围栏块且其 info 以{code-cell}开头的即判定为一个代码单元指令中{code-cell}之后的文本如{code-cell} sas会被作为语法高亮语言lexer处理若所有代码单元语言一致该 lexer 会被写入 notebook 元数据中的jupytext.default_lexermyst.py围栏内的全部文本行拼接为该代码单元的source出现在代码单元之前的普通 Markdown 文本会被收集为 Markdown 单元对应 sas.md 中的# SAS Notebooks with jupytext标题。反方向notebook → MyST由notebook_to_mystmyst.py完成它遍历 notebook 单元将代码单元输出为{code-cell}围栏块并把单元格级元数据以 YAML 或:key: value形式写在指令体内部。这是镜像往返测试能成立的基础。三、示例中的 SAS 代码单元逐一解读该示例的四个代码单元覆盖了 SAS 编程的三种典型形态也顺便验证了 jupytext 对%宏指令文本的原样保留能力。3.1 SQL 过程步proc sql; select * from sashelp.cars (obs10) ; quit;这是 SAS 中通过proc sql直接执行 SQL 查询的典型写法读取 SAS 自带示例数据集sashelp.cars的前 10 行。文本笔记本中它被原样存储没有任何转义或改写。3.2 宏变量定义与引用%let name Jupytext;%put name;%let定义宏变量name引用它%put将解析后的值打印到日志。%是 SAS 宏语言的关键前缀也是 jupytext 文本表示中最需要小心的字符之一。源码 magics.py 中有一个针对性处理对于octave、matlab、sas、logtalk等语言行首的%不会被误判为需要注释掉的 Jupyter magic——这正是 SAS 宏代码能在文本与 ipynb 之间逐字符往返而不损坏的根本保证。3.3 宏定义单元含重要注释/* Note when defining macros %macro cannot be the first line of text in the cell */ %macro test; data temp; set sashelp.cars; name testx; run; proc print data temp (obs10); run; %mend test; %test这个单元示范了两件事SAS 块注释.sas语言在 jupytext 中登记的注释符是/*、*/见下文第 4.1 节因此示例使用/* ... */书写说明文字宏定义的边界约束单元内明确指出定义宏时%macro不能作为单元文本的第一行——必须在前面先放一条注释。这是 SAS 内核解析文本单元的实操经验也是该示例特意保留注释的原因它确保代码单元被真正执行而不是被当作特殊指令处理。四、源码级深度解析jupytext 如何认识 SAS4.1 SAS 在语言注册表中的位置jupytext 支持的所有脚本语言集中登记在 languages.py 的_SCRIPT_EXTENSIONS字典中。SAS 的登记条目为.sas: { language: sas, comment: /*, comment_suffix: */, },这告诉 jupytext 三件事.sas扩展名对应的语言名是sas在 percent / light 等“注释式”文本格式中行注释使用/* ... */块注释。同时sas也出现在_JUPYTER_LANGUAGES列表languages.py中意味着它既可作为 notebook 的主语言也可作为单元格级 magic 语言被识别。此外 languages.py 的usual_language_name把sas规范化为SAS用于与内核声明的语言做大小写无关的等价比较。4.2 主语言判定与单元格语言default_language_from_metadata_and_ext 决定文本笔记本的主语言优先取metadata.jupytext.main_language其次取metadata.kernelspec.language最后回退到扩展名映射。SAS 与 R 一样被单独列出、直接返回原值而不做小写化——这保证kernelspec.language: sas在转换中不会被改写。当 notebook 没有设置内核时set_main_and_cell_language 会统计各单元格语言、取多数者为main_language并写入jupytext元数据确保后续其他格式的转换仍然稳定。4.3 MyST 格式的完整解析/生成流程MyST 的读写主逻辑都在 myst.py 中读取方向myst_to_notebookmyst.py用markdown-it-py配合front_matter_plugin、myst_block_plugin、myst_role_plugin解析文本 → 提取 front matter 为 notebook 元数据 → 按 token 顺序把普通 Markdown 文本 flush 为 Markdown 单元、把{code-cell}/{raw-cell}围栏块解析为代码/原始单元 → 支持分块标记承载 Markdown 单元元数据。若解析 YAML 失败会抛出MystMetadataParsingError并附带行号定位myst.py。写出方向notebook_to_mystmyst.py将 notebook 元数据经dump_yaml_blocksmyst.py压缩为 YAML 块代码单元写成{code-cell}围栏且会智能选择不少于三反引号的围栏分隔符three_backticks_or_more以避免与单元内容中的反引号冲突。当.md文件同时满足“以---开头 含{code-cell}指令”等特征时matches_mystnb 会判定其为 MyST 文本笔记本——这正是 jupytext 在打开文件时自动选择myst格式的依据。五、同源多格式对照一份 SAS Notebook 的多种文本形态仓库的 outputs 目录保存了同一份 SAS ipynb 在不同文本格式下的镜像输出是理解 jupytext 格式矩阵的最佳材料格式输出文件代码单元表示元数据表示MyST Markdownipynb_to_myst/sas.md{code-cell}围栏块顶层 YAML front matterMarkdownipynb_to_md/sas.md普通 sas 围栏块YAML front matterR Markdownipynb_to_Rmd/sas.Rmd{sas}围栏块jupyter:命名空间下的 front matterPercent 脚本ipynb_to_percent/sas.sas/* %% */单元分隔注释 块注释/* ... */块注释包裹的 YAMLHydrogen 脚本ipynb_to_hydrogen/sas.sas/* %% */分隔注释块注释包裹的 YAMLLight 脚本ipynb_to_script/sas.sas空行分隔块注释包裹的 YAML以 ipynb_to_percent/sas.sas 为例可以看到.sas语言下的“注释式”写法由于 SAS 的注释符是/*、*/来自 4.1 节的注册表jupytext 用/* %% */标记单元边界、用/* --- */ ... /* --- */包裹 YAML 元数据而%let、%put、%macro等宏代码行则完全原样保留、不做注释化处理与 3.2 节的 magic 豁免逻辑一致。六、测试如何保障 SAS 往返无损SAS 示例文件的生成与验证由镜像测试体系保障。test_mirror.py 中的test_ipynb_to_myst对所有tests/data/notebooks/inputs下的 ipynb包括ipynb_sas/sas.ipynb执行pytest.mark.requires_myst def test_ipynb_to_myst(ipynb_file, no_jupytext_version_number): assert_conversion_same_as_mirror(ipynb_file, md:myst, ipynb_to_myst)assert_conversion_same_as_mirror会做两件事一是把 ipynb 转成 MyST 文本并与outputs/ipynb_to_myst/目录下的基准文件逐字节比对二是把转换结果再读回 ipynb验证与原 notebook 等价。这两个方向共同保证“文本是 ipynb 的忠实镜像”防止新版本发布时产生无意的格式漂移。同一文件还参与test_ipynb_to_md、test_ipynb_to_Rmd、test_ipynb_to_percent等其它格式的镜像测试test_mirror.py因此 SAS 示例在多格式间的行为都被持续回归监控。七、在自己的项目中复现与使用查看示例直接阅读 sas.md 了解 MyST 文本笔记本的排版规范对照 sas.ipynb 观察两种形态的对应关系。命令行转换在已安装 jupytext 与markdown-it-py的环境中# ipynb - mystmd 文件带 {code-cell} 指令即视为 myst 格式 jupytext --to md:myst sas.ipynb -o sas.myst.md # myst - ipynb jupytext --to ipynb sas.myst.md -o sas.ipynbmd:myst中的myst是格式名myst_extensions允许.md、.myst、.mystnb、.mnb扩展名见 myst.pyMyST 格式要求环境提供markdown-it-py及三个 mdit 插件myst.py否则会抛出明确的导入错误提示。配对同步为让 ipynb 与 MyST 文本保持实时镜像可在jupytext配置中声明配对格式例如在jupytext.toml中设置formats ipynb,myst此后 Jupyter 中保存 notebook 会自动同步写两份文件文本文件的编辑也会触发 ipynb 的更新。这也是本仓库 demo 目录如demo/World population.myst.md所演示的日常工作流。八、小结通过 sas.md 这一示例可以看到jupytext 对 SAS 笔记本的 MyST 化表达已经形成完整闭环语言注册表languages.py负责识别.sas扩展名与sas内核、豁免%宏指令被误注释magics.pyMyST 模块myst.py负责 front matter、{code-cell}指令与单元格的双向解析/生成镜像测试test_mirror.py则持续验证 ipynb ↔ MyST 之间不丢失任何单元格、元数据与 SAS 宏代码。对于需要在 Git 中版本管理 SAS 分析流程、或用 Markdown 撰写可执行的 SAS 文档的团队这套文本表示提供了既适合人读、又适合机器往返的中间形态。赞分享开发工具【免费下载链接】jupytextJupyter Notebooks as Markdown Documents, Julia, Python or R scripts项目地址https://gitcode.com/gh_mirrors/ju/jupytext点击查看免费下载相关推荐Jupytext 实战将 Octave 笔记本转换为 MyST Markdown 文档Jupytext 实战将 Octave 笔记本转换为 MyST Markdown 文档 导读本文以 Jupytext 仓库中的真实转换产物 tests/da开发工具Jupytext 实战将含 Plotly 交互图表的 Notebook 转换为 MyST Markdown 轻量文档Jupytext 实战将含 Plotly 交互图表的 Notebook 转换为 MyST Markdown 轻量文档 本指南以 Jupytext 仓库中的真实开发工具Jupytext 实战将含文本、HTML、图片与错误输出的 Notebook 转换为 MyST MarkdownJupytext 实战将含文本、HTML、图片与错误输出的 Notebook 转换为 MyST Markdown 本文以 Jupytext 仓库中的真实转换产开发工具上一篇本地运行LLM的终极方案ChatMLX如何保障你的数据隐私安全下一篇Happy Island Designer数据持久化方案本地存储与图像编码的巧妙实现 ️创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考