编写插件
Plug-ins offer additional features to software applications, usually provided by third parties. This overview covers plug-in development for Glyphs 2.3 or later. Don’t be shy, grab a cup of great coffee, and relax: Others have done it before you.
插件会为软件提供额外功能,通常是由第三方提供的。本教程供你概览如何进行插件开发。你可以在我们 GlyphsSDK 库中的 Readme.md
里找到详细的描述。
别害羞,拿一杯上好的咖啡,放松:前人已经做过不少了。
1. 获取插件模板
我们在 GitHub 页面上提供多种用途的插件骨架(例如文件导出、自定义轮廓滤镜等)。如果你对 Git 已经熟悉,你可以在你最喜欢的版本管理软件中查看文件结构(Git 自己的,或者很多其他可用软件中的某一款。虽然 Versions.app 是一个 SVN 客户端,但本教程作者依然推荐使用它)。
如果你不熟悉代码版本管理的概念,或者只是其他人代码的用户而已,你也可以直接从 Glyphs SDK 主页下载包含整个 Glyphs SDK(软件开发套件)的 ZIP 压缩包。
专业提示:请让自己适应代码版本系统。你以后在工作中的各个领域都会有所受益的。
所以,我们的 SDK 页面在这里:https://github.com/schriftgestalt/GlyphsSDK,插件模板在 Python Templates 子文件夹中。在这里,你会找到一系列插件骨架,等你去赋予生命。每个插件模板都包含全功能的示例代码,以便于理解。
- File format:文件格式。导出你自己的字体格式。
- Filter without dialog:不带对话框的滤镜。通过 “滤镜” 菜单,或在字体导出时修改字体。
- Filter with dialog:带对话框的滤镜。和前一条相同,但带有用户界面对话框。
- General plug-in:通用插件。没有特别的目的,我们看看能发生什么。
- Palette:右边栏面板。向右侧边栏中添加一个面板显示。
- Reporter:汇报器。在 “编辑视图” 和 “预览” 区域中绘图,用于可视化字符形的特征。
- Select Tool:选择工具。使用自己的功能来增强 “选择工具”。
对于 Glyphs.app,插件以 Mac 系统的所谓 “包” 的形式存在,它们需要被放在 Glyphs 的 “Plugins” 文件夹中,位于 ~/Library/Application Support/Glyphs/Plugins
路径下(~
代表用户账户的个人文件夹)。如果你将插件文件拖动到 Glyphs 软件图标上,或者通过双击来打开,Glyphs 会自动将其放到上述文件夹中。这些 “包” 的外观和行为和 “访达” 中的单个文件一致,但它们实际上是文件夹,你可以通过在 “访达” 中右键单击这样的文件,选择 “显示包内容” 来访问其中的文件。
下图为这样一个插件文件夹看上去的结构。你的主要代码在 Contents/Resources/plugins.py
文件中。其他值得注意的文件有,包含插件各种相关信息的 Info.plist
,以及对于带对话框的插件,还有两个包含用户界面对话框视图的 .nib
/.xib
文件。
当今的很多文本编辑器会同时打开整个文件夹,让你能够在同一个面板中以看到文件的树状结构。所以你可以在你的文本编辑中一次打开整个 .glyphsFilter
文件包:
目前,用于这种用途的、最流行的文本编辑器是 TextMate、SublimeText 和 Atom。
2. 重命名几个 ____Names____
我们 GitHub 库中的 Python 模板 页面里,包括了如何设置插件文件结构的详尽信息。你需要在这最多三个文件中重命名所有带 “四重下划线” 的内容(比如 ____PluginClassName____
)。
对于插件名称,我们要处理两个不同的名称变体:
____PluginName____
是出现在软件中某些位置的、人类可读的名称,比如在 Glyphs “偏好设置” 窗口的 “插件” 选项卡中。这一名称可以带有空格和 Unicode 字符。____PluginClassName____
是你代码中机器可读的 Python 类名称,会出现在几个地方。它需要是独一无二的,你不能同时安装两个类名称相同的插件。尽管我说是 “机器可读”,但用户在一个特定的交互中也会看到插件的这个名称:通过自定义参数在导出时调用滤镜。所以请为其取一个友好而独特的名字。这里只允许出现 ASCII 字符,不能有空格。我们建议使用驼峰式大小写(形如camelCaseNames
)。
Info.plist
中的一节会告诉 Glyphs 在哪里查找你插件的更新,以便在更新可用时通知用户。要实现这一功能,你需要插入一个指向在线 Info.plist
文件的 URL 链接, 其中包含当前版本号。这可以是一个手动编辑的文件,也可以是自动生成的,比如来自在线商店,或着也可以是和下载版插件中的 Info.plist
完全一样的文件。
如果使用 GitHub 分发,你的 Info.plist
文件链接会是:https://raw.githubusercontent.com/*user*/*plugin*/master/*filename*/Contents/Info.plist
。用你的 GitHub 用户名替换 *user*
,用 GitHub 库名称替换 *plugin*
,用插件名称带上后缀来替换 *filename*
,比如 MyPlugin.glyphsFilter
。
现在,是时候读一下 Python 模板页面的详细内容了。
3. 使用 Interface Builder 创建对话框
某些类型的插件可以在 Glyphs.app 中打开对话框:
和 Glyphs 中的所有应用一样,我们使用 Apple 自家的 Cocoa 来创建对话框,特别是 Interface Builder。为此你需要安装 Apple 的 Xcode,可以从 AppStore 免费下载。如果你还没有拥有它,请寻找一处网速够快的地方开始下载。它有 4 GB 大。
如果你想使用 Tal Leming 的 Vanilla 库,你会在所有带对话框插件的 Readme 文件中找到有用的信息。
你的 Python 代码和 Cocoa 用户界面通过 IBOutlets(代码到界面)和 IBActions(界面到代码)互相交流。
它们在 Python 代码中的定义如下所示。IBOutlets 被定义为像这样的类变量:
class CSVFileExport (FileFormatPlugin):
textField = objc.IBOutlet() # 界面中的一个文本框
而 IBActions 为类方法,带有 @objc.IBAction
前缀:
@objc.IBAction
def buttonClicked_(self, sender):
# 按钮点击时执行
这是你在 Xcode 的 Interface Builder 中创建对话框时的样子:
所有必要细节都在 Python 模板页面中详述。请通读逐步指南,船到桥头自然直。
4. 分步指南
应对每种插件的方法,都在相应插件的 GitHub 页面中详细描述:
5. 插件管理器
完成后,你就可以让插件通过 “窗口 > 插件管理器” 中简便安装(Glyphs 2.3 或更新的版本)。为此只需给 glyphs-packages 库中的 packages.plist
文件提交拉取请求(pull request)即可。你需要做的,只有在那个文件中添加这样几行:
{
name = "PluginNameWithExtension.glyphsPlugin";
url = "https://github.com/userName/repositoryName";
description = "Single-line description. Careful: WITHOUT LINEBREAKS! Use \n instead.";
}
条目间必须由逗号分隔。所以,如果这段代码之后还有一个条目,别忘了在花括号 }
后添加逗号。(如果这段代码之前还有,就在前面一行加上逗号。)条目间的顺序没有关系,插件管理器会按首字母顺序排列所有注册的插件。
还有一些选项可供你的条目使用,比如指定一张截图,或是最低/最高版本。请确保读过 glyphs-packages readme 文档以便了解全部细节。
祝贺你
就是这样了!这应该可以帮你开始你的 Glyphs 插件。如果你在哪里卡住了,请尽管在我们的论坛中询问。
Jan Gerner (Yanone) 撰写,Rainer Erich Scheichelbauer 编辑。
2018-11-18 更新:修正少量录入错误。
Chinese translation by Willie Liu (刘育黎) and Stone Zeng (曾祥东) from 3type (三言).