查看: 1828|回复: 9
打印 上一主题 下一主题

[教程] 最近学习到的制作mdict词库时候的一些经验

[复制链接]
匿名
跳转到指定楼层
1
匿名  发表于 2019-4-24 17:21:38 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 匿名 于 2020-10-9 02:27 编辑


更新历史

2019.4.24 9:22 PM添加新内容

2019.4.24 5:21 PM
开始写此文,尚未完成先保存一下


前言

大家好啊!

最近我自己制作了Macmillan在线词典,也修改了其他几个词典,都已经发出来了。大家也给了很多反馈,绝大多数的问题我也都修复了。这个过程中确实学习到了很多东西,有技术方面的,当然也有和mdict词库紧密相关的。这个帖子就是想分享一下我在制作mdict词库方面的经验,和大家讨论一下。下面的内容仅仅代表我(ogrishman)的一家之言,具体说的对不对,我们一起讨论讨论。然后我们一起完善这个帖子,并且宣传这个帖子,这样大家制作词库的时候都follow best practice,词库的质量一定会得到提高,而且问题还会少很多。下面我就一条一条列出我要说的这些best practices。



正文

  • 词库相关文件的命名要一致,并且清晰全面
比如我们要制作一个Oxford Advanced Learner's Dictionary第九版的词库,那么相关的文件名可以命名为:

Oxford Advanced Learner's Dictionary 9th.mdx
Oxford Advanced Learner's Dictionary 9th.mdd
Oxford Advanced Learner's Dictionary 9th.1.mdd
Oxford Advanced Learner's Dictionary 9th.js
Oxford Advanced Learner's Dictionary 9th.css

我们要考虑到,某些情况下我们可能必须把很多词库的文件放到一个文件夹里,这时遵守这一点的优点就突显出来了,用户可以一眼看出哪些文件属于哪个词典,而且文件排序一般也会把这些相关文件排在一起。这里要注意,不要用缩写,比如OALD9.mdx,这样不够清晰!


  • 每个词典都要提供外置的js文件和css文件供有能力的用户深度定制词典
每个词典最好都有外置的js文件和css文件。css文件基本上现在所有词典都会有,但是我建议,即使你的词库没有用到js,也在你的词条里加入一个外置js文件,这样可以给用户留下自己扩展的空间。

  • 你的词库中的一个词条只是整个网页中的一部分,深入理解这一点,并且牢牢记住
现在主流的词典软件(欧路词典、GoldenDict)在渲染一个单词时候都是用网页的形式。现在基本上所有用户都会安装多于一本的词典,这些不同的词典中的相同的词条凑成了一个网页,也就是您看到的结果。比如下图是我在Windows上的欧路词典查询frequency后的结果,其中部分词典的结果被我折叠起来了,其中每个红色方框表示一个词典的结果:



这里要理解的是,这里每个红色方框不是单独的一个网页,而是整个网页的一部分!理解这一点非常重要,不然你制作的词典可能会有各种各样的问题,比如影响了其他词典的正常显示,或者被其他词典的CSS或者JS所影响。具体在应用中怎样实践对这一点的理解,请继续看下面的内容。


  • mdx源文件中,每个词条要用单独的一个<div>标签包含起来
比如在mdx源文件中,有一个词条:


这样写非常不好!我们已经说过,您的词典中的一个词条只是最终整个查询结果网页的一部分。现在您的这个词条虽然有一些div标签有class属性,可以用来添加CSS,但是如果其他的某个词典里面也有<div class="pf">,那么您针对您的词典制作的CSS就会影响其他词典。正确的做法是,把整个词条的所有内容包含在一个div标签内,并且给这个div标签一个很独特,针对您当前制作词典的一个id或者class属性。比如我们可以修改上面的例子,如下:



这个示例中,我们用了<div id="tldimproved">来包住了您的词条的所有内容,这样,在CSS和JS中您可以仅仅针对您的词典内容进行样式的设置,而不会影响其他词典。那具体该怎样设置CSS和JS呢?请继续看。


  • 正确使用CSS,仅仅对您自己的词条设置样式
上面我说了,最终查询结果的网页中,您的词条内容仅仅是其中的一部分,所以您设置CSS时候必须只针对您自己的词典,这样才不会影响其他词典的显示。有了上一条的包含住整个词条的div标签,这个任务就很好完成了。

比如假设您的词条中有一段内容:

<div class="gdc">
        <div class="dcb">
            <span class="pos">n.</span>
            <span class="dcn">(提供各种生活和服务设施的)汽车宿营地</span>
        </div>
</div>


要对这个class="gdc"的div标签设置CSS,你可能会写:

.gdc {...}

或者

div.gdc {...}

这两种写法都不好!因为我们已经有了<div id="tldimproved">包含住整个词条的内容,那么正确的写法是:

div#tldimproved .gdc {...}
或者
div#tldimproved div.gdc {...}
或者
div#tldimproved > .gdc {...}
或者
div#tldimproved > div.gdc {...}

这样写的效果是,您指定的CSS只会对<div id="tldimproved">里面的那个css等于gdc的标签生效,而其他词典不可能有一个div叫做tldimproved的,这样也就避免了CSS的冲突。


  • 正确使用JS,仅仅对您自己的词条内容进行修改
上面我说了,最终查询结果的网页中,您的词条内容仅仅是其中的一部分,所以您编写JS的时候必须只针对您自己的词条,这样才不会影响其他词典的显示。有了包含住整个词条的div标签,这个任务就很好完成了。
通常在JS中,您最终的目标是动态地修改您的词条,不管是修改内容还是修改CSS,反正目标就是修改。修改的第一步是获取要修改的对象,获取的对象如果错了,那么您做的修改可能就应用到了不正确的地方。比如您想给您的词条中的图片加一个三个像素的边框,如果您使用JS不当,那最终结果可能是您修改了所有词典中的图片,都加上了边框。那么怎样正确地获得你要修改的对象呢?我们还以上面的示例代码为例:

<div class="gdc">
        <div class="dcb">
            <span class="pos">n.</span>
            <span class="dcn">(提供各种生活和服务设施的)汽车宿营地</span>
        </div>
</div>

正确的方法是:

如果您使用jQuery:
$("div#tldimproved div#gdc")
或者
$("div#tldimproved > div#gdc")
或者
$("div#tldimproved #gdc")
或者
$("div#tldimproved > #gdc")


如果您使用的是vanilla JavaScript,那么正确的方法是:
document.getElementById("tldimproved ").getElementById("...")
或者
document.getElementsByTagName("body")[0].getElementById("tldimproved").getElementById("...")
或者
document.querySelector("div#tldimproved")....
或者
document.querySelectorAll("body")[0].querySelector("div#tldimproved")....
等等,因为vanilla JS写起来比较复杂,我仅仅列出了几个常用的函数,大家应该领会我的意思了,就是你不管干嘛,总要表明“我想要获取的是id等于tldimproved下面的内容”,这个思想和上面的关于CSS的写法是完全一样的,目标只有一个,就是您只是修改您自己的内容,而不会影响其他词典!

  • 正确使用CSS reset framework
现在有很多CSS reset framework,有些人在自己的mdict词库中使用,上来就是:
* {
  box-sizing: border-box;
}
::before,
::after {
  box-sizing: inherit;
}
html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
  -webkit-tap-highlight-color: transparent; /* 3*/
}
body {
  margin: 0;
}
main {
  display: block;
}


这么做不合适!如果你理解我上面反复强调的内容,你的词条只是最终查询结果网页中的一部分,那么相信你能理解为什么这么做不合适。你的词库只应该设置你自己词条的样式,而上面的CSS修改的所有词条的设置,尤其是box-sizing,这会导致其他大量词典显示不正常。正确的方式是,仅仅修改你自己词典的样式!所以,你可以写成比如像下面这样:

div#tldimproved * {
    box-sizing: border-box;
}
div#tldimproved ::before,
div#tldimproved ::after {
    box-sizing: inherit;
}
div#tldimproved main {
    display: block;
}


大家理解我的意思了吧,牢记一点,只修改自己词典的内容,不要影响到其他词典!

评分

2

查看全部评分

本帖被以下淘专辑推荐:

  • TA的每日心情
    擦汗
    前天 16:06
  • 签到天数: 885 天

    [LV.10]以坛为家III

    7

    主题

    2845

    回帖

    2万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    24806
    推荐
    发表于 2019-4-24 20:25:05 | 只看该作者
    经验好贴,先收藏起来。赞。
  • TA的每日心情
    开心
    2022-1-21 00:52
  • 签到天数: 699 天

    [LV.9]以坛为家II

    17

    主题

    1754

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    19738
    推荐
    发表于 2019-4-24 18:44:09 | 只看该作者
    本帖最后由 cocowind 于 2019-4-24 18:45 编辑

    赞成总结一下制作词库应follow的 best practices。

    正如楼主所说的,手机上可能必须把很多词库的文件放到一个文件夹里,因此命名不能过于简单,否则可能因名称重复而导致js/css互相干扰。
    另外,鉴于有The little dict这样的发音词典大全集,所有词典的音频文件都应放在“词典名字.1.mdd”里,用户可根据需要选择是否下载以避免臃肿。同时,css中设置自适应代码,当文件夹中没有“词典名字.1.mdd”时隐去发音图标。
    还有,双解词典应该有中文翻译内容的隐藏功能,要有标注以便可通过js来实现。


  • TA的每日心情

    2020-8-15 10:40
  • 签到天数: 146 天

    [LV.7]常住居民III

    23

    主题

    363

    回帖

    3万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    39693
    3
    发表于 2019-4-24 20:21:05 | 只看该作者
    cocowind 发表于 2019-4-24 18:44
    赞成总结一下制作词库应follow的 best practices。

    正如楼主所说的,手机上可能必须把很多词库的文件放到 ...

    在手机 必须把很多词库的文件放到同一个文件夹里,这个到没想过。
  • TA的每日心情

    2020-8-15 10:40
  • 签到天数: 146 天

    [LV.7]常住居民III

    23

    主题

    363

    回帖

    3万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    39693
    5
    发表于 2019-4-25 06:01:26 | 只看该作者

    经验虽好,但是不可能实行。

    现在好多词典基本的 html / css 规范都不能保证,如何保证你这些额外要求。
  • TA的每日心情
    开心
    2019-6-23 00:02
  • 签到天数: 18 天

    [LV.4]偶尔看看III

    43

    主题

    391

    回帖

    5万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    54723
    6
    发表于 2019-4-25 12:31:22 | 只看该作者
    zzzz_sleep 发表于 2019-4-25 06:01
    经验虽好,但是不可能实行。

    现在好多词典基本的 html / css 规范都不能保证,如何保证你这些额外要求。

    您说的很对,昨天看了一下朗文五加加,标签都没有闭合。这个只能自己修改了,或者自己做词库的时候遵守这些。

    该用户从未签到

    3

    主题

    790

    回帖

    2720

    积分

    解元

    Rank: 5Rank: 5

    积分
    2720

    灌水大神章

    7
    发表于 2019-6-7 00:40:30 | 只看该作者
    thanks alot
  • TA的每日心情
    开心
    2022-1-21 00:52
  • 签到天数: 699 天

    [LV.9]以坛为家II

    17

    主题

    1754

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    19738
    8
    发表于 2019-12-20 13:44:17 | 只看该作者
    正确的做法是,把整个词条的所有内容包含在一个div标签内,并且给这个div标签一个很独特,针对您当前制作词典的一个id或者class属性。
    -------
    学了点HTML/css的皮毛,回头看这个贴,觉得楼主说的这一点确实不错。
    很多mdx/css没有做到这一点,好在GoldenDict自动把各个词典查询结果分别包含在一个div标签内,不然真的很容易乱套。
  • TA的每日心情
    奋斗
    昨天 06:46
  • 签到天数: 1047 天

    [LV.10]以坛为家III

    1

    主题

    1592

    回帖

    2万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    23059

    QQ 章

    9
    发表于 2020-3-9 08:35:42 | 只看该作者
    学习了,收藏。
  • TA的每日心情
    开心
    2023-3-23 12:28
  • 签到天数: 442 天

    [LV.9]以坛为家II

    31

    主题

    842

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    13085

    QQ 章

    10
    发表于 2021-7-26 13:35:13 | 只看该作者
    请问一下,我想把一万多个单词的mp3音频制作成一个mdd格式的发音库,该怎么弄?