粗略地分的话,iOS 的自动化,至少包含 3 个基础知识:
URL Schemes
Workflow
JavaScript
前两者可以说占据了大部分的应用场景,但是如果想再往前精进,就需要掌握 JavaScript。
但可惜的是,多数情况下我们读到的文章,一提及 JavaScript 就言「不在本文讨论范畴」,似乎 JavaScript 是洪水猛兽,只有专业程序员才能驯服。
其实不然,我作为一个没有任何理工科背景的用户,就经常使用 JavaScript 来满足自己的一些自动化需求。在少数派上也撰写了至少 5 篇相关文章:
而我写这篇文章的目的,就是希望能通过自己学习、使用 JavaScript 的经历,辅以大量能够直接使用的 JavaScript 代码,和你分享这样一个简单的事实:
多数效率工具内置的 JavaScript 并不难学。一旦学会,你就能更灵活地驾驭这些工具。
为什么要学习 JavaScript
在 iOS 应用相关的自动化场景里,JavaScript 主要被用于处理文本。通过处理文本这个需求来认识 JavaScript,不仅适用范围相对广一些,能够覆盖到到的应用也会多一些。因此我打算在这篇文章里,从处理文本这个角度切入,来带大家入门 iOS 自动化中的 JavaScript。
标准 JavaScript 语言 中关于文本处理的内容其实非常少,在经典教材《JavaScript 经典实例》里还不到 30 页,而且其中包括的是文本格式转换、正则表达式、文本替换等实用内容。 一般来说,效率工具中的 JavaScript 都采用一种很简单的工作方式:
获取变量
处理变量
输出变量
所不同的是,各个工具中获取、输出变量的方式各有不同,好在这些工具一般都会提供一个供你套用的模板,下面我就用几个典型的例子,由浅入深来介绍 JavaScript 的使用。
认识 JavaScript 语法模板
虽说 JavaScript 的语法千变万化,但终归有迹可循,一般来说,一条完整的语句有两种形式:
第一种比较简单,var 自定义了一个新变量(蓝色部分),它的名字可以随意取,甚至用中文也不要紧;等号右边是另一个变量(绿色部分)加上需要的函数(红色部分),注意函数名后面需要加上一对英文括号 ()。变量.函数() 表示用该函数处理该变量,整行的作用是把处理完的值赋予我们设置的自定义变量。
第二种稍稍复杂一些,红色函数部分的括号中还有两个参数(两两之间用英文逗号 , 隔开),实际使用时视需求可以增加到任意多个;括号中的参数就像是佐料,而点号前的变量则是原料,函数把它们一同变成我们所需的文本处理结果。
TextExpander 中的简单语法
TextExpander 对 JavaScript 提供了良好的支持。我们来看其中一个最简单的 JavaScript 例子:
TextExpander.pasteboardText.toUpperCase( )
这段只有一行的代码能把剪贴板内的英文全变成大写字母,然后直接粘贴上去。如果你想表达自己情绪激动,就可以利用这段脚本这么干:
虽然它简单,但是包含了 JavaScript 中的两个关键概念:变量和函数。
左侧这一串代表一个 TextExpander 的自带变量——剪贴板内容(后一节会介绍去哪里寻找这些应用自带的函数或变量),而点号 . 后面的 toUpperCase( ); 则是一个函数,用于将点号前的内容变成大写。
这里还有两个我常用的函数:
.toLowerCase( ):变小写;
.trim():去除空格。
这些格式转换、拼接就是最基础的 JavaScript 语法。
进阶语法:TextExpander 中的文本替换
我常常拿 TextExpander 来做文本替换,比如每周处理读者回复时,就可以把留言源码中的 <br></br> 快速换成符合后台格式的换行符:
这个 TextExpander Snippet 的代码是:
var input = TextExpander.pasteboardText;
var re1 = /<br>/g;
var re2 = /<br\s\/><br\s\/>/g;
var result = input.replace(re1,"")
var result = input.replace(re2,"\n")
TextExpander.appendOutput(result);
其中的核心是两次文本替换,我们拆一部分出来看:
var input = TextExpander.pasteboardText;
var re1 = /<br>/g;
var result = input.replace(re1,"")
TextExpander.appendOutput(result);
var 表示我们要自定义一个变量,等号前的变量名可以随意取,不过等号后面的那串东西显然就不是那么随意了,这里这串东西表示「剪贴板内容」。
re1 也是我们自定义的变量,一会儿要查找它所代表的文本——等号后面的内容;/<br>/g 是一个正则表达式,两个 / 之间的是需要查找的内容(即<br>,我想换掉的 HTML 标签),后面跟着的 g 意味着要搜索所有的 <br>,不然这段代码在找到第一个 <br> 后就下班休息了;
再定义一个变量 result。重点来了,等号后面的 input.replace(re1,"") 非常关键:
input 即第一行所获取的剪贴板内容;
replace 是一个函数,与上一节中那些简单的函数不同,它还需要两个参数,放在随后的括号中,用逗号 , 隔开;
re1 是第一个参数,即我们准备查找的内容;
"" 是第二个参数,即我们想要换成的内容——空文本。文本需要用前后两个引号包起来,即使是它是「空」;
最后一个函数作用是「粘贴」,括号里的 result(替换好的文本)就是需要粘贴的内容。
以上,完成了一次文本替换。
工作中我们常常遇到一些可以批量替换掉的格式错误,比如有的作者通篇使用 “” ,而在少数派的网页上更适合用 「」,这时直接用 TextExpander 敲几下按键来实现文本替换,比复制到 Word 里查找、替换要方便得多。
由于上面这些脚本都是 JavaScript 写成的,我们可以在 iOS 和 macOS 上使用同一个 Snippet,这体现了 JavaScript 的泛用性。
学会查字典:以 Drafts 为例
当你学会一些简单的文本格式转换之后,接踵而来的问题就是如何调用各种变量。比如,我想把 Drafts 草稿中选中的文字设为标题,怎样在 JavaScript 中称呼「选中的文字」?不知道怎样调用变量、函数,就像手里拿着上好的兵器,却不知向谁出手。
如果我们读一读各个应用的官方文档,不难发现它们已经为常用的变量和函数设置了专有名称,在 Drafts 的 字典 就很丰富: 我做了一个快捷键,可以以引用格式拷贝文字:
它的代码是这样的:
var input = getSelectedText();
var output = ">" + input
setClipboard(output)
留意最后一行的函数 setClipboard(output),它的作用是把前几步处理好的文本写入剪贴板。
上面的代码适用于 Drafts 4,如果你在使用 Drafts 5,请使用这份代码:
var input = editor.getSelectedText();
var output = ">" + input
app.setClipboard(output)
想知道更多的函数和变量,你得学会「查字典」——多看官方文档。
高级用法:Copied 中的循环
Copied 是一款自定义程度颇高的剪贴板管理工具,和 TextExpander 一样,它也有 iOS 和 macOS 两个版本,同样支持 JavaScript。Copied 的 JavaScript 模板有两种,第一类的作用也是文本的格式转换,和 TextExpander 类似,这里不再赘述,另一种 Merge Script 则比较厉害,可以用一定的格式组合多条剪贴板历史记录,我曾经专门写过文章 《用 Copied 组合剪贴板历史记录 | 工作日志》(Power+ 专属),这里直接引用模板和效果图: function merge(clippings) {
var merged = clippings.reduce(function(string, clipping) {
var stringToAppend
if (clipping.text != null) {
stringToAppend = clipping.text
} else if (clipping.url != null) {
stringToAppend = clipping.url
}
# 别看上面了,只有这里是你要写的
return string + stringToAppend # 这行作用是把记录组合起来
}, "")
return merged
}在 Merge Script 中我们会用到循环,它的原理比较复杂,请看我 以前的文章。 在这里,我们关注点在于这样一件事:Copied 的模板已经包括了输入、输出的代码,我们只需要写其中「处理」部分的。
等你掌握了循环,JavaScript 的文字处理相关功能也就掌握得差不多了。结合各个应用的参考文档,你就能比较熟练地使用 JavaScript 来提高文本处理的效率。
小结
我平时不少文章都涉及了代码,很多读者希望我写写「怎样学代码」相关的话题。我明白,这些读者想学的并非一门完整的编程语言,而是和自己工作关联最密切的那部分内容。于是我选了较为泛用的 JavaScript,来举例解决一些文字处理上的需求。
当然,JavaScript 的作用远远不止文字处理,例如 JSBox 就能用 JavaScript 打造许多小程序,但考虑到学习的成本和普世度,这类工具就不在本文讨论范围内了。