文本替换是 iOS、macOS 上一项很实用的功能,但是对于各位 Power User 来说,iOS 上的文本替换或许是够用了,但 macOS 上大家都会选择其他更专业的文本替换软件,比如大名鼎鼎的 TextExpander,或是性价比更高的 aText

TextExpander 作为订阅类 App,iOS、macOS 双平台都有,但是价格不菲,而且 iOS 版对中文支持不好,所以我选择的方案是在 iOS 上用系统的文本替换,在 macOS 上用 aText。

但是这就产生了一个问题:同步。在 aText 里存储的短语,如果不能在 iOS 端使用是一件很苦恼的事。为了解决这个问题,就要用到 macOS 文本替换和 iOS 能同步这一特点。我利用这一点打造了一套自动化地同步 aText 和系统文本替换的工作流。
首先我简述一下这个工作流。

  1. 导出 aText 数据,为 .rtf 格式。
  2. 用命令行将 .rtf 格式 转化为 .txt 格式。
  3. 用 Python 处理 .txt 文本,获得 .plist 文件。
  4. 系统文本替换能够自动解析 .plist 文件,并在双平台同步。

处理 .rtf

这里用到了 macOS 自带的命令行工具 textutil,使用格式为:

textutil -convert txt FILE.rtf

处理 .txt

这里用到了 Python 自带的库 plistlib,可以生成 macOS 独有的 plist 格式。在这之前我们来看看为何是 plist 文件。打开 macOS 文本替换,将其中的一个短语拖出来,用 Xcode 打开,可以看到其中的数据结构是这样的:

null

整体是一个数组形式,里面的 item 是字典,两个键分别是 phrase 和 shortcut 。任何具有这样结构的 plist 文件,都可以被系统文本替换解析。这样一来,用 Python 就可以很简单的生成这样的 plist 文件了。核心代码如下:

import plistlib 

def writeToPlist(array):
    plistlib.writePlist(array,"/Users/bigice/Documents/text.plist")

def main():
    with open("/Users/bigice/Documents/aText Snippets.txt",encoding="utf-8") as file:
        #处理文本
        text = file.readlines()
        for i in range(len(text)):
            text[i] = text[i][:-1]
        t = text[1:-1]
        shortcut = []
        phrase = []
        for i in range(len(t)):
            if i%2 == 0:
                shortcut.append(t[i])
            else:
                phrase.append(t[i])
        array = []
        for i in range(len(shortcut)):
            array.append(dict(phrase=phrase[i],shortcut=shortcut[i]))

        writeToPlist(array)

main()

自动化

最后将生成的 plist 文件拖入文本替换中,在通过 iCloud 同步,一切都完成了。
但是这样还是不够自动化,我们再把这些步骤用自动化工具整合一下,当文件夹中检测到 .rtf 文件,自动调用命令行工具生成 .txt 文件,当检测到 .txt 文件,自动调用 Python 程序,生成 plist 文件,移动到桌面,然后自动打开文本替换界面,最后再拖一下,大功告成。这里我用 Hazel 写了几个动作,仅供参考。
首先是将 rtf 转化为 txt:

null

然后将 txt 转化为 plist:
null

然后将 plist 移动到桌面:
null

最后打开文本替换界面:
null

OK,一个自动化同步文本片段的功能就完成了。整个过程其实很简单,但对于一些没有编程基础的人来说,这个教程应该有些许参考价值。