关于日记自定义日期文件名、代办任务排序、内容聚合等问题

首先感谢官方开发这么好玩、好用的产品,也感谢ob群的兄弟们。


在转战有道、为知、印象数年后,最终还是入坑Obsidian了。
入坑一周多,感觉越来越有意思,ob很多功能都可以自定义,
但因为非计算机专业人士,一些细节还是遇到了困难,特向各位大佬求助。


#问题1
描述:想实现日记文件自定义文件名,但目前核心日记插件只能实现以日期生成文件名,
经摸索,可以通过更改日期插件中的日期格式,以“日志 YYYY-MM-DD dddd”为例,实现了“日志 2022-12-18 星期日”这样的文件名,
随之而来的问题就是日记模板中调用的日期也变成了“日志 2022-12-18 星期日”,
请问:(1)怎么自定义日记文件名而不影响全局日期格式?(2)或者有没有什么方法在模板中以其他方式实现日期、时间,目前用 {YYYY-MM-DD}、 {HH:mm}、 { {HH:mm}}均不行。


#问题2

```dataviewjs
// 修改其中的标签 todo 以及修改 LOLOLO
dv.taskList(
    dv.pages("").where(t => { return t.file.name != "日记模板-备份" }).file.tasks
    .where(t => t.text.includes("") ),1)

想用以上代码实现聚合所有日记中的代办任务,已经实现上图效果,
请问:(1)怎么实现任务列表的倒序排列,最新的排列在前面,目前用的sort语句无效。


#问题3
请问:怎么实现聚合指定文档或所有文档中的某一部分内容,比如下图中,聚合所有文档中一周内的重要事项部分、今日感悟部分:

重要事项:

#重要事项

今日感悟:

#今日感悟

需要改进:

#需要改进


非常感谢各位大佬!

问题1第二问解决,代码:

{{DATE:YYYY-MM-DD HH:mm:ss dddd}}

效果:

2022-12-18 10:30:05 星期日

同蹲问题3

应该是用dataview,但我不太会用:laughing:,不知道“一周内”要怎么解决。

#问题2

```dataviewjs
dv.taskList(
    dv.pages().where(t => { return t.file.name != "日记模板-备份" }).sort(p=>p.file.name,'desc').file.tasks
    .where(t => t.text.includes("") ),1)
```

#问题3

刚好整理完善了一个标题聚合的功能

```dataviewjs
let files = dv.pages(`"文件夹"`).filter(p=>moment(Number(p.file.ctime.ts))>moment().subtract(7, 'days');).sort(p=>p.file.name)
await HeaderAggregation(files,['重要事项:','今日感悟:'])

async function HeaderAggregation(files,headers) {
    files.map(async function(file) {
        let contents = []
        for(let i in headers) {
            let content = await app.vault.readRaw(file.file.path)
            content = content.split(/#+ /).find(p=>p.startsWith(headers[i]))
            contents.push(content.slice(headers[i].length))
        }
        if(contents.every(p=>p.replace(/\s+/,'')=='')) return
        dv.header(2,file.file.name)
        contents.map((p,i)=> {
            if(p.replace(/\s+/,'')=='') return
            dv.header(3,headers[i])
            dv.paragraph(p)
        })
    })
}
```
1 个赞

Evaluation Error: SyntaxError: missing ) after argument list
at DataviewInlineApi.eval (plugin:dataview:19673:21)
at evalInContext (plugin:dataview:19674:7)
at asyncEvalInContext (plugin:dataview:19681:16)
at DataviewJSRenderer.render (plugin:dataview:19705:19)
at DataviewRefreshableRenderer.maybeRefresh (plugin:dataview:19283:22)
at t.e.tryTrigger (app://obsidian.md/app.js:1:1027924)
at t.e.trigger (app://obsidian.md/app.js:1:1027857)
at t.trigger (app://obsidian.md/app.js:1:1648741)
at DataviewPlugin.eval (plugin:dataview:20688:76)
at s (app://obsidian.md/app.js:1:692224)

谢谢回复,
运行代码报错,能给看看么

好像不小心多打了一个分号 :rofl:

```dataviewjs
let files = dv.pages(`"文件夹"`).filter(p=>moment(Number(p.file.ctime.ts))>moment().subtract(7, 'days')).sort(p=>p.file.name)
await HeaderAggregation(files,['重要事项:','今日感悟:'])

async function HeaderAggregation(files,headers) {
    files.map(async function(file) {
        let contents = []
        for(let i in headers) {
            let content = await app.vault.readRaw(file.file.path)
            content = content.split(/#+ /).find(p=>p.startsWith(headers[i]))
            contents.push(content?.slice(headers[i].length)??'')
        }
        if(contents.every(p=>p.replace(/\s+/,'')=='')) return
        dv.header(2,file.file.name)
        contents.map((p,i)=> {
            if(p.replace(/\s+/,'')=='') return
            dv.header(3,headers[i])
            dv.paragraph(p)
        })
    })
}
```
1 个赞

大佬牛逼,膜拜。

修改后确实可以了。

有两个小问题:
1、怎么按文件名倒序排列
2、怎么只筛选出里面的待办任务

非常感谢

想倒序在第 sort 函数的二个参数填 desc 就可以了
.sort(p=>p.file.name,'desc')

只筛选 task 就麻烦多了,里面的内容得重新写一遍,而不能用已经得到的内容进行加工,因为用 dv.taskList 是可以在代码生成的页面反向修改原始内容的,直接提取的话页面是写死的,相当于是少了很多功能

```dataviewjs
let files = dv.pages(`"600-日常"`).sort(p=>p.file.name)
HeaderAggregation(files,['日程安排'])

function HeaderAggregation(files,headers) {
    files.map(function(file) {
        let tasks = file.file.tasks.filter(p=>!p.completed).groupBy(p=>p.header.subpath)
        if(headers.map(p=>tasks.find(q=>q.key==p)?.rows.length??0).some(p=>p>0)) {
            dv.header(2,file.file.path)
            headers.map(p=> {
                if(!tasks.find(q=>q.key==p)?.rows) return
                dv.header(3,p)
                dv.taskList(tasks.find(q=>q.key==p).rows)
            })
        }
    })
}
```

大佬,desc实测无效

下面这段长代码获取不到内容 :joy:

请教下大佬,我和楼主同样的问题三。我是想要汇总日记文件下每篇日记的 二级标题:感悟和思考。但用你的这个代码后还是报错,想问下是什么原因:

Evaluation Error: Error: Failed to parse query in 'pagePaths': Error: 
-- PARSING FAILED --------------------------------------------------

Got the end of the input

Expected:

string

    at DataviewApi.pagePaths (plugin:dataview:19957:19)
    at DataviewApi.pages (plugin:dataview:19979:21)
    at DataviewInlineApi.pages (plugin:dataview:19444:25)
    at eval (eval at <anonymous> (plugin:dataview), <anonymous>:1:69)
    at eval (eval at <anonymous> (plugin:dataview), <anonymous>:21:4)
    at DataviewInlineApi.eval (plugin:dataview:19673:16)
    at evalInContext (plugin:dataview:19674:7)
    at asyncEvalInContext (plugin:dataview:19681:16)
    at DataviewJSRenderer.render (plugin:dataview:19705:19)
    at DataviewRefreshableRenderer.maybeRefresh (plugin:dataview:19283:22)

第一个,desc 应该是有效的,不知道你是怎么写的
第二个就不知道了是什么原因了,至少在我自己的库里是没有问题的

能看一下你修改的代码吗

我就是修改了 dv.pages("文件夹") 里面的文件夹路径为我自己的路径,然后

await HeaderAggregation(files,['重要事项:','今日感悟:'])

这里换成了我自己的标题。改成了

await HeaderAggregation(files,['感悟与思考'])

这样的,就会报错。
不过已经在论坛其他大佬的帮助下搞定了,他教的代码是这样:

```dataview
table 
    L.text as 感悟和思考, 
    L.link as 链接
from "30-Life/每日笔记"
flatten file.lists as L
where 
    !L.parent and
    meta(L.section).subpath = "感悟和思考" and
    dateformat(date(file.link), "yyyy-'W'WW") = this.file.name   
这样是没问题的

那挺好,我就是好奇这个报错是怎么来的,没见过这个报错 :rofl:,不过经过测试发现缺了第二个双引号可以触发这样的报错

感谢大佬!正好需要!不过输出可以改成表格吗?不是很懂代码,尝试修改了几次都还没达到效果,请问方便指导一下怎么修改吗?

```dataviewjs
let files = dv.pages(`"600-日常/日记"`)
HeaderAggregation(files,['日程安排','日常记录'])

async function HeaderAggregation(files,headers) {
    let d = await Promise.all(files.map(async function(file) {
        let contents = []
        for(let i in headers) {
            let content = await app.vault.readRaw(file.file.path)
            content = content.split(/^#+ /m).find(p=>p.startsWith(headers[i]))
            contents.push(content?.slice(headers[i].length)??'')
        }
        if(contents.every(p=>p.replace(/\s+/,'')=='')) return
        return [file.file.link,...contents]
    }))
    d=d.filter(p=>p)
    dv.table(['name',...headers],d)
}
```
1 个赞

成功了!感谢作者!

大佬,用了你这段代码发现一个问题
截取的内容下,如果再出现下级标题,则无法识别到了

亦即

## 重要事项
### 哈哈
真好笑
### 嘿嘿
悄悄的笑

则上述 二级标题 重要事项 下的内容,都无法提取出来

确实是这样,因为这段代码的逻辑是切分每一个标题,不管它是多少级,这会导致 重要事项 的内容到 哈哈 就停止了

```dataviewjs
let files = dv.pages(`"600-日常/日记"`)
HeaderAggregation(files,['日程安排','日常记录'])

async function HeaderAggregation(files,headers) {
    let d = await Promise.all(files.map(async function(file) {
        let contents = []
        for(let i in headers) {
            let content = await app.vault.readRaw(file.file.path)
            let header = content.match(/^#+ .*$/mg)
            if(!header) return
            header = header.map(p=>[p.split(' ')[0].length,p.slice(p.split(' ')[0].length+1)])
            content = content.split(/^#+ /m)
            let index = header.indexOf(header.find(p=>p[1]==headers[i]))
            let num = []
            for(let j =index+1;header[j]&&header[j][0]>header[index][0];j++) num.push(header[j]);
            let c = content.find(p=>p.startsWith(headers[i]))
            for(let j=0;header[index+1+j] && j<num.length;j++)
	            c+='#'.repeat(header[index+1+j][0])+' '+content.find(p=>p.startsWith(header[index+1+j][1]))
            contents.push(c?.slice(headers[i].length)??'')
        }
        if(contents.every(p=>p.replace(/\s+/,'')=='')) return
        return [file.file.link,...contents]
    }))
    d=d.filter(p=>p)
    dv.table(['name',...headers],d)
}
```

很奇怪,使用你这段代码,复制进去是正常的,可以看到已经实现了对应的内容(出现了dateview的表头)。
但是,将600-日常/日记修改为自己的目录,好像就连表头都显示不出来了
看了一下报错是这样的