DEVONthink 社区已经有十几年历史,那些比较有名气的脚本,往往都经过了无数高手的修改,而且通常来自工作流复杂的学术领域,导致一般人既看不懂,也用不上。这导致许多对 DEVONthink 感兴趣的人望洋兴叹。
我自己也编写过不少脚本,一般的做法同样是写完直接打包,别人要改也可以,但后果我可不能保证。但这和我写文章的初衷并不相符,我无意创造无人能理解的黑箱(black box),只是 DEVONthink 确实缺少一个简明的脚本例子。
近日整理旧数据库时,翻出不少老文章,我无意深入处理,径直写了一个导出文章清单的脚本,忽然福至心灵——这就是我要的简单例子,同时也很实用。在下面的文章中,我将通过导出文章清单的例子,谈谈 DEVONthink 脚本的入门。
如何导出文章清单的脚本
导出阅读清单功能简单,但可四两拨千斤。有时候,别人问我一个没有标准答案的问题,与其表演左右互搏人格分裂——往往还会讲错——不如直接给出参考文件,让他自己判断;另外,我自己也会经常制作文章阅读清单,就像给图书编目一样,方便以后回溯查询,从之前停下之处捡起。
从浏览器中直接导出阅读清单的方法,可见前作《用 Shortcuts 导出 Safari 网页》。不过,习惯良好的读者,可能已经把值得读的内容剪藏到本地,此时则可以用 DEVONthink 统一管理,并且用脚本方便地导出阅读清单。1
DEVONthink 脚本以苹果官方自动化语言 AppleScript 写成,运行方式多样,包括直接运行脚本文件、使用 Smart Rules 自动化以及配合第三方软件。后两者涉及较复杂的触发场景,这里我只介绍第一种,即直接在 DEVONthink 内部运行,先不涉及改动脚本本身——如果你确实没有需要,完全可以不理会后文涉及脚本修改的部分,先看看怎么用就行。
在右键菜单中运行脚本
DEVONthink 自带的脚本运行功能,也包括菜单栏、右键菜单、工具栏等多种方式,就和 Chrome 一样,四处都可以装插件。初次使用者为避免混乱,建议直接把脚本置入右键菜单文件夹(右键菜单的标准名称应当是“上下文菜单”,Contextual Menu),即下面的路径:
~/Library/Application Scripts/com.devon-technologies.think3/Contextual Menu
随后,即可在右键菜单的“Scripts”选项下看到您添加的脚本(图中为“dt Markdown Link List”,意为从 DEVONthink 中导出 Markdown 格式的链接列表)。一般情况下,选中一系列文章文件,然后在右键菜单中运行脚本,就可以把 Markdown 格式的阅读清单拷贝到剪贴板了。
在工具栏中运行脚本
不过,DEVONthink 自己的功能就多如一间军火库,再塞一个脚本进去——何况还是塞在二级菜单——可能并不便于使用。这时候可以考虑一下其他位置,如果您喜欢直接也光标点选,那么工具栏(Toolbar)正对胃口。和前一节类似,脚本可以放到下面的路径:
~/Library/Application Scripts/com.devon-technologies.think3/Toolbar
随后在顶部工具栏的空白处点一下右键,选择“Customize Toolbar…”,就可以看到刚刚添加的脚本。把它拖到工具栏上,就能看到一个脚本文件形状的按钮。以后选中文件并点击该按钮,就能从所选文件中导出阅读清单。
在菜单栏中运行脚本,以及绑定快捷键
前两节的方法适合脚本不多的读者,而一旦掌握基本用法就难免忍不住攒一堆脚本,正如 Chrome 用户刚开始也难以抵抗收集实用插件。到了这个阶段,菜单栏就是更合适的脚本管理所在。菜单栏文件夹和右键菜单文件夹、工具栏文件夹并列,但它下面还有十几个子文件夹,一看便知,这是用于分类管理大量脚本。DEVONthink 官方已经往这些子文件夹里塞了一些脚本,我们也可以往里面任意丢脚本,就像装插件一样。脚本文件具体放到哪个子文件夹并不要紧,只要你自己日后能找到就行,我一般把这些导出数据的脚本放到“Export”文件夹中。
/Users/Min/Library/Application Scripts/com.devon-technologies.think3/Menu/Export
和之前类似,稍等几秒,DEVONthink 的菜单栏中就会出现导出阅读清单的脚本(不行就重启 DEVONthink :-P),可假如只是在菜单栏中运行,那与使用右键菜单不过与朝三暮四,并未得菜单栏的真正滋味。菜单栏的强项,其实是进一步绑定快捷键。绑快捷键不需要任何新工具,直奔系统设置即可:在键盘的快捷键(Keyboard Shortcut…)设置中,添加一个“App Shortcuts”,将“Application”设置为“DEVONthink 3”,要启用的菜单栏选项为你安装的脚本名,快捷键随君喜好。
设置完成后,就可以通过快捷键运行脚本,免去鼠标拖来点去。
如何用脚本处理选中的文件
所谓脚本(Script),起源于戏剧,而戏剧脚本恰恰是最简单易懂的体裁,通常是“某人在某个地方做了某事”的句式,清晰明了,远比小说和散文易懂。这么一想,其实脚本一点都不值得畏惧,不过就是指挥 DEVONthink 做这个、做那个而已。
而这个下命令的过程,首先要确定对象,也就是哪些文件。在 DEVONthink,你可以指定处理某个文件、某个文件夹中的文件,更复杂的还有处理符合条件的一组文件,但本文不会把事情弄得那么复杂。我们来看看怎么处理当前选中的文件。
处理当前选中的文件属于最寻常的操作,比如在 Finder 中,选中任意文件后都可以在右键菜单中看到相应自动化操作,而在 DEVONthink,同样可以选中一系列文件后再执行自动化脚本。前述大白话可以转写为下面的脚本。
tell application id "DNtp"
repeat with r in selected records
这里是你的脚本
end repeat
end tell
以上脚本的意思是,召唤 DEVONthink,对于当前选中的所有文件,执行既定的操作。在导出阅读清单的脚本中,我们就是从每一个选中的文件中取出文章名和链接数据,然后拼接成 Markdown 列表格式。
如何自定义需要的文章数据
在前面的例子中,我们只是简单从 DEVONthink 提取文章标题和链接,而 DEVONthink 还有丰富的元数据(Metadata),包括作者、日期、标签或者自定义元数据,等等。我在命名文件时就会带上作者和发布日期,一般也用不到更多的文件信息,下面用创建日期做个例子,演示如何导出带阅读日期的文章列表。2
我们首先增加一行 set dateList to {}
,用于存储接下来获取的日期数据;然后在 repeat
部分再加一行 set the end of dateList to (creation date of this_record as string)
;最后,在生成列表项目的地方调整一下,把刚刚获取的日期插入进去、放到每一行的开头,就完成了新脚本。
其中最重要的是 creation date of this_record as string
,它用于从文件中获取创建日期相关信息,而“creation date”是 DEVONthink 内置的属性,类似属性还包括文件的大小、文件类型、字数、作者、地点等等,大大小小几十项,这还不包括 DEVONthink Pro 用户可以自己随意设置的 custom metadata。3
修改后的完整脚本如下:
set dateList to {}
set urlList to {}
set nameList to {}
set mdlinkList to {}
tell application "DEVONthink 3"
set theSelection to the selected records
repeat with this_record in theSelection
set the end of dateList to (creation date of this_record as string)
set the end of urlList to (URL of this_record as string)
set the end of nameList to (name of this_record as string)
end repeat
end tell
repeat with t from 1 to the count of nameList
set the end of mdlinkList to ("- " & (item t of dateList) & ": [" & (item t of nameList) & "](" & (item t of urlList) & ")")
end repeat
set old_delim to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
set mdlinkList to ("
" & mdlinkList) as text
set AppleScript's text item delimiters to old_delim
set the clipboard to mdlinkList
再运行一下,就可以获得附带创建日期的文章阅读清单。如果想做个阅读记录备份,看看自己在哪年哪月读了什么文章,这是一个切入的方向。
小结
阅读清单是一件小事,但见微知著,简单到功能恰好涉及到 DEVONthink 最基础的脚本知识,也是入门 DEVONthink 的一个门径。
如有必要,也可以用 DEVONthink 做文献管理,把各项元数据排列组合,一次性导出符合规范的引文。当然,常读英文文献的人完全用不着这么折腾,Zotero 更合适;而需要读中文文献的人,鉴于目前似乎没有太合适的管理工具——即便有,要同时满足国标和各学校自创的格式,似乎也太难为开发者了——这时候,或许真的要考虑 DEVONthink。
我自己真正的用途自然不是用 DEVONthink 管理文献,而是把它作为一个数据库,而通过组合各项元数据,很容易就可以导出类似图书馆书目的索引信息,无需打开 DEVONthink 就可以一览乃至初步检索“馆藏”——尤其在移动设备上——这是另一个话题,而本文的技术是其基础。
🛍 我撰写的付费栏目《信息管理,文件为本位的方案》正在 UNTAG 售卖,对本文话题有进一步讨论,欢迎选购。
- 前提显然是文件已经带有 URL 元数据。一般从 Safari 中直接保存的网页以及用 DEVONthink 剪藏的网页都会带有这一数据。如果没有,也可以在 DEVONthink 的属性界面中手动添加 URL 信息。这里也有自动化的可能,我暂未来得及撰文,有兴趣的读者可以直接找我交流。 ↩
- 我在《用 DEVONthink 批量翻译外文 RSS 标题》中曾用 custom metadata 存储翻译后的文本。 ↩
- 写论文的读者估计知道,引用一个网页时应当带上浏览的时间,而对于剪藏到 DEVONthink 的网页而言,添加时间刚好就是阅读时间。当然,当然,Zotero 可以并更适合完成这事,这里只是用 DEVONthink 举个例子。 ↩