欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > 【非主题的方式】Typora 标题自动编号功能的实现——全网首发!

【非主题的方式】Typora 标题自动编号功能的实现——全网首发!

2025/9/21 4:49:36 来源:https://blog.csdn.net/qq_43535992/article/details/147092675  浏览:    关键词:【非主题的方式】Typora 标题自动编号功能的实现——全网首发!

文章目录

  • 先看动态图效果展示
  • 实操步骤
    • 第一步:找到 Typora 的安装位置
    • 第二步:对原文件进行备份【需要管理员权限】
    • 第三步:用管理员权限打开系统自带的记事本
    • 第四步:复制下方代码到指定位置
  • 简述原理
  • 其他方式

先看动态图效果展示

实际效果如下图,未录制按键显示,按下的快捷键就是 F5 和 F6:
可以直接影响到:大纲视图、目录、导出的PDF的序号。

在这里插入图片描述

实操步骤

这种方式的优点有:

  • 在 Typora 中使用 快捷键 F5 来实现一键自动给标题添加编号,也能处理:有些标题已有编号,但前后又新增标题的情况。
  • 在 Typora 中使用 快捷键 F6 来实现一键移除所有标题的编号。【为的是兼容那种自带 CSS 编号的主题】
  • 具体的快捷键也可以根据自己的喜好更改,但,最好不要包含 Alt 键,处理起来麻烦,因为 Typora 与大多数软件一样,都可以使用 Alt 键与其他字母组合成新的快捷键来操作菜单栏。
  • 只需要使用 Typora 就可以实现,不需要使用别的软件来辅助完成。
  • 编号都是 真实添加 的,而不是视觉上的编号。
  • 较为良好的 提示功能,添加序号、移除序号等操作都有提示。
  • 可以在未保存的情况下进行一键自动编号和移除编号,操作后,自动保存变更后的内容,不需要手动按 Ctrl + S 快捷键。【这个功能给我卡了挺长时间】
  • 与主题无关,任何主题都可以使用,但最好不要与添加了 CSS 计数器的主题联合使用,因为两个序号看着别扭,当然,你也无需担心,移除编号的功能就是为此准备的。

我的 Typora 版本信息【并且取消了软件的自动更新】:

在这里插入图片描述

第一步:找到 Typora 的安装位置

因为我们要修改安装目录下的 window.html 文件的内容。

通过右键 Typora 的图标,然后选:找到文件位置,如果找到的是快捷方式的目录,那么再右键这个快捷方式,选择:打开文件所在位置。

进入 resources 目录中,就可以看到 window.html 这个文件了。

据说 window.html 文件:正式版的 Typora 是在 resources 目录下,而试用版的是在 resources 目录下的一个名为 app 的目录下,我的不是免费版,所以不清楚。

第二步:对原文件进行备份【需要管理员权限】

需要注意:在默认的安装路径下,对 window.html 文件进行 Ctrl + C 和 Ctrl + V 操作来备份时,会提示需要管理员权限。

在这里插入图片描述

第三步:用管理员权限打开系统自带的记事本

先用管理员身份打开记事本,然后再用记事本来打开这个 window.html 文件。

因为我们要做的就是对 window.html 文件内容进行修改,如果不用管理员权限打开记事本,修改后,是无法保存的。

你可以使用别的软件来编辑,为了满足大多数人,这里就只说记事本了,只要你能向 window.html 写入内容,什么方式都可以。

第四步:复制下方代码到指定位置

先在 window.html 文件中找到下图中的位置:

其实就是在倒数第二个标签 </body> 的前面按一下回车,然后,再按 Ctrl + V 粘贴我给的代码即可。

在这里插入图片描述

复制下方完整代码,并粘贴到上图中所指的位置:

<script>
// 标题自动编号工具 - 完全适配 Typora 1.9.5
(() => {const showNotification = (message, isSuccess = true) => {const toast = document.createElement('div');toast.style = `position: fixed;top: 20px;left: 50%;transform: translateX(-50%);background: ${isSuccess ? '#4CAF50' : '#F44336'};color: white;padding: 12px 24px;border-radius: 4px;z-index: 9999;font-family: -apple-system, sans-serif;box-shadow: 0 3px 10px rgba(0,0,0,0.2);animation: fadeIn 0.3s, fadeOut 0.3s 2.7s;`;toast.textContent = message;document.body.appendChild(toast);setTimeout(() => toast.remove(), 3000);};// 添加序号功能const addNumbering = async () => {try {await window.File.saveUseNode();const mdContent = await window.File.getContent();const lines = mdContent.split('\n');const counters = [0,0,0,0,0,0];let lastLevel = 0;const processed = lines.map(line => {const match = line.match(/^(#{1,6})\s*((?:\d+\.)*)\s*(.*)/);if (!match) return line;const [_, hashes, oldNum, text] = match;const level = hashes.length;counters[level-1]++;if (level < lastLevel) counters.fill(0, level);lastLevel = level;const newNum = counters.slice(0, level).join('.');return `${hashes} ${newNum}. ${text.trim()}`;}).join('\n');if (processed !== mdContent) {window.File.reloadContent(processed);window.File.saveUseNode();showNotification('✅ 标题已自动添加序号');} else {showNotification('ℹ️ 未检测到需要添加序号的标题', false);}} catch (error) {console.error('添加序号失败:', error);showNotification('❌ 添加序号失败', false);}};// 移除序号功能const removeNumbering = async () => {try {await window.File.saveUseNode();const mdContent = await window.File.getContent();const processed = mdContent.split('\n').map(line => {// 匹配带有序号的标题(如 ## 1.2. 标题)const match = line.match(/^(#{1,6})\s*([\d.]+\.)\s*(.*)/);return match ? `${match[1]} ${match[3]}` : line; // 移除非标题行的序号}).join('\n');if (processed !== mdContent) {window.File.reloadContent(processed);window.File.saveUseNode();showNotification('✅ 标题序号已移除');} else {showNotification('ℹ️ 未检测到可移除的标题序号', false);}} catch (error) {console.error('移除序号失败:', error);showNotification('❌ 移除序号失败', false);}};// 快捷键绑定document.addEventListener('keydown', e => {if (e.key === 'F5' || e.keyCode === 116) {  // F5 添加序号e.preventDefault();addNumbering();}else if (e.key === 'F6' || e.keyCode === 117) {  // F6 移除序号e.preventDefault();removeNumbering();}});// 添加CSS动画const style = document.createElement('style');style.textContent = `@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }`;document.head.appendChild(style);console.log('📌 标题编号工具已加载\nF5: 添加标题序号\nF6: 移除标题序号');
})();
</script>

保存 window.html 文件,并关闭记事本,重启 Typora ,并测试功能是否正常。

简述原理

其实,哪有什么原理,Typora 又不是我开发的,我又没有源码,全靠在控制台 瞎猜穷举般的测试 以及一些调试技巧。

核心就是:找到那个可以获取到 markdown 文件未被渲染时的内容的 API,也就是拿到 Markdown 文件的 ”源文件“,说人话就是标题中包含井号的那种内容,因为 Typora 中,Markdown 的内容已经被渲染成 html 页面了,标题一被渲染成 h1 标签,而不是:“# 一级标题” 了。可以说只要能拿到原文,你让任何一个 AI 来写自动编号的功能,我想都是没有任何问题的。

我在测试的过程中找到的关键 api 有:

  • 获取未被渲染时的内容: window.File.getContent()
  • 将编号后的内容重新加载到 Typora 中: window.File.reloadContent()
  • 自动保存内容: window.File.saveUseNode()

遇到的坑:

  • 在调试的过程中,发现原文找到了,处理后的结果也是正确的,但就是页面的内容就是没有变化,关键就是不知道这个 reloadContent() 方法。然后自己在控制台输出 window.File 的所有内容,一个一个的看,感觉这个方法有点像,于是就去尝试,又去调试测试它的传参。可算是找到了。
  • 调用 saveUseNode() 方法来进行自动保存的时候,需要加上 await 关键字,而且需要在调用 getContent() 方法前就调用一次,否则就会出现难以描述的诡异 bug。
  • 被AI坑了,用的是 deepseek,它资料库中的 Typora 的版本还是以前的免费版。然后它还非常肯定的告诉你,你应该用某个 api ,但其实,那些 api 早就换掉了,根本就不存在,再加上内容越来越长,它出现了太多幻觉了。所以,你在使用的过程中,最好确定下版本,如果版本不一致,最好在 Typora 的控制台测试下,我提到的三个关键api是否存在。【打开 Typora 控制台的方法快捷键是:Shift + F12】

注意事项:就是需要确定你的 Typora 的版本号是否为 1.9.5,如果不是,那么就需要确保三个关键的 api 都有。如果没有这三个关键的api ,那么你就需要自己去测试你的 Typora 版本下,可以实现上述 3个功能的 api 以及对应的调用方法,替换掉代码中的位置,并进行测试。所以,在正式修改前,请务必做好备份

其他方式

聊点我的经历,想必你也会感同身受:

对 markdown文本内容进行 标题自动编号和标题编号管理 对于我来说是一个很重要的功能,尝试过多种方案来实现:

1、编写过一个静态网页工具来处理标题编号,如下图:

在这里插入图片描述

网页工具的缺点是:即使将网页固定到浏览器的标签页,但每次都要切换到浏览器中处理一次,再将处理的结果合并到原文件中,还是挺麻烦的。

2、用 Rust、golang、C 语言、python 等编程语言都写过一个工具,最终保留了 C 语言编写的 exe文件,因为它体积最小,只有 17KB,处理的速度也很快。但每次要使用标题自动编号,都需要切换到终端去操作,我的 Markdown 编辑软件主要就是 typora,也比较麻烦。如下图:

在这里插入图片描述

3、试过通过别的软件的插件来处理,比如:Obsidian,VSCode等软件的第三方插件,同样的,我写 markdown 用的主要就是 typora,操作分裂了。

4、使用过网络上能找到 教程最多的方案:也就是通过自定义主题并 使用 CSS 计数器 来实现 视觉上的编号,但,假的终究是假的。经过:用别的软件打开、复制到别的地方、导出 PDF 等操作后,就会原形毕露。不过倒是可以与前面提到的方案组合,也勉强可用。

我还为其写过一些花里胡哨的主题,如下图中的编号就是通过 CSS 计数器实现的:

在这里插入图片描述

5、还听说过 Typora 有插件可以实现,但自己未实际尝试。

6、还在 AI 的帮助下,尝试过多种向 CSS 主题文件中注入 JS 脚本的方式,也测试了挺久,依然没有成功。

自己寻找解决方法的过程中,也看到不少人需要这个功能,于是就花点时间写了下,写得不好请见谅,希望对你们有点帮助!如果需要前面提到的 html 文件或者 exe 文件等,也可以告诉我。但我平常不太会看这些账号,所以,可能会回复不及时,不过看到后都会尽量回复。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词