掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 6737|回复: 8

[教程] Python辅助MDX转MOBI(以AHD5th为例)

[复制链接]
  • TA的每日心情
    开心
    2023-9-27 20:45
  • 签到天数: 847 天

    [LV.10]以坛为家III

    发表于 2019-9-30 10:32:44 | 显示全部楼层 |阅读模式
    本帖最后由 nullname 于 2019-9-30 10:39 编辑 , h9 i! K+ w7 A8 J2 A

    ( U5 x& l& S* ~3 c) d) l: ^: x; C# M一、前言
    ( B7 O0 w* @( e/ J+ r1 t. Q, Z  }; O9 Q8 J: Z
    本篇文章的所有部分均来源于书伴的《如何把 MDX 格式词典转换成 Kindle 字典》 ,只是仅通过该教程的方法所转出来的词典基本没法用,原因是Kindle不支持@LINK跳转、不需要音频、以及需要添加Kindle支持的变形词搜索功能。经过几天的摸索,逐渐有了点头绪,并制作了AHD5th,试用两天后觉得尚可。便于昨天发布。帖子见此:[Kindle词典]美国传统词典American Heritage Dictionary 5th(精制版)
    0 Z: G! X7 L3 E9 W3 G, M
    ) l4 y, D0 \5 L- M' ?本文章展示如何通过Python来最大限度的优化以生成体验较好的Kindle MOBI词典,为各位提供一种思路,以期众人群策群力,制作出更多好用的Kindle词典。7 L0 J+ n7 T- p8 a( g
    " E. m1 m5 \8 s! K9 e/ |. d/ f
    为了文章的连续性和完整性,对于完全相同的部分将全文引用这篇文章《如何把 MDX 格式词典转换成 Kindle 字典》 的内容。! a, n1 l: r$ d* }  s

    8 d; i" l# g/ K) n. g' q4 M
    / M6 z. \; x; H& W/ j二、正文        5 s# @* H- \, Z* \" |+ c  Y
    : I, t( A( a! H4 \( Z! `" o* N
    书伴的这篇教程共有四步,还用到了一些工具。工具请自行下载,因下面所用的代码是Python 3的,所以除了Python 2 ,Python 3 也需要安装。第一步和第二步是一样的,不赘言,仅截一张图于此。
    + X& d! _# j' m  f! v8 ]$ ~7 p: B1 L1 z; A9 t
    1 Q6 ]4 o: `5 \% I

    ( H2 }' b: k: s8 m7 B1 O# t9 @" c0 T. v: F4 s8 N. C1 a5 O
    9 S: |0 m6 P# _# M, a5 |7 M
    工具准备好后,选择你想转制的MDX词典(本文只针对英文词典,即英英/英汉),下面以论坛里的American Heritage Dictionary 5th [IPA]为例。
    7 E, ^* `0 j+ Q. c' @5 O' O& v- X' T9 W" P

    2 ^# j  T/ W' i, o* `( g经过第一步和第二步的处理,我们会得到一个体积较大(视MDX而定)的TXT文件。其内容格式应该是这样的:5 d1 O; ~+ d% z8 ^! n+ H- I( S: y
    7 G9 t; R' S. ?, D; M. |' H

    ( m, p- W& }! x  z) P" @" c( l: |! b! r2 u  \  X+ e

      [$ v- z) h7 q
    9 K, v3 P( r5 ]/ z( Q得到该TXT文件后,我们可以选择几行看一下或者搜索一下如".jpg", "<img", ".wav",="" ".mp3"之类的关键词,把图片和音频等等鸡肋全部删掉。同时,这类CSS引用也可以删掉,以减少文件体积,提高后续处理的速度。CSS引用可以在最后一步添加。比如随便看一下,扫一下就有这些:
    ) u5 E1 M3 J- O1 V2 @+ p7 K, ~) a. Z+ n. e. j, H) j9 ^) d' x. d
    * `( s, J) w9 a- V% q
    1 |9 D; n. C# Y9 L  o: U
    : ^  c! {) y: l8 U6 Z

    5 J# o3 }% [- {# R. c1 f' G我用的是Notepad++,以下是我用来替换的正则表达式:  X0 M' v1 L! Y, A% {$ V

    6 A+ z4 P6 U, a3 F9 m        图片:<img.*?>
    * y0 r5 D7 u! L; o4 I        9 K$ }2 O- \$ Z' @$ e
            音频:<a href="sound://.*?"></a>; g5 l' Y8 W- n  Q
    3 ]6 o* ^3 v! Z  s5 r# i
            注释行:<!--.*?-->
    & m! i  r* A7 r: e8 D9 ]- B# d        
    8 O6 h4 ]/ q8 ?# P可能还有一些冗余的标签,视词典而定,比如我这里就有<span> </span>,直接全词匹配删掉即可。
    ) ]# k8 u& c0 o8 }! r9 u; A& M
    * D, R4 Z3 b4 m$ d$ [$ ^- i; X7 E我这里这样处理了一下之后,文件的体积直接下降了25%(约100MB --> 约75MB)。+ {7 d' P* b: m7 ^$ @3 r9 H
    7 l9 k& R0 \8 d* q7 w/ @6 d& p+ K
    简单处理完之后,便是正式处理@LINK跳转了。TXT文件的格式只有这两种:单词 + Tab + 意项  或者 单词 + Tab + @@@LINK=另一个单词
    / p( o& q% u! ~/ a0 X2 C- j4 ~2 B% I  @: p' z
    这里我们主要要将跳转词后@@@LINK的跳转链接替换成目标词的意项,因为Kindle不支持@LINK跳转。为方便后续称呼的方便,我在此做个定义。以开头两个词条为例:
    9 N6 e/ x3 U; Q7 {! r  d! b
    $ Y4 o  R. }. S9 X" G% a3 n6 f. Y# Z3 {! v! F
    ) i5 U2 t  _+ O) Y( E- _' Y
    . T# w5 V/ B1 i' u# G

    ! v$ h( b! @' a) ]9 Q但是这里也要分情况,因为如果一股脑全部将@LINK跳转都替换为目标词意项的话,看起来简单。但实际上会导致文件的体积无比巨大,因为里面存在着大量的像这样的跳转:
    , Y/ L& m  \0 ?  [& i- d. f* M9 h8 S; d0 V4 U, Y7 u( c* c
    0 f; l6 h7 @* H2 m% o3 T2 k

    : n: Z6 D. s. M: _: z  [. j: ]+ d9 P6 O) W; v3 E

    ! x5 T' ]# y8 t. ?仅仅是advocate这样一个词,就有七个变形词,它们的目标词都是一样的,如果只是粗暴的替换,那么最后生成的词典肯定无比庞大,甚至如果你内存低点最后都不够用来生成词典。(猜想而已,我没这么干过,有兴趣有空闲的朋友可以试试)  [# X0 `  A% I, V, ]
    4 [3 F. b: @! P- ~
    因为Kindle词典支持为某个单词添加不同的变形词,利用这一特点,我们可以在此处判断,如果跳转词是目标词的一个简单变形,那就跳过该词条。判断的依据来源于dsl2mobi这个工具里面附带的英语单词变形词列表。文件名称:forms-EN.txt,内容如下:
    5 A9 I6 n9 ~7 w
    1 Q* |* F$ G# S: ?6 z( J$ q5 @) m5 i+ a
    2 K- z1 ]; R  e$ Q% J
            
    5 p  z$ Y# ]$ P0 h: e( c% O" `2 r3 m, f$ Z+ V+ d  F; J% U% [
    简单总结一下,做了个程序流程图:
    2 B% L% K' x3 u+ e$ m4 F4 q. R. C
    * J0 L; b2 O1 Z( y; m
    0 C# F/ B! _4 ]+ H+ s/ h. I) v& X
    ) C& L( n3 ]9 O" e
    " ]0 K9 R1 Q- G# G3 s
    + j! o+ {+ R( }6 I; T9 `这是代码,你需要修改第3、4、5行的文件路径和第50、51行endswith方法和replace方法中的值改为你操作的字典的实际值。详细的内容请看注释。1 \; N3 ~7 b, e8 l( P

    ; `  a4 q/ w, M( c; y# @+ n2 p, ^5 t" q0 y5 _+ E
    * g3 h# B1 ?' T3 P3 R9 |; S9 }4 j$ `

    1 b7 N* O# N! |% I. z. P6 R, p* y) }  J* O5 ]. C: g

    ; q! l4 ^* o3 @4 h$ c" @4 _4 x3 Q$ _5 S6 E' h
    7 R4 e5 G+ s2 X1 d' j# r% l
    注意:Fix_Redirections.py有一个同级文件夹wordforms,文件夹内有forms-EN.txt,请勿修改。7 W; H+ x0 i5 @4 Y
    ) I8 X& D- C% z* C

    % Z" i$ W) l2 H4 Z" Y& n" ?# e5 B修改完了然后执行代码,你看到的图应该是这样的:
    , e6 m3 {; J$ u) y+ N9 f0 D- [: W
    ( w0 T7 |3 \" z9 r, c( I% l0 o* v. C2 s0 I

    7 t" {1 k8 x8 d! v/ s% C! _: I  t# V+ `( T1 k6 _

    - k8 O! e# A4 a/ ]% r, H0 C. n. Q这一过程的速度取决于你的电脑配置和词典的词头数,我跑这部AHD大概花了大半天的功夫。
    # o3 Y8 r: L1 b! U8 K+ w9 T6 `9 y# f: Q3 S- S
    跑完之后的文件可能存在很多空行(不一定,看词典),这里附上一个去空行的脚本,使用方法:& Z  `: R) K7 t4 ~! D! b' k

    ) X: d7 p- u8 F$ h1 o) {: H1 ^$ O" f+ ]) @1 O' a4 }
      w6 c$ M7 l& K0 n& x0 A

    ( @/ i4 i; G3 t6 B9 h' a7 p8 X- C/ _1 z. x# l; F; e
    2 N# r3 S) r, Q

    9 j. T! S5 c3 k* A2 b执行完成后会在处理的文件目录下生成一个名字带_stripped的文件,这就是去除了空行的文件。
    * ^5 E; u  m' {/ g, `& q! n
    - H1 R3 e6 K1 ^( W! C9 e4 {) N, {4 \1 B* i" }
    0 n* w* @1 F* p5 h: ]4 s

    . b& T! ~. `" z: f8 B7 K9 Q: ?# E( [$ n' ]% z. T+ c# C
    这时候可以打开文件看一看,应该是满屏紧凑,没有空行,没有@LINK跳转的,就像这样:0 Y3 I7 N4 n$ a

    + \7 t$ i8 X/ \, {! s! e" x/ z' Y( n

    / [& N/ j* w. _4 j  F! P5 f( L$ n+ s% t; R8 d; y' ]' T2 l6 x! ?
    $ G1 ?$ C4 c. l# j* m7 S$ B
    到了这里,就可以开始正式进行第三步了。这里用到的是tab2opf.py这个工具,该工具基于py2,所以要用py2来执行。从书伴直接下载的tab2opf虽然没问题,但是根据我的经验,把253行的print df给注释掉,速度会提升许多,而且出错的机率也会减少。除此之外,由于词典的不规范及其他特殊原因,我们上述生成的xxx_stripped.txt难免会有几个或十几个错误行(MDX词典本身的问题),因此,最好加一个异常处理的块,遇到错误行直接提示一下就跳过,免得程序中止运行,你们可以参照下图修改,注意红色箭头的地方。6 y# ]9 G  O8 t0 o& H9 v* R

    4 @5 F# f6 B' t4 E* t# `: d3 O2 @! y# y
    5 B9 s/ s& n- h) D, e- L6 J

    1 f, C! A7 i; D: p
    / V4 ~/ m- n( t! [3 K0 ]/ Q$ g然后执行命令:python2 tab2opf.py -utf xxx_stripped.txt! w2 A/ {; {5 g( V

    5 m+ G: R: L6 ?8 y; u; Q8 U执行完毕后会生成一个opf文件和一堆html文件,如下图所示:9 v9 o8 y, ^1 K' b% q

    $ ~9 z' p  Y9 e  r" R0 |* j4 _" T$ E5 W* {/ N4 e

    + z! u$ t) {* n1 B  c8 S5 ]  Y3 T. H2 O5 M2 V/ l5 X

    " o: ~* k; f+ `$ }8 A0 F在进行下一步之前,我们还得写好CSS,我的电脑配置不行,打开太大的HTML文件很卡很卡,因此我提取一些意项较多的词条来单独修改建议"go", "take", "in", "the"等,这里我提取“go”词条,复制"go"词条所在的一整块<idx:entry> </idx:entry>,然后加上头和尾(头尾可在任意一个html文件中复制即可),保存为html即可。如图所示:# o( e( Z, {+ l) B# A# p8 K: h
    : F  w2 p0 S3 x& e4 \' Y

    ! ~+ K( W8 o1 b( F) w" q, S5 `: s# p  u) T( u9 j6 a/ B
    ' K% W0 H8 o3 x# C, j

    3 N6 o$ @  w& H9 p/ A  c因为我们要测试css,所以再添加一个head标签并在其中用link标签引用一个css文件,然后就可以写css了。  X0 l% \  @) g3 n

    & y; l4 _7 X' T0 S( Q1 {. S! h
    8 J4 g& c; l+ t# T3 q$ F: {7 J2 J, d+ @6 v7 Y3 a7 s! W

    . k0 F( ~( @: ~4 u5 X0 r; O
    ' C) e" o# Q5 d' x9 zMOBI的字典只能生成v7版本,该版本对CSS的支持极其有限,margin只支持left其他方向都不支持,即使是看起来有效的margin-left,也不过是在转化过程中替换为blockquote而已。所以只考虑粗体、斜体、下划线和颜色即可,当然不管这里用什么颜色,Kindle上都是浅灰色。
    : d# t1 H( L+ l" W1 ]- K2 U7 R( B3 c; O. Q( i- ?
    这是我修改完毕后的效果。
    , R; A: O5 u% E9 p" [3 ]
    2 u4 }7 G8 A9 X; z$ S- o8 A( {8 l: l+ ]3 F
    * J, ~- |! _/ o& ]

    2 H' E- R, h% {: _6 G
      i8 a( l" S9 ^3 y6 D( qcss满意后,那就可以给所有的html文件批量添加link引用了,这里notepad++可以单独完成,就不写脚本了。方法如下:
    2 _  B/ \+ y+ I" |8 h+ r6 c7 L% q' X* d
    打开任意一个html,Ctrl + F,然后切换到文件查找选项卡,下面注意选择正则表达式,如图所示:/ a$ X& E" X+ h- l
    ; E( b( i- x  B

    - J& @0 Y3 N6 _' G! s: ~% ~& s6 @
    8 }- X) V6 p, ]) g& V
    : N4 D! U: l5 q. ~" c  X  q: S) y/ t' X+ v% \" j% u

    1 N- l2 ^) w6 }" ]# k查找目标: (<html.*?>)6 z4 ^2 c0 P9 K$ y7 J8 E$ |+ q+ [

    8 L0 t: M: S# b* L+ _9 W3 j9 ]' @替换为:\1<head><link rel="stylesheet" type="text/css" href="test.css" /></head>, A* |, c+ ?. U; Q' v

    ; g/ X! j/ W  k" f: E! S* F6 Y; V文件类型:*.html
    , n0 i0 f' n; i  L6 {1 R1 n) m  ^+ N
    目录:即html文件所在的目录; }9 k0 j$ r1 B+ H! B3 _6 B$ R

    * y! B2 Y4 K" {/ Z) ?* x" R
    4 i2 \4 V, h; Q
    ' f  I3 a. t9 o+ y- I, w
    然后点击文件中替换即可,这样,所有HTML都添加了CSS引用了。
    / ?9 T7 r9 ]- V5 Q6 J! e" W
    , F# Z- G# Z1 j2 T) D/ [2 k现在到了另一个重要时刻了:为即将生成的Kindle词典添加变形词,原理就是检测forms-en.txt里面的单词然后提取出变形词添加进去,上面说过了,此处不再赘言。
    5 z$ L9 P+ }2 P# J! N! Z) X& L, E6 R; k; f/ g0 X& E$ c
    代码很长,不贴了。用法很简单:Add_Infl.py html文件所在的目录  N" ~! W( r( E2 ^" z+ s' R, D! ]

    / O  \. u" J% B) T9 h( }& K8 ~* b$ W# p3 u7 ^( J: s
    . X6 p- b; N+ z& \. @

    ; F8 [. u7 r; @2 A2 |6 N7 s: L3 |8 W* q( g  x4 m7 X& ^* j8 Q
    文件在此,解压后其他文件和文件夹勿动,以免程序不能正常运行。0 s; z4 S8 t3 |9 \/ U  x/ E

    6 t# z- ?9 c  z* J9 _
      F6 Q" \, M( K, E2 I: P3 m6 p- l. h  b2 V' W5 V2 k
    然后会在目录下生成一个名为OK的新目录,新的HTML文件即在此。' P3 B9 {9 Y2 o) t, d' v, U

    4 N8 i  [9 }- `最后就是把之前的opf和css复制进去,然后用mobigen.exe生成即可,mobigen.exe -unicode xxxx.opf
    , c3 f- H  `: j! b7 p
    % r2 Q4 r" Z  K9 g如果你想修改生成后的词典名称,打开opf,修改这一行即可$ h$ `0 E) `+ p! c7 w5 ]
    1 b( x( I9 e+ l/ L

    $ I/ {! n( N; l0 k  V. b* D2 L4 |/ I  f+ K0 C, w" p

    4 ~6 c- E1 |: ?) d7 K5 u* A
    " d1 {, Q+ S1 k" @  L) K6 {/ X完。0 u% M, D4 ?7 z5 f

    & K) A( g* e, Q8 u1 h# v0 r: _三、结束4 m2 \' I7 x! W! x1 o- T1 p

    / _/ k. h+ ]* W$ P  [9 N第一次写这种教程帖,步骤、截图等等都很繁琐,几次我都差点晕了。简单看了几遍,算不上流畅但也不至于晦涩。若诸位有什么问题或发现什么错误也可以在下面回复,希望能有更多优秀的Kindle词典出现。
    ' N8 @& l$ K4 ^% c
    5 A$ V1 B3 f# d0 N! a" E: Q5 R另外:关于Kindle上的汉语词典,我发现kindle支持将繁体作为简体的变形词,意味着若处理得当,那就直接为简体词头添加繁体的变形就够了,不必再另添词条,词典体积将大大减少。各位有兴趣可以试试。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?免费注册

    x

    评分

    10

    查看全部评分

    本帖被以下淘专辑推荐:

    该用户从未签到

    发表于 2019-9-30 11:03:05 | 显示全部楼层
    这种技术贴,要好好给楼主点赞
  • TA的每日心情
    奋斗
    2021-3-15 08:06
  • 签到天数: 585 天

    [LV.9]以坛为家II

    发表于 2019-9-30 11:09:32 | 显示全部楼层
    技术文章,不错。
  • TA的每日心情
    擦汗
    2024-2-8 08:54
  • 签到天数: 902 天

    [LV.10]以坛为家III

    发表于 2019-9-30 12:56:27 | 显示全部楼层
    给技术型楼主,点赞。
  • TA的每日心情
    开心
    2022-1-21 00:52
  • 签到天数: 699 天

    [LV.9]以坛为家II

    发表于 2019-9-30 13:16:44 | 显示全部楼层
    过程详细,及时总结惠己惠人
  • TA的每日心情
    开心
    2020-1-5 08:04
  • 签到天数: 50 天

    [LV.5]常住居民I

    发表于 2019-11-22 11:42:11 | 显示全部楼层
    这种技术贴,要好好给楼主点赞,惠人以漁!
  • TA的每日心情
    开心
    2026-5-27 19:42
  • 签到天数: 1051 天

    [LV.10]以坛为家III

    发表于 2020-3-10 18:28:21 | 显示全部楼层
    喜欢技术贴, 感谢楼主。
    您需要登录后才可以回帖 登录 | 免费注册

    本版积分规则

    小黑屋|手机版|Archiver|PDAWIKI |网站地图

    GMT+8, 2026-9-2 00:02 , Processed in 0.024679 second(s), 25 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

    快速回复 返回顶部 返回列表