Templater-根据标题创建目录,并在标题下创建span标签

这是一个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 %>


留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注