小玩 Apple Script

forsil
forsil
Dec 29, 2016 · 7 min read

我之前一直想要在 Alfred 中搜索 DEVONthink Pro Office(缩写:DTPO). DTPO 自身有一个系统服务可以用来查询,但是 Alfred 无法直接调用服务( LaunchBar 倒是可以直接调用服务)。不过欣喜的是 DTPO 有着非常强大的脚本功能,可以通过 Apple Script 来脚本化实现在 Alfred 中搜索资料库(Database)。

最终效果:

Alfred Workflow:

最终代码:

on run
tell application "DEVONthink Pro"
try
launch
set itemList to search "{query}"
set theLength to the length of itemList
if theLength = 0 then
return ""
else
set aitems to ""
set acount to 0
repeat with i in itemList
set auid to the uuid of i
set atitle to the name of i
set asubtitle to ", score: " & the score of i
set aarg to the reference URL of i
set ai to "{\"uid\": \"" & auid & "\",\"type\": \"file\",\"title\": \"" & atitle & "\",\"subtitle\": \"" & asubtitle & "\",\"arg\": \"" & aarg & "\"}"
if acount = 0 then
set aitems to aitems & ai
else
set aitems to aitems & "," & ai
end if
set acount to acount + 1
end repeat
set showItems to "{\"items\": [" & aitems & "]}"
get showItems
end if
end try
end tell
end run

获取 DEVONthink Pro Office 的 Apple Script API

可以通过 Mac 自带的 Script Editor.app 的 File -> Open Dictionary 来打开 DTPO 的字典,字典里面包括了 Apple Script 能够调用的所有 API。(这是个获取 Mac APP Apple Script API 的通用方法,但是有些 Mac APP 本身就没有 Apple Script API,那么字典里面就没有该 APP)

Alfred Feedback

想要把结果显示在 Alfred 上,就必须遵守 Alfred 的输出格式,而且只能在 Script Filter 中有效。

JSON 格式(Alfred 3 中推荐):

{"items": [
{
"uid": "desktop",
"type": "file",
"title": "Desktop",
"subtitle": "~/Desktop",
"arg": "~/Desktop",
"autocomplete": "Desktop",
"icon": {
"type": "fileicon",
"path": "~/Desktop"
}
}
]}

XML 格式(Alfred 2 时使用的):

<?xml version="1.0"?>
<items>
<item uid="desktop" arg="~/Desktop" valid="YES" autocomplete="Desktop" type="file">
<title>Desktop</title>
<subtitle>~/Desktop</subtitle>
<icon type="fileicon">~/Desktop</icon>
</item>
</items>

编写 Apple Script

原本应该是要把 Apple Script 说明看一遍的,但是实在没有动力将全部都过一遍,最后就是写到哪看到哪,需要什么查什么。

设置变量

set 变量名 to <表达式或者属性>

set <var> to <expr>

判断

if <boolean> then
<statement>
else
<statement>
end if

循环

repeat with <var> in <list>
<expr>
end repeat

捕捉异常

try
<statement>
end try

字符串中的特殊字符

想要在字符串中显示双引号,要在双引号前面加个反斜杠。

"\""

如果想要在字符串中显示反斜杠+双引号,则是要在反斜杠前加反斜杠,在双引号前加反斜杠。

"\\\""

解释 Alfred 中的 Apple Script 代码

on run
......
end run

Alfred 默认的调用 Apple Script 方式

tell application "DEVONthink Pro"

呼叫 DTPO

try	
launch
set itemList to search "{query}"
set theLength to the length of itemList
...
end try

launch:如果程序没有启动,则启动之;如果已经启动了,则没效果。

“{query}”:是 Alfred 的默认传参

set itemList to search “{query}”:获取搜索结果列表,默认在当前资料库中搜索

set theLength to the length of itemList:获取搜索结果列表长度

if theLength = 0 then
return ""
else
......
end if

如果没有搜索列表,直接返回空

set aitems to ""
set acount to 0

初始化结果项,和项数

repeat with i in itemList
set auid to the uuid of i
set atitle to the name of i
set asubtitle to ", score: " & the score of i
set aarg to the reference URL of i
set ai to "{\"uid\": \"" & auid & "\",\"type\": \"file\",\"title\": \"" & atitle & "\",\"subtitle\": \"" & asubtitle & "\",\"arg\": \"" & aarg & "\"}"
......
end repeat

repeat with …:遍历搜索结果列表

set auid to the uuid of i:获取uuid

set atitle to the name of i:获取文件名

set asubtitle to “, score: “ & the score of i:获取相关匹配度(0.0–1.0)

set aarg to the reference URL of i:获取引用 URL

set ai to ……:将搜索结果单项转换为 json 格式

if acount = 0 then
set aitems to aitems & ai
else
set aitems to aitems & "," & ai
end if
set acount to acount + 1

如果是不是第一项,在项前加逗号,项数加1

set showItems to "{\"items\": [" & aitems & "]}"

将所有搜索项转换为 json 格式

get showItems

打印结果,传递给 Alfred

结尾语

尽管最后总结起来感觉很简单,但是因为之前根本就没接触过 Apple Script,将这个小脚本从开始编写到调试完成整整花了一个下午加一个晚上。令人欣慰的是最后还是完成了。

至此,留念。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade