小狼毫编译手记
RIME
浏览 - 次 字数6569 2019-06-13

主要工具

梯子准备

GitHub 处于半屏蔽状态,拉代码很慢,最好有 VPN 工具。

开发环境

调整 BOOST 库

拉代码

准备好 VPN 工具,然后右键调出「git bash here」,拉代码:

git clone --recursive https://github.com/rime/weasel.git

调整 opencc 编码格式

「Microsoft Visual Studio」对「UTF-8」支持有些问题,调整一下「PhraseExtract」相关文件的编码格式,设为「UTF-16 BE」,调整工具,强烈建议使用 Visual Studio Code,它是微软家的类 notepad++ 式的代码编辑器,用它可以避免其它意外。

D:\weasel\librime\thirdparty\src\opencc\src

将这三个文件,用 Visual Studio Code 打开,在程序右下角,默认显示「UTF-8」,点一下,会弹出「通过编码保存」,在「通过编码保存」中,选「UTF-16 BE」。

设置 BOOST 引用路径

在「weasel/librime」下面,有「env.bat.template」,你需要将之更名为「env.bat」,清空其中的默认的内容,并写入如下新的内容:

注意,我是放在了 D 盘根目录上,你未必需要跟我一样,在这里要改成你自己的路径,「boost_1_70_0」是一个有着「b2.exe」的文件夹,路径的层级务必要保证是对的。

set BOOST_ROOT="D:\boost_1_70_0"

起头写,顶格写,写好保存。并将这份改好的「env.bat」,复制给上级目录,即「weasel」文件夹一份。

因为编译「weasel」主体部分与「librime」部分,都会有调用「boost库」的需求。

编译核心引擎

开始菜单中,在「Visual Studio 2017」下面,有「适用于 VS 2017 的 x64 本机工具命令提示」。所有编译,用它完成。

在这个命令提示工具中,进入 weasel/librime 下面,如下分步编译:

include 头文件调整

编译过 librime 之后,会有「weasel\librime\dist」这个目录,其中有「include」文件夹。

图标调整

weasel\resource 下面,有程序所需要的图标,在此替换成我们的样式。同时放入「alternative-icons」及相关图标到此。

D:\weasel\WeaselServer\WeaselServer.rc

IDI_WEASEL              ICON                    "..\\resource\\weasel.ico"

IDI_EN                  ICON                    "..\\resource\\alternative-icons\\en.ico"

IDI_ZH                  ICON                    "..\\resource\\alternative-icons\\zh.ico"

IDI_RELOAD              ICON                    "..\\resource\\alternative-icons\\reload.ico"

D:\weasel\WeaselServerWeaselServer.vcxproj

  <ItemGroup>
    <None Include="..\resource\alternative-icons\en.ico" />
    <None Include="..\resource\alternative-icons\reload.ico" />
    <None Include="..\resource\alternative-icons\zh.ico" />
    <None Include="..\resource\weasel.ico" />
  </ItemGroup>

D:\weasel\WeaselServer\WeaselServer.vcxproj.filters

  <ItemGroup>
    <None Include="..\resource\alternative-icons\en.ico">
      <Filter>Resource Files</Filter>
    </None>
    <None Include="..\resource\alternative-icons\reload.ico">
      <Filter>Resource Files</Filter>
    </None>
    <None Include="..\resource\alternative-icons\zh.ico">
      <Filter>Resource Files</Filter>
    </None>
    <None Include="..\resource\weasel.ico">
      <Filter>Resource Files</Filter>
    </None>
  </ItemGroup>

之所以特意调整「悬浮图标」,是因为在程序中,它们本是有独立的代码索引的。但是默认的悬浮图标实在太丑了。 托盘图标,在我们的设定里是有透明背景的 ico ,但是如果悬浮也是同样透明背景的话,透明部分会显示成「黑色」。 为了避免这个问题,在「alternative-icons」下放入事先做好的悬浮图标,并在代码中如上添加索引,以尽善尽美。

编译主程序

使用「适用于 VS 2017 的 x64 本机工具命令提示」进入 weasel 文件夹内:

build.bat all

几分钟后,会在「weasel\output\archives」下生成 exe 包。

这样,就完成了对 librime_1.5 时代新版小狼毫的源代码编译工作。

接下来,就可以放入我们的脚本,封装我们的方案了。

install.nsi 适配

install.nsi 似乎有所变动,保险起见,可以将我们的脚本参数迁移到新的 install.nsi 上来。

LUA 插件支持

上述编译过程,不涉及「LUA 插件」的支持。新版的 Librime 引擎中,代码树里缺少对「LUA 插件」的引用,所以 git 拉下的代码,编译出来是默认不支持 LUA 插件的。

下面讲一下如何编译进对「LUA 插件」的支持。

插件代码拉到本地

使用「适用于 VS 2017 的 x64 本机工具命令提示」,进入 librime 文件夹下的 plugins 下面,典型的路径如下所示:

D:\weasel\librime\plugins

右键打开 git bash 工具,拉一下「LUA 插件」的源代码:

git clone https://github.com/98wb/librime-lua.git

拉下代码之后,可以看到类似如下目录,对照你的路径,确认「lua5.3」的存在。

D:\weasel\librime\plugins\librime-lua\thirdparty\lua5.3

重新编译 Librime 模块

使用「适用于 VS 2017 的 x64 本机工具命令提示」,去到「weasel/librime」下面,重新编译 Librime

再次分部编译,可以避免意外发生。然后,会在「weasel\librime\dist\include」下生成新的「rime_api.h」和「rime_levers_api.h」。

这两个文件被再一次生成了,它可能关联着「LUA 插件」支持的信息,将它们再次覆盖到之前我们丢入的地方:

重新编译 weasel 主体

使用「适用于 VS 2017 的 x64 本机工具命令提示」,去到「weasel」下面,重新编译全部程序

build.bat all

再次编译,会验证并无变化的相关文件,速度会很快,不需要担心时间问题,稳是最重要的。

Lua 脚本举例

下面的路径,是我预放入的,98五笔专版所用到的 LUA 脚本。

‪> D:weasel\librime\plugins\librime-lua\sample\rime-98WB.lua

LUA 脚本文件,名称必须是「rime.lua」,所以「rime-98WB.lua」更名为「rime.lua」才能使用。

「rime.lua」最好放在「用户文件夹」下面,这样无论修改,还是权限,都比较好。

LUA 脚本,需要与 schema 对接一下,才能生效。

典型的 schema.yaml 文件,如下对接 LUA 插件:

关键字「single_char」,「lua_filter」,「lua_translator」。

下面的 schema ,做了「开关对接」,「快捷键对接」,「过滤器对接」,「翻译器对接」。

switches:
  - name: ascii_mode
    reset: 0
  - name: zh_trad
    reset: 0
    states: [ 简,繁 ]
  - name: 98wb_spelling
    reset: 0
    states: [ 隐,显 ]    
  - name: jiayin
    reset: 1
  - name: gb2312
    reset: 0
    states: [ 扩,常 ]
  - name: single_char
    states: [ 词,单 ]

engine:
  filters:
    - charset_filter@gb2312  
    - simplifier
    - "reverse_lookup_filter@ci_reverse_lookup"
    - "simplifier@98wb_spelling"    
    - "simplifier@jiayin"
    - "lua_filter@single_char"
    - uniquifier
  processors:
    - ascii_composer
    - recognizer
    - key_binder
    - speller
    - punctuator
    - selector
    - navigator
    - express_editor
  segmentors:
    - ascii_segmentor
    - matcher
    - "affix_segmentor@mkst"
    - "affix_segmentor@rvlk1"
    - "affix_segmentor@zhuyin_fix"
    - abc_segmentor
    - punct_segmentor
    - fallback_segmentor
  translators:
    - punct_translator
    - reverse_lookup_translator
    - "table_translator@rvlk1"
    - table_translator
    - "table_translator@fixed"
    - "table_translator@mkst"
    - "table_translator@zhuyin_fix"
    - "history_translator@history"
    - "lua_translator@time_date"


key_binder:
  bindings:
    - {accept: Left, send: Up, when: has_menu}
    - {accept: Right, send: Down, when: has_menu}  
    - {accept: minus, send: Page_Up, when: has_menu}
    - {accept: equal, send: Page_Down, when: has_menu}
    - {accept: semicolon, send: 2, when: has_menu}
    - {accept: apostrophe, send: 3, when: has_menu}
    - {accept: space, send: Escape, when: composing}
    - {accept: space, send: space, when: has_menu}
    - {accept: Return, send: Escape, when: composing}
    - {accept: Return, send: Escape, when: has_menu}
    - {accept: "Control+Shift+4", toggle: zh_trad, when: always}
    - {accept: "Control+Shift+dollar", toggle: zh_trad, when: always}
    - {accept: "Control+Shift+F", toggle: zh_trad, when: always}
    - {accept: "Control+Shift+H", toggle: 98wb_spelling, when: always}
    - {accept: "Control+Shift+J", toggle: single_char, when: always} 
    - {accept: "Control+Shift+K", toggle: 98wb_spelling_rk, when: always}
    - {accept: "Control+Shift+U", toggle: gb2312, when: always} 
    - {accept: "Control+Shift+I", toggle: gb2312, when: always} 
    - {accept: "Control+Shift+O", toggle: gb2312, when: always}

欲加入上述「rime-98WB.lua」,在使用时,需要更名为「rime.lua」,并如上添加 schema 对接。

在98五笔专版中,「single_char」这个以 LUA 实现的「单字模式」,只给了「含词」选单。

而使用 LUA 实现的时间日期等输出功能,则两份选单兼有。

在这份 rime-98WB.lua 脚本中,已解决单字模式下,日期时间等字符串被过滤掉的问题,示例代码如下:

--- single_char
function single_char(input, env)
   b = env.engine.context:get_option("single_char")
   for cand in input:iter() do
      if (not b or utf8.len(cand.text) == 1 or cand.type == "qsj"or cand.type == "time"or cand.type == "date") then
         yield(cand)
      end
   end
end

其中,if 语句是过滤条件:

if (not b or utf8.len(cand.text) == 1 or cand.type == "qsj"or cand.type == "time"or cand.type == "date")

在这里,添加 qsj 、 time 、 date 、 week ,就可以避免它们所代表的函数类型被滤掉。

比如「time」,它其实对应着下面 Candidate() 的第一个参数 time , 这个是函数类型的定义,并非触发函数的关键字

yield(Candidate("time", seg.start, seg._end, os.date("%H:%M:%S"), "〔时间〕"))

下面的语句,才是触发函数的关键字

if (input == "time") then

也许,使用 LUA 做个字符集过滤开关,就能针对性地放行被过滤掉的某些字符,从而曲线弥补中州韵引擎在这方面的缺点。

LUA 好像是个很简单的脚本语言,期待未来能够玩出花来。

现在基本完美了

喵呜。

WuBiXiaoZhu