自制 Kindle 字典简明教程(进阶篇)

Kindle 伴侣之前曾写过一篇《自制 Kindle 字典简明教程(入门篇)》,可以通过软件 Mobipocket Creator 的辅助,从零开始制作一个简单的 Kindle 字典。在那篇文章中,该软件其实并没有做什么特别的工作,虽然操作步骤看起来挺多,也只不过是根据我们填写的参数和选择的选项生成了一个 opt 文件,以及最后把编写的 HTML 源代码转换成了 PRC 格式字典而已。

没错。实际上制作 Kindle 字典和制作 Kindle 电子书所需要的文件一样,都要使用的 OPF、HTML 以及封面图片。只不过和电子书相比,字典基本上用不着如 CSS、字体之类用于排版的东西。当然,和制作电子书一样,我们也可以使用 KindleGen 将这些文件转换成 MOBI 格式字典(Kindle 同时支持 PRC、AZW 和 MOBI 格式,入门篇生成的是 PRC 格式)。

目录

一、下载制作 Kindle 字典所需软件
二、制作 Kindle 字典所需要的文件
1、Kindle 字典封面图片
2、HTML 格式字典源文件
3、OPF 格式字典配置文件
三、用 KindleGen 生成 Kindle 字典

一、准备制作字典所需要的软件

凡事工欲善其事,必先利其器。在开始阅读下面的内容之前,请先准备好 KindleGen 软件和一个你用着顺手的文件编辑器(推荐 Sublime Text),软件可以在下面列表中下载。另外可能还需要你知道一点点 HTML 基础知识,至少知道什么是 HTML 的开始标签和闭合标签。

二、制作 Kindle 字典所需要的文件

  • 一张 Kindle 字典封面图片(用来显示字典的封面)
  • 一份 HTML 格式的字典源文件(包含词条、释义等)
  • 一份包含字典详细信息的 OPF 文档(包括字典的元数据等)

可以点击这里下载 Kindle 字典模板文件。对这三个生成 Kindle 字典必需的文件,下面将会详细解释他们的代码构成细节以及相关注意事项,你可以参照这些解释对模板进行修改和扩充。

1、Kindle 字典封面图片

首先,你可以给你的字典制作一张精美的封面图片,规格建议如下:

  • 格式:JPG、JPEG、PNG 或 TIFF 格式
  • 尺寸:宽 758 像素,长 1024 像素(也可按此比例制作)

新建一个名为“images”的文件夹,把封面图片命名为“cover.png”放进去(这里只是以此为例,你可以选择其他的格式,请保证下面文件中的图片文件名和该格式一致)。

2、HTML 格式字典源文件

字典中的所有词条都以一种特殊的 HTML 代码格式存放在一份 HTML 文档中,我们只需要按照这种格式和规则把词条一条条添加进去即可。下面是一份简化了的“英汉字典” HTML 文档模板,挑选了一个具有代表性的、能代表大多数单词格式的单词“do”作为示例。其中标签 <!-- 注释 --> 以及被其包裹的内容仅起到注释说明的作用,对相关代码进行了详细解释,使用时可删除。

<html>
 
<head>
	<!-- 指定文件编码为 UTF-8 -->
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
 
<body>

	<div>
		<!-- 添加封面图片,注意确保路径正确 -->
		<p><img src="images/cover.png" width="100%" height="100%" alt="cover" /></p>
	</div>

	<mbp:pagebreak/><!-- 分页符。以上为第 1 页。 -->
 
		<!-- 字典扉页。不需要也可以忽略这一块内容 -->
		<p>《My Advanced Dict》</p>
		<br/>
		<p>这里可以撰写字典介绍。</p>
		<br/>
		<p>版权信息</p>
		<p>© kindlefre.com 2015</p>

	<mbp:pagebreak/><!-- 分页符。以上为第 2 页。 -->
 
		<!-- 字典说明。不需要也可以忽略这一块内容 -->
		<h2 align="center">说明</h2><!-- 标题 -->
		<!-- 说明条目1 -->
		<p><b>1.说明条目1</b></p>
		<blockquote>
			<p>1) 详细说明1。</p>
			<p>2) 详细说明2。</p>
			<p>3) 详细说明3</p>
			<!-- 如果小项还需要细分条目可以再嵌套一个 blockquote -->
			<blockquote>
				<p>详细说明</p>
				<p>详细说明</p>
			</blockquote>
		</blockquote>
		<!-- 说明条目2 -->
		<p><b>2.说明条目2</b></p>
		<blockquote>
			<p>1) 详细说明1。</p>
			<p>2) 详细说明2:</p>
		</blockquote>

	<mbp:pagebreak/><!-- 分页符。以上为第 3 页。 -->

	<!-- 起始位置标记 -->
	<a id="filepos1" />
 
	<!--
		第 1 个分组。
		可以把单词贵在一类。比如 a 开头的为一组,则把所有 a 开头
		的单词用 <mbp:frameset> ... </mbp:frameset> 包裹起来。
	-->
	<mbp:frameset>
		<hr/>
		<!-- 词条块 -->
		<idx:entry scriptable="yes">
			<!-- 锚定单词 do -->
			<idx:orth value="do">
				<!--
					下面这些都是单词 do 的词形变化,当选取这些单词的时候都显示
					do 的释义。如果单词只有一种形态,可以不添加<idx:infl></idx:infl>区块。
				-->
				<idx:infl>
					<idx:iform name="" value="did" />
					<idx:iform name="" value="does" />
					<idx:iform name="" value="doing" />
					<idx:iform name="" value="done" />
					<idx:iform name="" value="dos" />
					<idx:iform name="" value="done" />
					<!--
						除了词形的变化,还可以添加其他的比如带有 ' 的,还有词组
						do something,这样当选取带 ' 的如 do's 或者 do sometings
						时也会显示 do 的释义。
					-->
					<idx:iform name="" value="do's" />
					<idx:iform name="" value="'do" />
					<idx:iform name="" value="'dos" />
					<idx:iform name="" value="'do something" />
				</idx:infl>
			</idx:orth>
			<!--
				显示单词 do 的第一种解释,可以对其显示做一些简单的样式改变,
				如加粗<b>、上标<sup>。
				没有相关单词 <word> 标签内可不加 homo_no="1"、homo_no="2"。
			-->
			<b><word homo_no="1">do<sup>1</sup></word></b>
			<br/><!-- 换行 -->
			<!-- 单词音标 -->
			<phonetic>/dʊ,də;duː/</phonetic>
			<!-- 单词释义 -->
			<category>
				<!-- 词性,同样可以进行一些简单的样式改变,如加粗<b>、斜体<i> -->
				<cat><b><i>vt</i></b></cat>
				<br/>
				<!-- do 的第 1 条释义 -->
				<sense>
					<!-- 标号 -->
					<b>1.</b>
					<!-- 含义 -->
					<description>做,办,干;尽(力)</description>
					<!-- 示例 -->
					<example>
						<!-- 源语言 -->
						<source><i>do</i> good deeds </source>
						<!-- 目标语言 -->
						<target>做好事</target>
					</example>
					<example>
						<source>I know what to <i>do</i>. </source>
						<target>我知道应该做什么。</target>
					</example>
				</sense>
				<br/>
				<!-- 第 2 条释义 -->
				<sense><b>2.</b>
					<description>担任,从事;学习,研究</description>
					<example>
						<source><i>do</i> carpentry </source>
						<target>做木工活</target>
					</example>
				</sense>
				<br/>
				<!-- 第 n 条释义 -->
				<sense><b>n.</b>
					<description>完成,做完</description>
					<example>
						<source>I have done my homework. </source>
						<target>我已经做完了家庭作业。</target>
					</example>
				</sense>
			</category>
		</idx:entry>
		<hr/><!-- 分割线 -->
		<!-- 词条块 -->
		<idx:entry scriptable="yes">
			<!-- 单词释义 -->
			<!--
				因为这里的锚定的 do 和上面的单词一样,所以 Kindle 会对该单词进行
				分页处理,也就是在单词释义面板上方出现箭头“<”和“>”,可以在同
				义不同形的单词之间进行切换。
			-->
			<idx:orth value="do">
				<idx:infl>
					<idx:iform name="" value="did" />
					<idx:iform name="" value="do's" />
					<idx:iform name="" value="does" />
					<idx:iform name="" value="doing" />
					<idx:iform name="" value="done" />
					<idx:iform name="" value="dos" />
					<idx:iform name="" value="done" />
					<idx:iform name="" value="'do" />
					<idx:iform name="" value="'dos" />
				</idx:infl>
			</idx:orth>
			<!-- 显示单词 do 的第二种解释,加粗、上标 -->
			<b><word homo_no="2">do<sup>2</sup></word></b>
			<br/>
			<phonetic>/dʊ,də;duː/</phonetic>
			<category>
				<cat><b><i>vt</i></b></cat>
				<br/>
				<sense><b>1.</b>
					<description>做,办,干;尽(力)</description>
					<example>
						<source><i>do</i> good deeds </source>
						<target>做好事</target>
					</example>
					<example>
						<source>I know what to <i>do</i>. </source>
						<target>我知道应该做什么。</target>
					</example>
					<example>
						<source><i>do</i> all one can </source>
						<target>竭尽全力</target>
					</example>
					<example>
						<source><i>do</i> one's duty </source>
						<target>尽本分</target>
					</example>
				</sense>
				<!-- 下面还可以继续添加 sense,这里不再重复 -->
			</category>
		</idx:entry>
		<hr/>
	</mbp:frameset>

	<mbp:pagebreak/><!-- 分页符。以上为第 4 页。 -->

	<!-- 第 2 个分组。 -->
	<mbp:frameset>
		<hr/>
			<!-- 内容格式同第 1 个分组。 -->
		<hr/>
	</mbp:frameset>

	<mbp:pagebreak/><!-- 分页符。以上为第 5 页。 -->

</body>
</html>

从上面的代码可以看出 <mbp:frameset> ... </mbp:frameset> 是大分组,这是可选的,如果你不需要分组可以删掉这两个标签。大分组包含每个用 <idx:entry scriptable="yes"> ... </idx:orth> 包裹着的单词块。单词块里面又细分为由 <idx:orth value="do"> ... </idx:orth> 包裹的锚定单词(作用是让点选单词与本词条相关联)、由 <idx:infl> ... </idx:infl> 包裹的同义不同形的单词(单词只有一种形式可删掉这块代码)、由 <category> ... </category> 包裹着的单词释义,不同的释义又被 <sense> ... </sense> 区分开。

另外,大分组间用 <mbp:pagebreak/> 分页(当然如果你不用大分组,也可以用它把每个单词分页),单词与单词间用 <hr/> 添加分割线,不同段落或释义间用 <br/> 换行。

字典的结构就是这种很简单的嵌套关系。制作的时候只需要不断的复制 <idx:entry scriptable="yes"> 并修改其间的内容,就可以把新单词增加进去了。如果一个单词有多个释义,那就保证两个单词的代码块中的 <idx:orth value="do"></idx:orth> 是相同的就可以了。

需要特别说明一下,有很多小伙伴反应 Kindle 第三方字典如 “牛津高阶英语词典(英英&英汉双解)(第七版)Oxford Advanced Learner’s Dictionary 7th”会出现无法滚动、翻页的情况,而官方字典却正常。其实这是因为第三方字典的内部结构问题导致的。

上面的这段 HTML 源码就是从官方字典中析取出来的,可以看出官方的字典没有什么特别的,只是把很多释义分成了若干小段,用很多代码段组织了一下。但第三方字典就没这么讲究了,他们的内容其实并没有缺失,只是有些释义特别长,但是只用了一个 <p> .. </p> 标签简单包裹了一下,可能就是因为单个标签内的内容过多,导致 Kindle 在读取的时候丢失了信息的。

如果没有下载模板文件,可以把上面这段 HTML 代码复制到编辑器中,修改、添加完毕后另存为“My_Advanced_Dict.html”备用。注意后缀名是 .html。

3、OPF 格式字典配置文件

我们最终是需要用 KindleGen 把上面编辑好的 HTML 字典源文件转换成适用于 Kindle 的 MOBI 格式字典的,所以还需要用一个配置文件告诉 KindleGen 生成时该怎么样处理上面的 HTML 文件,否则直接转换出来的只是普通的 MOBI 电子书文件,不能作为字典使用。OPF 文件只是个简单的 XML 文件,下面是一个标准的模板,对于其中一些有用的参数也做了说明。

<?xml version="1.0" encoding="utf-8"?>
<package unique-identifier="uid" version="2.0" xmlns="http://www.idpf.org/2007/opf">
	<!-- 字典元数据 -->
	<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
		<dc-metadata xmlns:dc="http://purl.org/metadata/dublin_core" xmlns:oebpackage="http://openebook.org/namespaces/oeb-package/1.0/">
			<dc:Title>My Advanced Dict</dc:Title><!-- 字典名称 -->
			<dc:Language>en</dc:Language><!-- 字典语言 -->
			<dc:Identifier id="uid">02FFA518EB</dc:Identifier><!-- 字典标识符 -->
			<dc:creator>KindleFere</dc:creator><!-- 创建人 -->
			<dc:publisher>kindlefere.com</dc:publisher><!-- 发布商 -->
			<dc:date opf:event="publication">2015-09-08</dc:date><!-- 发布日期 -->
		</dc-metadata>
		<x-metadata>
			<output encoding="utf-8"/>
			<DictionaryInLanguage>en</DictionaryInLanguage><!-- 输入语言 -->
			<DictionaryOutLanguage>zh-cn</DictionaryOutLanguage><!-- 输出语言 -->
			<EmbeddedCover>images/cover.png</EmbeddedCover><!-- 封面图片 -->
		</x-metadata>
	</metadata>
	<!-- 资源列表 -->
	<manifest>
		<item href="My_Advanced_Dict.html" id="item1" media-type="text/x-oeb1-document"/><!-- HTML 文件 -->
		<item href="images/cover.png" id="item2" media-type="image/png"/><!-- 图片文件 -->
	</manifest>
	<!-- 文件骨架 -->
	<spine>
		<itemref idref="item1"/> <!-- 对应 <manifest> 中的 html 文件 -->
	</spine>
	<tours/>
	<!-- 页面指引 -->
	<guide>
		<reference href="My_Advanced_Dict.html#filepos1" title="Start Reading" type="start"/><!-- 打开起始位置,对应 HTML 文件中的相应 ID -->
	</guide>
</package>

注意,如果你的封面图片是 jpg 格式请把 <item href="images/cover.png" id="item2" media-type="image/png"/> 中的 cover.png 修改成 cover.jpg,再把 media-type=”image/png” 修改成 media-type=”image/jpeg”(其他图片格式请参考“这里”)。

如果没有下载模板文件,请把上面这段代码复制到编辑器中,修改添加完毕后另存为“My_Advanced_Dict.opf”备用。注意后缀名是 .opf。

可能有的小伙伴会产生疑问,Kindle 是怎么区别字典文件和普通电子书文件的呢?秘密就在上面代码中的两段声明,如下所示,正是“DictionaryInLanguage(输入语言)”和“DictionaryOutLanguage(输出语言)”这两个声明告诉 Kindle 这是一本字典而不是普通电子书。

...
<DictionaryInLanguage>en</DictionaryInLanguage><!-- 输入语言 -->
<DictionaryOutLanguage>zh-cn</DictionaryOutLanguage><!-- 输出语言 -->
...

如果你想要做的字典不是“英汉字典”而是“汉语字典”,那就只需要把上面代码中与语言相关声明都改成中文即可(英文或其他语言如“日日字典”同理),如下所示:

...
<dc:Language>zh-cn</dc:Language><!-- 字典语言 -->
...
<DictionaryInLanguage>zh-cn</DictionaryInLanguage><!-- 输入语言 -->
<DictionaryOutLanguage>zh-cn</DictionaryOutLanguage><!-- 输出语言 -->
...

三、用 KindleGen 生成 Kindle 字典

现在我们准备好了所有生成 Kindle 字典必需的文件:字典封面图片文件HTML 格式字典源文件OPF 格式配置文件,他们的放置位置关系应该如下所示:

├──── images
    ├──── cover.png
├──── My_Advanced_Dict.html
├──── My_Advanced_Dict.opf

接下来就可以使用 KindleGen 进行转换了。如果是 Windows 系统打开“命令提示符”,如果是 MAC OS X 系统打开“终端”。先把 KindleGen 文件拖放到窗口上,然后再把 My_Advanced_Dict.opf 拖放进去,回车,生成最终的 MOBI 文件(如果你还不会使用 KindleGen 请点击这里学习详细用法)。

生成过程中会出现下面的提示,这是因为 Kindle 字典文件不支持最新的 KF8 标准,所以 KindleGen 会自动将期降级为 KF7 标准,请忽略,不要以为出错了。

警告(parser8):W26001: 索引不支持改进的 mobi 域名。
信息(parser8):I12001: 禁止改进 mobi 域名。

当 KindleGen 出现“成功创建 Mobi 域名文件”的提示时,就可以看到名为 My_Advanced_Dict.mobi 的字典文件已经创建成功了(可点击这里下载制作好的字典文件)。

把 Kindle 用 USB 连接到电脑,把字典文件拖到 documents 文件夹,或 documents 里的 dictionaries 文件夹中。断开 USB 连接。打开 Kindle,进入字典收藏夹,就可以看到名为“My Advanced Dict”的字典了。随便打开一本英文电子书,找到单词“do”,点选调出字典解释面板。点击面板右下角的字典名,在字典列表中选择刚放进去的“My Advanced Dict”。是不是你自定义的释义就出现了。你可以对字典内容进行上下滚动以及翻页的操作。效果如下所示:

My_Advanced_Dict

OK,到现在 Kindle 字典的制作教程就结束了。如果您对制作字典有什么问题请留言提出,如果发现本文有任何错误敬请留言指正。Kindle 字典会因您的参与变得更加丰富多彩。

—————

参考资料:

  1. Mobigen Index not supported for enhanced mobi
  2. NADSAT Translation dictionary (#16)

有帮助,[ 捐助本站 ] 或分享给小伙伴:

发表评论

标注为 * 的是必填项。您填写的邮箱地址将会被保密。如果是在本站首次留言,审核后才能显示。
若提问,请务必描述清楚该问题的前因后果,提供尽可能多的对分析该问题有帮助的线索。

小伙伴们发表了 27 条评论

  1. Kindlegen报错了 ,html源文件是358M
    错误(prcgen):E23026: 我们支持书的最大尺寸为 650 MB。请缩小书的总尺寸并重新编译。
    信息(prcgen):I1038: 由于出现错误,无法生成 MOBI 域名文件!

  2. 将html文件转换成电子词典,用kindlegen制作的mobi文件比html文件还大,用Mobipocket Creator制作的prc文件则只有html的1/5,有没有办法给mobi文件优化下大小

    • Miao 您好。默认情况下 KindleGen 生成的 mobi 文件会带有源文件,您可以在使用时添加一个参数 -dont_append_source 禁止包含源文件。对于已经生成好的 mobi 文件也可以使用 KindleStrip 剔除源文件。

  3. <guide><reference title="Dictionary Search" type="search" onclick="index_search()"/></guide>

    查看其他字典源文件发现很多字典开头都会有这么一行代码,请问是什么意思

    • 出现这行代码的字典应该是从其他格式转换而来的,对 Kindle 字典来说不起作用,可以删除。

  4. 这几天我在做一个字典,查看其他字典源文件发现很多字典开头都会有这么一行代码,请问是什么意思

  5. 在屏幕取词的词典中使用idx:orth 标签,如〈idx:orth〉一日千里〈/idx:orth〉。
    在浏览型词典中,目录使用H3、H4之类的标签,如〈H3〉一日千里〈/H3〉。
    如果既使用idx:orth 标签屏幕取词,又希望使用H3、H4之类的标签抽取目录,有办法实现吗?

  6. 在上面的举例中看到这样的标注:
    〈span class=”bold”〉〈word homo_no=”1″〉do〈sup class=”calibre7″〉1〈/sup〉〈/word〉〈/span〉
    〈word〉大小多少〈/word〉中的词是不是用作屏幕取词的用途?
    〈dc:Identifier id=”uid”〉02FFA518EB〈/dc:Identifier〉〈!– 字典标识符 –〉是字典的关键标示吗?

    • xiaohua 您好。起取词作用的是 idx:orth 标签及里面的内容。决定是否是字典类型是 DictionaryInLanguage 和 DictionaryOutLanguage 这两个声明。

  7. 我的意思是有没有什么代码或方法,能让指定的条目只被抽取在目录中,不出现在正文中。

  8. 谢谢回复。
    在纸书排版中,用〖CT(〗词条〖CT)〗,中间的内容在正文中出现,也上书眉。如果改用〖CT(#〗隐词条〖CT)〗,中间的内容不在正文中出现,只上书眉。
    联想到mobi的制作,词条的方式能抽取目录。那么能不能让隐词条的内容不在正文中出现,只出现在目录中?

    • xiao hua 您好。很抱歉,不能理解您要表述的意思。能否描述的更清楚一些?如果需要输入 HTML 代码,请点击这里转义一下然后再贴上来。

  9. 如果有造字或特殊字体我这么处理,在CSS中加上:
    @font-face {
    font-famili: “abcd”;
    src: url(“../Fonts/abcd.ttf”)
    }
    myxihz2{
    font-famili: abcd;
    }
    然后在特殊字体标注:
    请帮忙看看这些字。
    正文中的造字可以这样解决,目录中的造字却没有解决。
    请问字典目录(字目)中的造字有办法解决吗?

    • xiao hua 您好。您说的“目录”应该是在 Kindle 中点击“前往”所显示的目录吧。因为这个不受 CSS 控制,属于被 Kindle 系统直接调用的,所以没有办法通过图片或者 CSS 自定义字体实现。

  10. >KindleGen – 亚马逊官方电子书转换工具
    >最新更新:2015.08.18,版本号:2.9
    >Windows 版(XP, Vista, 7):官方下载 | 百度网盘(10.3MB)
    在WIN XP SP3上不能打开使用。请问应该怎么解决?

      • 您好!谢谢回复。
        我对自制 Kindle 字典教程(进阶)有兴趣,请问Kindle Previewer能制作字典吗?
        如果也想制作epub的字典,有这方面的软件和教程吗?

  11. 感谢教程。已经做出了一个基本的字典,见https://github.com/lianzhao/wiki2dict
    请问如果想把字典发布给用户使用,如何给他们自动更新呢?这样做可以么:让用户接受xxx.gmail.com的邮件,有新版本后用xxx.gmail.com发送给用户。

    • lianzhao 您好。非常感谢您提供的字典,更希望更多小伙伴参与进来。

      个人不建议让用户添加接收邮件的方式更新字典,一来这可能涉及到隐私,二来因为 Kindle 的推送并不是替换形式,如果重复推送可能会导致字典文件的重复。如果今后有更好的解决方案可再议。

      您提供的自制字典,Kindle 伴侣会进行基本的验证,如果质量没问题会添加到“字典下载”页并添加署名,同时链接至您的 Github 页面。关于字典更新,Kindle 伴侣会不定期检查您的字典是否有更新,当然您也可以在更新后发送邮件到 i@kindlefere.com 通知我们。

      • 呃。。。所以用户应该如何更新字典呢?还是需要手动删掉旧字典然后添加新字典?kindle没有更新字典的功能么?即使保持opf文件中的uid相同也不行?

        • 是的,亚马逊服务器并不会识别推送的内容是否重复。如果使用您的这种方式,每次推送的内容都会留在用户的云端,这样对于旧版本,用户不仅要删除本地的,还需要删除云端的,比较麻烦。所以还是建议只是提供下载链接,由用户自行下载替换。

  12. 改变语言种类 也可以用calibre修改元数据 感觉更简单 一个回复在评论下的问题 先是花费大量时间测试 随即就编辑成一篇文章 顿时感觉这个伴侣真的很有人情味

  13. 是厉害啊~终于有一个比较清晰的讲解字典的内部结构了~以后想修or做也有资料参考了~