重新佈署的操作方法
【中州韵】点击输入法状态栏上的 ⟲ (Deploy) 按钮
•【小狼毫】在托盘图标上右键选择「重新佈署」
•【鼠鬚管】在系统语言文字选单中选择「重新佈署」
对设置的修改於重新佈署后生效。编译新的输入方案需要一段时间,此间若无法输出中文,请稍等片刻。
若部署完毕后,可以通过 Ctrl+` 唤出方案选单,输入方案却仍无法正常使用,请查看日誌文件定位错误。
查阅 DIY 处方集
已将一些定製 Rime 的常见问题、解法及定製档链接收录於此〔DIY 处方集〕
定製指南
Rime 输入方案,将 Rime 输入法的设定整理成完善的、可分发的形式。 但并非一定要创作新的输入方案,才可以改变 Rime 的行为。
当用户需要对 Rime 中的各种设定做小幅的调节,最直接、但不完全正确的做法是:编辑用户资料夹中那些 .yaml 文档。
这一方法有弊端:
•当 Rime 软件升级时,也会升级各种设定档、预设输入方案。用户编辑过的文档会被覆写为更高版本,所做调整也便丢失了。
•即使在软件升级后再手动恢复经过编辑的文件,也会因设定档的其他部分未得到更新而失去本次升级新增和修复的功能。
因此,对於随 Rime 发行的设定档及预设输入方案,推荐的定製方法是:
创建一个文件名的主体部份(「.」之前)与要定製的文件相同、次级扩展名(「.yaml」之前)为 .custom 的定製文档:
patch: "一级设定项/二级设定项/三级设定项": 新的设定值 "另一个设定项": 新的设定值 "再一个设定项": 新的设定值就是这样:patch 定义了一组「补靪」,以源文件中的设定为基础,写入新的设定项、或以新的设定值取代现有设定项的值。
不懂?那看我来示范。
一例、定製每页候选数
Rime 中,默认每页至多显示 5 个候选项,而允许的范围是 1〜9(个别 Rime 发行版可支持10个候选)。
设定每页候选个数的默认值为 9,在用户目录建立文档 default.custom.yaml :
patch: "menu/page_size": 9重新佈署 即可生效。
〔注意〕如果 default.custom.yaml 里面已经有其他设定内容,只要以相同的缩进方式添加 patch: 以下的部分,不可重复 patch: 这一行。
若只需要将独孤一个输入方案的每页候选数设为 9,以【朙月拼音】为例,建立文档 luna_pinyin.custom.yaml 写入相同内容,重新佈署 即可生效。
一例、定製标点符号
有的用家习惯以 / 键输入标点「、」。
仍以【朙月拼音】为例,输入方案中有以下设定:
# luna_pinyin.schema.yaml # ... punctuator: import_preset: default解释:
punctuator 是 Rime 中负责转换标点符号的组件。该组件会从设定中读取符号映射表,而知道该做哪些转换。
punctuator/import_preset 是说,本方案要继承一组预设的符号映射表、要从另一个设定档 default.yaml 导入。
查看 default.yaml ,确有如下符号表:
punctuator: full_shape: # ……其他…… "/" : [ /, "/", ÷ ] # ……其他…… half_shape: # ……其他…… "/" : [ "/", /, ÷ ] # ……其他……可见按键 / 是被指定到 "/", /, ÷ 等一组符号了。 并且全角和半角状态下,符号有不同的定义。
欲令 / 键直接输出「、」,可如此定製 luna_pinyin.custom.yaml:
patch: "punctuator/full_shape": "/" : "、" "punctuator/half_shape": "/" : "、"以上在输入方案设定中写入两组新值,合併后的输入方案成为:
# luna_pinyin.schema.yaml # ... punctuator: import_preset: default full_shape: "/" : "、" half_shape: "/" : "、"含义是、在由 default 导入的符号表之上,覆写对按键 / 的定义。
通过这种方法,既直接继承了大多数符号的默认定义,又做到了局部的个性化。
还有一种情况:
有些用户习惯在中文里使用ASCII标点,那麼与其一个一个覆写,不如 整套都换掉 。
取得这份设定档—— Rime 别样设定,使用西文标点 在用户资料夹保存为 alternative.yaml ;
再将输入方案中的「继承自 default 」通过打 patch 替换为「继承自 alternative 」
# luna_pinyin.custom.yaml patch: 'punctuator/import_preset': alternative就换上了自己习惯的一套标点!
一例、定製简化字输出
注意:
•如果您只是需要 Rime 输出简化字,敲 Ctrl+` 组合键、从菜单中选择「汉字→汉字」即可!
•本例说明了其中原理,以及通过设定档修改预设输出字形的方法。
Rime 预设的词汇表使用传统汉字。 这是因为传统汉字较简化字提供了更多信息,做「繁→简」转换能够保证较高的精度。
Rime 中的过滤器组件 simplifier,完成对候选词的繁简转换。
# luna_pinyin.schema.yaml # ... switches: - name: ascii_mode reset: 0 states: [ 中文, 西文 ] - name: full_shape states: [ 半角, 全角 ] - name: simplification # 转换开关 states: [ 汉字, 汉字 ] engine: filters: - simplifier # 必要组件一 - uniquifier # 必要组件二以上是【朙月拼音】中有关繁简转换功能的设定。
在 engine/filters 中,除了 simplifier,还用了一件 uniquifier。 这是因为有些时候,不同的候选会转化为相同的简化字,例如「鐘→钟」、「钟→钟」。 uniquifier 的作用是在 simplifier 执行转换之后,将文字相同的候选项合併。
该输入方案设有三个状态开关:中/西文、全/半角、繁简字。即 switches 之下三项。
每个开关可在两种状态(states)之间切换,simplifier 依据名为 simplification 的开关状态来决定是否做简化:
•初始状态下、输出为传统汉字、〔方案选单〕中的开关选项显示为「汉字→汉字」。
•选择该项后、输出为简化汉字、〔方案选单〕中显示「汉字→汉字」。
•Rime 会记忆您的选择,下次打开输入法时、直接切换到所选的字形。
•亦可无视上次记住的选择,在方案中重设初始值:reset 设为 0 或 1,分别选中 states 列表中的两种状态。
如果日常应用以简化字为主:-(,则每每在〔方案选单〕中切换十分不便; 於是佛振献上默认输出简化字的设定档:
# luna_pinyin.custom.yaml patch: switches: # 注意缩进 - name: ascii_mode reset: 0 # reset 0 的作用是当从其他输入方案切换到本方案时, states: [ 中文, 西文 ] # 重设为指定的状态,而不保留在前一个方案中设定的状态。 - name: full_shape # 选择输入方案后通常需要立即输入中文,故重设 ascii_mode = 0; states: [ 半角, 全角 ] # 而全/半角则可沿用之前方案中的用法。 - name: simplification reset: 1 # 增加这一行:默认启用「繁→简」转换。 states: [ 汉字, 汉字 ]其实预设输入方案中就提供了一套【朙月拼音】的简化字版本,名为【简化字】,以应大家“填表”之需。 看他的代码如何却与上篇定製档写得不同:
# luna_pinyin_simp.schema.yaml # ... switches: - name: ascii_mode reset: 0 states: [ 中文, 西文 ] - name: full_shape states: [ 半角, 全角 ] - name: zh_simp # 注意这里(※1) reset: 1 states: [ 汉字, 汉字 ] simplifier: option_name: zh_simp # 和这里(※2)前文说,simplifier 这个组件会检查名为 simplification 的开关状态; 而这款【简化字】方案却用了一个不同名的开关 zh_simp,即 ※1 处所示; 并通过在 ※2 行设定 simplifier/option_name 告知 simplifier 组件所需关注的开关名字。
何故?
还记得否,前文对「全/半角」这个开关的讨论—— 当切换方案时,未明确使用 reset 重置的开关,会保持之前设定过的状态。
【朙月拼音】等多数方案,并未重设 simplification 这个选项—— 因为用户换了一种输入编码的方式、并不意味著需要变更输出的字形。
而【简化字】这一方案不同,恰恰是表达变更输出字形的需求; 用户再从【简化字】切回【朙月拼音】时,一定是为了「回到」繁体输出模式。 所以令【简化字】使用独立命名的开关、而非方案间共用的 simplification 开关, 以避免影响其他输入方案的繁简转换状态。
一例、定製方案选单
在【小狼毫】方案选单设定介面上勾勾选选,就可以如此定製输入方案列表:
# default.custom.yaml patch: schema_list: # 对於列表类型,现在无有办法指定如何添加、消除或单一修改某项,於是要在定製档中将整个列表替换! - schema: luna_pinyin - schema: cangjie5 - schema: luna_pinyin_fluency - schema: luna_pinyin_simp - schema: my_coolest_ever_schema # 这样就启用了未曾有过的高级输入方案!其实这麼好的方案应该排在最前面哈。无有设定介面时,又想启用、禁用某个输入方案,手写这样一份定製档、重新佈署就好啦。
一例、定製唤出方案选单的快捷键
唤出方案选单,当然要用键盘。默认的快捷键为 Ctrl+` 或 F4。
不过,有些同学电脑上 Ctrl+` 与其他软件衝突,F4 甚至本文写作时在【鼠鬚管】中还不可用。又或者有的玩家切换频繁,想定义到更好的键位。
那麼……
# default.custom.yaml patch: "switcher/hotkeys": # 这个列表里每项定义一个快捷键,使哪个都中 - "Control+s" # 添加 Ctrl+s - "Control+grave" # 你看写法并不是 Ctrl+` 而是与 IBus 一致的表示法 - F4按键定义的格式为「修饰符甲+修饰符乙+…+按键名称」,加号为分隔符,要写出。
所谓修饰符,就是以下组合键的状态标誌或是按键弹起的标誌:
•Release——按键被放开,而不是按下
•Shift
•Control
•Alt——Windows上 Alt+字母 会被系统优先识别为程序菜单项的快捷键,当然 Alt+Tab 也不可用
•嗯,Linux 发行版还支持 Super, Meta 等组合键,不过最好选每个平臺都能用的啦
按键的名称,大小写字母和数字都用他们自己表示,其他的按键名称参考这里 <X11/keysymdef.h> 的定义,去除代码前缀 XK_ 即是。
一例、定製【小狼毫】字体字号
虽与输入方案无关,也在此列出以作参考。
# weasel.custom.yaml patch: "style/font_face": "明兰" # 字体名称,从记事本等处的系统字体对话框里能看到 "style/font_point": 14 # 字号,只认数字的,不认「五号」、「小五」这样的一例、定製【小狼毫】配色方案¶註:这款配色已经在新版本的小狼毫里预设了,做练习时,你可以将文中 starcraft 换成自己命名的标识。
# weasel.custom.yaml patch: "style/color_scheme": starcraft # 这项用於选中下面定义的新方案 "preset_color_schemes/starcraft": # 在配色方案列表里加入标识为 starcraft 的新方案 name: 星际我争霸/StarCraft author: Contralisk <contralisk@gmail.com>, original artwork by Blizzard Entertainment text_color: 0xccaa88 # 编码行文字顏色,24位色值,用十六进制书写方便些,顺序是蓝绿红0xBBGGRR candidate_text_color: 0x30bb55 # 候选项文字顏色,当与文字顏色不同时指定 back_color: 0x000000 # 底色 border_color: 0x1010a0 # 边框顏色,与底色相同则为无边框的效果 hilited_text_color: 0xfecb96 # 高亮文字,即与当前高亮候选对应的那部份输入码 hilited_back_color: 0x000000 # 设定高亮文字的底色,可起到凸显高亮部份的作用 hilited_candidate_text_color: 0x60ffa8 # 高亮候选项的文字顏色,要醒目! hilited_candidate_back_color: 0x000000 # 高亮候选项的底色,若与背景色不同就会显出光棒效果自己看!
DIY 处方集
已将一些定製 Rime 的常见问题、解法及定製档链接收录於此。
建议您首先读完《定製指南》、通晓相关原理,以正确运用这些处方。
初始设定
在方案选单中添加五笔、双拼
放此例,可启用任一预设或自订输入方案,如【粤拼】、【注音】等。(详解)
如果下载、自己製作了非预设的输入方案,将源文件复製到「用户资料夹」后,也用上面的方法将方案标识加入选单!
修改於重新佈署后生效。
【小狼毫】外观设定
使用横向候选栏:
# weasel.custom.yaml
patch:
style/horizontal: true
【鼠鬚管】外观与键盘设定
〔注意〕鼠鬚管从 0.9.6 版本开始支持选择配色方案,并改用squirrel.custom.yaml 保存用户的设定。
针对特定程序禁用汉字输入
【鼠鬚管】0.9.9 开始支持这项设定:
在指定的应用程序中,改变输入法的初始转换状态。如在
•终端 Terminal / iTerm
•代码编辑器 Emacs / MacVim / Sublime Text / Xcode
•快速启动工具 QuickSilver / Alfred
等程序里很少需要输入中文,於是鼠鬚管在这些程序里默认不开启中文输入。
自定义 Mac 应用程序的初始转换状态,首先查看应用的 Info.plist 文件得到 该应用的 Bundle Identifier,通常是形如 com.apple.Xcode 的字符串,然后如此设定:
# squirrel.custom.yaml example patch: app_options/com.googlecode.iterm2: ascii_mode: true app_options/com.alfredapp.Alfred: ascii_mode: true app_options/com.apple.Xcode: ascii_mode: true
输入习惯
使用Control键切换中西文
以及修改左、右Shift、Control键的行为,提供三种切换方式。 详见代码註释。
方便地输入含数字的西文用户名
通常,输入以小写拉丁字母组成的编码后,数字键的作用是选择相应序号的候选字。
假设我的邮箱地址是 rime123@company.com,则需要在输入rime之后上屏或做临时中西文切换,方可输入数字部分。
为了更方便输入我的用户名 rime123,设置一组特例,将 rime 与其后的数字优先识别西文
以方括号键换页
添加 Mac 风格的翻页键 [ ] 。这是比较直接的设定方式。下一则示例给出了一种更系统、可重用的设定方式。
使用西文标点兼以方括号键换页
这份设定档汇集了多个方面的输入习惯,可成套导入到输入方案。
以回车键清除编码兼以分号、单引号选字
适合一些形码输入法(如五笔、郑码)的快手。
关闭用户词典和字频调整
以【五笔86】为例:
# wubi86.custom.yaml patch: translator/enable_user_dict: false模糊音
【朙月拼音】模糊音定製模板
类似方案如双拼、粤拼等可参考这里演示的方法。
【吴语】模糊音定製模板
编码反查¶设定【速成】的反查码为粤拼
设定【仓頡】的反查码为双拼
在Mac系统上输入emoji表情把 emoji 加入输入方案选单;
切换到 emoji 输入方案,即可通过拼音代码输入表情符号。查看符号表
输入 all 可以列出全部符号,符号后面的括弧里标记其拼音代码。
五笔简入繁出
【小狼毫】用家请到下载页取得「扩展方案集」。
安装完成后,执行输入法设定,添加【五笔・简入繁出】输入方案。
当然,因为您理想中的输入方式千奇百怪、也许从没有人那样玩过,所以不可能在那种勾勾选选的介面上做得出来;需要亲手来创作——
Rime 输入方案 !
Rime 是啥
Rime 不是一种输入法。是从各种常见键盘输入法中提炼出来的抽象的输入算法框架。因为 Rime 涵盖了大多数输入法的「共性」,所以在不同的设定下,Rime 可化为不同的输入法用来打字。
Rime 输入方案又是啥
要让 Rime 实现某种具体输入法的功能,就需要一些数据来描述这种输入法以何种形式工作。即,定义该输入法的「个性」。
如「汉语拼音」、「注音」、「仓頡码」、「五笔字型」,这些方法可凭藉 Rime 提供的通用设施、给定不同的工作参数来实作。以本文介绍的规格写成一套套的配方,就是 Rime 输入方案。
为啥这麼繁?
一键就搞掂,必然选项少,功能单一。不好玩。
输入法程序一写两三年,也许还不够火候;花两三个小时来读入门书,已是输入法专业速成班。
準备开工
Rime 是跨平臺的输入法软件,Rime 输入方案可通用於以下发行版:
•【中州韵】 ibus-rime → Linux
•【小狼毫】 Weasel → Windows
•【鼠鬚管】 Squirrel → Mac OS X
取得适合你系统的最新版 Rime 输入法,印一份《指南书》,準备开工了!
Rime with Text Files
文本为王。 Rime 的配置文件、输入方案定义及词典文件,均为特定格式的文本文档。 因此,一款够专业的 文本编辑器 ,是设计 Rime 输入方案的必备工具。
Rime 中所有文本文档,均要求以 UTF-8 编码,并建议使用 UNIX 换行符(LF)。
鑑於一些文本编辑器会为 UTF-8 编码的文件添加 BOM 标记,为防止误将该字符混入文中, 莫要从文件的第一行开始正文,而请在该行行首以 # 记号起一行註释,如:
# Rime default settings# Rime schema: My First Cool Schema# Rime dictionary: Lingua Latina也可继续以註释行写下方案简介、码表来源、製作者、修订记录等信息,再切入正文。
必知必会
Rime 输入法中,多用扩展名为「.yaml」的文本文档,这是以一种可读性高的数据描述语言—— YAML 写成。
请访问 http://yaml.org/ 瞭解 YAML 文档格式。 下文只对部分语法作简要说明,而将重点放在对语义的解读上面。
Rime 输入方案亦会用到「正则表达式」实现一些高级功能。
输入方案设计者需要掌握这份文档所描述的 Perl 正则表达式语法:
http://www.boost.org/doc/libs/1_49_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html
Rime 中的数据文件分佈及作用
除程序文件以外,Rime 还包括多种数据文件。 这些数据文件存在於以下位置:
共享资料夹
•【中州韵】 /usr/share/rime-data/
•【小狼毫】 "安装目录\data"
•【鼠鬚管】 "/Library/Input Methods/Squirrel.app/Contents/SharedSupport/"
用户资料夹
•【中州韵】 ~/.config/ibus/rime/ (0.9.1 以下版本为 ~/.ibus/rime/)
•【小狼毫】 "%APPDATA%\Rime"
•【鼠鬚管】 ~/Library/Rime/
共享资料夹包含预设输入方案的源文件。 这些文件属於 Rime 所发行软件的一部份,在访问权限控制较严格的系统上对用户是只读的,因此谢绝软件版本更新以外的任何修改—— 一旦用户修改这里的文件,很可能影响后续的软件升级或在升级时丢失数据。
在「部署 Rime」操作时,将用到这里的输入方案源文件、并结合用户定製的内容来编译预设输入方案。
用户资料夹则包含为用户準备的内容,如:
•〔全局设定〕 default.yaml
•〔发行版设定〕 weasel.yaml
•〔预设输入方案副本〕 <方案标识>.schema.yaml
•※〔安装信息〕 installation.yaml
•※〔用户状态信息〕 user.yaml
编译输入方案所產出的二进制文件:
•〔Rime 棱镜〕 <方案标识>.prism.bin
•〔Rime 固态词典〕 <词典名>.table.bin
•〔Rime 反查词典〕 <词典名>.reverse.bin
记录用户写作习惯的文件:
•※〔用户词典〕 <词典名>.userdb.kct
•※〔用户词典备份〕 <词典名>.userdb.kct.snapshot
以及用户自己设定的:
•※〔用户对全局设定的定製信息〕 default.custom.yaml
•※〔用户对预设输入方案的定製信息〕 <方案标识>.custom.yaml
•※〔用户自製输入方案〕及配套的词典源文件
註:以上标有 ※ 号的文件,包含用户资料,您在清理文件时要注意备份!
详解输入方案
方案定义
一套输入方案,通常包含「方案定义」和「词典」文件。
方案定义,命名为 <方案标识>.schema.yaml,是一份包含输入方案配置信息的 YAML 文档。
文档中需要有这样一组方案描述:
# 以下代码片段节选自 luna_pinyin.schema.yaml schema: schema_id: luna_pinyin name: 朙月拼音 version: "0.9" author: - 佛振 <chen.sst@gmail.com> description: | Rime 预设的拼音输入方案。首先来为方案命名。schema/name 字段是显示在〔方案选单〕中的名称。
然后——重点是——要定一个在整个 Rime 输入法中唯一的「方案标识」,即 schema/schema_id 字段的内容。 方案标识由小写字母、数字、下划线构成。 仅於输入法内部使用,且会构成方案定义文件名的一部分,因此为了兼容不同的文件系统,不要用大写字母、汉字、空格和其他符号做方案标识。 一例:这款名为【朙月拼音】的输入方案,方案标识为「luna_pinyin」。
方案如做升级,通过版本号(schema/version)来区分相互兼容的新旧版本。
版本号——以「.」分隔的整数(或文字)构成的字符串。
如下都是版本号常见的形式:
"1" # 最好加引号表明是字符串! "1.0" # 最好加引号表明是字符串! "0.9.8" "0.9.8.custom.86427531" # 这种形式是经过用户自定义的版本;自动生成然而,若对方案的升级会导致原有的用户输入习惯无法在新的方案中继续使用,则需要换个新的方案标识。
比如【仓頡五代】之於【仓頡三代】、【五笔98】之於【五笔86】,其实已是互不兼容的输入法。
schema/author ——列出作者和主要贡献者,格式为文字列表:
schema: author: - 作者甲 <alpha@rime.org> - 作者乙 <beta@rime.org> - 作者丙schema/description ——对方案作简要介绍的多行文字。
以上 schema/schema_id、schema/version 字段用於在程序中识别输入方案, 而 schema/name、schema/author、schema/description 则主要是展示给用户的信息。
除方案描述外,方案定义文件中还包含各种功能设定,控制着输入法引擎的工作方式。
输入法引擎与功能组件
论 Rime 输入法的工作流程:
按键消息→后臺「服务」→分配给对应的「会话」→由「方案选单」或「输入引擎」处理…… 这里要点是,有会话的概念:多窗口、多线操作嘛,你懂得的,同时与好几位 MM 聊天时,有无有好几组会话。 每一组会话中都有一部输入引擎完成按键序列到文字的变换。
Rime 可以在不同会话里使用不同输入方案。因为有「方案选单」。 方案选单本身可响应一些按键。但由於他不会写字的缘故,更多时候要把按键递给同一会话中的「输入引擎」继续处理。 方案选单的贡献,就是给用户一个便捷的方案切换介面,再把用户挑中的输入方案加载到输入引擎。
再论输入引擎的工作流程:
加载输入方案、预备功能组件;各就位之后就进入处理按键消息、处理按键消息……的循环。 响应各种按键、產生各类结果的工作,教不同的功能组件分担了。
好,看代码:
# luna_pinyin.schema.yaml # ... engine: # 输入引擎设定,即掛接组件的「处方」 processors: # 一、这批组件处理各类按键消息 - ascii_composer - recognizer - key_binder - speller - punctuator - selector - navigator - express_editor segmentors: # 二、这批组件识别不同内容类型,将输入码分段 - ascii_segmentor - matcher - abc_segmentor - punct_segmentor - fallback_segmentor translators: # 三、这批组件翻译特定类型的编码段为一组候选文字 - echo_translator - punct_translator - r10n_translator - reverse_lookup_translator filters: # 四、这批组件过滤翻译的结果 - simplifier - uniquifier输入引擎把完成具体功能的逻辑拆分为可装卸、组合的部件。 「加载」输入方案,即按该处方掛接所需的功能组件、令这些组件从输入方案定义中加载各自的设定、準备各司其职。 而他们接下来要完成的作业,先是由引擎收到的一份按键消息引发。
理解 Processors
输入引擎,作为整体来看,以按键消息为输入,输出包括三部分:
•一是对按键消息的处理结果:操作系统要一个结果、这按键、轮入法接是不接?
•二是暂存於输入法、尚未完成处理的内容,会展现在输入法候选窗中。
•三是要「上屏」的文字,并不是每按一键都有输出。通常中文字都会伴随「确认」动作而上屏,有些按键则会直接导致符号上屏,而这些还要视具体场景而定。
那麼第一类功能组件 processors,就是比较笼统地、起着「处理」按键消息的作用。
按键消息依次送往列表中的 processor,由他给出对按键的处理意见:
•或曰「收」、即由 Rime 响应该按键;
•或曰「拒」、回禀操作系统 Rime 不做响应、请对按键做默认处理;
•或曰这个按键我不认得、请下一个 processor 继续看。
优先级依照 processors 列表顺序排定,接收按键者会针对按键消息做处理。
虽然看起来 processor 通过组合可以承担引擎的全部任务,但为了将逻辑继续细分、Rime 又为引擎设置了另外三类功能组件。这些组件都可以访问引擎中的数据对象——输入上下文,并将各自所做处理的阶段成果存於其中。
processor 最常见的处理,便是将按键所產生的字符记入上下文中的「输入码」序列。 当「输入码」发生变更时,下一组组件 segmentors 开始一轮新的作业。
理解 Segmentors¶Rime 可将文字、数字、符号等不同内容连续输入,此时需要识别不同格式的输入码、将输入码分成若干段分而治之。 这通过数轮代码段划分操作完成。每一轮操作中、一众 segmentors 分别给出起始於某一处、符合特定格式的代码段,识别到的最长代码段成为本轮划分的结果,而给出这一划分的一个或多个 segmentor 组件则可为该代码段打上「类型标籤」;从这一新代码段的结束位置,开始下一轮划分,直到整个输入码序列划分完毕。
举例来说,【朙月拼音】中,输入码 2012nian\,划分为三个编码段:2012(贴number标籤)、nian(贴abc标籤)、\(贴punct标籤)。
那些标籤是初步划分后判定的类型,也可能有一个编码段贴多个标籤的情况。下一个阶段中,translators 会把特定类型的编码段翻译为文字。
理解 Translators
顾名思义,translator 完成由编码到文字的翻译。但有几个要点:
•一是翻译的对象是划分好的一个代码段。
•二是某个 translator 组件往往只翻译具有特定标籤的代码段。
•三是翻译的结果可能有多条,每条结果成为一个展现给用户的候选项。
•四是代码段可由几种 translator 分别翻译、翻译结果按一定规则合併成一列候选。
•五是候选项所对应的编码未必是整个代码段。用拼音敲一个词组时,词组后面继续列出单字候选,即是此例。
双目如探针般进入内存查看,发现翻译的结果呈现这种形式:
input | tag | translations ------+--------+------------------------------------- 2012 | number | [ "2012" ], [ "二〇一二" ] nian | abc | [ "年", "念", "唸",... ], [ "nian" ] \ | punct | [ "、", "\" ]输入串划分为多个代码段、每段代码又可具有多组翻译结果;取各代码段的首选结果连接起来,就是预备上屏的文字「2012年、」。
且将以上所示的数据称为「作文」。这是一篇未定稿(未搞定)的作文,输入法介面此时显示预备上屏的文字「2012年、」,并列出最末一个代码段上的候选「、」及「\」以供选择。
有两款主力 translator 完成主要文字内容的翻译,其实现的方式很不一样:
•r10n_translator 修炼罗马字分析法,以「固定音节表」为算法的基础,识别输入码的音节构成,推敲排列组合、完成遣词造句。
•table_translator 修炼传承自上世纪的码表功夫,基於规则的动态码表,构成编码空间内一个开放的编码集合。
拼音、注音、方言拼音,皆是以固定音节表上的拼写排列组合的方式產生编码,故适用罗马字分析法。 仓頡、五笔字型这类则是传统的码表输入法。
如果以码表方式来写拼音输入方案,是怎样的效果呢?虽然仍可完成输入,但无法完全实现支持简拼、模糊拼音、使用隔音符号的动态调频、智能语句等有用的特性。
反之,以罗马字方式使用码表输入法,则无法实现定长编码顶字上屏、按编码规则构词等功能。在 Rime 各发行版预设输入方案中,有一款「速成」输入方案,即是以 r10n_translator 翻译仓頡码,实现全、简码混合的语句输入。
概括起来,这是两种构造新编码的方式:罗马字式输入方案以一组固定的基本音节码创造新的组合而构词,而码表式输入方案则以一定码长为限创造新的编码映射而构词。
理解 Filters
上一步已经收集到各个代码段的翻译结果,当输入法需要在介面呈现一页候选项时,就从最末一个代码段的结果集中挑选、直至取够方案中设定的页最大候选数。
每从结果集选出一条字词、会经过一组 filters 过滤。多个 filter 串行工作,最终產出的结果进入候选序列。
filter 可以:
•改装正在处理的候选项,修改某些属性值:简化字、火星文、菊花文有无有?过时了!有 Rime,你对文字的想象力终於得救
•消除当前候选项,比如检测到重复(由不同 translator 產生)的候选条目
•插入新的候选项,比如根据已有条目插入关联的结果
•修改已有的候选序列
码表与词典
词典是 translator 的参考书。
他往往与同名输入方案配套使用,如拼音的词典以拼音码查字,仓頡的词典以仓頡码查字。但也可以由若干编码属於同一系统的输入方案共用,如各种双拼方案,都使用和拼音同样的词典,於是不仅复用了码表数据,也可共享用户以任一款此系列方案录入的自造词(仍以码表中的形式即全拼编码记录)。
Rime 的词典文件,命名为 <词典名>.dict.yaml,包含一份码表及对应的规则说明。 词典文件的前半部份为一份 YAML 文档:
# 注意这里以 --- ... 分别标记出 YAML 文档的起始与结束位置 # 在 ... 标记之后的部份就不会作 YAML 文档来解读 --- name: luna_pinyin version: "0.9" sort: by_weight use_preset_vocabulary: true ...解释:
•name: 词典名,内部使用,命名原则同「方案标识」;可以与配套的输入方案标识一致,也可不同;
•version: 管理词典的版本,规则同输入方案定义文件的版本号;
•sort: 词条排序方式,可选填 by_weight(按词频高低排序)或 original(保持原码表中的顺序);
•use_preset_vocabulary: 填 true 或 false,选择是否导入预设词汇表【八股文】。
码表,定义了输入法中编码与文字的对应关系。
码表位於词典文件中 YAML 结束标记之后的部份。 其格式为以製表符分隔的字段(TSV),每行定义一条「文字-编码」的对应关系:
# 单字 你 ni 我 wo 的 de 99% 的 di 1% 地 de 10% 地 di 90% 目 mu 好 hao # 词组 你我 你的 我的 我的天 天地 tian di 好天 好好地 目的 mu di 目的地 mu di di※注意: 不要 从网页复製以上代码到实作的词典文件!因为网页里製表符被转换成空格从而不符合 Rime 词典要求的格式。
码表部份,除了以上格式的编码行,还可以包含空行(不含任何字符)及註释行(行首为 # 符号)。
以製表符(Tab)分隔的第一个字段是所定义的文字,可以是单字或词组;
第二个字段是与文字对应的编码;若该编码由多个「音节」组成,音节之间以空个分开;
可选地、第三个字段是设定该字词权重的频度值(非负整数),或相对於预设权值的百分比(浮点数%)。 在拼音输入法中,往往多音字的若干种读音使用的场合不同,於是指定不同百分比来修正每个读音的使用频度。
词组如果满足以下条件,则可以省去编码字段:
•词组中每个单字均有编码定义
•词组中不包含多音字(例:你我),或多音字在该词组中读音的权值超过该多音字全部读音权值的5%(例:我的)
这种条件下,词组的编码可由单字编码的组合推导出来。
反之,则有必要给出词组的编码以消除自动註音的不确定性(例:天地)。
当含有多音字的词组缺少编码字段时,自动註音程序会利用权重百分比高於5%的读音进行组合、生成全部可能的註音,如:
「好好地」在编译时自动註音为「hao hao de」、「hao hao di」
八股文
Rime 有一份名为【八股文】的预设词汇表。
多数输入方案需要用到一些标準白话文中的通用词汇。为免重复在每份码表中包含这些词汇,减少输入方案维护成本,Rime 提供了一份预设词汇表及自动编码(註音)的设施。
创作输入方案时,如果希望完全控制词汇表的内容而不採用【八股文】中的词组,只须直接将词汇编入码表即可。
否则,在词典文件中设定 use_preset_vocabulary: true 将【八股文】导入该词典; 在码表中给出单字码、需要分辨多音字的词组编码、以及该输入方案特有的词汇,其他交给自动註音来做就好啦。
Rime预设输入方案正是利用这份词汇表及自动註音工具,在不牺牲效果及可维护性的前提下、使词典文件压缩到最小的行数。
【八股文】包含从 CC-CEDICT、新酷音等开源项目中整理出来的约二十三万条词汇,其用字及词频数据针对传统汉字做过调整。因此基於这份词汇表產生的输入结果,比较接近以传统汉字行文的实际用法。
为了充分利用【八股文】提供的词汇,自定义的词典应保证单字码表收录了符合 opencc 字形标準的常用字。特别注意,该标準对以下几组异体字的取捨,【八股文】将这些字(包括词组及字频)统一到左边一列的字形。
为 為 伪 偽 嬀 媯 为 溈 兄 凶 启 啟 棱 稜 污 污 泄 洩 涌 涌 牀 床 着 著 灶 灶 群 群 众 眾 里 裡 踊 踊 覈 核部署过程中,未能完成自动註音的字、词会以警告形式出现在日誌文件里。如果所报告的字为生僻字、您可以忽略他;如果警告中大量出现某个常用字,那麼应该注意到码表里缺失了该字的註音。
编译输入方案
将写好的输入方案佈署到 Rime 输入法的过程,称为「编译」:
为查询效率故,输入法工作时不直接加载文本格式的词典源文件,而要在编译过程中,为输入方案生成专为高速查询设计的「.bin」文件。
编译时程序做以下几件事:
•将用户的定製内容合併到输入方案定义中,在用户资料夹生成 .schema.yaml 文档副本;
•依照输入方案中指定的词典:求得音节表(不同种编码的集合)、单字表;
•对词典中未提供编码的词组自动註音,也包括从【八股文】导入的词组;
•建立按音节编码检索词条的索引,製作 Rime 固态词典;
•建立按词条检索编码的索引,製作 Rime 反查词典;
•依照音节表和方案定义中指定的拼写运算规则,製作 Rime 棱镜。
佈署 Rime
初次安装 Rime 输入法,无有任何输入方案和用户设定。因此安装的最后一个步骤即是把发行版预设的输入方案和设定文件佈署到 Rime 为该用户创建的工作目录,至此 Rime 纔成为一部可以发动的输入引擎。
此后无论是修改已有方案的设定,或是添加了新的输入方案,都需要「重新佈署 Rime」成功后方可使用户的新设定作用於 Rime 输入法。
〔★〕重新佈署 Rime 的方法是:
•【小狼毫】在托盘图标上右键选择「重新佈署」;
•【鼠鬚管】在系统语言文字选单中选择「重新佈署」;
•【中州韵】点击输入法状态栏上的 ⟲ (Deploy) 按钮;
•早於 ibus-rime 0.9.2 的版本:删除用户资料夹的 default.yaml 之后、执行 ibus-daemon -drx 重载 IBus
定製指南
Rime 输入方案,将 Rime 输入法的设定整理成完善的、可分发的形式。 但并非一定要创作新的输入方案,才可以改变 Rime 的行为。
当用户需要对 Rime 中的各种设定做小幅的调节,最直接、但不完全正确的做法是:编辑用户资料夹中那些 .yaml 文档。
这一方法有弊端:
•当 Rime 软件升级时,也会升级各种设定档、预设输入方案。用户编辑过的文档会被覆写为更高版本,所做调整也便丢失了。
•即使在软件升级后再手动恢复经过编辑的文件,也会因设定档的其他部分未得到更新而失去本次升级新增和修复的功能。
因此,对於随 Rime 发行的设定档及预设输入方案,推荐的定製方法是:
创建一个文件名的主体部份(「.」之前)与要定製的文件相同、次级扩展名(位於「.yaml」之前)写作 .custom 的定製档,形如:
patch: "一级设定项/二级设定项/三级设定项": 新的设定值 "另一个设定项": 新的设定值 "再一个设定项": 新的设定值patch 定义了一组「补靪」,以源文件中的设定为底本,写入新的设定项、或以新的设定值取代旧有的值。
重要!创作了新的输入方案,最后一步就是在「方案选单」里启用他。
拼写运算
应该算是 Rime 输入法最主要的独创技术。
概括来说就是将方案中的编码通过规则映射到一组全新的拼写形式! 也就是说能让 Rime 输入方案在不修改码表的情况下、适应不同的输入习惯。
拼写运算能用来:
•改革拼写法
◦将编码映射到基於同一音系的其他拼写法,如注音、拼音、国语罗马字相互转换
◦重定义注音键盘、双拼方案
•实现简拼查询
•在音节表上灵活地定义模糊音规则
•实现音节自动纠错
•变换回显的输入码或提示码,如将输入码显示为字根、注音符号、带声调标註的罗马字
给力吗?
综合演练
如果你安装好了Rime却不会玩,就一步一步跟我学吧。
【一】破空中出鞘
Hello, Rime!
第一个例子,总是最简单的(也是最傻的)。
# Rime schema # encoding: utf-8 # # 最简单的 Rime 输入方案 # schema: schema_id: hello # 注意此ID与文件名里 .schema.yaml 之前的部分相同 name: 大家好 # 将在〔方案选单〕中显示 version: "1" # 这是文字类型而非整数或小数,如 "1.2.3"起首几行是註释。而后只有一组必要的方案描述信息。
这一课主要练习建立格式正确的YAML文档。
•要点一,让你的文本编辑器以UTF-8编码保存该文件;
•要点二,注意将 schema: 之下的三行代码以空格缩进——我的习惯是用两个空格——而 不要 用Tab字符来缩进。
缩进表示设定项所属的层次。在他处引用到此文档中的设定项,可分别以 schema/schema_id, schema/name, schema/version 来指称。
我现在把写好的方案文档命名为 hello.schema.yaml,丢进用户资料夹——对,只要这一个文件就妥了;
然后,启用他。有些版本会有「方案选单设定」这个介面,在那里勾选【大家好】这个方案即可。若无有设定介面,则按照上文《定製方案选单》一节来做。
好运!我已建立了一款名为【大家好】的新方案!虽然他没有实现任何效果、按键仍会像无有输入法一样直接输出西文。
开始改装
为了处理字符按键、生成输入码,本例向输入引擎添加两个功能组件。
以下代码仍是ID为 hello 的新款输入方案,但增加了 schema/version 的数值。 以后每个版本,都以前一个版本为基础改写,引文略去无有改动的部分,以突出重点。
# ... schema: schema_id: hello name: 大家好 version: "2" engine: processors: - fluency_editor segmentors: - fallback_segmentorfluency_editor 将字符按键记入输入上下文,fallback_segmentor 将输入码连缀成一段。於是重新佈署后,按下字符键不再直接上屏,而显示为输入码。
你会发现,该输入法只是收集了键盘上的可打印字符,并於按下空格、回车键时令输入码上屏。
现在就好似写输入法程序的过程中,将将取得一小点成果,还有很多逻辑未实现。不同的是,在Rime输入方案里写一行代码,顶 Rime 开发者所写的上百上千行。因此我可以很快地组合各种逻辑组件、搭建出心里想的输入法。
创建候选项¶第二版的【大家好】将键盘上所有字符都记入输入码,这对整句输入有用,但是时下流行输入法只处理编码字符、其他字符直接上屏的形式。为了对编码字符做出区分,以下改用 speller + express_editor 的组合取代 fluency_editor:
# ... schema: # ... version: "3" engine: processors: - speller # 把字母追加到编码串 - express_editor # 空格确认当前输入、其他字符直接上屏 segmentors: - fallback_segmentorspeller 默认只接受小写拉丁字母作为输入码。 试试看,输入其他字符如大写字母、数字、标点,都会直接上屏。并且如果已经输入了编码时,下一个直接上屏的字符会将输入码顶上屏。
再接着,创建一个最简单的候选项——把编码串本身作为一个选项。故而会提供这个选项的新组件名叫 echo_translator。
# ... engine: # ... translators: - echo_translator # (无有其他结果时,)创建一个与编码串一个模样的候选项至此,【大家好】看上去与一个真正的输入法形似啦。只是还不会打出「大家好」哇?
编写词典
那就写一部词典,码表中设定以 hello 作为短语「大家好」的编码:
# Rime dictionary # encoding: utf-8 --- name: hello version: "1" sort: original ... 大家好 hello 再见 bye 再会 bye※注意: 不要 从网页复製以上代码到实作的词典文件!因为网页里製表符被转换成空格从而不符合 Rime 词典要求的格式。
同时修改方案定义:
#... schema: # ... version: "4" engine: #... segmentors: - abc_segmentor # 标记输入码的类型 - fallback_segmentor translators: - echo_translator - table_translator # 码表式转换 translator: dictionary: hello # 设定 table_translator 使用的词典名工作流程是这样的:
•speller 将字母键加入输入码序列
•abc_segmentor 给输入码打上标籤 abc
•table_translator 把带有 abc 籤的输入码以查表的方式译为中文
•table_translator 所查的码表在 translator/dictionary 所指定的词典里
现在可以敲 hello 而打出「大家好」。完工!
实现选字及换页
等一下。
记得 hello 词典里,还有个编码叫做 bye。敲 bye,Rime 给出「再见」、「再会」两个候选短语。
这时敲空格键,就会打出「再见」;那麼怎样打出「再会」呢?
大家首先想到的方法,是:打完编码 hello,按 1 选「再见」,按 2 选「再会」。 可是现在按下 2 去,却是上屏「再见」和数字「2」。可见并没有完成数字键选字的处理,而是将数字同其他符号一样做了顶字上屏处理。
增加一部 selector,即可实现以数字键选字。
schema: # ... version: "5" engine: processors: - speller - selector # 选字、换页 - navigator # 移动插入点 - express_editor # ...selector 除了数字键,还响应前次页、上下方向键。因此选择第二候选「再会」,既可以按数字2,又可以按方向键「↓」将「再会」高亮、再按空格键确认。
navigator 处理左右方向键、Home、End键,实现移动插入点的编辑功能。有两种情况需要用到他:一是发现输入码有误需要定位修改,二是缩小候选词对应的输入码的范围、精準地编辑新词组。
接下来向词典添加一组重码,以检验换页的效果:
--- name: hello version: "2" sort: original ... 大家好 hello 再见 bye 再会 bye 星期一 monday 星期二 tuesday 星期三 wednesday 星期四 thursday 星期五 friday 星期六 saturday 星期日 sunday 星期一 weekday 星期二 weekday 星期三 weekday 星期四 weekday 星期五 weekday 星期六 weekday 星期日 weekday默认每页候选数为5,输入 weekday,显示「星期一」至「星期五」。再敲 Page_Down 显示第二页后选词「星期六、星期日」。
输出中文标点
schema: # ... version: "6" engine: processors: - speller - punctuator # 处理符号按键 - selector - navigator - express_editor segmentors: - abc_segmentor - punct_segmentor # 划界,与前后方的其他编码区分开 - fallback_segmentor translators: - echo_translator - punct_translator # 转换 - table_translator # ... punctuator: # 设定符号表,这里直接导入预设的 import_preset: default这次的修改,要注意 punctuator, punct_segmentor, punct_translator 相对於其他组件的位置。
punctuator/import_preset 告诉 Rime 使用一套预设的符号表。他的值 default 可以换成其他名字如 xxx,则 Rime 会读取 xxx.yaml 里面定义的符号表。
如今再敲 hello. 就会得到「大家好。」
用符号键换页
早先流行用 - = 这一对符号换页,如今流行用 , 和 . 。 在第六版中「,」「。」是会顶字上屏的。现在要做些处理以达到一键两用的效果。
Rime 提供了 key_binder 组件,他能够在一定条件下,将指定按键绑定为另一个按键。对於本例就是:
•当展现候选菜单时,句号键(period)绑定为向后换页(Page_Down)
•当已有(向后)换页动作时,逗号键(comma)绑定为向前换页(Page_Up)
逗号键向前换页的条件之所以比句号键严格,是为了「,」仍可在未进行换页的情况下顶字上屏。
经过 key_binder 的处理,用来换页的逗号、句号键改头换面为前、后换页键,从而绕过 punctuator,最终被 selector 当作换页来处理。
最终的代码如下:
schema: schema_id: hello name: 大家好 version: "7" engine: processors: - key_binder # 抢在其他 processor 处理之前判定是否换页用的符号键 - speller - punctuator # 否则「,。」就会由此上屏 - selector - navigator - express_editor segmentors: - abc_segmentor - punct_segmentor - fallback_segmentor translators: - echo_translator - punct_translator - table_translator translator: dictionary: hello punctuator: import_preset: default key_binder: bindings: # 每条定义包含条件、接收按键(IBus规格的键名,可加修饰符,如「Control+Return」)、发送按键 - when: paging # 仅当已发生向后换页时, accept: comma # 将「逗号」键…… send: Page_Up # 关联到「向前换页」;於是 navigator 将收到一发 Page_Up - when: has_menu # 只要有候选字即满足条件 accept: period send: Page_Down【二】修炼之道¶与【大家好】这个方案不同。以下一组示例,主要演示如何活用符号键盘,以及罗马字转写式输入。
改造键盘
莫以为【大家好】是最最简单的输入方案。码表式输入法,不如「键盘式」输入法来得简单明快!
用 punctuator 这一套组件,就可实现一款键盘输入法:
# Rime schema # encoding: utf-8 schema: schema_id: numbers name: 数字之道 version: "1" engine: processors: - punctuator - express_editor segmentors: - punct_segmentor translators: - punct_translator punctuator: half_shape: &symtable "1" : 一 "2" : 二 "3" : 三 "4" : 四 "5" : 五 "6" : 六 "7" : 七 "8" : 八 "9" : 九 "0" : 〇 "s" : 十 "b" : 百 "q" : 千 "w" : 万 "n" : 年 "y" : [ 月, 元, 亿 ] "r" : 日 "x" : 星期 "j" : 角 "f" : 分 "z" : [ 之, 整 ] "d" : 第 "h" : 号 "." : 点 full_shape: *symtable对,所谓「键盘输入法」,就是按键和字直接对应的输入方式。
这次,不再写 punctuator/import_preset 这项,而是自订了一套符号表。
鴰!原来 punctuator 不单可以用来打出标点符号;还可以重定义空格以及全部 94 个可打印 ASCII 字符(码位 0x20 至 0x7e)。
在符号表代码里,用对应的ASCII字符表示按键。记得这些按键字符要放在引号里面,YAML 纔能够正确解析喔。
示例代码表演了两种符号的映射方式:一对一及一对多。一对多者,按键后符号不会立即上屏,而是……嘿嘿,自己体验吧 :-)
关於代码里 symtable 的一点解释:
这是YAML的一种语法,&symtable 叫做「锚点标籤」,给紧随其后的内容起个名字叫 symtable; *symtable 则相当於引用了 symtable 所标记的那段内容,从而避免重复。 Rime 里的符号有「全角」、「半角」两种状态。本方案里暂不作区分,教 half_shape、full_shape 使用同一份符号表。
大写数字键盘
灵机一动,不如利用「全、半角」模式来区分「大、小写」中文数字!
schema: # ... version: "2" switches: - name: full_shape states: [ 小写, 大写 ] # ...先来定义状态开关:0态改「半角」为「小写」,1态改「全角」为「大写」。
这样一改,再打开「方案选单」,方案「数字之道」底下就会多出个「小写→大写」的选项,每选定一次、状态随之反转一次。
接着给 half_shape、full_shape 定义不同的符号表:
punctuator: half_shape: "1" : 一 "2" : 二 "3" : 三 "4" : 四 "5" : 五 "6" : 六 "7" : 七 "8" : 八 "9" : 九 "0" : 〇 "s" : 十 "b" : 百 "q" : 千 "w" : 万 "n" : 年 "y" : [ 月, 元, 亿 ] "r" : 日 "x" : 星期 "j" : 角 "f" : 分 "z" : [ 之, 整 ] "d" : 第 "h" : 号 "." : 点 full_shape: "1" : 一 "2" : 贰 "3" : 参 "4" : 肆 "5" : 伍 "6" : 陆 "7" : 柒 "8" : 捌 "9" : 玖 "0" : 零 "s" : 拾 "b" : 佰 "q" : 仟 "w" : 万 "n" : 年 "y" : [ 月, 圆, 亿 ] "r" : 日 "x" : 星期 "j" : 角 "f" : 分 "z" : [ 之, 整 ] "d" : 第 "h" : 号 "." : 点哈,调出选单切换一下大小写,输出的字全变样!酷。
但是要去选单切换,总不如按下 Shift 就全都有了:
punctuator: half_shape: # ... 添加以下这些 "!" : 一 "@" : 贰 "#" : 参 "$" : [ 肆, ¥, "$", "€", "£" ] "%" : [ 伍, 百分之 ] "^" : 陆 "&" : 柒 "*" : 捌 "(" : 玖 ")" : 零 "S" : 拾 "B" : 佰 "Q" : 仟 "Y" : 圆於是在「小写」态,只要按 Shift + 数字键即可打出大写数字。
用了几下,发现一处小小的不满意:敲 $ 这个键,可选的符号有五个之多。想要打出殴元、英镑符号只得多敲几下 $ 键使想要的符号高亮;但是按上、下方向键并没有效果,按符号前面标示的数字序号,更是不仅上屏了错误的符号、还多上屏一个数字——
这反映出两个问题。一是 selector 组件缺席使得选字、移动选字光标的动作未得到响应。立即加上:
# ... engine: processors: - punctuator - selector # 加在这里 - express_editor # ...因为要让 punctuator 来转换数字键,所以 selector 得放在他后头。
好。二一个问题还在:无法用数字序号选字。为解决这个衝突,改用閒置的字母键来选字:
# ... menu: alternative_select_keys: "acegi"完工。
罗马字之道
毕竟,键盘上只有47个字符按键、94个编码字符,对付百十个字还管使。可要输入上千个常用汉字,嫌键盘式输入的编码空间太小,必得採用多字符编码。
罗马字,以拉丁字母的特定排列作为汉语音节的转写形式。一个音节代表一组同音字,再由音节拼写组合成词、句。
凡此单字(音节)编码自然连用而生词、句的输入法,皆可用 r10n_translator 组件完成基於音节码切分的智能词句转换。r10n 为 romanization 的简写。但不限於「拼音」、「注音」、「双拼」、「粤拼」等一族基於语音编码的输入法:形式相似者,如「速成」,虽以字形为本,亦可应用。
现在来把【数字之道】改成拼音→中文数字的变换。
schema: schema_id: numbers name: 数字之道 version: "3" engine: processors: - speller - punctuator - selector - express_editor segmentors: - abc_segmentor - punct_segmentor translators: - punct_translator - r10n_translator translator: dictionary: numbers punctuator: half_shape: &symtable "!" : 一 "@" : 贰 "#" : 参 "$" : [ 肆, ¥, "$", "€", "£" ] "%" : [ 伍, 百分之 ] "^" : 陆 "&" : 柒 "*" : 捌 "(" : 玖 ")" : 零 "S" : 拾 "B" : 佰 "Q" : 仟 "W" : 万 "N" : 年 "Y" : [ 月, 圆, 亿 ] "R" : 日 "X" : 星期 "J" : 角 "F" : 分 "Z" : [ 之, 整 ] "D" : 第 "H" : 号 "." : 点 full_shape: *symtable符号表里,把小写字母、数字键都空出来了。小写字母用来拼音,数字键用来选重。重点是本次用了 r10n_translator 这组件。与 table_translator 相似,该组件与 translator/dictionary 指名的词典相关联。
编製词典:
# Rime dictionary # encoding: utf-8 --- name: numbers version: "1" sort: by_weight use_preset_vocabulary: true ... 一 yi 二 er 三 san 四 si 五 wu 六 liu 七 qi 八 ba 九 jiu 〇 ling 零 ling 十 shi 百 bai 千 qian 万 wan 亿 yi 年 nian 月 yue 日 ri 星 xing 期 qi 时 shi 分 fen 秒 miao 元 yuan 角 jiao 之 zhi 整 zheng 第 di 号 hao 点 dian 是 shi※注意: 不要 从网页复製以上代码到实作的词典文件!因为网页里製表符被转换成空格从而不符合 Rime 词典要求的格式。
码表里给出了一个「示例」规格的小字集。其中包含几组重码字。
要诀 sort: by_weight 意图是不以码表的顺序排列重码字,而是比较字频。那字频呢?没写出来。
要诀 use_preset_vocabulary: true 用在输入方案需要支持输入词组、而码表中词组相对柜乏时。编译输入方案期间引入 Rime 预设的【八股文】词汇——及词频资料!这就是码表中未具字频的原因。
使用【八股文】,要注意码表所用的字形是否与该词汇表一致。八股文的词汇及词频统计都遵照 opencc 繁体字形标準。
如果缺少单字的编码定义,自然也无法导入某些词汇。所以本方案只会导入这个数字「小字集」上的词汇。
用拼写运算定义简码¶如今有了一款专门输入数字的拼音输入法。比一比昇阳拼音、朙月拼音和地球拼音,还有哪里不一样?
很快我发现敲 xingqiwu 或 xingqiw 都可得到来自【八股文】的词组「星期五」,这很好。可是敲 xqw 怎会不中呢?
原来 r10n_translator 罗马字中译的方法是,将输入码序列切分为音节表中的拼写形式,再按音节查词典。不信你找本词典瞧瞧,是不是按完整的拼音(注音)编排的。Rime 词典也一样。并没有 xqw 这样的检索码。
现在我要用 Rime 独门绝活「拼写运算」来定义一种「音序查字法」。令 x 作 xing 的简码,q 作数字之道所有音节中起首为 q 者的简码,即略代音节 qi 与 qian。
「汉语拼音」里还有三个双字母的声符,zh, ch, sh 也可做简码。
添加拼写运算规则:
schema: # ... version: "4" #... speller: algebra: - 'abbrev/^([a-z]).+$/$1/' - 'abbrev/^([zcs]h).+$/$1/'如此 Rime 便知,除了码表里那些拼音,还有若干简码也是行得通的拼写形式。再输入 xqw,Rime 将他拆开 x'q'w,再默默对应到音节码 xing'qi'wan、xing'qi'wu、xing'qian'wan 等等,一翻词典就得到了一个好词「星期五」,而其他的组合都说不通。
现在有无有悟到,罗马字转写式输入法与码表式输入法理念上的不同?
哈,做中了。试试看 sss,sss,sssss,sssss
却好像不是我要的「四是四,十是十,十四是十四,四十是四十」……
好办。如果某些词汇在方案里很重要,【八股文】又未收录,那麼,请添加至码表:
--- name: numbers version: "2" sort: by_weight use_preset_vocabulary: true ... # ... 四是四 十是十 十四是十四 四十是四十善哉。演示完毕。当然休想就此把 Rime 全盘掌握了。一本《指南书》,若能让读者入门,我止说「善哉〜」
再往后,就只有多读代码,纔能见识到各种新颖、有趣的玩法。
【三】最高武艺
〔警告〕最后这部戏,对智力、技术功底的要求不一般。如果读不下去,不要怪我、不要怀疑自己的智商!
即使跳过本节书也无妨,只是不可忽略了下文《关於调试》这一节!(重要哇……)
请检查是否:
•※ 已将前两组实例分析透彻
•※ 学习完了《拼写运算》
•※ 知道双拼是神码
•※ 预习 Rime 预设输入方案之【朙月拼音】
设计一款【智能ABC双拼】输入方案做练习!
# Rime schema # encoding: utf-8 schema: schema_id: double_pinyin_abc # 专有的方案标识 name: 智能ABC双拼 version: "0.9" author: - 佛振 <chen.sst@gmail.com> description: | 朙月拼音,兼容智能ABC双拼方案。 switches: - name: ascii_mode reset: 0 states: [ 中文, 西文 ] - name: full_shape states: [ 半角, 全角 ] - name: simplification states: [ 汉字, 汉字 ] engine: processors: - ascii_composer - recognizer - key_binder - speller - punctuator - selector - navigator - express_editor segmentors: - ascii_segmentor - matcher - abc_segmentor - punct_segmentor - fallback_segmentor translators: - echo_translator - punct_translator - r10n_translator - reverse_lookup_translator filters: - simplifier - uniquifier speller: alphabet: zyxwvutsrqponmlkjihgfedcba # 唉,倒背字母表完全是个人喜好 delimiter: " '" # 隔音符号用「'」;第一位的空白用来自动插入到音节边界处 algebra: # 拼写运算规则,这个纔是实现双拼方案的重点。写法有很多种,当然也可以把四百多个音节码一条一条地列举 - erase/^xx$/ # 码表中有几个拼音不明的字,编码成xx了,消灭他 - derive/^([jqxy])u$/$1v/ - xform/^zh/A/ # 替换声母键,用大写以防与原有的字母混淆 - xform/^ch/E/ - xform/^sh/V/ - xform/^([aoe].*)$/O$1/ # 添上固定的零声母o,先标记为大写O - xform/ei$/Q/ # 替换韵母键 - xform/ian$/W/ # ※2 - xform/er$|iu$/R/ # 对应两种韵母的;音节er现在变为OR了 - xform/[iu]ang$/T/ # ※1 - xform/ing$/Y/ - xform/uo$/O/ - xform/uan$/P/ # ※3 - xform/i?ong$/S/ - xform/[iu]a$/D/ - xform/en$/F/ - xform/eng$/G/ - xform/ang$/H/ # 检查一下在此之前是否已转换过了带介音的ang;好,※1处有了 - xform/an$/J/ # 如果※2、※3还无有出现在上文中,应该把他们提到本行之前 - xform/iao$/Z/ # 对——像这样让iao提前出场 - xform/ao$/K/ - xform/in$|uai$/C/ # 让uai提前出场 - xform/ai$/L/ - xform/ie$/X/ - xform/ou$/B/ - xform/un$/N/ - xform/[uv]e$|ui$/M/ - xlit/QWERTYOPASDFGHJKLZXCVBNM/qwertyopasdfghjklzxcvbnm/ # 最后把双拼码全部变小写 translator: dictionary: luna_pinyin # 与【朙月拼音】共用词典 prism: double_pinyin_abc # prism 要以本输入方案的名称来命名,以免把朙月拼音的拼写映射表覆盖掉 preedit_format: # 这段代码用来将输入的双拼码反转为全拼显示;待见双拼码的可以把这段拿掉 - xform/o(\w)/0$1/ # 零声母先改为0,以方便后面的转换 - xform/(\w)q/$1ei/ # 双拼第二码转换为韵母 - xform/(\w)n/$1un/ # 提前转换双拼码 n 和 g,因为转换后的拼音里就快要出现这两个字母了,那时将难以分辨出双拼码 - xform/(\w)g/$1eng/ # 当然也可以採取事先将双拼码变为大写的办法来与转换过的拼音做区分,可谁让我是高手呢 - xform/(\w)w/$1ian/ - xform/([dtnljqx])r/$1iu/ # 对应多种韵母的双拼码,按搭配的声母做区分(最好别用排除式如 [^o]r 容易出状况) - xform/0r/0er/ # 另一种情况,注意先不消除0,以防后面把e当作声母转换为ch - xform/([nljqx])t/$1iang/ - xform/(\w)t/$1uang/ # 上一行已经把对应到 iang 的双拼码 t 消灭,於是这里不用再列举相配的声母 - xform/(\w)y/$1ing/ - xform/([dtnlgkhaevrzcs])o/$1uo/ - xform/(\w)p/$1uan/ - xform/([jqx])s/$1iong/ - xform/(\w)s/$1ong/ - xform/([gkhaevrzcs])d/$1ua/ - xform/(\w)d/$1ia/ - xform/(\w)f/$1en/ - xform/(\w)h/$1ang/ - xform/(\w)j/$1an/ - xform/(\w)k/$1ao/ # 默默检查:双拼码 o 已经转换过了 - xform/(\w)l/$1ai/ - xform/(\w)z/$1iao/ - xform/(\w)x/$1ie/ - xform/(\w)b/$1ou/ - xform/([nl])m/$1ve/ - xform/([jqxy])m/$1ue/ - xform/(\w)m/$1ui/ - "xform/(^|[ '])a/$1zh/" # 复原声母,音节开始处的双拼字母a改写为zh;其他位置的才真正是a - "xform/(^|[ '])e/$1ch/" - "xform/(^|[ '])v/$1sh/" - xform/0(\w)/$1/ # 好了,现在可以把零声母拿掉啦 - xform/([nljqxy])v/$1ü/ # 这样纔是汉语拼音 :-) reverse_lookup: dictionary: cangjie5 prefix: "`" tips: 〔仓頡〕 preedit_format: - "xlit|abcdefghijklmnopqrstuvwxyz|日月金木水火土竹戈十大中一弓人心手口尸廿山女田难卜符|" comment_format: - xform/([nl])v/$1ü/ punctuator: import_preset: default key_binder: import_preset: default recognizer: import_preset: default patterns: reverse_lookup: "`[a-z]*$"完毕。
这是一道大题。通过改造拼写法而创作出新的输入方案。
关於调试¶如此复杂的输入方案,很可能需要反覆调试方可达到想要的结果。
请於试验时及时查看日誌中是否包含错误信息。日誌文件位於:
•【中州韵】 /tmp/rime.ibus.*
•【小狼毫】 %TEMP%\rime.weasel.*
•【鼠鬚管】 $TMPDIR/rime.squirrel.*
•各发行版的早期版本 用户资料夹/rime.log
按照日誌的级别分为 INFO / 信息、WARNING / 警告、ERROR / 错误。 后两类应重点关注,如果新方案部署后不可用或输出与设计不一致,原因可能在此。
没有任何错误信息,就是不好使,有可能是码表本身的问题,比如把码表中文字和编码两列弄颠倒了——Rime 等你输入由汉字组成的编码,然而键盘没有可能做到这一点(否则也不再需要输入法了)。
后续有计划为输入方案创作者开发名为「拼写运算调试器」的工具,能够较直观地看到每一步拼写运算的结果。有助於定义双拼这样大量使用拼写运算的方案。
东风破¶「东风破早梅,向暖一枝开。」
构想在 Rime 输入软件完善后、能够连结汉字字形、音韵、输入法爱好者的共同兴趣,形成稳定的使用者社群,搭建一个分享知识的平臺。
而【东风破】,定义为 Rime 输入方案仓库,则是分享 Rime 输入方案的平臺。
Rime 是一款强调个性的输入法。
Rime 不要定义输入法应当是哪个样、而要定义输入法可以玩出哪些花样。
Rime 不可能通过预设更多的输入方案来满足玩家的需求;真正的玩家一定有一般人想不到的高招。
未来一定会有,【东风破】,让用家轻鬆地找到最新、最酷、最适合自己的 Rime 输入方案。
教程终于是介绍完了~~各位大大们还得慢慢研究的~