非计算机专业,研究 Ob 学习,卡在不知道 this.file、this. 具体指什么,代码发出来更多供测试,期待交流建议。
Ob“重命名当前小标题”命令无法做到的这个也无法做到。
比如同文档同名标题,引用时可以采用类似路径的格式做到区分,
见【已解决】为什么引用文档内的同名标题永远显示第一个 #3,
但重命名希望同步更新反向链接时,使用 Ob 内置“重命名当前小标题”命令无法区分,见下:
→
测试结果能看到 Ob 内置的命令修改的是同文档同名二级标题的引用。
基本配置参 QuickAdd JS & Templater JS 简介及相互修改“QuickAdd Capture 加载内部代码”。
效果 GIF,点击展开
原理同 QuickAdd 正则保值替换选单,
对鼠标选区内小标题使用 JS 方法 .replace()
正则查找替换,
选区需覆盖标题前 # 号。全文替换 Ctrl A 全选即可。
预填了一个格式化序号便于调试。实际使用多半用来批量改错别字。
第一个填空输入希望作用的标题级别或级别范围。第二个输入正则。第三个输入替换函数。
js quickadd 代码
let rgx = '/.*/', form = '`$&-${i+1}`'; const prompt = (str, holder, value)=> this.quickAddApi.inputPrompt(str, holder, value)
, { editor: Editor, file } = app.workspace.activeEditor, lv = await prompt('级别', '1-6', '1-6')
, confirm = async file=> { let r = []
, repChan = (raw, isRef)=> { chans.map(chan=> {
let rgx = new RegExp(isRef ? `\\[\\[.+?#${chan[0]}.*?]]` : `^#{${chan[2]}} ${chan[0]}$`, 'gm')
raw = raw.replace(rgx, m=> m.replace(chan[0], chan[1])) }); return raw }, test = chans[0].heading
do { rgx = await prompt(`正则`, rgx, rgx); if (!rgx) return; form = await prompt(`替换`, form, form) } while (!form)
if (await this.quickAddApi.yesNoPrompt(test, [test].map((p, i)=> test.replace(eval(rgx), eval(form))))) {
chans = chans.filter(p=> p.level >= lv.slice(0, 1) && p.level <= lv.slice(-1))
.map((p, i)=> [p.heading, p.heading.replace(eval(rgx), eval(form)), p.level])
app.fileManager.iterateAllRefs((rPath, rbj)=> {
if (app.metadataCache.getFirstLinkpathDest(rbj.link.split('#')[0], rPath)?.path == file.path) r.includes(rPath) || r.push(rPath)
}); r.map(async rPath=> await app.vault.process(app.vault.getAbstractFileByPath(rPath), raw=> repChan(raw, 1)))
setTimeout(()=> Editor.replaceSelection(repChan(Editor.getSelection(), 0)), 50)
} else confirm(file)
}, hds = app.metadataCache.getFileCache(file).headings; if (!hds) return; let chans = hds.filter(hd=>
hd.position.end.line >= Editor.getCursor('from').line && hd.position.end.line <= Editor.getCursor('to').line
); if (!chans[0]) { new Notice('无选中', 1000); return }; confirm(file)
用了一个应该不在 Obsidian Docs 里的 API,对应解释是根据返回结果猜测的:
app.fileManager.iterateAllRefs((参数1, 参数2)=> )
这个 API 似乎找到的是全库全部出链 outlinks。
参数 1 代表出链文本所在文档的路径,如上文中文档“Wiki”的路径。
参数 2 代表一个对象,包含这个出链文本和所在编辑器位置等信息。