一日一技 | 借助 Obsidian 插件和快捷指令快速添加阅读记录
2024-6-5 11:30:10 Author: sspai.com(查看原文) 阅读量:3 收藏

利用 Obsidian 插件和快捷指令快速添加阅读记录

新点子

今年 2 月份的时候在我派发表了第一篇文章重新梳理我的阅读待办清单,到今天忙忙碌碌也读了不少文章,为了方便自己回顾和总结读过的内容,我希望能在每次阅读完成后快速形成阅读记录,主要的需求有三点:

  • 每次添加新记录时自动插入到同一个文档的最上方;
  • 每次添加新记录时自动生成「时间」「文章名称」「文章链接」;
  • 使用不同的 App 阅读时,都能获取信息并添加记录,对我来说主要是 Safari 浏览器、Reeder 和微信读书。

成果展示

经过一个下午的鼓捣,我利用 Obsidian 插件结合 macOS 快捷指令搭建了一套能快速添加阅读记录的流程。

整个添加的过程如下面的动图:

最后形成的记录如下图:

实现过程

整个实现过程可以拆解为两步:

获取文章的名称和 URL

我自己目前阅读文章时使用的 App 主要是 Safari 浏览器、Reeder 和微信读书。
从浏览器获取信息是最简单的,先从 Safari 开始。这里我借助了快捷指令直接获取网页的名称和 URL,以 Markdown 格式拼接后拷贝到剪贴板上,如下图:

Reeder 和微信读书虽然无法直接获取文章名称和 URL,但是可以分享文章的链接。于是利用快捷指令获取分享的链接并在浏览器打开,再重复执行上面的快捷指令即可,如下图:

部分网页打开速度较慢,因此需设置等待 2 秒钟之后再执行接下来的快捷指令

至此,我们已经可以从 Safari、Reeder 和微信读书拿到文章的名称和 URL,拼接成 Markdown 格式,并粘贴到剪贴板。

在 Obsidian 中添加记录

有了文章的名称和 URL 信息后,接下来就需要在文档中添加记录。

首先需要用到 Obsidian 的第一个插件:QuickAdd。这个插件的作用是在指定的文档中插入记录,并添加时间信息。

QuickAdd 插件本身有多种功能,选择「Capture To(捕获)」功能创建新的指令并命名为「Reading」具体的设置项可以参考下图:

创建完成后,每次执行这个指令时,就会在「阅读记录」文档的最上方添加一条新的记录。

第二个要用到的 Obsidian 插件是 Advanced URL。这个插件的作用是为上面添加的指令生成一个全局性的链接,以便在快捷指令中调用,将第一步和第二步串联成完成的流程。

搜索并执行 Advanced URL,就可以获取到「Reading」指令的全局链接:obsidian://advanced-uri?vault=你的仓库名称&commandid=quickadd%253Achoice%链接信息。参考下面的动图:

接下来需要在之前的快捷指令中添加打开全局链接的操作:

在最后添加「运行 Shell 脚本」操作并填入:open "全局链接"。(注意两者间有个空格)

这样就完成了全部流程的设置。

一点补充

可以为快捷指令添加全局快捷键,这样在 Safari 浏览器上阅读文章时,就不用手动点击分享按钮打开快捷指令。我是通过 raycast 来设置了全局快捷键。但是在 Reeder 或者微信读书上阅读时,仍然需要手动点击。

快捷指令中的「运行 Shell 脚本」无法将上一步的结果作为参数传递过去,因此只能先拷贝到剪贴板,再粘贴到 Obsidian 的输入框中。

dataview 的 js 代码如下,凭借我粗浅的理解加上 AI 的协助居然成功了,不得不说 AI 是人类之光:

const page = dv.page("阅读记录. md"); 
const content = await dv.io.load(page.file.path);

// 正则表达式
const regex = new RegExp(`(- (?<date>\\d{4}-\\d{2}-\\d{2}) (?<time>\\d{2}:\\d{2}) \\[(?<name>[^\\]]+)\\]\\((?<link>[^\\)]+)\\) #(?<tag>[^\\s]+))`, 'gm');

// 存储匹配结果的数组
const matchesArray = [];

// 执行匹配并收集结果
let match;
while ((match = regex.exec(content)) !== null) {const { groups: { date, time, name, link, tag} } = match;
    matchesArray.push({date, time, name, link, tag}); // 将匹配信息作为对象推入数组
}

dv.table(["date","time","name","tag","link"],
  matchesArray.sort(b => b.date,"asc")
      .map(b => [b.date, b.time,b.name, b.tag, b.link])
);

> 关注 少数派小红书,感受精彩数字生活 🍃

> 实用、好用的 正版软件,少数派为你呈现 🚀

小胡小胡0009


文章来源: https://sspai.com/post/89317
如有侵权请联系:admin#unsafe.sh