这是一个Templater插件的模板,用途是根据笔记的标题创建目录,并且在标题的下面创建一个<span>
标签,id
为标题内容。因为我是使用插件将Obsidian的笔记上传到WordPress上的,所以创建目录就比较的繁琐,标题的链接要使用URL编码处理过,并且为了能实现点击后跳转的效果,给每个标题下面增加了一个id为标题内容的<span>
标签。
具体内容如下:
<%*
// let content = await tp.file.content;
// const cleanedData = content.replace(/^<span id="(.+?)"><\/span>$\r?\n?/gm, '');
// var file = app.workspace.activeLeaf.view.file;
// await app.vault.modify(file, cleanedData);
// 获取当前文件
const activeFile = await this.app.workspace.getActiveFile();
const mdCache = await this.app.metadataCache.getFileCache(activeFile);
const editor = this.app.workspace.activeLeaf.view.editor;
const lineCount = editor.lineCount();
// 生成目录
let toc = "***\n";
let createLineCount = 0
if (mdCache && mdCache.headings) {
// 找到最小标题级别作为基准
const minLevel = Math.min(...mdCache.headings.map(item => item.level));
mdCache.headings.forEach(item => {
const headerText = item.heading;
const headerLevel = item.level;
// 对标题文本进行URL编码
const encodedText = encodeURIComponent(headerText);
// 生成目录项,使用空格缩进(每个级别2个空格,更符合Markdown习惯)
// 计算相对于最小级别的缩进级别
const indentLevel = headerLevel - minLevel;
const indent = ' '.repeat(indentLevel*4);
toc += `> ${indent}- [${headerText}](#${encodedText})\n`;
//插入<span>标签
// console.log(item.position.start.line, "---", item.position.end.line, "---", createLineCount);
// 生成span标签内容
const spanLine = `<span id="${headerText}"></span>`;
// 因为标题读取的是metadataCache,是缓存,而增加span标签是直接在笔记内操作的,所以行数会对不上,要额外计算span增加导致的行数变动。
// 获取标题所在行数的下一行 = 缓存中标题所在行数+前面增加过的span标签次数
const headerLine = item.position.start.line + createLineCount;
// const nextText = editor.getLine(headerLine + 1);
// console.log(nextText);
// if (nextText.match(/^<span id="(.+?)"><\/span>$/)) {
// editor.setLine(headerLine + 1, spanLine)
// } else {
// // editor.replaceRange(`${spanLine}\n`,
// // { line: headerLine, ch: 0 }
// // )
// editor.setLine(headerLine + 1, `${spanLine}\n${nextText}`)
// createLineCount++;
// }
// 从标题行开始向后搜索,跳过空行,寻找span标签
let foundSpanLine = -1;
for (let i = headerLine + 1; i < lineCount; i++) {
const currentLine = editor.getLine(i);
// 如果遇到非空行且不是span标签,就停止搜索
if (currentLine.trim() !== '' && !currentLine.match(/^<span id=\"(.+?)\"><\/span>$/)) {
break;
}
// 如果找到span标签,记录行号
if (currentLine.match(/^<span id=\"(.+?)\"><\/span>$/)) {
foundSpanLine = i;
break;
}
}
if (foundSpanLine !== -1) {
// 找到span标签,更新它
editor.setLine(foundSpanLine, spanLine);
} else {
// 没有找到span标签,在标题下一行插入
const nextText = editor.getLine(headerLine + 1);
editor.setLine(headerLine + 1, `${spanLine}\n${nextText}`)
createLineCount++;
}
});
toc += "\n***"
}
%>
<% toc %>