@青稚Quentin 他有两个开发工具按钮,在查词主界面的那个 “虫子” 图标是用来调试查出来的词条内容的,在设置界面是用来调试APP的,我理解你的需求是想用 “虫子” 图标的那个调试工具,你说的选中的功能支持的,我就是这么用的。
初始宽度设置小了,拉伸一下窗口就出来了,这个今天我修复一下
查询有些MDX还有问题:
只能查到“干” 前三个义项?
v2.0.4
- 修复了 windows UI 的问题
- 优化了翻译、插件界面的UI
好的,这个我跟进一下
刚刚2.0.3版本无法添加词典, 我卸载后更换了2.0.4版本依旧有这个问题
词典名称、词典别名、mdx、mdd文件添加成功后,点击【添加】 没有任何反应,也无法做出任何操作。退出后重新操作依旧是此问题。
系统:macOS Big Sur 11.5
版本:2.0.4
词典别名输入过 “ Oxford Learner’s Thesaurus ” ,后又重新操作输入中文 依旧是此问题
你这个问题是这样的,别名只能是英文字符,而且不能超过12个字符我记得,主要是为了防止在下拉框显示的时候出问题,你可以先试试,我后面的版本会放开限制
这个可能不好弄,因为相同词条有的词典意思不同的
还有就是现在相同的词条,内容是有重复的。
take1显示 take1,take2,take3 的解释。
take2显示 take2,take3 的解释。
take3显示 take3 的解释。
take4显示 take4,take5,take6,take7,take8,take9 的解释。
take5显示 take5,take6,take7,take8,take9 的解释。
…
鉴于目前遇到了好多种词典在特定词条可能出现查询不到的情况,我需要解释一下Medict现在的查词逻辑:
首先先解析 mdx 文件中的 keyBlockInfo
, 这个结构是由 [startKey,endKey]
组成的,如果当前所查询的词条为在特定的 keyBlockInfo
范围中,也就是 startKey<=key<=endKey
时,再读取这个keyBlockInfo
对应的 recordBlockInfo
, 在该 recordBlockInfo
中有 [startKey->endKey]
的所有词条,然后遍历这些词条得到最后的结果。
在上面的过程当中,有几个问题:
-
[startKey, endKey]
是大小写敏感的,实际测试时,存在大写词条和小写词条即使首字母相同,也不一定在同一个keyBlockInfo
中的情况 - 在词典词条比较时,会将词条进行 Strip 操作这个会把特殊符号去除,最后再进行比较,这个操作实测会把一些词条修改为词典中不存在的词条
- 词条解释终结符问题,因为词条设计的时候没有定义词条长度,是使用终结符来表示当前词条定义的结束位置的,一般情况下是正确截断的,但是如果词典终结符有问题,就有可能把后面词条的解释合并到当前词条解释中
Medict 是不需要建立索引的,采用的是mdx格式设计的索引方式查词,效率目前看还行,就是由于排序方式和比较方式的问题,导致有些场景词会查不出来,当然也存在无法大小写模糊查询的问题。
想请问大家,如果Medict改成和 gd 一样先建立词条索引是否能够接受呢?这样就会有一个建立索引的过程,可能在首次启动的时候,或是添加词典之后需要花点时间建立索引才能使用
社区里常用的两款制作工具,官方的 mdxbuilder 3.0和 mdict-utils 都不会修改词条。你可以参考下后者的实现。
这个是 medict 在比较的时候进行的 strip 处理,既然社区里面实际制作的时候都不会进行strip,那么我在查询的时候也不进行strip就可以了
词典的 Record 部分是有记录词条内容的偏移量和内容长度的,读取的时候依赖这个。具体怎么读到的忘记了。看代码是在读取压缩块的偏移量和长度时,通过 shadowEndPos
计算出来的。曾经写过这一块,供参考:
let record_index = &self.parser.record_indexes[i];
let record_size = match iter.peek() {
Some((next_offset, _)) => (next_offset - offset),
None => (record_index.shadow_end_pos - offset),
};
let record_addr = RecordAddr {
id: self.parser.id,
comp_pos: self.parser.record_blocks_pos + record_index.start_pos,
record_offset: offset - record_index.shadow_start_pos,
decomp_size: record_index.decomp_size,
comp_size: record_index.comp_size,
record_size: record_size,
};
let range =
addr.record_offset as usize..(addr.record_offset + addr.record_size as u64) as usize;
let record_buf = &decomp_buf[range];
let (content, encoding, has_err) = self.parser.encoding_rs.decode(&record_buf);
if has_err {
return Err(format!(
"failed to decode '{}' content with '{}' data",
self.parser.encoding,
encoding.name()
))?;
}
let content = content.trim_matches(|c: char| c == '\x00');
Ok(content.to_string())
当初写的时候,实际上是复刻的 GoldenDict 的实现,在如下链接位置:
shadowEndPos 的读取过程:
感谢大佬指点,这块我需要再仔细完善一下查询部分的代码,不然总是有些小毛病