librime-lua icon indicating copy to clipboard operation
librime-lua copied to clipboard

LUA是否有接口改变未经翻译器转换的编码显示

Open mokapsing opened this issue 3 years ago • 37 comments

如这个ISSUE 的需求

https://github.com/rime/librime/issues/454

很早之前不知道用LUA,现在再次提出来问问能否实现 @shewer @hchunhui @TsinamLeung 麻烦看下是否有可行性

mokapsing avatar Nov 28 '21 03:11 mokapsing

如果你對 Segment(segmention) --> Translator -->filter 熟悉 ,就會放棄吧

細部的部分我是不熟悉 preedit_format 是在 translator or segment 轉換??? 以下是我初步預想 , 你可以試試

1 translator 不可行 lua_translator 只能管自己的 translator 無法控制其他~~ translator 2 lua_segmentor -- 不熟悉
3 lua_filter 分不出來 tag segment 所以 無法找到對應的preeedit_format 轉換 context.input

如果你的方案 translators 都有自己獨立tag 或是只有一個 translator (tag: abc) 還可能可以在~~lua_filter 強制轉換 或指定轉換 context.text

lua_filter@editor --yaml tags: # all lua_filter@editor@tran1 --yaml: tran1/tags: [ tran1 ]
lua_filter@editor@tran2 -- yaml tran2/tags: [ tran2 ]

20210417 librime-lua 有 Projection 可以轉換 pattern

  local pattern= Projection()
  pattern:load( env.engine.schema.config:get_list("translator/preedit_format")) -- cangjie5
  local preedit_str=pattern:apply("abc") -- 日月金

shewer avatar Nov 28 '21 08:11 shewer

如果你對 Segment(segmention) --> Translator -->filter 熟悉 ,就會放棄吧

細部的部分我是不熟悉 preedit_format 是在 translator or segment 轉換??? 以下是我初步預想 , 你可以試試

1 translator 不可行 lua_translator 只能管自己的 translator 無法控制其他~~ translator 2 lua_segmentor -- 不熟悉 3 lua_filter 分不出來 tag segment 所以 無法找到對應的preeedit_format 轉換 context.input

如果你的方案 translators 都有自己獨立tag 或是只有一個 translator (tag: abc) 還可能可以在~~lua_filter 強制轉換 或指定轉換 context.text

lua_filter@editor --yaml tags: # all lua_filter@editor@tran1 --yaml: tran1/tags: [ tran1 ] lua_filter@editor@tran2 -- yaml tran2/tags: [ tran2 ]

20210417 librime-lua 有 Projection 可以轉換 pattern

  local pattern= Projection()
  pattern:load( env.engine.schema.config:get_list("translator/preedit_format")) -- cangjie5
  local preedit_str=pattern:apply("abc") -- 日月金

目前我的方案只有一个translator, 那么是否可以做呢

rime 1.7.3 lua_filter不能识别Projection ,是还没有合入吗

mokapsing avatar Nov 28 '21 08:11 mokapsing

你是 win or linux https://ci.appveyor.com/api/buildjobs/m4yhqfofhqfmw8f0/artifacts/rime.zip <-- 找不到最新的 這是我 pr opencc 時產生的~~ rime.dll ( 最後commit + opencc)

shewer avatar Nov 28 '21 09:11 shewer

你是 win or linux https://ci.appveyor.com/api/buildjobs/m4yhqfofhqfmw8f0/artifacts/rime.zip <-- 找不到最新的 這是我 pr opencc 時產生的~~ rime.dll ( 最後commit + opencc)

果然用这个是可以的,现在该怎么改写回去呢,context.text是不可用的

mokapsing avatar Nov 28 '21 09:11 mokapsing

我只調整過 candidate 你這試試 或詢問 librime那 api 如何使用置換 在到 librime-lua src/types.cc 查詢 lua api ContextReg 有三個 get_ 前二個 return String , Preedit obj 可以比較一下差異 context:get_preedit_text() -- return Preedit https://github.com/hchunhui/librime-lua/blob/67ef681a9fd03262c49cc7f850cc92fc791b1e85/src/types.cc#L460-L482

PreeditReg local preedit= context:get_preedit_text() preedit.text --get preedit.text= String -- set https://github.com/hchunhui/librime-lua/blob/67ef681a9fd03262c49cc7f850cc92fc791b1e85/src/types.cc#L523-L536

不曉得 Candidate preedit 有何差別 https://github.com/hchunhui/librime-lua/blob/67ef681a9fd03262c49cc7f850cc92fc791b1e85/src/types.cc#L181

shewer avatar Nov 28 '21 10:11 shewer

context:get_preedit().text = "test" 似乎没有效果,是不是只能读不能写呢

官方似乎不太愿意把光标后的部分作改写

mokapsing avatar Nov 28 '21 10:11 mokapsing

Preedit 是Struct log.error 沒有錯的話, 應該是有設定 可以再取回確認 ,說不定是程序上沒有刷新 或是在 改cand.preedit 但是 cand 是translator 產生的 和segment start _end 相關 ,不知道有沒有影響,可以一試 可以在 lua_filter yield debug candidate 查看

candidata 也有 preedit

      local preeidt=context:get_preedit()
      local s= preedit.text
      preedit.text="abc"
   
     yield( Candidate( "debug" , seg.start,seg._end , s, preedit.txt ) )   

Segmentor 在 librime 中也是核心 切字段打tag
對了 會出現 ascii 說不定也有 tag raw or phony context.composition -- "composition", WRAP(get_composition) } 找 raw 字段

以目前的 tag 的preedit_format 轉換 raw or phony 的preedit


src/rime/gear/ascii_segmentor.cc:27:    segment.tags.insert("raw");
src/rime/gear/echo_translator.cc:38:  auto candidate = New<SimpleCandidate>("raw",
src/rime/gear/fallback_segmentor.cc:38:    if (last.HasTag("raw")) {
src/rime/gear/fallback_segmentor.cc:44:      last.tags.insert("raw");
src/rime/gear/fallback_segmentor.cc:52:    segment.tags.insert("raw");
src/rime/gear/selector.cc:37:  if (!current_segment.menu || current_segment.HasTag("raw"))
src/rime/composition.cc:46:        if (!at(i).HasTag("phony")) {
src/rime/composition.cc:116:      if (!seg.HasTag("phony")) {
src/rime/gear/affix_segmentor.cc:77:  prefix_segment.tags.insert("phony");  // do not commit raw input
src/rime/gear/affix_segmentor.cc:103:    suffix_segment.tags.insert("phony");  // do not commit raw input
src/rime/gear/chord_composer.cc:124:      !ctx->composition().back().HasTag("phony");
src/rime/gear/chord_composer.cc:174:    placeholder.tags.insert("phony");
src/rime/gear/chord_composer.cc:214:  if (comp.size() == 1 && last_segment.HasTag("phony")) {

shewer avatar Nov 28 '21 11:11 shewer

Preedit 是Struct log.error 沒有錯的話, 應該是有設定 可以再取回確認 ,說不定是程序上沒有刷新 或是在 改cand.preedit 但是 cand 是translator 產生的 和segment start _end 相關 ,不知道有沒有影響,可以一試 可以在 lua_filter yield debug candidate 查看

candidata 也有 preedit

      local preeidt=context:get_preedit()
      local s= preedit.text
      preedit.text="abc"
   
     yield( Candidate( "debug" , seg.start,seg._end , s, preedit.txt ) )   

Segmentor 在 librime 中也是核心 切字段打tag 對了 會出現 ascii 說不定也有 tag raw or phony context.composition -- "composition", WRAP(get_composition) } 找 raw 字段

以目前的 tag 的preedit_format 轉換 raw or phony 的preedit


src/rime/gear/ascii_segmentor.cc:27:    segment.tags.insert("raw");
src/rime/gear/echo_translator.cc:38:  auto candidate = New<SimpleCandidate>("raw",
src/rime/gear/fallback_segmentor.cc:38:    if (last.HasTag("raw")) {
src/rime/gear/fallback_segmentor.cc:44:      last.tags.insert("raw");
src/rime/gear/fallback_segmentor.cc:52:    segment.tags.insert("raw");
src/rime/gear/selector.cc:37:  if (!current_segment.menu || current_segment.HasTag("raw"))
src/rime/composition.cc:46:        if (!at(i).HasTag("phony")) {
src/rime/composition.cc:116:      if (!seg.HasTag("phony")) {
src/rime/gear/affix_segmentor.cc:77:  prefix_segment.tags.insert("phony");  // do not commit raw input
src/rime/gear/affix_segmentor.cc:103:    suffix_segment.tags.insert("phony");  // do not commit raw input
src/rime/gear/chord_composer.cc:124:      !ctx->composition().back().HasTag("phony");
src/rime/gear/chord_composer.cc:174:    placeholder.tags.insert("phony");
src/rime/gear/chord_composer.cc:214:  if (comp.size() == 1 && last_segment.HasTag("phony")) {

Seg是lua_translator里面的对吧,而context又是 lua_filter里面的 我一时不知道怎么写这个DEBUG了

      local preeidt=context:get_preedit()
      local s= preedit.text
      preedit.text="abc"
   
     yield( Candidate( "debug" , seg.start,seg._end , s, preedit.txt ) )   

mokapsing avatar Nov 28 '21 12:11 mokapsing

'''lua local function func(inp,env) yield( Candidate( "debug" , 1 ,1, text, comment) ) for cand in inp:iter() do .... end end

shewer avatar Nov 28 '21 12:11 shewer

'''lua local function func(inp,env) yield( Candidate( "debug" , 1 ,1, text, comment) ) for cand in inp:iter() do .... end end

这样赋值,preedit.txt没有改变

local s= context:get_preedit().text
context:get_preedit().text = "abc"
yield( Candidate( "debug" , 1, 1 , s, context:get_preedit().text ) )

mokapsing avatar Nov 28 '21 12:11 mokapsing

你是說 text= "abc" 無法改成功是嗎 preedxt.text 是 ascii or preed_format? 看來是沒用 不是參照

 24   │ Preedit Composition::GetPreedit(const string& full_input, size_t caret_pos,
 25   │                                 const string& caret) const {
 26   │   Preedit preedit;

shewer avatar Nov 28 '21 13:11 shewer

你是說 text= "abc" 無法改成功是嗎 preedxt.text 是 ascii or preed_format?

是ascii(输入的编码) image 我尝试放在循环yield(cand)后面,他就是首个cand的preed_format image

mokapsing avatar Nov 28 '21 13:11 mokapsing

table_translator.cc

 33   │ TableTranslation::TableTranslation(TranslatorOptions* options,
 34   │                                    const Language* language,
 35   │                                    const string& input,
 36   │                                    size_t start,
 37   │                                    size_t end,
 38   │                                    const string& preedit,
 39   │                                    DictEntryIterator&& iter,
 40   │                                    UserDictEntryIterator&& uter)
 41   │     : options_(options), language_(language),
 42   │       input_(input), start_(start), end_(end), preedit_(preedit),
 43   │       iter_(std::move(iter)), uter_(std::move(uter)) {
 44   │   if (options_)
 45   │     options_->preedit_formatter().Apply(&preedit_);
 46   │   CheckEmpty();
 47   │ }

有用 Projection.Apply()
可知 是在 translator 產出的 translation 轉換 表示 如果能夠 可以做個 raw translator ,不知道沒有candidate 是否可行???? EchoTranslator tag "raw" 但是沒有 extend OptionTranslator (Projection) 無用

shewer avatar Nov 28 '21 14:11 shewer

table_translator.cc

 33   │ TableTranslation::TableTranslation(TranslatorOptions* options,
 34   │                                    const Language* language,
 35   │                                    const string& input,
 36   │                                    size_t start,
 37   │                                    size_t end,
 38   │                                    const string& preedit,
 39   │                                    DictEntryIterator&& iter,
 40   │                                    UserDictEntryIterator&& uter)
 41   │     : options_(options), language_(language),
 42   │       input_(input), start_(start), end_(end), preedit_(preedit),
 43   │       iter_(std::move(iter)), uter_(std::move(uter)) {
 44   │   if (options_)
 45   │     options_->preedit_formatter().Apply(&preedit_);
 46   │   CheckEmpty();
 47   │ }

有用 Projection.Apply() 可知 是在 translator 產出的 translation 轉換 表示 如果能夠 可以做個 raw translator ,不知道沒有candidate 是否可行???? EchoTranslator tag "raw" 但是沒有 extend OptionTranslator (Projection) 無用

table_translator.cc

 33   │ TableTranslation::TableTranslation(TranslatorOptions* options,
 34   │                                    const Language* language,
 35   │                                    const string& input,
 36   │                                    size_t start,
 37   │                                    size_t end,
 38   │                                    const string& preedit,
 39   │                                    DictEntryIterator&& iter,
 40   │                                    UserDictEntryIterator&& uter)
 41   │     : options_(options), language_(language),
 42   │       input_(input), start_(start), end_(end), preedit_(preedit),
 43   │       iter_(std::move(iter)), uter_(std::move(uter)) {
 44   │   if (options_)
 45   │     options_->preedit_formatter().Apply(&preedit_);
 46   │   CheckEmpty();
 47   │ }

有用 Projection.Apply() 可知 是在 translator 產出的 translation 轉換 表示 如果能夠 可以做個 raw translator ,不知道沒有candidate 是否可行???? EchoTranslator tag "raw" 但是沒有 extend OptionTranslator (Projection) 無用

所以结论是暂时无法实现?

mokapsing avatar Nov 28 '21 14:11 mokapsing

是吧 如果 游標在右 還好處理 在左 右邊字串 不好處理

librime 對於 segment 處理嚴謹,從source ( processor segment translator) .. 都在算 input 位置 librime-lua 只要 yield( candidate )segment 位置不對也可以

shewer avatar Nov 28 '21 14:11 shewer

@shewer 其实我有个想法,在最开始的一个processor里将a-y转成「日-卜」,码表里以「日-卜」为编码是否可行呢,全面改造为中文编码输入法

mokapsing avatar Nov 28 '21 14:11 mokapsing

會有~衝突 context.input --> utf-8 1 字串長度 2 context.input processors segmentors 都要用大部份都在處理 ascii code 3 translators 字典 code --> 詞彙 (utf8-> 詞彙)

shewer avatar Nov 28 '21 15:11 shewer

會有~衝突 context.input --> utf-8 1 字串長度 2 context.input processors segmentors 都要用大部份都在處理 ascii code 3 translators 字典 code --> 詞彙 (utf8-> 詞彙)

看来要从代码定制了

mokapsing avatar Nov 28 '21 15:11 mokapsing

改 promptt 容昜些 一大 一大大大| 一大大|k(大) 一大|kk(大大) 因爲 prompt 只要檢查右邊字串加入 prompt

shewer avatar Nov 28 '21 15:11 shewer

改 promptt 容昜些 一大 一大大大| 一大大|k(大) 一大|kk(大大) 因爲 prompt 只要檢查右邊字串加入 prompt

能否给个demo,因为我不知如何获取光标右侧的编码

mokapsing avatar Nov 28 '21 21:11 mokapsing

不確定 要試才知道. 因爲用的少 一直沒搞懂 segmention segment menu

context.caret_pos (set & get) 可以取得和設定 光標 和 context.input:sub( context.caret_pos)

// rime/gear/navigator.cc  navigator 處理輸入欄內的光標移動
if (input_ != ctx->input() || ctx->caret_pos()   

在 SegmentReg CompositionReg 有關於 prompt 下面曾經在lua_segment 就改過prompt

local function segmentor_func(segs ,env) -- segmetation:Segmentation,env_
    local context=env.engine.context
    local cartpos= segs:get_current_start_position()

    -- 在english_mode() 為 input 打上 english tag
    if english_mode(env) and context:is_composing() then
        local str = segs.input:sub(cartpos)
        if not  str:match([[^%a[%a'?*_.-]*]]) then  return true  end
        local str= segs.input:sub(segs:get_current_start_position() )
        local seg=Segment(cartpos,segs.input:len())
        seg.tags=  Set({English})
        seg.prompt="(english)"  -- <---------
        segs:add_segment(seg)

        -- 終止 後面 segmentor   打tag
        return false
    end
    -- 不是 english_mode  pass 此 segmentor  由後面處理
    return true

shewer avatar Nov 28 '21 22:11 shewer

不確定 要試才知道. 因爲用的少 一直沒搞懂 segmention segment menu

context.caret_pos (set & get) 可以取得和設定 光標 和 context.input:sub( context.caret_pos)

// rime/gear/navigator.cc  navigator 處理輸入欄內的光標移動
if (input_ != ctx->input() || ctx->caret_pos()   

在 SegmentReg CompositionReg 有關於 prompt 下面曾經在lua_segment 就改過prompt

local function segmentor_func(segs ,env) -- segmetation:Segmentation,env_
    local context=env.engine.context
    local cartpos= segs:get_current_start_position()

    -- 在english_mode() 為 input 打上 english tag
    if english_mode(env) and context:is_composing() then
        local str = segs.input:sub(cartpos)
        if not  str:match([[^%a[%a'?*_.-]*]]) then  return true  end
        local str= segs.input:sub(segs:get_current_start_position() )
        local seg=Segment(cartpos,segs.input:len())
        seg.tags=  Set({English})
        seg.prompt="(english)"  -- <---------
        segs:add_segment(seg)

        -- 終止 後面 segmentor   打tag
        return false
    end
    -- 不是 english_mode  pass 此 segmentor  由後面處理
    return true

谢谢 我会尝试下,是否有可以不从translator获取format来转换的方式?固定死实现

  • "xlit|abcdefghijklmnopqrstuvwxyz~|日月金木水火土的戈十大中一弓人心手口尸廿山女田止卜片~|"

mokapsing avatar Nov 28 '21 23:11 mokapsing

https://github.com/hchunhui/librime-lua/blob/67ef681a9fd03262c49cc7f850cc92fc791b1e85/src/types.cc#L887 Projection ConfigList 是全域變數 也可以在 lua 中create config_list

-- 從 yaml 中取得 preedit_format
local config= env.engine.schema.config
local config_list= config:get_list( "translator" .."/" .. "preedit_format")
local projection= Projection()
projection:load(config_list)
local pstr= projection:apply("abc") 
-- 自制 preedit_format 
local config_list= ConfigList()
config_list:append(
     ConfigValue( pattern_str1).element --  create ConfigValue 轉換成 ConfigItem
)
config_list:append( .... )

shewer avatar Nov 29 '21 00:11 shewer

Projection()

如果手机上librime版本低用不了Projection(),有办法自定义一个吗?另外上面的demo是作为lua_segmentor使用对吧?

mokapsing avatar Nov 29 '21 00:11 mokapsing

是的

我記得 trime 3.2.3 己有最新版本 有更新到 20210417 Projection Config Memory 有支援 librime-lua 作者在七月有 PR trime

shewer avatar Nov 29 '21 00:11 shewer

是的

我記得 trime 3.2.3 己有最新版本 有更新到 20210417 Projection Config Memory 有支援 librime-lua 作者在七月有 PR trime

我挂在lua_segmentor上,去掉english mode较验,但是没有加上prompt

我用的iRime还不知道是否支持

mokapsing avatar Nov 29 '21 00:11 mokapsing

IRime 不曾涉略

shewer avatar Nov 29 '21 00:11 shewer

最终我通过filter加上了prompt,也算是拆中实现了吧 CA267A5A-B1A4-4826-9BF8-239AAE447188

mokapsing avatar Nov 29 '21 04:11 mokapsing

分享 code

shewer avatar Nov 29 '21 04:11 shewer

分享 code

function func(input, env)
	local context = env.engine.context
	for cand in input:iter() do
        yield(cand)
        if string.len(context.input) > cand._end then
			local comp = context.composition
			local pattern= Projection()
			local config_list= ConfigList()
			local un_trans_input = context.input:sub(cand._end + 1)
			config_list:append(
				 ConfigValue("xlit|abcdefghijklmnopqrstuvwxy|日月金木水火土的戈十大中一弓人心手口尸廿山女田止卜|").element --  create ConfigValue 轉換成 ConfigItem
			)
			pattern:load(config_list)
			comp:back().prompt = "〔"..pattern:apply(un_trans_input).."〕"
		end
    end
end
return {func = func}

mokapsing avatar Nov 29 '21 04:11 mokapsing