快速创建同级或次级标题的脚本
本文档由 PKMer 论坛导入
- 作者: Moy
- 原始链接: 快速创建同级或次级标题的脚本
痛点
当你在写一篇长文档的时候,如果这篇文档涉及到比较多的标题层级,层层嵌套…… 那在创建新标题的时候可能遇到一个问题:接下去是几级标题了?
(前文)
#### 四级标题
(文本)
### 三级标题
(文本)
#### 四级标题
(文本)
*⬇️这里要插入同级别的新标题,应该创建几级标题呢?*
这时候有两种办法:
- 翻到前面的标题,数一下是几级,然后创建相同层级的标题
- 直接用脚本创建和前一个标题相同层级的新标题
这篇分享就是介绍的第二种办法。
效果

解释一下:我用 si+空格 作为「插入同层级标题」的触发文本,用 su+空格 作为「插入次级标题」的触发文本。
这是为了避免中断打字输入过程的最快的方式。
这种情况下,你不需要知道自己现在在具体哪个级别的标题,你只需要知道要创建相同层级还是子级标题就可以了,剩下的脚本会帮你搞定。
为什么是 si 和 su
si是sibling(兄弟)的简写,代表相同级别;
su是sub(下级)的简写,代表次级标题。
其实你也可以用中文,比如同级标题+空格和子级标题+空格,看你习惯。
实现方案
分为两个部分,一个是基础部分:功能脚本。 另一个是进阶部分:快速触发。
功能脚本 🌶️
功能脚本就是一串 JS 代码,如下:
const offset = 0;
/* ⬆️ 修改这里的数字来实现不同层级的标题
- 同级标题 填 0
- 次级标题 填 1
- 父级标题 填 -1
*/
const lines = app.workspace.activeLeaf.view.editor.getCursor().line
const content = tp.file.content.split('\n').slice(0, lines).join('\n')
const headings = content.match(/^#+ \S/mg)
const prevHeaderLevel = headings.pop().match(/^(#+)/)[1].length
const targetHeaderLevel = prevHeaderLevel+offset;
// NEW: Use command to set heading
const commandName = `editor:set-heading-${targetHeaderLevel}`
const command = app.commands.commands[commandName];
if (command) {
app.commands.executeCommandById(commandName);
} else {
new Notice(`${targetHeaderLevel} 级标题不存在,无法插入`);
}
简单来说,它会获取到你光标的位置,并且向前找到最近的一个标题行,数一下前一个标题是什么层级,然后基于它算出接下来应该插入什么层级的标题。
offset 是指层级的增减,默认 0 就是同层级,前面是三级标题就插入相同的三级标题。
改成 1 就是更小的层级,前面是三级标题就插入四级标题,以此类推。
调用脚本
调用脚本的方式,常见的有 Templater 插件和 NoteToolbar 插件。 可以选一个喜欢的,把它注册成命令。这里不再赘述。
(实在不会的话可以回帖问……)
快速触发 🌶️🌶️
当你把脚本注册成命令之后,就可以通过命令面板来执行。
有一些简化的方案,比如放进 EditingToolbar 或者 NoteToolbar 插件的工具栏中,点击触发。 但我更喜欢的还是在打字的过程中可以直接触发,所以选择 LatexSuite 插件。
虽然这个插件名字叫 Latex,但是我从来不用它输入数学公式……
它的作用是可以用特定文字来触发命令。
具体介绍可以看: 快速编辑的魔法——OB内的文本指令 - 知识管理工具 / 笔记软件 - PKMer
我这边直接放配置代码:
// 常用标题层级的快捷输入
{trigger: "sup ", replacement: () => {
app.commands.executeCommandById("templater-obsidian:_global/templates/snippets/父级标题 sup heading.md");
return "";
}, options: "tA"},
{trigger: "su ", replacement: () => {
app.commands.executeCommandById("templater-obsidian:_global/templates/snippets/次级标题 sub heading.md");
return "";
}, options: "tA"},
{trigger: "si ", replacement: () => {
app.commands.executeCommandById("templater-obsidian:_global/templates/snippets/同级标题 sib heading.md");
return "";
}, options: "tA"},
替换 trigger 中的文本就可以修改成你喜欢的触发文本。
后面的 excuteCommandById 中的参数换成你注册的命令的 ID,具体怎么查找在上面的文章中也有说明。
总结
本文介绍了一个在Obsidian中快速创建标题的自动化解决方案,主要解决在长文档编写过程中需要频繁创建同级或次级标题时,不确定标题层级的痛点。
实现方案:
- 功能脚本:核心JS代码,通过正则表达式匹配前面的标题并计算目标层级
- 快速触发:结合LatexSuite插件实现文本触发,使用文本指令快速创建同级标题
优势:
- 无需中断打字流程,输入触发文本即可
- 不需要记忆当前标题层级,只需知道创建同级还是子级
以上,感谢收看。
讨论
若阁下有独到的见解或新颖的想法,诚邀您在文章下方留言,与大家共同探讨。