如何更有效地利用“标题”来做主题管理

很多时候,我们会用 文件名 来作为搜索时候的关键字。

比如说,搜索“苹果派”,可以找到 苹果派.md 这个笔记。

但是——如果不是严格践行原子笔记的方法,将每篇笔记都拆到极小,那么很多时候并没不会给每个“主题”都专门创建单独的笔记。

比如,如果我只是有一个 想要尝试的菜谱.md 笔记,里面有 ## 苹果派 ## 千层蛋糕 等子标题……
这个情况下,我要如何更好地利用这些标题呢?

I. 搜索

在搜索/快速打开方面,我会推荐使用 Quick Switcher++ 插件的 Heading Mode 标题检索模式。

在这个模式下,它会搜索库内所有的标题。

我直接给这个搜索模式分配了默认的 Ctrl+P 快捷键:

文件名作为标题

有同学可能会问:老师,那每次搜索前我得先确定搜的是文件名还是标题,这不是很麻烦吗?

这就涉及到一个知识点——“把文件名作为一级标题”。

这样一来,每个文件名同时也是文档的最高标题,搜索框可以同时检索“文件名”和“标题”。
(这其实算是一种约定俗成的 markdown 规范)

你可以使用 Linter 插件来自动给每个文件都自动格式化成“文件名作为标题”:

我个人则是在 Templater 的模板中就自动生成同名的一级标题:

<%*
let filename = tp.file.title;
-%>
# <% filename %>

一种最简化版本的模板,在创建文件时将文件名作为一级标题

II. 嵌入

在双链笔记中,文件名的另一个作用则是:快速嵌入

例如,使用 [[苹果派]] 就可以快速嵌入一个笔记;
但如果要插入 [[菜谱#苹果派]],这样就麻烦不少——不但输入步骤变多,而且文本还变长了。

文本长度

对于文本长度,可以用 [[菜谱#苹果派|苹果派]] 来将它显示为 苹果派

这个是 wiki 链接中“显示文本”的语法,markdown 链接的格式中写成: [苹果派](菜谱#苹果派)

快速插入

但是,这样要输入更多的文字——更麻烦了。

有没有更省力的方案呢?
image

有的兄弟,有的。

我写了一个脚本,可以直接搜索所有的标题,并且用上述格式插入。

使用效果:
250709_更有效地利用标题-img-250709_130636

脚本地址:Gist: 搜索并插入标题链接

如果没法访问,也可以直接复制粘贴以下内容:

<%* 
	// const headings = allMarkdownFiles.map(file => app.metadataCache.getFileCache(file).headings).flat();
	// const userSelected = await tp.system.suggester( (item) => item.basename, headings)
	// const headings = app.metadataCache.getFileCache(app.metadataCache.getFirstLinkpathLinktarget(app.workspace.getActiveFile().path)).headings;
	
	// console.log(suggestList)

const headings = [];
const headingDict = {};

const files = app.vault.getMarkdownFiles();
files.forEach(file => {
    let headingsInNote = app.metadataCache.getFileCache(file).headings;
    if (headingsInNote) {
        headingsInNote.forEach(heading => {
            if (heading.heading){
                const headingStr = heading.heading;
                const headingDisplayText = `[#${headingStr}]  | ${file.basename}`;
                const LinkContent = `[[${file.basename}#${headingStr}|${headingStr}]]`;
                const selection = {
                    headingStr: headingDisplayText,
                    LinkContent: LinkContent
                }
                // console.log(headingStr);
                headingDict[headingDisplayText] = LinkContent;
                headings.push(selection);
            }
        });
        // headings.concat(app.metadataCache.getFileCache(file).headings);
        // console.log(app.metadataCache.getFileCache(file).headings);
    };
});

const userSelected = await tp.system.suggester( (item) => item.headingStr, headings)
console.log(userSelected);

tR += userSelected ? userSelected.LinkContent : "";

%>

(保存到自己的库里,后缀名用 .md,然后用 Templater 模板调用该脚本)

结语

这篇文章分享了2个插件(Quick Switcher ++ 快速检索、Linter 格式化)和1个脚本。

但是,除了工具层面,更主要的是分享我自己对于“标题”的用法。

我自己的笔记工作流中,通常会将一个“主题”先记录在特定的汇总页面中,例如我有一个“插件记录”的笔记,会将看到的一些有趣的插件先作为标题记录下来:

如果这个插件足够有趣或者有用,我才会给它单独开一个专题笔记:

这是我管理“小主题”和“专题”的方式,而在这篇文章介绍的“将标题作为子文件名使用”工作流中,我可以自由地在不同主题之间浏览,而不需要在意它是否是单独文件。

希望这个分享能对你们有所帮助。

1 个赞

不谋而合的管理方式。就我个人而言,这种管理方式兼备了卡片式管理和PARA的优点,并很大程度上消解了缺点。

我目前采用“树-枝-叶-种子”的方式来管理。

  • 我习惯把关于某个大主题的一篇长文档称为““,与之链接的更低级别的文档称为”“,里面的各级小标题称为”“;只有当某个小标题内容足够多才将之单独建一个文档(从”叶“到”枝“)
  • 定期修改和回顾文档(我称之为“剪枝”):我使用Dataview监控每一个”“的修改时间,加上书签标记具体要修改和回顾的“”或“
  • 新内容:在inbox.md中需要合并到已有文档的内容称之为“新枝”或者“新叶”,它们会成为一个新文档(“新枝”)或者新标题(“新叶”)的内容
  • 感兴趣的领域:在平时阅读中遇到感兴趣的领域我会标记为“种子”,它们可能会因精力、时间方面的原因会被放弃或者进一步了解。如果有被进一步了解,那么“种子”就会变成“新枝”或者“新叶”。
2 个赞

好恰当的比喻,学习到了