- 不是只汇总图片,是汇总文本,且正常显示图片
- 解决 DataviewJS 本地图片裂图痛点
- 支持 MD、Wiki 两种链接
- 支持最短、相对、绝对三种链接类型
- 支持不同路径同名同后缀(但请尽量不要有类似情况)
- 支持图片名含空格含英文括号(但请尽量不要有类似情况)
- 保留原文图片大小
- 图片同行可有其他内容,包括双链
非计算机专业,写了一周,希望有大佬能多多交流建议,争取能有更简洁的代码。
折叠三角可点击展开,点击图片或右键 - 打开图片查看大图。
档 1 文本
---
档: 1号
---
其他内容1
## 任务一
同行混排测试 ![|120](<同名同后缀( )含.jpg>) 同行文本 ![](文件目录/测.试.png) [引用](引用) ![[../测.试.png]]
中间内容测试。
别名测试 ![别名|140](<../其他路径/同名同后缀( )含.jpg>)
### 三级标题
1号内容
档 2 文本
---
档: 2号
---
其他内容2
## 任务一
同行混排测试 ![[同名同后缀( )含.jpg|120]] 同行文本 ![[文件目录/测.试.png]] [[引用|引用]] ![](../测.试.png)
中间内容测试。
别名测试 ![[../其他路径/同名同后缀( )含.jpg|别名|140]]
### 三级标题
2号内容
汇总各文档全文
要点:比对原文与文档出链元数据,从元数据中获取完整路径返还到原文。
代码
let files = dv.pages(`"文件目录"`)
let rg1 = /!\[(?!\[).*?\]\((?!<?http:|<?https:|<?file:)(.+?\.[a-zA-Z]{3,4})\>?\)|!\[\[(.+?\.[a-zA-Z]{3,4})\|?.*?\]\]/g
function extract(str) { let r = []; str.replace(rg1, (m, p1, p2)=> {r.push(p1||p2)}); return r[0] }
files.map(async p=> {
let y = app.metadataCache.getFileCache(app.vault.getAbstractFileByPath(p.file.path)).frontmatterPosition
let A = ( await app.vault.readRaw(p.file.path) ).split('\n') // 分块
if (y) A.splice(y.start.line, y.end.line-y.start.line+1) // 去掉 YAML
let mats = []; A.map(a=> { for (m of a.matchAll(rg1)) mats.push(m[0]) })
let B = p.file.outlinks.filter(p=> p.embed && !/\.md$/.test(p.path))
B.map(b=> { let path = b.path.split('/'); let dis = /.*?(?:\|)?(.*?)(?:\|)?(\d+)$/.exec(b.display);
let src = encodeURI(`file:${app.vault.adapter.basePath}/${b.path}`);
mats.map(m=> { let e = extract(m);
let boo = e.replace( /\.\// ).includes('/') ? e.endsWith(path.slice(-2).join('/')) : e.endsWith(path.slice(-1))
A = A.map(a=> a.replace(m, ()=> {
if (boo) { return dis ? `<img width='${dis[2]}' src='${src}'>` : `<img src='${src}'>` } else { return m }
}))})}); dv.paragraph(`##### ${p.file.link}\n${A.join('\n')}`) // 合块、输出
})
- JS 方法:
.replace()
、.push()
、.map()
、.split()
、.splice()
、.matchAll()
、.filter()
、.test()
、.exec()
、.includes()
、.endsWith()
、.slice()
、.join()
- Ob API:
app.metadataCache.getFileCache()
、app.vault.getAbstractFileByPath()
、app.vault.readRaw()
汇总标题下内容
以汇总二级标题“任务一”为例。要点:
- 若文档中无标题(
!fc
),则return
,不再进行后续步骤。 - 截取该索引和下一索引间内容,如果该索引为最后一个,截取至末。
对比“汇总各文档全文”可发现,其实只有截取部分不同,其余是完全一致的。 - 虽然观念上三、四…级标题比二级标题“小”,但级数 3、4…是大于 2 的。
代码
let term = '任务一'; dv.header(2, `汇总 ${term}`)
let files = dv.pages(`"文件目录"`)
let rg1 = /!\[(?!\[).*?\]\((?!<?http:|<?https:|<?file:)(.+?\.[a-zA-Z]{3,4})\>?\)|!\[\[(.+?\.[a-zA-Z]{3,4})\|?.*?\]\]/g
function extract(str) { let r = []; str.replace(rg1, (m, p1, p2)=> {r.push(p1||p2)}); return r[0] }
files.map(async p=> {
let fc = app.metadataCache.getFileCache(app.vault.getAbstractFileByPath(p.file.path)).headings
if (!fc) return; let i = fc.findIndex(p=> p.level == 2 && p.heading == term) // 获取二级且等于 term 的索引
let j = i+1; while (fc[j]?.level > 2) j++ // fc[j]存在且级数大于二跳到下个索引
let A = ( await app.vault.readRaw(p.file.path) ).split('\n') // 分块
A = fc[j] ? A.slice(fc[i].position.end.line+1, fc[j].position.end.line) : A.slice(fc[i].position.end.line+1) // 截取
let mats = []; A.map(a=> { for (m of a.matchAll(rg1)) mats.push(m[0]) })
let B = p.file.outlinks.filter(p=> p.embed && !/\.md$/.test(p.path))
B.map(b=> { let path = b.path.split('/'); let dis = /.*?(?:\|)?(.*?)(?:\|)?(\d+)$/.exec(b.display);
let src = encodeURI(`file:${app.vault.adapter.basePath}/${b.path}`);
mats.map(m=> { let e = extract(m);
let boo = e.replace( /\.\// ).includes('/') ? e.endsWith(path.slice(-2).join('/')) : e.endsWith(path.slice(-1))
A = A.map(a=> a.replace(m, ()=> {
if (boo) { return dis ? `<img width='${dis[2]}' src='${src}'>` : `<img src='${src}'>` } else { return m }
}))})}); dv.paragraph(`##### ${p.file.link}\n${A.join('\n')}`) // 合块、输出
})
当然,你可以通过不同的条件判断自由选择截取范围。
你也可以在 .findIndex()
中用 .startsWith()
、.includes()
等多种方法,选择以特定字符开头或包含特定字符的标题下内容,等等。
相关:dataview图片显示问题;怎么在dataview生成的表格里添加正文指定标题里的内容?;Dataviewjs的奇技淫巧 #115
- 注意:连续纯图指图片间无其他内容,包括仅有换行符的情况。
为省空间,默认连续纯图并排显示,可自行修改代码或配合其他方式自行调整。 - 代码中的
rg1
在 MD 和 Wiki 格式基础上匹配中间或末尾.
+ 3~4 个英文字符,若遇其他形式的后缀可自行更改。
遇任何问题,请使用最新代码,先电脑端使用本话题提供的示例档沙箱测试(图片换成自己的),尝试刷新代码块或重启 Ob。错误报告请参 论坛发帖指导2023“求助反馈不重不漏自查表”,提供必要信息。
本话题主要提供方法,表格输出可参 #3,其余不一一列举。若理解困难,可依 DataviewJS 小白手册 中“小白入门 DataviewJS 方法”,先掌握基础。额外需求仍请另建话题。
了解更多: