使用 Dataview 读取文件中所有标题

最近想要在Dataview中读取文件下的所有标题。发现论坛历史上很多人有需求但没有解决方案,因此我通过JavaScript自己实现了一个简单的视图程序。

const fs = require('fs');
const path = require('path');
const viewBox = dv.el("div","",{cls:"card"});

[...
    fs.readFileSync(path.join(app.vault.adapter.basePath, dv.current().file.path), 'utf8')
    .matchAll(/^#+ (.*$)/gm)
    .map(group => group[1])
].forEach(title => {
    viewBox.appendChild(dv.el("div",`[[${dv.current().file.name}#${title}]]`));
});

1 个赞

挺好的,你也可以试试帖子“DataviewJS 的提取与汇总”里面的方法,那个不用正则匹配和 Node.js。为渲染为代码块方便复制,每行前面多了四个空格,想要直接显示可以调整代码。

非常棒 :+1: 但有个报错,是不是复制错了,[].map(group => group[1]).forEach() 应当这样,map应写在[]和foreach中间,不然会报错Evaluation Error: TypeError: fs.readFileSync.matchAll.map is not a function or its return value is not iterable

应该是哪里复制错了,在我的Obsidian中测试没有出现问题。

一个需要注意的地方是方括号中的三个点,它表示列表解引用运算符,可以将一个迭代器转换为一组逗号分隔的数据。

这就奇怪了,matchAll返回是一个迭代对象,不是数组,后面怎么可以用map直接遍历呢?应该用[…]转换为数组后才能用map遍历才对。

map遍历的就是可迭代对象啊。 Iterator.prototype.map

事实上这个程序全程都不需要转换成数组,用了一次解析引用运算还是因为我测试时方便查看的。

const fs = require('fs');
const path = require('path');
const viewBox = dv.el("div","",{cls:"card"});

fs.readFileSync(path.join(app.vault.adapter.basePath, dv.current().file.path), 'utf8')
    .matchAll(/^#+ (.*$)/gm)
    .map(group => group[1])
    .forEach(title => {
        viewBox.appendChild(dv.el("div",`[[${dv.current().file.name}#${title}]]`));
    });

这就不知道了,我的版本是1.6.3,报错如下

1122556688

而且matchAll后面直接用map都是报错的

可能版本问题,迭代器的map新版ob才支持。

想了一下,可能是dataview的JavaScript运行时版本问题。

dataview在插件内部维护了一个独立的node运行时,我的node版本是v20.14.0

我这边 OB 版本 1.6.6,Dataview 版本 0.5.67
默认也会有和你一样的报错,按照你的方法改完之后正常

感谢,我ob1.6.3, dataview0.5.67

打印node和v8版本分别是(无论在dataviewjs中还是ob控制台版本都一样)

Node.js版本: v18.15.0
V8引擎版本: 11.4.183.29-electron.0
Electron Version: 25.8.1
Chrome Version: 114.0.5735.289

console.log("Node.js版本:", process.version);
console.log("V8引擎版本:", process.versions.v8);
console.log('Electron Version:', process.versions.electron);
console.log('Chrome Version:', process.versions.chrome);

不知道是否和nodejs或v8引擎版本有关,另外,ob的Node.js版本和电脑安装的nodejs版本无关,我电脑安装的nodesj版本是v20.11.1

根据我上面对Obsidian Electron版本的打印可知

Electron Version: 25.8.1的chromium版本是114.0.5735.289

参考: electronv25.8.1

而,Iterator.prototype.map() Chrome122才支持,可能是这个原因吧

参考: Iterator.prototype.map

1 个赞