Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何保存英文自造词? #280

Closed
Nicked639 opened this issue May 21, 2023 · 24 comments
Closed

如何保存英文自造词? #280

Nicked639 opened this issue May 21, 2023 · 24 comments

Comments

@Nicked639
Copy link

输入词库中不存在的英文单词后,都是用回车键上屏的,这个如何记录在词典中以便下次复用呢?

方案里中有

# 次翻译器,英文
melt_eng:
  dictionary: melt_eng     # 挂载词库 melt_eng.dict.yaml
  enable_sentence: true   # 禁止造句
  enable_user_dict: true  # 禁用用户词典
  initial_quality: 1.1     # 初始权重
  comment_format:          # 自定义提示码
    - xform/.*//           # 清空提示码

请问上面的 enable_sentenceenable_user_dict是用来做这件事的吗?

@iDvel
Copy link
Owner

iDvel commented May 21, 2023

不是的。
enable_sentence: false 是不生成 loveyou 这种两个词汇组合。
enable_user_dict: false 是不让英文调频,防止重码的 size 超过「四则」。

没有给英文自造词的功能,缺失的常见单词可以提个 issue。
或者你看看 #101 有个自动写入词库的 Lua,但还是需要重新部署才生效。

@Nicked639
Copy link
Author

Nicked639 commented May 21, 2023

enable_sentence设定之后可否支持在单词之间自动插入空格呢?不然打出来的是几个英文单词的拼接。
可以参考一下iOS自带输入法的模式。

@iDvel
Copy link
Owner

iDvel commented May 21, 2023

rime-easy-en 这个可以,但是在英文方案下。

@boomker
Copy link
Contributor

boomker commented May 21, 2023

enable_sentence设定之后可否支持在单词之间自动插入空格呢?不然打出来的是几个英文单词的拼接。 可以参考一下iOS自带输入法的模式。

可以参考我的 lua 脚本实现 , 点这里

我的是只给英文单词 左侧加上了空格

@Nicked639
Copy link
Author

enable_sentence设定之后可否支持在单词之间自动插入空格呢?不然打出来的是几个英文单词的拼接。 可以参考一下iOS自带输入法的模式。

可以参考我的 lua 脚本实现 , 点这里

我的是只给英文单词 左侧加上了空格

你好,我下载了这个lua脚本,在方案的custom里加入了

engine/processors/+:
    - lua_processor@top_word_autocommit_processor

但是重新部署后没有起作用,是还需要其他额外的操作吗?

@boomker
Copy link
Contributor

boomker commented May 21, 2023

在方案的custom里加入了, 但是重新部署后没有起作用,是还需要其他额外的操作吗?

不是 processor 哦, 是要加这两个:

  engine/+:
    translators/+:
      - lua_translator@engword_autocaps_translator
    filters/+:
      - lua_filter@engword_autocaps_filter

@Nicked639
Copy link
Author

在方案的custom里加入了, 但是重新部署后没有起作用,是还需要其他额外的操作吗?

不是 processor 哦, 是要加这两个:

  engine/+:

    translators/+:

      - lua_translator@engword_autocaps_translator

    filters/+:

      - lua_filter@engword_autocaps_filter

成功了!能让首词大写按大写输出真的方便了不少。不过在单词前追加空格的方式跟我的输入有点不符,我给改了。

谢谢分享🙏

@hoofcushion
Copy link
Contributor

hoofcushion commented May 21, 2023

输入以-=结尾执行加词,注意手动关闭-=翻页
image
如果词已经存在则执行删词
image
 
上述效果如此配置即可:
 
 
新建这个文件,用于存放保存下来的用户词
en_dicts\en_custom.dict.yaml

---
name: en_custom
version: "20230523225854"
...

 
 
直接粘贴下方代码,也可以模块化
rime.lua

local sep = package.config:sub(1, 1)
local user_data_dir = nil
local shared_data_dir = nil
if(sep=="\\")then
 user_data_dir = string.gsub(rime_api:get_user_data_dir(),"\\","\\\\")
 shared_data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")
elseif(sep=="/")then
 user_data_dir = rime_api:get_user_data_dir()
 shared_data_dir = rime_api:get_shared_data_dir()
else return
end
local dict_name = sep.."en_dicts"..sep.."en_custom.dict.yaml"
local dict_dir = user_or_shared(dict_name)

local function user_or_shared(file_name)
 if (io.open(user_data_dir..file_name,"r")  )then --在用户文件夹中找到
  return user_data_dir..file_name
 else
  if(io.open(shared_data_dir..file_name,"r"))then --只在程序文件夹中找到
  return shared_data_dir..file_name
  else return nil --什么也没找到
  end
 end
end
local function user_dict_exists_(str,dir) --判断词条str是否已经在文件夹dir中存在
 local file = io.open(dir, "r")
 for line in file:lines() do
  if line == str then
   file:close()
   return true
  end
 end
 file:close()
 return false
end

function en_custom(input,seg)
 if(input:sub(-2)=="-=" and input~="-=")then --输入末尾必须是-=,并且排除只包含-=的情况。
  local inp = input:sub(1,-3):gsub("|"," ")
  local unconfirm = inp.."\t"..inp:gsub("[^%a]+",""):lower().."\t100000"
  if(user_dict_exists_(unconfirm,dict_dir))then
   local file = io.open(dict_dir, "r+")
   local content = file:read("*all")
   file:close()
   content = content:gsub("\n"..unconfirm:gsub("([%%%(%)%[%]%-*+?%.%^])", "%%%1"), "")
   file = io.open(dict_dir, "w+")
   file:write(content)
   file:close()
   yield(Candidate("en_custom",seg.start,seg._end,inp," 词已删 再输-=可重添"))
  else
   local file = io.open(dict_dir,"a")
   file:write("\n"..unconfirm):close()
   yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))
  end
 end
end

 
 
在方案中加入Lua插件,并将-=加入码元表就可以使用了
rime-ice.schema.yaml

engine:
 translators: ...
+ - lua_translator@en_custom
speller:
-  alphabet: zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA
+  alphabet: zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA-=

 
 
加词部分结束了,但别忘了在主词典中引入用户词典
melt_eng.dict.yaml

name: melt_eng
version: "2023-05-09"
import_tables:
  - en_dicts/en_ext  # 补充
  - en_dicts/en      # 英文主词库
+  - en_dicts/en_custom # 英文用户词

 
 
在Lua部分采用这种模块化写法也可以
rime.lua

en_custom= require("en_custom")

 
lua\en_custom.lua

local sep = package.config:sub(1, 1)
local user_data_dir = nil
local shared_data_dir = nil
if(sep=="\\")then
 user_data_dir = string.gsub(rime_api:get_user_data_dir(),"\\","\\\\")
 shared_data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")
elseif(sep=="/")then
 user_data_dir = rime_api:get_user_data_dir()
 shared_data_dir = rime_api:get_shared_data_dir()
else return
end
local dict_name = sep.."en_dicts"..sep.."en_custom.dict.yaml"
local dict_dir = user_or_shared(dict_name)

local function user_or_shared(file_name)
 if (io.open(user_data_dir..file_name,"r")  )then --在用户文件夹中找到
  return user_data_dir..file_name
 else
  if(io.open(shared_data_dir..file_name,"r"))then --只在程序文件夹中找到
  return shared_data_dir..file_name
  else return nil --什么也没找到
  end
 end
end
local function user_dict_exists_(str,dir) --判断词条str是否已经在文件夹dir中存在
 local file = io.open(dir, "r")
 for line in file:lines() do
  if line == str then
   file:close()
   return true
  end
 end
 file:close()
 return false
end

return function (input,seg)
 if(input:sub(-2)=="-=" and input~="-=")then --输入末尾必须是-=,并且排除只包含-=的情况。
  local inp = input:sub(1,-3):gsub("|"," ")
  local unconfirm = inp.."\t"..inp:gsub("[^%a]+",""):lower().."\t100000"
  if(user_dict_exists_(unconfirm,dict_dir))then
   local file = io.open(dict_dir, "r+")
   local content = file:read("*all")
   file:close()
   content = content:gsub("\n"..unconfirm:gsub("([%%%(%)%[%]%-*+?%.%^])", "%%%1"), "")
   file = io.open(dict_dir, "w+")
   file:write(content)
   file:close()
   yield(Candidate("en_custom",seg.start,seg._end,inp," 词已删 再输-=可重添"))
  else
   local file = io.open(dict_dir,"a")
   file:write("\n"..unconfirm):close()
   yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))
  end
 end
end
}

总结:很方便的小功能,考虑加入雾凇呀
image

附件:Rime ice en custom test 20230523230639.zip

@Nicked639
Copy link
Author

输入以-=结尾执行加词

image

如果词已经存在则执行删词

image

 

上述效果如此配置即可:

 

 

新建这个文件,用于存放保存下来的用户词

en_dicts\en_custom.dict.yaml

---

name: en_custom

version: "2023-02-15"

...

 

 

直接粘贴下方代码,也可以模块化

rime.lua

local data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")--

function user_dict_exists_(str,dir)--

 --判断用户词典中是否已经存在指定字符串

 local file = io.open(data_dir..dir, "r")--

 -- io.open() 打开指定文件,并返回一个文件

 -- 第二个参数 "r" 表示以只读模式打开文件

 -- file:lines() 返回一个迭代器,用于逐行读取文件内容

 for line in file:lines() do

  if line == str then -- 如果找到了与指定字符串相同的行

   file:close()

   return true -- 返回 true,表示用户词已存在

  end

 end

 file:close()

 return false -- 没有找到与指定字符串相同的行,返回 false,表示用户词不存在

end

en_custom = {

 func = function (input,seg)--

  -- 判断输入内容是否以-=结尾

  if(string.find(input,"-=$"))then--

   -- 将输入内容中的|替换为空格

   local inp = input:sub(1,-3):gsub("|"," ")--

   -- 构造新的用户词

   local unconfirm = inp.."\t"..inp:gsub("[^%a]+",""):lower().."\t100000"--

   --

   -- 判断用户词典中是否已存在该用户词

   if(user_dict_exists_(unconfirm,"\\en_dicts\\en_custom.dict.yaml"))then--

    -- 若已存在,则删除用户词并提示

    local file = io.open(data_dir .. "\\en_dicts\\en_custom.dict.yaml", "r+")

    local content = file:read("*all")

    file:close()

    content = content:gsub("\n"..unconfirm:gsub("([%%%(%)%[%]%-*+?%.%^])", "%%%1"), "")

    file = io.open(data_dir .. "\\en_dicts\\en_custom.dict.yaml", "w+")

    file:write(content):close()



    yield(Candidate("en_custom",seg.start,seg._end,inp," 词已删 再输-=可重添"))

   else--

    -- 若不存在,则将该用户词添加到用户词典中并返回提示信息

    local file = io.open(data_dir.."\\en_dicts\\en_custom.dict.yaml","a")

    file:write("\n"..unconfirm):close()

    yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))

   end

  end

 end

}

 

 

在方案中加入Lua插件就可以使用了

rime-ice.schema.yaml

engine:

 translators: ...

+ - lua_translator@en_custom

 

 

加词部分结束了,但别忘了在主词典中引入用户词典

melt_eng.dict.yaml

name: melt_eng

version: "2023-05-09"

import_tables:

  - en_dicts/en_ext  # 补充

  - en_dicts/en      # 英文主词库

+ - en_dicts/en_custom #Lua用户词典

 

 

在Lua部分采用这种写法也可以

rime.lua

en_custom= require("en_custom")

 

lua\en_custom

local data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")--

local function user_dict_exists_(str,dir)--

 --判断用户词典中是否已经存在指定字符串

 local file = io.open(data_dir..dir, "r")--

 -- io.open() 打开指定文件,并返回一个文件

 -- 第二个参数 "r" 表示以只读模式打开文件

 -- file:lines() 返回一个迭代器,用于逐行读取文件内容

 for line in file:lines() do

  if line == str then -- 如果找到了与指定字符串相同的行

   file:close()

   return true -- 返回 true,表示用户词已存在

  end

 end

 file:close()

 return false -- 没有找到与指定字符串相同的行,返回 false,表示用户词不存在

end

return {

 func = function (input,seg)--

  -- 判断输入内容是否以-=结尾

  if(string.find(input,"-=$"))then--

   -- 将输入内容中的|替换为空格

   local inp = input:sub(1,-3):gsub("|"," ")--

   -- 构造新的用户词

   local unconfirm = inp.."\t"..inp:gsub("[^%a]+",""):lower().."\t100000"--

   --

   -- 判断用户词典中是否已存在该用户词

   if(user_dict_exists_(unconfirm,"\\en_dicts\\en_custom.dict.yaml"))then--

    -- 若已存在,则删除用户词并提示

    local file = io.open(data_dir .. "\\en_dicts\\en_custom.dict.yaml", "r+")

    local content = file:read("*all")

    file:close()

    content = content:gsub("\n"..unconfirm:gsub("([%%%(%)%[%]%-*+?%.%^])", "%%%1"), "")

    file = io.open(data_dir .. "\\en_dicts\\en_custom.dict.yaml", "w+")

    file:write(content):close()



    yield(Candidate("en_custom",seg.start,seg._end,inp," 词已删 再输-=可重添"))

   else--

    -- 若不存在,则将该用户词添加到用户词典中并返回提示信息

    local file = io.open(data_dir.."\\en_dicts\\en_custom.dict.yaml","a")

    file:write("\n"..unconfirm):close()

    yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))

   end

  end

 end

}

总结:很方便的小功能,考虑加入雾凇呀

image

老哥有没有用过iOS上的仓输入法,我按你的教程设置后重新部署不起作用。 不知道是不是文件读写路径的问题?

@hoofcushion
Copy link
Contributor

老哥有没有用过iOS上的仓输入法,我按你的教程设置后重新部署不起作用。 不知道是不是文件读写路径的问题?

不是很了解ios,不知道什么问题

@Nicked639
Copy link
Author

Nicked639 commented May 23, 2023

老哥有没有用过iOS上的仓输入法,我按你的教程设置后重新部署不起作用。 不知道是不是文件读写路径的问题?

不是很了解ios,不知道什么问题

我在PC上也试了一下,也不行,我做的步骤是这样的:

  1. 用你的代码新建一个 en_custom.lua 放在 lua 文件夹
  2. rime.lua 里添加 en_custom= require("en_custom")
  3. 在我的方案xxx.custom.ymal里添加 engine/translators/+: - lua_translator@en_custom
  4. en_dicts文件夹内新建一个en_custom.dict.yaml,并复制填入你上面的内容
  5. melt_eng.dict.yaml 里添加 - en_dicts/en_custom
  6. 同时我发现直接按-或者=会上屏,就在方案 xxx.custom.ymalspeller/alphabet:也添加上了-=

最终在输入时出来的结果是这样
image

会是什么原因呢,还有哪里没设置好吗?

@hoofcushion
Copy link
Contributor

hoofcushion commented May 23, 2023

image
不生效,可能的原因:
1雾凇拼音默认使用-=作为翻页键
解决办法 1 : 进入default.yaml中注释掉图中所示内容
解决办法 2 : 进入en_custom中将-=替换为其他可用符号
2配置有错误
解决办法 1 : 参照附件给出的详细信息
附件: 附件:Rime ice en custom test 20230523230639.zip
3未知原因
解决办法 1 : 重新安装雾凇拼音,将附件内的文件解压到雾凇拼音根目录,替换掉雾凇拼音的文件,部署即可使用

@Nicked639
Copy link
Author

Nicked639 commented May 24, 2023

image

不生效,可能的原因:

1雾凇拼音默认使用-=作为翻页键

解决办法 1 : 进入default.yaml中注释掉图中所示内容

解决办法 2 : 进入en_custom中将-=替换为其他可用符号

2配置有错误

解决办法 1 : 参照附件给出的详细信息

附件: 附件:Rime ice en custom test 20230523230639.zip

3未知原因

解决办法 1 : 重新安装雾凇拼音,将附件内的文件解压到雾凇拼音根目录,替换掉雾凇拼音的文件,部署即可使用

尝试了你罗列的三种解决方法,均无效。
包括重新下载雾凇配置,用你上面的压缩包内容进行文件替换。其中压缩包里的default文件并没有注释掉用-=进行翻页,我进行了手动注释。最终出来的效果还是和我上面类似,输入-=不能弹出保存用户词的提示。

我感觉还是lua文件的问题,因为我将rime.lua中require这个en_custom.lua前置后发现连拼音都打不出了

@hoofcushion
Copy link
Contributor

那只可能是你的librime版本有问题了
image
我打包了一个可以直接运行的绿色Rime ice包,基于fxliang的小狼毫,支持win8.1+系统,并且支持英文自造词功能
Rime Ice.zip

@Nicked639
Copy link
Author

那只可能是你的librime版本有问题了

image

我打包了一个可以直接运行的绿色Rime ice包,基于fxliang的小狼毫,支持win8.1+系统,并且支持英文自造词功能

Rime Ice.zip

用了这个安装包的确可行了。再请教一下,我想将用户文件夹设置为我之前使用的路径,但在程序的设定中设定后重新部署并不能生效,是因为这个安装包修改过的关系吗?

@hoofcushion
Copy link
Contributor

不清楚,建议把原先的复制粘贴进来,这个Rime ice包是绿色,不会影响原先的Rime

@Nicked639
Copy link
Author

不清楚,建议把原先的复制粘贴进来,这个Rime ice包是绿色,不会影响原先的Rime

因为用户文件夹不能自定义的原因,我尝试去下载fxliang 最新的构建,重新安装,设定成我自定义的用户文件夹后,又不能出来英文自造词的提示了。 会不会是en_custom.lua 文件里指定的共享数据文件夹路径不同有关系?

@hoofcushion
Copy link
Contributor

hoofcushion commented May 26, 2023

这么一说我就回过神来了
是的,我在en_custom中引入了变量data_dir,指向了共享文件夹/程序文件夹

local data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")

因此提到en_dicts/en_custom.dict.yaml这个文件时,Lua是在程序文件夹中检索,而将这个文件放在用户文件夹中,自然就找不到en_dicts/en_custom.dict.yaml因此Lua插件会崩溃,导致你打不出字。

具体解决办法是,使用以下代码替换原本代码,基本上没有区别,但是能同时在用户文件夹程序文件夹中检索dict_name指向的词库文件,而且如果没有检索到的话,整个英文造词插件都不会运行,避免了文件缺失带来的崩溃,如果需要更换词库位置,就需要手动修改dict_name的值。

local user_data_dir = string.gsub(rime_api:get_user_data_dir(),"\\","\\\\")
local shared_data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")
local dict_name = "\\_dic_en\\en_custom.dict.yaml"

local dict_dir = nil -- 初始化变量
if (io.open(user_data_dir..dict_name,"r")  )then --如果用户文件夹中找到了dict_name指向的词库文件,则将文件目录赋值给dict_dir
 dict_dir = user_data_dir..dict_name
else
 if(io.open(shared_data_dir..dict_name,"r"))then --如果用户文件夹中没找到dict_name指向的词库文件,但是程序文件夹中找到了,则将文件目录赋值给dict_dir
 dict_dir = shared_data_dir..dict_name
 else return
 end
end
local function user_dict_exists_(str,dir) --输入字符串和文件路径,在路径指向文件中逐行查找完全对应的字符串,如果已存在则返回true,适用于小狼毫判断词条是否已经存在
 local file = io.open(dir, "r")
 for line in file:lines() do
  if line == str then
   file:close()
   return true
  end
 end
 file:close()
 return false
end
return function (input,seg)
 if(input:sub(-2)=="-=" and input~="-=")then --输入末尾必须是-=,并且排除只包含-=的情况。
  local inp = input:sub(1,-3):gsub("|"," ")
  local unconfirm = inp.."\t"..inp:gsub("[^%a]+",""):lower().."\t100000"
  if(user_dict_exists_(unconfirm,dict_dir))then
   local file = io.open(dict_dir, "r+")
   local content = file:read("*all")
   file:close()
   content = content:gsub("\n"..unconfirm:gsub("([%%%(%)%[%]%-*+?%.%^])", "%%%1"), "")
   file = io.open(dict_dir, "w+")
   file:write(content)
   file:close()
   yield(Candidate("en_custom",seg.start,seg._end,inp," 词已删 再输-=可重添"))
  else
   local file = io.open(dict_dir,"a")
   file:write("\n"..unconfirm):close()
   yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))
  end
 end
end

@Nicked639
Copy link
Author

Nicked639 commented May 26, 2023

这么一说我就回过神来了

是的,我在en_custom中引入了变量data_dir,指向了共享文件夹/程序文件夹

local data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")

因此提到en_dicts/en_custom.dict.yaml这个文件时,Lua是在程序文件夹中检索,而将这个文件放在用户文件夹中,自然就找不到en_dicts/en_custom.dict.yaml因此Lua插件会崩溃,导致你打不出字。

具体解决办法是,使用以下代码替换原本代码,基本上没有区别,但是能同时在用户文件夹程序文件夹中检索dict_name指向的词库文件,而且如果没有检索到的话,整个英文造词插件都不会运行,避免了文件缺失带来的崩溃,如果需要更换词库位置,就需要手动修改dict_name的值。

local user_data_dir = string.gsub(rime_api:get_user_data_dir(),"\\","\\\\")

local shared_data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")

local dict_name = "\\_dic_en\\en_custom.dict.yaml"



local dict_dir = nil -- 初始化变量

if (io.open(user_data_dir..dict_name,"r")  )then --如果用户文件夹中找到了dict_name指向的词库文件,则将文件目录赋值给dict_dir

 dict_dir = user_data_dir..dict_name

else

 if(io.open(shared_data_dir..dict_name,"r"))then --如果用户文件夹中没找到dict_name指向的词库文件,但是程序文件夹中找到了,则将文件目录赋值给dict_dir

 dict_dir = shared_data_dir..dict_name

 else return

 end

end

local function user_dict_exists_(str,dir) --输入字符串和文件路径,在路径指向文件中逐行查找完全对应的字符串,如果已存在则返回true,适用于小狼毫判断词条是否已经存在

 local file = io.open(dir, "r")

 for line in file:lines() do

  if line == str then

   file:close()

   return true

  end

 end

 file:close()

 return false

end

return function (input,seg)

 if(input:sub(-2)=="-=" and input~="-=")then --输入末尾必须是-=,并且排除只包含-=的情况。

  local inp = input:sub(1,-3):gsub("|"," ")

  local unconfirm = inp.."\t"..inp:gsub("[^%a]+",""):lower().."\t100000"

  if(user_dict_exists_(unconfirm,dict_dir))then

   local file = io.open(dict_dir, "r+")

   local content = file:read("*all")

   file:close()

   content = content:gsub("\n"..unconfirm:gsub("([%%%(%)%[%]%-*+?%.%^])", "%%%1"), "")

   file = io.open(dict_dir, "w+")

   file:write(content)

   file:close()

   yield(Candidate("en_custom",seg.start,seg._end,inp," 词已删 再输-=可重添"))

  else

   local file = io.open(dict_dir,"a")

   file:write("\n"..unconfirm):close()

   yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))

  end

 end

end

总算可以了,在win上现在能正常使用了。
同样的代码在iOS上的仓输入法中还有问题。将上面代码中的\\换成/后在iOS的仓输入法中输入-=能在候选词看到保存或者删除的提示了,但是en_custom.dict.yaml中却没有写入内容,不知道是不是iOS的限制?

@hoofcushion
Copy link
Contributor

hoofcushion commented May 26, 2023

总算可以了,在win上现在能正常使用了。 同样的代码在iOS上的仓输入法中还不起作用,应该也是文件路径的关系。在iOS上我用的方案和win上是一样的,可能是代码前两行的api在iOS上有不同的作用方式?

不,iOS使用的文件夹路径分隔符与Windows不同,具体地说,Windows使用\,iOS使用/
解决办法是,用下方代码替换原本的代码,他能够判断系统使用何种文件夹分隔符,并使用正确的文件路径,可能能够解决这个问题

local sep = package.config:sub(1, 1)
local user_data_dir = nil
local shared_data_dir = nil
if(sep=="\\")then
 user_data_dir = string.gsub(rime_api:get_user_data_dir(),"\\","\\\\")
 shared_data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")
elseif(sep=="/")then
 user_data_dir = rime_api:get_user_data_dir()
 shared_data_dir = rime_api:get_shared_data_dir()
else return
end
local dict_name = sep.."en_dicts"..sep.."en_custom.dict.yaml"
local dict_dir = user_or_shared(dict_name)

local function user_or_shared(file_name)
 if (io.open(user_data_dir..file_name,"r")  )then --在用户文件夹中找到
  return user_data_dir..file_name
 else
  if(io.open(shared_data_dir..file_name,"r"))then --只在程序文件夹中找到
  return shared_data_dir..file_name
  else return nil --什么也没找到
  end
 end
end
local function user_dict_exists_(str,dir) --判断词条str是否已经在文件夹dir中存在
 local file = io.open(dir, "r")
 for line in file:lines() do
  if line == str then
   file:close()
   return true
  end
 end
 file:close()
 return false
end

return function (input,seg)
 if(input:sub(-2)=="-=" and input~="-=")then --输入末尾必须是-=,并且排除只包含-=的情况。
  local inp = input:sub(1,-3):gsub("|"," ")
  local unconfirm = inp.."\t"..inp:gsub("[^%a]+",""):lower().."\t100000"
  if(user_dict_exists_(unconfirm,dict_dir))then
   local file = io.open(dict_dir, "r+")
   local content = file:read("*all")
   file:close()
   content = content:gsub("\n"..unconfirm:gsub("([%%%(%)%[%]%-*+?%.%^])", "%%%1"), "")
   file = io.open(dict_dir, "w+")
   file:write(content)
   file:close()
   yield(Candidate("en_custom",seg.start,seg._end,inp," 词已删 再输-=可重添"))
  else
   local file = io.open(dict_dir,"a")
   file:write("\n"..unconfirm):close()
   yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))
  end
 end
end

@Nicked639
Copy link
Author

总算可以了,在win上现在能正常使用了。 同样的代码在iOS上的仓输入法中还不起作用,应该也是文件路径的关系。在iOS上我用的方案和win上是一样的,可能是代码前两行的api在iOS上有不同的作用方式?

不,iOS使用的文件夹路径分隔符与Windows不同,具体地说,Windows使用\,iOS使用/

解决办法是,用下方代码替换原本的代码,他能够判断系统使用何种文件夹分隔符,并使用正确的文件路径,可能能够解决这个问题

local sep = package.config:sub(1, 1)

local user_data_dir = nil

local shared_data_dir = nil

if(sep=="\\")then

 user_data_dir = string.gsub(rime_api:get_user_data_dir(),"\\","\\\\")

 shared_data_dir = string.gsub(rime_api:get_shared_data_dir(),"\\","\\\\")

elseif(sep=="/")then

 user_data_dir = rime_api:get_user_data_dir()

 shared_data_dir = rime_api:get_shared_data_dir()

else return

end

local dict_name = sep.."en_dicts"..sep.."en_custom.dict.yaml"

local dict_dir = user_or_shared(dict_name)



local function user_or_shared(file_name)

 if (io.open(user_data_dir..file_name,"r")  )then --在用户文件夹中找到

  return user_data_dir..file_name

 else

  if(io.open(shared_data_dir..file_name,"r"))then --只在程序文件夹中找到

  return shared_data_dir..file_name

  else return nil --什么也没找到

  end

 end

end

local function user_dict_exists_(str,dir) --判断词条str是否已经在文件夹dir中存在

 local file = io.open(dir, "r")

 for line in file:lines() do

  if line == str then

   file:close()

   return true

  end

 end

 file:close()

 return false

end



return function (input,seg)

 if(input:sub(-2)=="-=" and input~="-=")then --输入末尾必须是-=,并且排除只包含-=的情况。

  local inp = input:sub(1,-3):gsub("|"," ")

  local unconfirm = inp.."\t"..inp:gsub("[^%a]+",""):lower().."\t100000"

  if(user_dict_exists_(unconfirm,dict_dir))then

   local file = io.open(dict_dir, "r+")

   local content = file:read("*all")

   file:close()

   content = content:gsub("\n"..unconfirm:gsub("([%%%(%)%[%]%-*+?%.%^])", "%%%1"), "")

   file = io.open(dict_dir, "w+")

   file:write(content)

   file:close()

   yield(Candidate("en_custom",seg.start,seg._end,inp," 词已删 再输-=可重添"))

  else

   local file = io.open(dict_dir,"a")

   file:write("\n"..unconfirm):close()

   yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))

  end

 end

end

我将之前代码中的斜杠转换后,能在iOS仓输入法上看到保存用户词的提示。但是我打开en_custom.dict.yaml,却没在里面看到增加对应的用户词,

然而这时候我再次输入这个词再用-=关键词引导,却出现了词已删的提示。

照理说,如果没有存到词典,就不会检测到输入内容的存在从而提示词已删。

所以,我推测用上面API获取的用户文件夹,也许并不是仓输入法App内的那个Rime文件夹?

@hoofcushion
Copy link
Contributor

然而这时候我再次输入这个词再用-=关键词引导,却出现了词已删的提示。

照理说,如果没有存到词典,就不会检测到输入内容的存在从而提示词已删。

所以,我推测用上面API获取的用户文件夹,也许并不是仓输入法App内的那个Rime文件夹?

有这么邪门,试试把

yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))

改成

yield(Candidate("en_custom",seg.start,seg._end,dict_dir ," 已保存为用户词"))

这样,他就会显示究竟检索到了哪个文件了。

@Nicked639
Copy link
Author

然而这时候我再次输入这个词再用-=关键词引导,却出现了词已删的提示。

照理说,如果没有存到词典,就不会检测到输入内容的存在从而提示词已删。

所以,我推测用上面API获取的用户文件夹,也许并不是仓输入法App内的那个Rime文件夹?

有这么邪门,试试把

yield(Candidate("en_custom",seg.start,seg._end,inp," 已保存为用户词"))

改成

yield(Candidate("en_custom",seg.start,seg._end,dict_dir ," 已保存为用户词"))

这样,他就会显示究竟检索到了哪个文件了。

我刚刚还真试过,是类似这样的文件:/private/var/mobile/Containers/Shared/AppGroup/ACC508BD-517F-4EB1-9FAE/InputSchema/Rime,我现在推测可能是出于iOS的安全机制,新词是被被保存在键盘内的对应字典中,而不是App内的,也许键盘无法直接访问、修改App内的文件

@hoofcushion
Copy link
Contributor

那就没有办法了

@iDvel iDvel closed this as completed May 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants