轉(zhuǎn)自 https://github.com/rime
Rime 輸入方案創(chuàng)作者的第一本參考書
※ 佛振 chen.sst@gmail.com 修訂于 2013年5月4日
作者的一點(diǎn)主張:選用適合自己的輸入法。
來折騰 Rime 的同學(xué),我只能說,您對(duì)輸入法的追求比較與衆(zhòng)不同啦!
當(dāng)然,因爲(wèi)您理想中的輸入方式千奇百怪、也許從沒有人那樣玩過,所以不可能在那種勾勾選選的介面上做得出來;需要親手來創(chuàng)作——
Rime 輸入方案!
Rime 不是一種輸入法。是從各種常見鍵盤輸入法中提煉出來的抽象的輸入算法框架。因爲(wèi) Rime 涵蓋了大多數(shù)輸入法的「共性」,所以在不同的設(shè)定下,Rime 可化身爲(wèi)不同的輸入法用來打字。
要讓 Rime 實(shí)現(xiàn)某種具體輸入法的功能,就需要一些數(shù)據(jù)來描述這種輸入法以何種形式工作。即,定義該輸入法的「個(gè)性」。
如「漢語拼音」、「注音」、「倉頡碼」、「五筆字型」,這些方法可憑藉 Rime 提供的通用設(shè)施、給定不同的工作參數(shù)來實(shí)作。以本文介紹的規(guī)格寫成一套套的配方,就是 Rime 輸入方案。
一鍵就搞掂,必然選項(xiàng)少,功能單一。不好玩。
輸入法程序一寫兩三年,也許還不夠火候;花兩三個(gè)小時(shí)來讀入門書,已是輸入法專業(yè)速成班。
Rime 是跨平臺(tái)的輸入法軟件,Rime 輸入方案可通用于以下發(fā)行版:
取得適合你系統(tǒng)的最新版 Rime 輸入法,印一份《指南書》,準(zhǔn)備開工了!
文本爲(wèi)王。
Rime 的配置文件、輸入方案定義及詞典文件,均爲(wèi)特定格式的文本文檔。
因此,一款夠?qū)I(yè)的 文本編輯器 ,是設(shè)計(jì) Rime 輸入方案的必備工具。
Rime 中所有文本文檔,均要求以 UTF-8 編碼,并建議使用 UNIX 換行符(LF)。
鑑于一些文本編輯器會(huì)爲(wèi) UTF-8 編碼的文件添加 BOM 標(biāo)記,爲(wèi)防止誤將該字符溷入文中,
莫要從文件的第一行開始正文,而請(qǐng)?jiān)谠撔行惺滓?# 記號(hào)起一行注釋,如:
# Rime default settings# Rime schema: My First Cool Schema# Rime dictionary: Lingua Latina
也可繼續(xù)以注釋行寫下方案簡介、碼表來源、製作者、修訂記錄等信息,再切入正文。
Rime 輸入法中,多用擴(kuò)展名爲(wèi)「.yaml
」的文本文檔,這是以一種可讀性高的數(shù)據(jù)描述語言—— YAML 寫成。
請(qǐng)?jiān)L問 http://yaml.org/ 瞭解 YAML 文檔格式。
下文只對(duì)部分語法作簡要說明,而將重點(diǎn)放在對(duì)語義的解讀上面。
Rime 輸入方案亦會(huì)用到「正則表達(dá)式」實(shí)現(xiàn)一些高級(jí)功能。
輸入方案設(shè)計(jì)者需要掌握這份文檔所描述的 Perl 正則表達(dá)式語法:
http://www.boost.org/doc/libs/1_49_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html
除程序文件以外,Rime 還包括多種數(shù)據(jù)文件。
這些數(shù)據(jù)文件存在于以下位置:
共享資料夾
/usr/share/rime-data/
'安裝目錄\data'
'/Library/Input Methods/Squirrel.app/Contents/SharedSupport/'
用戶資料夾
~/.config/ibus/rime/
(0.9.1 以下版本爲(wèi) ~/.ibus/rime/
)'%APPDATA%\Rime'
~/Library/Rime/
共享資料夾包含預(yù)設(shè)輸入方案的源文件。
這些文件屬于 Rime 所發(fā)行軟件的一部份,在訪問權(quán)限控制較嚴(yán)格的系統(tǒng)上對(duì)用戶是只讀的,因此謝絕軟件版本更新以外的任何修改——
一旦用戶修改這里的文件,很可能影響后續(xù)的軟件升級(jí)或在升級(jí)時(shí)丟失數(shù)據(jù)。
在「部署 Rime」操作時(shí),將用到這里的輸入方案源文件、并結(jié)合用戶定製的內(nèi)容來編譯預(yù)設(shè)輸入方案。
用戶資料夾則包含爲(wèi)用戶準(zhǔn)備的內(nèi)容,如:
〔全局設(shè)定〕 default.yaml
〔發(fā)行版設(shè)定〕 weasel.yaml
〔預(yù)設(shè)輸入方案副本〕 <方案標(biāo)識(shí)>.schema.yaml
※〔安裝信息〕 installation.yaml
※〔用戶狀態(tài)信息〕 user.yaml
編譯輸入方案所產(chǎn)出的二進(jìn)制文件:
<方案標(biāo)識(shí)>.prism.bin
<詞典名>.table.bin
<詞典名>.reverse.bin
記錄用戶寫作習(xí)慣的文件:
<詞典名>.userdb.kct
<詞典名>.userdb.txt
、<詞典名>.userdb.kct.snapshot
見于同步文件夾以及用戶自己設(shè)定的:
default.custom.yaml
<方案標(biāo)識(shí)>.custom.yaml
注:以上標(biāo)有 ※ 號(hào)的文件,包含用戶資料,您在清理文件時(shí)要注意備份!
一套輸入方案,通常包含「方案定義」和「詞典」文件。
方案定義,命名爲(wèi) <方案標(biāo)識(shí)>.schema.yaml
,是一份包含輸入方案配置信息的 YAML 文檔。
文檔中需要有這樣一組方案描述:
# 以下代碼片段節(jié)選自 luna_pinyin.schema.yamlschema: schema_id: luna_pinyin name: 朙月拼音 version: '0.9' author: - 佛振 <chen.sst@gmail.com> description: | Rime 預(yù)設(shè)的拼音輸入方案。
首先來爲(wèi)方案命名。schema/name
字段是顯示在〔方案選單〕中的名稱。
然后——重點(diǎn)是——要定一個(gè)在整個(gè) Rime 輸入法中唯一的「方案標(biāo)識(shí)」,即 schema/schema_id
字段的內(nèi)容。
方案標(biāo)識(shí)由小寫字母、數(shù)字、下劃線構(gòu)成。
僅于輸入法內(nèi)部使用,且會(huì)構(gòu)成方案定義文件名的一部分,因此爲(wèi)了兼容不同的文件系統(tǒng),不要用大寫字母、漢字、空格和其他符號(hào)做方案標(biāo)識(shí)。
一例:這款名爲(wèi)【朙月拼音】的輸入方案,方案標(biāo)識(shí)爲(wèi)「luna_pinyin
」。
方案如做升級(jí),通過版本號(hào)(schema/version
)來區(qū)分相互兼容的新舊版本。
版本號(hào)——以「.」分隔的整數(shù)(或文字)構(gòu)成的字符串。
如下都是版本號(hào)常見的形式:
'1' # 最好加引號(hào)表明是字符串!'1.0' # 最好加引號(hào)表明是字符串!'0.9.8''0.9.8.custom.86427531' # 這種形式是經(jīng)過用戶自定義的版本;自動(dòng)生成
然而,若對(duì)方案的升級(jí)會(huì)導(dǎo)致原有的用戶輸入習(xí)慣無法在新的方案中繼續(xù)使用,則需要換個(gè)新的方案標(biāo)識(shí)。
比如【倉頡五代】之于【倉頡三代】、【五筆98】之于【五筆86】,其實(shí)已是互不兼容的輸入法。
schema/author
——列出作者和主要貢獻(xiàn)者,格式爲(wèi)文字列表:
schema: author: - 作者甲 <alpha@rime.org> - 作者乙 <beta@rime.org> - 作者丙
schema/description
——對(duì)方案作簡要介紹的多行文字。
以上 schema/schema_id
、schema/version
字段用于在程序中識(shí)別輸入方案,
而 schema/name
、schema/author
、schema/description
則主要是展示給用戶的信息。
除方案描述外,方案定義文件中還包含各種功能設(shè)定,控制著輸入法引擎的工作方式。
論 Rime 輸入法的工作流程:
按鍵消息→后臺(tái)「服務(wù)」→分配給對(duì)應(yīng)的「會(huì)話」→由「方案選單」或「輸入引擎」處理……
這里要點(diǎn)是,有會(huì)話的概念:多窗口、多線操作嘛,你懂得的,同時(shí)與好幾位 MM 聊天時(shí),有無有好幾組會(huì)話。
每一組會(huì)話中都有一部輸入引擎完成按鍵序列到文字的變換。
Rime 可以在不同會(huì)話里使用不同輸入方案。因爲(wèi)有「方案選單」。
方案選單本身可響應(yīng)一些按鍵。但由于他不會(huì)寫字的緣故,更多時(shí)候要把按鍵遞給同一會(huì)話中的「輸入引擎」繼續(xù)處理。
方案選單的貢獻(xiàn),就是給用戶一個(gè)便捷的方案切換介面,再把用戶挑中的輸入方案加載到輸入引擎。
再論輸入引擎的工作流程:
加載輸入方案、預(yù)備功能組件;各就位之后就進(jìn)入處理按鍵消息、處理按鍵消息……的循環(huán)。
響應(yīng)各種按鍵、產(chǎn)生各類結(jié)果的工作,由不同的功能組件分擔(dān)。
好,看代碼:
# luna_pinyin.schema.yaml# ...engine: # 輸入引擎設(shè)定,即掛接組件的「處方」 processors: # 一、這批組件處理各類按鍵消息 - ascii_composer # ※ 處理西文模式及中西文切換 - recognizer # ※ 與 matcher 搭配,處理符合特定規(guī)則的輸入碼,如網(wǎng)址、反查等 - key_binder # ※ 在特定條件下將按鍵綁定到其他按鍵,如重定義逗號(hào)、句號(hào)爲(wèi)候選翻頁鍵 - speller # ※ 拼寫處理器,接受字符按鍵,編輯輸入碼 - punctuator # ※ 句讀處理器,將單個(gè)字符按鍵直接映射爲(wèi)文字符號(hào) - selector # ※ 選字處理器,處理數(shù)字選字鍵、上、下候選定位、換頁鍵 - navigator # ※ 處理輸入欄內(nèi)的光標(biāo)移動(dòng)鍵 - express_editor # ※ 編輯器,處理空格、回車上屏、回退鍵等 segmentors: # 二、這批組件識(shí)別不同內(nèi)容類型,將輸入碼分段 - ascii_segmentor # ※ 標(biāo)識(shí)西文段落 - matcher # ※ 標(biāo)識(shí)符合特定規(guī)則的段落,如網(wǎng)址、反查等 - abc_segmentor # ※ 標(biāo)識(shí)常規(guī)的文字段落 - punct_segmentor # ※ 標(biāo)識(shí)句讀段落 - fallback_segmentor # ※ 標(biāo)識(shí)其他未標(biāo)識(shí)段落 translators: # 三、這批組件翻譯特定類型的編碼段爲(wèi)一組候選文字 - echo_translator # ※ 沒有其他候選字時(shí),回顯輸入碼 - punct_translator # ※ 轉(zhuǎn)換標(biāo)點(diǎn)符號(hào) - script_translator # ※ 腳本翻譯器,用于拼音等基于音節(jié)表的輸入方案 - reverse_lookup_translator # ※ 反查翻譯器,用另一種編碼方案查碼 filters: # 四、這批組件過濾翻譯的結(jié)果 - simplifier # ※ 繁簡轉(zhuǎn)換 - uniquifier # ※ 過濾重複的候選字,有可能來自繁簡轉(zhuǎn)換
注:除示例代碼中引用的組件外,尚有
- fluid_editor # ※ 句式編輯器,用于以空格斷詞、回車上屏的【注音】、【語句流】等輸入方案,替換 express_editor,也可以寫作 fluency_editor- chord_composer # ※ 和絃作曲家或曰并擊處理器,用于【宮保拼音】等多鍵并擊的輸入方案- table_translator # ※ 碼表翻譯器,用于倉頡、五筆等基于碼表的輸入方案,替換 script_translator
輸入引擎把完成具體功能的邏輯拆分爲(wèi)可裝卸、組合的部件。
「加載」輸入方案,即按該處方掛接所需的功能組件、令這些組件從輸入方案定義中加載各自的設(shè)定、準(zhǔn)備各司其職。
而他們接下來要完成的作業(yè),由引擎收到的一份按鍵消息引發(fā)。
輸入引擎,作爲(wèi)整體來看,以按鍵消息爲(wèi)輸入,輸出包括三部分:
那麼第一類功能組件 processor
s,就是比較籠統(tǒng)地、起著「處理」按鍵消息的作用。
按鍵消息依次送往列表中的 processor
,由他給出對(duì)按鍵的處理意見:
processor
繼續(xù)看。優(yōu)先級(jí)依照 processors
列表順序排定,接收按鍵者會(huì)針對(duì)按鍵消息做處理。
雖然看起來 processor
通過組合可以承擔(dān)引擎的全部任務(wù),但爲(wèi)了將邏輯繼續(xù)細(xì)分、Rime 又爲(wèi)引擎設(shè)置了另外三類功能組件。這些組件都可以訪問引擎中的數(shù)據(jù)對(duì)象——輸入上下文,并將各自所做處理的階段成果存于其中。
processor
最常見的處理,便是將按鍵所產(chǎn)生的字符記入上下文中的「輸入碼」序列。
當(dāng)「輸入碼」發(fā)生變更時(shí),下一組組件 segmentor
s 開始一輪新的作業(yè)。
Rime 可將文字、數(shù)字、符號(hào)等不同內(nèi)容連續(xù)輸入,此時(shí)需要識(shí)別不同格式的輸入碼、將輸入碼分成若干段分而治之。
這通過數(shù)輪代碼段劃分操作完成。每一輪操作中、一衆(zhòng) segmentor
s 分別給出起始于某一處、符合特定格式的代碼段,識(shí)別到的最長代碼段成爲(wèi)本輪劃分的結(jié)果,而給出這一劃分的一個(gè)或多個(gè) segmentor
組件則可爲(wèi)該代碼段打上「類型標(biāo)籤」;從這一新代碼段的結(jié)束位置,開始下一輪劃分,直到整個(gè)輸入碼序列劃分完畢。
舉例來說,【朙月拼音】中,輸入碼 2012nian\
,劃分爲(wèi)三個(gè)編碼段:2012
(貼number
標(biāo)籤)、nian
(貼abc
標(biāo)籤)、\
(貼punct
標(biāo)籤)。
那些標(biāo)籤是初步劃分后判定的類型,也可能有一個(gè)編碼段貼多個(gè)標(biāo)籤的情況。下一個(gè)階段中,translator
s 會(huì)把特定類型的編碼段翻譯爲(wèi)文字。
顧名思義,translator
完成由編碼到文字的翻譯。但有幾個(gè)要點(diǎn):
translator
組件往往只翻譯具有特定標(biāo)籤的代碼段。translator
分別翻譯、翻譯結(jié)果按一定規(guī)則合併成一列候選。雙目如探針般進(jìn)入內(nèi)存查看,發(fā)現(xiàn)翻譯的結(jié)果呈現(xiàn)這種形式:
input | tag | translations------+--------+-------------------------------------2012 | number | [ '2012' ], [ '二〇一二' ]nian | abc | [ '年', '念', '唸',... ], [ 'nian' ]\ | punct | [ '、', '\' ]
輸入串劃分爲(wèi)多個(gè)代碼段、每段代碼又可具有多組翻譯結(jié)果;取各代碼段的首選結(jié)果連接起來,就是預(yù)備上屏的文字「2012年、
」。
且將以上所示的數(shù)據(jù)稱爲(wèi)「作文」。這是一篇未定稿(未搞定)的作文,輸入法介面此時(shí)顯示預(yù)備上屏的文字「2012年、
」,并列出最末一個(gè)代碼段上的候選「、
」及「\
」以供選擇。
有兩款主力 translator
完成主要文字內(nèi)容的翻譯,其實(shí)現(xiàn)的方式很不一樣:
script_translator
也叫做 r10n_translator
修煉羅馬字分析法,以「固定音節(jié)表」?fàn)?wèi)算法的基礎(chǔ),識(shí)別輸入碼的音節(jié)構(gòu)成,推敲排列組合、完成遣詞造句。table_translator
修煉傳承自上世紀(jì)的碼表功夫,基于規(guī)則的動(dòng)態(tài)碼表,構(gòu)成編碼空間內(nèi)一個(gè)開放的編碼集合。拼音、注音、方言拼音,皆是以固定音節(jié)表上的拼寫排列組合的方式產(chǎn)生編碼,故適用羅馬字分析法。
倉頡、五筆字型這類則是傳統(tǒng)的碼表輸入法。
如果以碼表方式來寫拼音輸入方案,是怎樣的效果呢?雖然仍可完成輸入,但無法完全實(shí)現(xiàn)支持簡拼、模煳拼音、使用隔音符號(hào)的動(dòng)態(tài)調(diào)頻、智能語句等有用的特性。
反之,以羅馬字方式使用碼表輸入法,則無法實(shí)現(xiàn)定長編碼頂字上屏、按編碼規(guī)則構(gòu)詞等功能。在 Rime 各發(fā)行版預(yù)設(shè)輸入方案中,有一款「速成」輸入方案,即是以 script_translator
翻譯倉頡碼,實(shí)現(xiàn)全、簡碼溷合的語句輸入。
概括起來,這是兩種構(gòu)造新編碼的方式:羅馬字式輸入方案以一組固定的基本音節(jié)碼創(chuàng)造新的組合而構(gòu)詞,而碼表式輸入方案則以一定碼長爲(wèi)限創(chuàng)造新的編碼映射而構(gòu)詞。
上一步已經(jīng)收集到各個(gè)代碼段的翻譯結(jié)果,當(dāng)輸入法需要在介面呈現(xiàn)一頁候選項(xiàng)時(shí),就從最末一個(gè)代碼段的結(jié)果集中挑選、直至取夠方案中設(shè)定的頁最大候選數(shù)。
每從結(jié)果集選出一條字詞、會(huì)經(jīng)過一組 filter
s 過濾。多個(gè) filter
串行工作,最終產(chǎn)出的結(jié)果進(jìn)入候選序列。
filter
可以:
translator
產(chǎn)生)的候選條目詞典是 translator
的參考書。
他往往與同名輸入方案配套使用,如拼音的詞典以拼音碼查字,倉頡的詞典以倉頡碼查字。但也可以由若干編碼屬于同一系統(tǒng)的輸入方案共用,如各種雙拼方案,都使用和拼音同樣的詞典,于是不僅復(fù)用了碼表數(shù)據(jù),也可共享用戶以任一款此系列方案錄入的自造詞(仍以碼表中的形式即全拼編碼記錄)。
Rime 的詞典文件,命名爲(wèi) <詞典名>.dict.yaml
,包含一份碼表及對(duì)應(yīng)的規(guī)則說明。
詞典文件的前半部份爲(wèi)一份 YAML 文檔:
# 注意這里以 --- ... 分別標(biāo)記出 YAML 文檔的起始與結(jié)束位置# 在 ... 標(biāo)記之后的部份就不會(huì)作 YAML 文檔來解讀---name: luna_pinyinversion: '0.9'sort: by_weightuse_preset_vocabulary: true...
解釋:
name
: 詞典名,內(nèi)部使用,命名原則同「方案標(biāo)識(shí)」;可以與配套的輸入方案標(biāo)識(shí)一致,也可不同;version
: 管理詞典的版本,規(guī)則同輸入方案定義文件的版本號(hào);sort
: 詞條初始排序方式,可選填 by_weight
(按詞頻高低排序)或 original
(保持原碼表中的順序);use_preset_vocabulary
: 填 true
或 false
,選擇是否導(dǎo)入預(yù)設(shè)詞彙表【八股文】。碼表,定義了輸入法中編碼與文字的對(duì)應(yīng)關(guān)係。
碼表位于詞典文件中 YAML 結(jié)束標(biāo)記之后的部份。
其格式爲(wèi)以製表符分隔的值(TSV),每行定義一條「文字-編碼」的對(duì)應(yīng)關(guān)係:
# 單字你 ni我 wo的 de 99%的 di 1%地 de 10%地 di 90%目 mu好 hao# 詞組你我你的我的我的天天地 tian di好天好好地目的 mu di目的地 mu di di
※注意: 不要 從網(wǎng)頁複製以上代碼到實(shí)作的詞典文件!因爲(wèi)網(wǎng)頁里製表符被轉(zhuǎn)換成空格從而不符合 Rime 詞典要求的格式。
碼表部份,除了以上格式的編碼行,還可以包含空行(不含任何字符)及注釋行(行首爲(wèi) # 符號(hào))。
以製表符(Tab)分隔的第一個(gè)字段是所定義的文字,可以是單字或詞組;
第二個(gè)字段是與文字對(duì)應(yīng)的編碼;若該編碼由多個(gè)「音節(jié)」組成,音節(jié)之間以空格分開;
可選地、第三個(gè)字段是設(shè)定該字詞權(quán)重的頻度值(非負(fù)整數(shù)),或相對(duì)于預(yù)設(shè)權(quán)值的百分比(浮點(diǎn)數(shù)%)。
在拼音輸入法中,往往多音字的若干種讀音使用的場合不同,于是指定不同百分比來修正每個(gè)讀音的使用頻度。
詞組如果滿足以下條件,則可以省去編碼字段:
這種條件下,詞組的編碼可由單字編碼的組合推導(dǎo)出來。
反之,則有必要給出詞組的編碼以消除自動(dòng)注音的不確定性(例:天地)。
當(dāng)含有多音字的詞組缺少編碼字段時(shí),自動(dòng)注音程序會(huì)利用權(quán)重百分比高于5%的讀音進(jìn)行組合、生成全部可能的注音,如:
「好好地」在編譯時(shí)自動(dòng)注音爲(wèi)「hao hao de
」、「hao hao di
」
雪齋的文檔 全面而詳細(xì)解釋了輸入方案及詞典中各設(shè)定項(xiàng)的含義及用法。
Rime 有一份名爲(wèi)【八股文】的預(yù)設(shè)詞彙表。
多數(shù)輸入方案需要用到一些標(biāo)準(zhǔn)白話文中的通用詞彙。爲(wèi)免重複在每份碼表中包含這些詞彙,減少輸入方案維護(hù)成本,Rime 提供了一份預(yù)設(shè)詞彙表及自動(dòng)編碼(注音)的設(shè)施。
創(chuàng)作輸入方案時(shí),如果希望完全控制詞彙表的內(nèi)容而不採用【八股文】中的詞組,只須直接將詞彙編入碼表即可。
否則,在詞典文件中設(shè)定 use_preset_vocabulary: true
將【八股文】導(dǎo)入該詞典;
在碼表中給出單字碼、需要分辨多音字的詞組編碼、以及該輸入方案特有的詞彙,其他交給自動(dòng)注音來做就好啦。
Rime預(yù)設(shè)輸入方案正是利用這份詞彙表及自動(dòng)注音工具,在不犧牲效果及可維護(hù)性的前提下、使詞典文件壓縮到最小的行數(shù)。
【八股文】包含從 CC-CEDICT、新酷音等開源項(xiàng)目中整理出來的約二十三萬條詞彙,其用字及詞頻數(shù)據(jù)針對(duì)傳統(tǒng)漢字做過調(diào)整。因此基于這份詞彙表產(chǎn)生的輸入結(jié)果,比較接近以傳統(tǒng)漢字行文的實(shí)際用法。
爲(wèi)了充分利用【八股文】提供的詞彙,自定義的詞典應(yīng)保證單字碼表收錄了符合 opencc 字形標(biāo)準(zhǔn)的常用字。特別注意,該標(biāo)準(zhǔn)對(duì)以下幾組異體字的取捨,【八股文】將這些字(包括詞組及字頻)統(tǒng)一到左邊一列的字形。
爲(wèi) 為僞 偽嬀 媯潙 溈兇 兇啓 啟棱 稜污 污泄 洩涌 涌牀 床著 著灶 灶衆(zhòng) 眾里 裡踴 踴麪 麵羣 群峯 峰
請(qǐng)務(wù)必在碼表中收錄左列的單字;并建議收全右列的單字。
輸入法詞典往往對(duì)下列幾組字不做嚴(yán)格區(qū)分,opencc 則傾向于細(xì)分異體字的不同用法。
喫 吃霉 霉攷 考覈 核
請(qǐng)儘量在碼表中收全以上單字。
部署過程中,未能完成自動(dòng)注音的字、詞會(huì)以警告形式出現(xiàn)在日誌文件里。如果所報(bào)告的字爲(wèi)生僻字、您可以忽略他;如果警告中大量出現(xiàn)某個(gè)常用字,那麼應(yīng)該注意到碼表里缺失了該字的注音。
將寫好的輸入方案佈署到 Rime 輸入法的過程,稱爲(wèi)「編譯」:
爲(wèi)查詢效率故,輸入法工作時(shí)不直接加載文本格式的詞典源文件,而要在編譯過程中,爲(wèi)輸入方案生成專爲(wèi)高速查詢設(shè)計(jì)的「.bin」文件。
編譯時(shí)程序做以下幾件事:
初次安裝 Rime 輸入法,無有任何輸入方案和用戶設(shè)定。因此安裝的最后一個(gè)步驟即是把發(fā)行版預(yù)設(shè)的輸入方案和設(shè)定文件佈署到 Rime 爲(wèi)該用戶創(chuàng)建的工作目錄,至此 Rime 纔成爲(wèi)一部可以發(fā)動(dòng)的輸入引擎。
此后無論是修改已有方案的設(shè)定,或是添加了新的輸入方案,都需要「重新佈署」成功后方可使用戶的新設(shè)定作用于 Rime 輸入法。
〔★〕重新佈署的方法是:
default.yaml
之后、執(zhí)行 ibus-daemon -drx
重載 IBusRime 輸入方案,將 Rime 輸入法的設(shè)定整理成完善的、可分發(fā)的形式。
但并非一定要?jiǎng)?chuàng)作新的輸入方案,才可以改變 Rime 的行爲(wèi)。
當(dāng)用戶需要對(duì) Rime 中的各種設(shè)定做小幅的調(diào)節(jié),最直接、但不完全正確的做法是:編輯用戶資料夾中那些 .yaml 文檔。
這一方法有弊端:
因此,對(duì)于隨 Rime 發(fā)行的設(shè)定檔及預(yù)設(shè)輸入方案,推薦的定製方法是:
創(chuàng)建一個(gè)文件名的主體部份(「.」之前)與要定製的文件相同、次級(jí)擴(kuò)展名(位于「.yaml」之前)寫作 .custom
的定製檔,形如:
patch: '一級(jí)設(shè)定項(xiàng)/二級(jí)設(shè)定項(xiàng)/三級(jí)設(shè)定項(xiàng)': 新的設(shè)定值 '另一個(gè)設(shè)定項(xiàng)': 新的設(shè)定值 '再一個(gè)設(shè)定項(xiàng)': 新的設(shè)定值 '含列表的設(shè)定項(xiàng)/@0': 列表第一個(gè)元素新的設(shè)定值 '含列表的設(shè)定項(xiàng)/@last': 列表最后一個(gè)元素新的設(shè)定值 '含列表的設(shè)定項(xiàng)/@before 0': 在列表第一個(gè)元素之前插入新的設(shè)定值(不建議在補(bǔ)靪中使用) '含列表的設(shè)定項(xiàng)/@after last': 在列表最后一個(gè)元素之后插入新的設(shè)定值(不建議在補(bǔ)靪中使用) '含列表的設(shè)定項(xiàng)/@next': 在列表最后一個(gè)元素之后插入新的設(shè)定值(不建議在補(bǔ)靪中使用)
patch
定義了一組「補(bǔ)靪」,以源文件中的設(shè)定爲(wèi)底本,寫入新的設(shè)定項(xiàng)、或以新的設(shè)定值取代舊有的值。
以下這些例子,另載于一篇[[《定製指南》|CustomizationGuide]],其中所介紹的知識(shí)和技巧,復(fù)蓋了不少本文未討論的細(xì)節(jié),想必對(duì)于創(chuàng)作新的輸入方案會(huì)有啓發(fā)。
重要!創(chuàng)作了新的輸入方案,最后一步就是在「方案選單」里啓用他。
應(yīng)該算是 Rime 輸入法最主要的獨(dú)創(chuàng)技術(shù)。
概括來說就是將方案中的編碼通過規(guī)則映射到一組全新的拼寫形式!
也就是說能讓 Rime 輸入方案在不修改碼表的情況下、適應(yīng)不同的輸入習(xí)慣。
拼寫運(yùn)算能用來:
給力嗎?
[[★這里|SpellingAlgebra]] 有介紹拼寫運(yùn)算的專題文章。
如果你安裝好了Rime卻不會(huì)玩,就一步一步跟我學(xué)吧。
本系列課程每個(gè)步驟的完整代碼可由此查閱:
https://github.com/lotem/rimeime/tree/master/doc/tutorial
第一個(gè)例子,總是最簡單的(也是最傻的)。
# Rime schema# encoding: utf-8## 最簡單的 Rime 輸入方案#schema: schema_id: hello # 注意此ID與文件名里 .schema.yaml 之前的部分相同 name: 大家好 # 將在〔方案選單〕中顯示 version: '1' # 這是文字類型而非整數(shù)或小數(shù),如 '1.2.3'
起首幾行是注釋。而后只有一組必要的方案描述信息。
這一課主要練習(xí)建立格式正確的YAML文檔。
schema:
之下的三行代碼以空格縮進(jìn)——我的習(xí)慣是用兩個(gè)空格——而 不要 用Tab字符來縮進(jìn)。縮進(jìn)表示設(shè)定項(xiàng)所屬的層次。在他處引用到此文檔中的設(shè)定項(xiàng),可分別以 schema/schema_id
, schema/name
, schema/version
來指稱。
我現(xiàn)在把寫好的方案文檔命名爲(wèi) hello.schema.yaml
,丟進(jìn)用戶資料夾——對(duì),只要這一個(gè)文件就妥了;
然后,啓用他。有些版本會(huì)有「方案選單設(shè)定」這個(gè)介面,在那里勾選【大家好】這個(gè)方案即可。若無有設(shè)定介面,則按照上文《定製方案選單》一節(jié)來做。
好運(yùn)!我已建立了一款名爲(wèi)【大家好】的新方案!雖然他沒有實(shí)現(xiàn)任何效果、按鍵仍會(huì)像無有輸入法一樣直接輸出西文。
爲(wèi)了處理字符按鍵、生成輸入碼,本例向輸入引擎添加兩個(gè)功能組件。
以下代碼仍是ID爲(wèi) hello
的新款輸入方案,但增加了 schema/version
的數(shù)值。
以后每個(gè)版本,都以前一個(gè)版本爲(wèi)基礎(chǔ)改寫,引文略去無有改動(dòng)的部分,以突出重點(diǎn)。
# ...schema: schema_id: hello name: 大家好 version: '2'engine: processors: - fluid_editor segmentors: - fallback_segmentor
fluid_editor
將字符按鍵記入輸入上下文,fallback_segmentor
將輸入碼連綴成一段。于是重新佈署后,按下字符鍵不再直接上屏,而顯示爲(wèi)輸入碼。
你會(huì)發(fā)現(xiàn),該輸入法只是收集了鍵盤上的可打印字符,并于按下空格、回車鍵時(shí)令輸入碼上屏。
現(xiàn)在就好似寫輸入法程序的過程中,將將取得一小點(diǎn)成果,還有很多邏輯未實(shí)現(xiàn)。不同的是,在Rime輸入方案里寫一行代碼,頂 Rime 開發(fā)者所寫的上百上千行。因此我可以很快地組合各種邏輯組件、搭建出心里想的輸入法。
第二版的【大家好】將鍵盤上所有字符都記入輸入碼,這對(duì)整句輸入有用,但是時(shí)下流行輸入法只處理編碼字符、其他字符直接上屏的形式。爲(wèi)了對(duì)編碼字符做出區(qū)分,以下改用 speller
+ express_editor
的組合取代 fluid_editor
:
# ...schema: # ... version: '3'engine: processors: - speller # 把字母追加到編碼串 - express_editor # 空格確認(rèn)當(dāng)前輸入、其他字符直接上屏 segmentors: - fallback_segmentor
speller
默認(rèn)只接受小寫拉丁字母作爲(wèi)輸入碼。
試試看,輸入其他字符如大寫字母、數(shù)字、標(biāo)點(diǎn),都會(huì)直接上屏。并且如果已經(jīng)輸入了編碼時(shí),下一個(gè)直接上屏的字符會(huì)將輸入碼頂上屏。
再接著,創(chuàng)建一個(gè)最簡單的候選項(xiàng)——把編碼串本身作爲(wèi)一個(gè)選項(xiàng)。故而會(huì)提供這個(gè)選項(xiàng)的新組件名叫 echo_translator
。
# ...engine: # ... translators: - echo_translator # (無有其他結(jié)果時(shí),)創(chuàng)建一個(gè)與編碼串一個(gè)模樣的候選項(xiàng)
至此,【大家好】看上去與一個(gè)真正的輸入法形似啦。只是還不會(huì)打出「大家好」哇?
那就寫一部詞典,碼表中設(shè)定以 hello
作爲(wèi)短語「大家好」的編碼:
# Rime dictionary# encoding: utf-8---name: helloversion: '1'sort: original...大家好 hello再見 bye再會(huì) bye
※注意: 不要 從網(wǎng)頁複製以上代碼到實(shí)作的詞典文件!因爲(wèi)網(wǎng)頁里製表符被轉(zhuǎn)換成空格從而不符合 Rime 詞典要求的格式。
同時(shí)修改方案定義:
#...schema: # ... version: '4'engine: #... segmentors: - abc_segmentor # 標(biāo)記輸入碼的類型 - fallback_segmentor translators: - echo_translator - table_translator # 碼表式轉(zhuǎn)換translator: dictionary: hello # 設(shè)定 table_translator 使用的詞典名
工作流程是這樣的:
speller
將字母鍵加入輸入碼序列abc_segmentor
給輸入碼打上標(biāo)籤 abc
table_translator
把帶有 abc
籤的輸入碼以查表的方式譯爲(wèi)中文table_translator
所查的碼表在 translator/dictionary
所指定的詞典里現(xiàn)在可以敲 hello
而打出「大家好」。完工!
等一下。
記得 hello
詞典里,還有個(gè)編碼叫做 bye
。敲 bye
,Rime 給出「再見」、「再會(huì)」兩個(gè)候選短語。
這時(shí)敲空格鍵,就會(huì)打出「再見」;那麼怎樣打出「再會(huì)」呢?
大家首先想到的方法,是:打完編碼 bye
,按 1
選「再見」,按 2
選「再會(huì)」。
可是現(xiàn)在按下 2
去,卻是上屏「再見」和數(shù)字「2」??梢姴]有完成數(shù)字鍵選字的處理,而是將數(shù)字同其他符號(hào)一樣做了頂字上屏處理。
增加一部 selector
,即可實(shí)現(xiàn)以數(shù)字鍵選字。
schema: # ... version: '5'engine: processors: - speller - selector # 選字、換頁 - navigator # 移動(dòng)插入點(diǎn) - express_editor # ...
selector
除了數(shù)字鍵,還響應(yīng)前次頁、上下方向鍵。因此選擇第二候選「再會(huì)」,既可以按數(shù)字2
,又可以按方向鍵「↓」將「再會(huì)」高亮、再按空格鍵確認(rèn)。
navigator
處理左右方向鍵、Home
、End
鍵,實(shí)現(xiàn)移動(dòng)插入點(diǎn)的編輯功能。有兩種情況需要用到他:一是發(fā)現(xiàn)輸入碼有誤需要定位修改,二是縮小候選詞對(duì)應(yīng)的輸入碼的范圍、精準(zhǔn)地編輯新詞組。
接下來向詞典添加一組重碼,以檢驗(yàn)換頁的效果:
---name: helloversion: '2'sort: original...大家好 hello再見 bye再會(huì) bye星期一 monday星期二 tuesday星期三 wednesday星期四 thursday星期五 friday星期六 saturday星期日 sunday星期一 weekday星期二 weekday星期三 weekday星期四 weekday星期五 weekday星期六 weekday星期日 weekday
默認(rèn)每頁候選數(shù)爲(wèi)5,輸入 weekday
,顯示「星期一」至「星期五」。再敲 Page_Down
顯示第二頁后選詞「星期六、星期日」。
schema: # ... version: '6'engine: processors: - speller - punctuator # 處理符號(hào)按鍵 - selector - navigator - express_editor segmentors: - abc_segmentor - punct_segmentor # 劃界,與前后方的其他編碼區(qū)分開 - fallback_segmentor translators: - echo_translator - punct_translator # 轉(zhuǎn)換 - table_translator# ...punctuator: # 設(shè)定符號(hào)表,這里直接導(dǎo)入預(yù)設(shè)的 import_preset: default
這次的修改,要注意 punctuator
, punct_segmentor
, punct_translator
相對(duì)于其他組件的位置。
punctuator/import_preset
告訴 Rime 使用一套預(yù)設(shè)的符號(hào)表。他的值 default
可以換成其他名字如 xxx
,則 Rime 會(huì)讀取 xxx.yaml
里面定義的符號(hào)表。
如今再敲 hello.
就會(huì)得到「大家好。」
早先流行用 -
和 =
這一對(duì)符號(hào)換頁,如今流行用 ,
和 .
。
在第六版中「,」「?!故菚?huì)頂字上屏的。現(xiàn)在要做些處理以達(dá)到一鍵兩用的效果。
Rime 提供了 key_binder
組件,他能夠在一定條件下,將指定按鍵綁定爲(wèi)另一個(gè)按鍵。對(duì)于本例就是:
period
)綁定爲(wèi)向后換頁(Page_Down
)comma
)綁定爲(wèi)向前換頁(Page_Up
)逗號(hào)鍵向前換頁的條件之所以比句號(hào)鍵嚴(yán)格,是爲(wèi)了「,」仍可在未進(jìn)行換頁的情況下頂字上屏。
經(jīng)過 key_binder
的處理,用來換頁的逗號(hào)、句號(hào)鍵改頭換面爲(wèi)前、后換頁鍵,從而繞過 punctuator
,最終被 selector
當(dāng)作換頁來處理。
最終的代碼如下:
schema: schema_id: hello name: 大家好 version: '7'engine: processors: - key_binder # 搶在其他 processor 處理之前判定是否換頁用的符號(hào)鍵 - speller - punctuator # 否則「,?!咕蜁?huì)由此上屏 - selector - navigator - express_editor segmentors: - abc_segmentor - punct_segmentor - fallback_segmentor translators: - echo_translator - punct_translator - table_translatortranslator: dictionary: hellopunctuator: import_preset: defaultkey_binder: bindings: # 每條定義包含條件、接收按鍵(IBus規(guī)格的鍵名,可加修飾符,如「Control+Return」)、發(fā)送按鍵 - when: paging # 僅當(dāng)已發(fā)生向后換頁時(shí), accept: comma # 將「逗號(hào)」鍵…… send: Page_Up # 關(guān)聯(lián)到「向前換頁」;于是 navigator 將收到一發(fā) Page_Up - when: has_menu # 只要有候選字即滿足條件 accept: period send: Page_Down
與【大家好】這個(gè)方案不同。以下一組示例,主要演示如何活用符號(hào)鍵盤,以及羅馬字轉(zhuǎn)寫式輸入。
莫以爲(wèi)【大家好】是最最簡單的輸入方案。碼表式輸入法,不如「鍵盤式」輸入法來得簡單明快!
用 punctuator
這一套組件,就可實(shí)現(xiàn)一款鍵盤輸入法:
# Rime schema# encoding: utf-8schema: schema_id: numbers name: 數(shù)字之道 version: '1'engine: processors: - punctuator - express_editor segmentors: - punct_segmentor translators: - punct_translatorpunctuator: 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' : 號(hào) '.' : 點(diǎn) full_shape: *symtable
對(duì),所謂「鍵盤輸入法」,就是按鍵和字直接對(duì)應(yīng)的輸入方式。
這次,不再寫 punctuator/import_preset
這項(xiàng),而是自訂了一套符號(hào)表。
鴰!原來 punctuator
不單可以用來打出標(biāo)點(diǎn)符號(hào);還可以重定義空格以及全部 94 個(gè)可打印 ASCII 字符(碼位 0x20 至 0x7e)。
在符號(hào)表代碼里,用對(duì)應(yīng)的ASCII字符表示按鍵。記得這些按鍵字符要放在引號(hào)里面,YAML 纔能夠正確解析喔。
示例代碼表演了兩種符號(hào)的映射方式:一對(duì)一及一對(duì)多。一對(duì)多者,按鍵后符號(hào)不會(huì)立即上屏,而是……嘿嘿,自己體驗(yàn)吧 :-)
關(guān)于代碼里 symtable
的一點(diǎn)解釋:
這是YAML的一種語法,&symtable
叫做「錨點(diǎn)標(biāo)籤」,給緊隨其后的內(nèi)容起個(gè)名字叫 symtable
;*symtable
則相當(dāng)于引用了 symtable
所標(biāo)記的那段內(nèi)容,從而避免重複。
Rime 里的符號(hào)有「全角」、「半角」兩種狀態(tài)。本方案里暫不作區(qū)分,教 half_shape
、full_shape
使用同一份符號(hào)表。
靈機(jī)一動(dòng),不如利用「全、半角」模式來區(qū)分「大、小寫」中文數(shù)字!
schema: # ... version: '2'switches: - name: full_shape states: [ 小寫, 大寫 ]# ...
先來定義狀態(tài)開關(guān):0
態(tài)改「半角」?fàn)?wèi)「小寫」,1
態(tài)改「全角」?fàn)?wèi)「大寫」。
這樣一改,再打開「方案選單」,方案「數(shù)字之道」底下就會(huì)多出個(gè)「小寫→大寫」的選項(xiàng),每選定一次、狀態(tài)隨之反轉(zhuǎn)一次。
接著給 half_shape
、full_shape
定義不同的符號(hào)表:
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' : 號(hào) '.' : 點(diǎn) 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' : 號(hào) '.' : 點(diǎn)
哈,調(diào)出選單切換一下大小寫,輸出的字全變樣!酷。
但是要去選單切換,總不如按下 Shift
就全都有了:
punctuator: half_shape: # ... 添加以下這些 '!' : 壹 '@' : 貳 '#' : 參 '$' : [ 肆, ¥, '$', '€', '£' ] '%' : [ 伍, 百分之 ] '^' : 陸 '&' : 柒 '*' : 捌 '(' : 玖 ')' : 零 'S' : 拾 'B' : 佰 'Q' : 仟 'Y' : 圓
于是在「小寫」態(tài),只要按 Shift
+ 數(shù)字鍵即可打出大寫數(shù)字。
用了幾下,發(fā)現(xiàn)一處小小的不滿意:敲 $
這個(gè)鍵,可選的符號(hào)有五個(gè)之多。想要打出毆元、英鎊符號(hào)只得多敲幾下 $
鍵使想要的符號(hào)高亮;但是按上、下方向鍵并沒有效果,按符號(hào)前面標(biāo)示的數(shù)字序號(hào),更是不僅上屏了錯(cuò)誤的符號(hào)、還多上屏一個(gè)數(shù)字——
這反映出兩個(gè)問題。一是 selector
組件缺席使得選字、移動(dòng)選字光標(biāo)的動(dòng)作未得到響應(yīng)。立即加上:
# ...engine: processors: - punctuator - selector # 加在這里 - express_editor # ...
因爲(wèi)要讓 punctuator
來轉(zhuǎn)換數(shù)字鍵,所以 selector
得放在他后頭。
好。二一個(gè)問題還在:無法用數(shù)字序號(hào)選字。爲(wèi)解決這個(gè)沖突,改用閒置的字母鍵來選字:
# ...menu: alternative_select_keys: 'acegi'
完工。
畢竟,鍵盤上只有47個(gè)字符按鍵、94個(gè)編碼字符,對(duì)付百十個(gè)字還管使??梢斎肷锨€(gè)常用漢字,嫌鍵盤式輸入的編碼空間太小,必得採用多字符編碼。
羅馬字,以拉丁字母的特定排列作爲(wèi)漢語音節(jié)的轉(zhuǎn)寫形式。一個(gè)音節(jié)代表一組同音字,再由音節(jié)拼寫組合成詞、句。
凡此單字(音節(jié))編碼自然連用而生詞、句的輸入法,皆可用 script_translator
組件完成基于音節(jié)碼切分的智能詞句轉(zhuǎn)換。他有個(gè)別名 r10n_translator
——r10n
爲(wèi) romanization
的簡寫。但不限于「拼音」、「注音」、「雙拼」、「粵拼」等一族基于語音編碼的輸入法:形式相似者,如「速成」,雖以字形爲(wèi)本,亦可應(yīng)用。
現(xiàn)在來把【數(shù)字之道】改成拼音→中文數(shù)字的變換。
schema: schema_id: numbers name: 數(shù)字之道 version: '3'engine: processors: - speller - punctuator - selector - express_editor segmentors: - abc_segmentor - punct_segmentor translators: - punct_translator - script_translatortranslator: dictionary: numberspunctuator: half_shape: &symtable '!' : 壹 '@' : 貳 '#' : 參 '$' : [ 肆, ¥, '$', '€', '£' ] '%' : [ 伍, 百分之 ] '^' : 陸 '&' : 柒 '*' : 捌 '(' : 玖 ')' : 零 'S' : 拾 'B' : 佰 'Q' : 仟 'W' : 萬 'N' : 年 'Y' : [ 月, 圓, 億 ] 'R' : 日 'X' : 星期 'J' : 角 'F' : 分 'Z' : [ 之, 整 ] 'D' : 第 'H' : 號(hào) '.' : 點(diǎn) full_shape: *symtable
符號(hào)表里,把小寫字母、數(shù)字鍵都空出來了。小寫字母用來拼音,數(shù)字鍵用來選重。重點(diǎn)是本次用了 script_translator
這組件。與 table_translator
相似,該組件與 translator/dictionary
指名的詞典相關(guān)聯(lián)。
編製詞典:
# Rime dictionary# encoding: utf-8---name: numbersversion: '1'sort: by_weightuse_preset_vocabulary: true...一 yi二 er三 san四 si五 wu六 liu七 qi八 ba九 jiu〇 ling零 ling十 shi百 bai千 qian萬 wan億 yi年 nian月 yue日 ri星 xing期 qi時(shí) shi分 fen秒 miao元 yuan角 jiao之 zhi整 zheng第 di號(hào) hao點(diǎn) dian是 shi
※注意: 不要 從網(wǎng)頁複製以上代碼到實(shí)作的詞典文件!因爲(wèi)網(wǎng)頁里製表符被轉(zhuǎn)換成空格從而不符合 Rime 詞典要求的格式。
※注意: 常用編輯器如VS editor以及Notepad++等軟體遇見*.yaml檔案時(shí)會(huì)預(yù)設(shè)禁止tab(ascii hex code 09)的使用,而將使用者鍵入的tab按鍵轉(zhuǎn)換成兩個(gè)空白(ascii hex code 20 20)。請(qǐng)一定要使用製表符來進(jìn)行詞典文件的編輯。
碼表里給出了一個(gè)「示例」規(guī)格的小字集。其中包含幾組重碼字。
要訣 sort: by_weight
意圖是不以碼表的順序排列重碼字,而是比較字頻。那字頻呢?沒寫出來。
要訣 use_preset_vocabulary: true
用在輸入方案需要支持輸入詞組、而碼表中詞組相對(duì)匱乏時(shí)。編譯輸入方案期間引入 Rime 預(yù)設(shè)的【八股文】詞彙——及詞頻資料!這就是碼表中未具字頻的原因。
使用【八股文】,要注意碼表所用的字形是否與該詞彙表一致。八股文的詞彙及詞頻統(tǒng)計(jì)都遵照 opencc 繁體字形標(biāo)準(zhǔn)。
如果缺少單字的編碼定義,自然也無法導(dǎo)入某些詞彙。所以本方案只會(huì)導(dǎo)入這個(gè)數(shù)字「小字集」上的詞彙。
如今有了一款專門輸入數(shù)字的拼音輸入法。比一比昇陽拼音、朙月拼音和地球拼音,還有哪里不一樣?
很快我發(fā)現(xiàn)敲 xingqiwu
或 xingqiw
都可得到來自【八股文】的詞組「星期五」,這很好。可是敲 xqw
怎會(huì)不中呢?
原來 script_translator
羅馬字中譯的方法是,將輸入碼序列切分爲(wèi)音節(jié)表中的拼寫形式,再按音節(jié)查詞典。不信你找本詞典瞧瞧,是不是按完整的拼音(注音)編排的。Rime 詞典也一樣。并沒有 xqw
這樣的檢索碼。
現(xiàn)在我要用 Rime 獨(dú)門絕活「拼寫運(yùn)算」來定義一種「音序查字法」。令 x
作 xing
的簡碼,q
作數(shù)字之道所有音節(jié)中起首爲(wèi) q
者的簡碼,即略代音節(jié) qi
與 qian
。
「漢語拼音」里還有三個(gè)雙字母的聲符,zh, ch, sh
也可做簡碼。
添加拼寫運(yùn)算規(guī)則:
schema: # ... version: '4'#...speller: algebra: - 'abbrev/^([a-z]).+$/$1/' - 'abbrev/^([zcs]h).+$/$1/'
如此 Rime 便知,除了碼表里那些拼音,還有若干簡碼也是行得通的拼寫形式。再輸入 xqw
,Rime 將他拆開 x'q'w
,再默默對(duì)應(yīng)到音節(jié)碼 xing'qi'wan
、xing'qi'wu
、xing'qian'wan
等等,一翻詞典就得到了一個(gè)好詞「星期五」,而其他的組合都說不通。
現(xiàn)在有無有悟到,羅馬字轉(zhuǎn)寫式輸入法與碼表式輸入法理念上的不同?
哈,做中了。試試看 sss,sss,sssss,sssss
卻好像不是我要的「四是四,十是十,十四是十四,四十是四十」……
好辦。如果某些詞彙在方案里很重要,【八股文】又未收錄,那麼,請(qǐng)?zhí)砑又链a表:
---name: numbersversion: '2'sort: by_weightuse_preset_vocabulary: true...# ...四是四十是十十四是十四四十是四十
善哉。演示完畢。當(dāng)然休想就此把 Rime 全盤掌握了。一本《指南書》,若能讓讀者入門,我止說「善哉?」
再往后,就只有多讀代碼,纔能見識(shí)到各種新穎、有趣的玩法。
〔警告〕最后這部戲,對(duì)智力、技術(shù)功底的要求不一般。如果讀不下去,不要怪我、不要懷疑自己的智商!
即使跳過本節(jié)書也無妨,只是不可忽略了下文《關(guān)于調(diào)試》這一節(jié)?。ㄖ匾邸?/p>
請(qǐng)檢查是否:
設(shè)計(jì)一款【智能ABC雙拼】輸入方案做練習(xí)!
# Rime schema# encoding: utf-8schema: schema_id: double_pinyin_abc # 專有的方案標(biāo)識(shí) 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 - script_translator - reverse_lookup_translator filters: - simplifier - uniquifierspeller: alphabet: zyxwvutsrqponmlkjihgfedcba # 呃,倒背字母表完全是個(gè)人喜好 delimiter: ' '' # 隔音符號(hào)用「'」;第一位的空白用來自動(dòng)插入到音節(jié)邊界處 algebra: # 拼寫運(yùn)算規(guī)則,這個(gè)纔是實(shí)現(xiàn)雙拼方案的重點(diǎn)。寫法有很多種,當(dāng)然也可以把四百多個(gè)音節(jié)碼一條一條地列舉 - erase/^xx$/ # 碼表中有幾個(gè)拼音不明的字,編碼成xx了,消滅他 - derive/^([jqxy])u$/$1v/ - xform/^zh/A/ # 替換聲母鍵,用大寫以防與原有的字母溷淆 - xform/^ch/E/ - xform/^sh/V/ - xform/^([aoe].*)$/O$1/ # 添上固定的零聲母o,先標(biāo)記爲(wèi)大寫O - xform/ei$/Q/ # 替換韻母鍵 - xform/ian$/W/ # ※2 - xform/er$|iu$/R/ # 對(duì)應(yīng)兩種韻母的;音節(jié)er現(xiàn)在變爲(wèi)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/ # 檢查一下在此之前是否已轉(zhuǎn)換過了帶介音的ang;好,※1處有了 - xform/an$/J/ # 如果※2、※3還無有出現(xiàn)在上文中,應(yīng)該把他們提到本行之前 - xform/iao$/Z/ # 對(duì)——像這樣讓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 要以本輸入方案的名稱來命名,以免把朙月拼音的拼寫映射表復(fù)蓋掉 preedit_format: # 這段代碼用來將輸入的雙拼碼反轉(zhuǎn)爲(wèi)全拼顯示;待見雙拼碼的可以把這段拿掉 - xform/o(\w)/0$1/ # 零聲母先改爲(wèi)0,以方便后面的轉(zhuǎn)換 - xform/(\w)q/$1ei/ # 雙拼第二碼轉(zhuǎn)換爲(wèi)韻母 - xform/(\w)n/$1un/ # 提前轉(zhuǎn)換雙拼碼 n 和 g,因爲(wèi)轉(zhuǎn)換后的拼音里就快要出現(xiàn)這兩個(gè)字母了,那時(shí)將難以分辨出雙拼碼 - xform/(\w)g/$1eng/ # 當(dāng)然也可以採取事先將雙拼碼變爲(wèi)大寫的辦法來與轉(zhuǎn)換過的拼音做區(qū)分,可誰讓我是高手呢 - xform/(\w)w/$1ian/ - xform/([dtnljqx])r/$1iu/ # 對(duì)應(yīng)多種韻母的雙拼碼,按搭配的聲母做區(qū)分(最好別用排除式如 [^o]r 容易出狀況) - xform/0r/0er/ # 另一種情況,注意先不消除0,以防后面把e當(dāng)作聲母轉(zhuǎn)換爲(wèi)ch - xform/([nljqx])t/$1iang/ - xform/(\w)t/$1uang/ # 上一行已經(jīng)把對(duì)應(yīng)到 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 已經(jīng)轉(zhuǎn)換過了 - 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/' # 復(fù)原聲母,音節(jié)開始處的雙拼字母a改寫爲(wèi)zh;其他位置的才真正是a - 'xform/(^|[ '])e/$1ch/' - 'xform/(^|[ '])v/$1sh/' - xform/0(\w)/$1/ # 好了,現(xiàn)在可以把零聲母拿掉啦 - xform/([nljqxy])v/$1ü/ # 這樣纔是漢語拼音 :-)reverse_lookup: dictionary: cangjie5 prefix: '`' tips: 〔倉頡〕 preedit_format: - 'xlit|abcdefghijklmnopqrstuvwxyz|日月金木水火土竹戈十大中一弓人心手口尸廿山女田難卜符|' comment_format: - xform/([nl])v/$1ü/punctuator: import_preset: defaultkey_binder: import_preset: defaultrecognizer: import_preset: default patterns: reverse_lookup: '`[a-z]*$'
完畢。
這是一道大題。通過改造拼寫法而創(chuàng)作出新的輸入方案。
如果需要製作完全屬于自己的輸入方案,少不了要瞭解 Rime 的標(biāo)準(zhǔn)庫。此時(shí),請(qǐng)客倌品讀《Rime方案製作詳解》。更多新意,就在你的筆下!
如此複雜的輸入方案,很可能需要反復(fù)調(diào)試方可達(dá)到想要的結(jié)果。
請(qǐng)于試驗(yàn)時(shí)及時(shí)查看日誌中是否包含錯(cuò)誤信息。日誌文件位于:
/tmp/rime.ibus.*
%TEMP%\rime.weasel.*
$TMPDIR/rime.squirrel.*
用戶資料夾/rime.log
按照日誌的級(jí)別分爲(wèi) INFO / 信息、WARNING / 警告、ERROR / 錯(cuò)誤。
后兩類應(yīng)重點(diǎn)關(guān)注,如果新方案部署后不可用或輸出與設(shè)計(jì)不一致,原因可能在此。
沒有任何錯(cuò)誤信息,就是不好使,有可能是碼表本身的問題,比如把碼表中文字和編碼兩列弄顛倒了——Rime 等你輸入由漢字組成的編碼,然而鍵盤沒有可能做到這一點(diǎn)(否則也不再需要輸入法了)。
后續(xù)有計(jì)劃爲(wèi)輸入方案創(chuàng)作者開發(fā)名爲(wèi)「拼寫運(yùn)算調(diào)試器」的工具,能夠較直觀地看到每一步拼寫運(yùn)算的結(jié)果。有助于定義雙拼這樣大量使用拼寫運(yùn)算的方案。
「東風(fēng)破早梅,向暖一枝開?!?/p>
構(gòu)想在 Rime 輸入軟件完善后,能夠連結(jié)漢字字形、音韻、輸入法愛好者的共同興趣,形成穩(wěn)定的使用者社羣,搭建一個(gè)分享知識(shí)的平臺(tái)。
【東風(fēng)破】,定義爲(wèi)配置管理器及 Rime 輸入方案倉庫,是廣大 Rime 用家分享配置和輸入方案的平臺(tái)。
Rime 是一款強(qiáng)調(diào)個(gè)性的輸入法。
Rime 不要定義輸入法應(yīng)當(dāng)是哪個(gè)樣、而要定義輸入法可以玩出哪些花樣。
Rime 不可能通過預(yù)設(shè)更多的輸入方案來滿足玩家的需求;真正的玩家一定有一般人想不到的高招。
未來一定會(huì)有,【東風(fēng)破】(注:現(xiàn)已投入運(yùn)行),讓用家輕鬆地找到最新、最酷、最適合自己的 Rime 輸入方案。
聯(lián)系客服