掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 4089|回复: 7

[教程] 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 编辑 3 B( v$ Y* s& ~
    $ Z( Z7 l! Z# k. p
    一、前言
    : B& r; j; i: X5 ?
    4 U1 k$ V; p3 ~1 l) Z本篇文章的所有部分均来源于书伴的《如何把 MDX 格式词典转换成 Kindle 字典》 ,只是仅通过该教程的方法所转出来的词典基本没法用,原因是Kindle不支持@LINK跳转、不需要音频、以及需要添加Kindle支持的变形词搜索功能。经过几天的摸索,逐渐有了点头绪,并制作了AHD5th,试用两天后觉得尚可。便于昨天发布。帖子见此:[Kindle词典]美国传统词典American Heritage Dictionary 5th(精制版)" }/ I2 `- u. ?- ^

    7 y* P6 P8 D* \4 n2 }/ M本文章展示如何通过Python来最大限度的优化以生成体验较好的Kindle MOBI词典,为各位提供一种思路,以期众人群策群力,制作出更多好用的Kindle词典。( ~# g: q( s7 [9 O  d. K8 w+ H
    - |7 R* n, D2 t1 X# t6 B
    为了文章的连续性和完整性,对于完全相同的部分将全文引用这篇文章《如何把 MDX 格式词典转换成 Kindle 字典》 的内容。
    9 m( s. E5 n9 B3 P
      N, u$ k, d, ~5 W1 `% `8 e1 Z
    3 k1 v' O, H# I二、正文        % f0 b" H/ }* w1 T# n
    " w( D& d" \) G, k5 j
    书伴的这篇教程共有四步,还用到了一些工具。工具请自行下载,因下面所用的代码是Python 3的,所以除了Python 2 ,Python 3 也需要安装。第一步和第二步是一样的,不赘言,仅截一张图于此。' Y9 Z0 ?! b7 Y# L7 n, Z) }

    * m1 J0 G/ v( ?7 H* N
    7 O2 ]* m) K# ^" V; V
    ( Z8 ?  d( d* W; o# ?% Z; i+ |' Q" W8 R
    ' b4 h" t- ^- [% k. n. a( b) B
    工具准备好后,选择你想转制的MDX词典(本文只针对英文词典,即英英/英汉),下面以论坛里的American Heritage Dictionary 5th [IPA]为例。
    % S' B' k& t- w" h4 ]" n$ [2 V' Y2 r: c, s1 B6 Q

    9 }/ {1 i# R- l' t! ~经过第一步和第二步的处理,我们会得到一个体积较大(视MDX而定)的TXT文件。其内容格式应该是这样的:9 d  d( Z, A8 Y; f4 G
    4 s# f+ @1 p5 P# h9 \

    * E) F, ?3 \, s5 \' u9 v/ L9 D9 K1 q6 q

    9 v* _( \' z+ Z( J, L' O
    % N$ P& b8 Y! }. H  b0 V. s! Q& X得到该TXT文件后,我们可以选择几行看一下或者搜索一下如".jpg", "<img", ".wav",="" ".mp3"之类的关键词,把图片和音频等等鸡肋全部删掉。同时,这类CSS引用也可以删掉,以减少文件体积,提高后续处理的速度。CSS引用可以在最后一步添加。比如随便看一下,扫一下就有这些:8 k. v# @& S) C5 A
    5 Y) M: d: E% I  ]( l% E/ w

    . x0 U4 e5 z  `& i) H: [8 e! z" m2 [, l; T

    0 D. q8 S0 |2 X9 h' k
    3 E& G3 ]3 {% ~) f! W3 F我用的是Notepad++,以下是我用来替换的正则表达式:
    9 F5 q  `7 `9 F( _4 d1 o; N
    * W' G, t) `+ r        图片:<img.*?>
    , M/ r! p) \  ^  s, ^' _        & d1 I0 y+ ]: \
            音频:<a href="sound://.*?"></a>4 u: G: [, z9 c- h

    6 ^. K8 P3 I3 G; H# ?# ^$ }0 Q        注释行:<!--.*?-->
    ; |2 ~2 w, m8 F4 ^. L9 ^        
    / O8 H  k  m  g4 }2 ~* J4 L. [可能还有一些冗余的标签,视词典而定,比如我这里就有<span> </span>,直接全词匹配删掉即可。
    # p; X$ k: A3 X& b- E7 Z, @- z+ t/ o' s% s% p
    我这里这样处理了一下之后,文件的体积直接下降了25%(约100MB --> 约75MB)。
    , R! Z; q- v. m/ }, j8 i2 n3 B
    3 j. v, P6 P' j. I3 ?简单处理完之后,便是正式处理@LINK跳转了。TXT文件的格式只有这两种:单词 + Tab + 意项  或者 单词 + Tab + @@@LINK=另一个单词9 n8 o( S/ W- i! f. `2 Z) M, C6 s; _

    1 b5 v4 X+ T2 J  R1 M, r" z这里我们主要要将跳转词后@@@LINK的跳转链接替换成目标词的意项,因为Kindle不支持@LINK跳转。为方便后续称呼的方便,我在此做个定义。以开头两个词条为例:) n, N' L% X1 B) T
    + J7 S$ A$ Q1 D0 l0 B3 z4 v
    1 m8 [0 A, f3 R' E
    ) Z  N' }) k2 X1 {

    ' P. t# q, N' v: g) L9 D5 b; N8 f: V  |0 X+ R( T$ G% @% V
    但是这里也要分情况,因为如果一股脑全部将@LINK跳转都替换为目标词意项的话,看起来简单。但实际上会导致文件的体积无比巨大,因为里面存在着大量的像这样的跳转:$ l1 g2 z3 m) V) J
    0 J6 k+ _% y, x
    8 t" n- ^1 m( d6 ~
    3 ^6 F0 r6 K& Y: ?3 T
    + a7 g3 k' v% B0 g, B8 Q: v- {5 V
    " c0 Z# q9 n3 y+ }% E- Z
    仅仅是advocate这样一个词,就有七个变形词,它们的目标词都是一样的,如果只是粗暴的替换,那么最后生成的词典肯定无比庞大,甚至如果你内存低点最后都不够用来生成词典。(猜想而已,我没这么干过,有兴趣有空闲的朋友可以试试)
    * g; b. }, `3 K: U# w& u, H
    + x# N% k9 l- a" o$ G" {* g因为Kindle词典支持为某个单词添加不同的变形词,利用这一特点,我们可以在此处判断,如果跳转词是目标词的一个简单变形,那就跳过该词条。判断的依据来源于dsl2mobi这个工具里面附带的英语单词变形词列表。文件名称:forms-EN.txt,内容如下:
    8 {6 C' J" Q9 Q% s; h- s+ n5 E
    % N" c6 a3 u  e* r0 X+ R) U: j- ?
    : E9 I6 Q* ~9 O6 Z" V
    , H/ ?, Y8 g, r        
    $ f) K) w7 ~6 A9 A- S- n8 e' y
    + W+ v, M* S% B4 N8 ~& R简单总结一下,做了个程序流程图:7 V5 K5 Q; e& l+ B
    ' v3 T' ^* v: _) ~( K: m8 \

    , U" @! p7 O: F& s4 J! b- |. z; A# {" N: |. M) W/ W, y0 D

    2 H' r( J8 \4 B% Z6 T% g! Z, b4 ^3 @. O, c+ Q
    这是代码,你需要修改第3、4、5行的文件路径和第50、51行endswith方法和replace方法中的值改为你操作的字典的实际值。详细的内容请看注释。
    ; I& O; W4 [+ n2 n$ C
    9 i+ r/ _/ M. f  i6 N) e- J. ]; f: I& ~# G2 K7 p+ x

    + V! c! u. D* V" N% P& x
    & k; g7 G' X8 \3 F% t* m. z6 Q1 q9 L. s$ [  h% }
    . f  v2 |; W# y7 i7 I
    2 u6 ?2 }* Q$ n& I4 V: Z
    " |- K; S7 F4 m6 H* a7 ^
    注意:Fix_Redirections.py有一个同级文件夹wordforms,文件夹内有forms-EN.txt,请勿修改。
    " q* k* C) u/ Z* Q+ C( Z
    ) ]/ U3 T. V# }) K5 @0 m/ q* z
    6 Z, B9 M! G1 h1 v& b: G
    修改完了然后执行代码,你看到的图应该是这样的:
    2 }' T& X  P& v9 A; S0 x4 Y( E8 y8 p. u2 T+ W& V1 u
    & p& `4 M$ a; o8 [4 c, y& ^! ?

    7 A+ L: e) G3 S! b/ G- s; u) T, a* I0 B

    $ E( g. p" `; `0 U0 B5 k8 L这一过程的速度取决于你的电脑配置和词典的词头数,我跑这部AHD大概花了大半天的功夫。
    7 _3 |  }9 e! r, L% S( s4 u; P2 R8 a
    跑完之后的文件可能存在很多空行(不一定,看词典),这里附上一个去空行的脚本,使用方法:( H. ~8 D( m( b8 {3 j6 j
    9 F6 j4 R4 B' E: [2 n5 ^

    " g! G9 I* u$ I, ~, J# e- }6 Z+ J& \: t2 i4 Y' R, [& c! u# Q/ F

    9 L' X6 g! s0 b
    9 w* M6 y; f  L8 }; b8 M; _% I% Y: N$ z  h- _& D- T

    ) N& S; o+ [; N2 A+ [6 T5 d执行完成后会在处理的文件目录下生成一个名字带_stripped的文件,这就是去除了空行的文件。
    + T% d0 |! J8 @+ G" q$ [+ P
      f6 C) n! o5 C
    , v1 s/ \- w0 @
    " _3 {1 @! q, X3 v* y: L1 h
    8 x# c6 {2 {7 c8 T) q- E
    7 [5 K. G9 R5 c& r( F8 a+ ~这时候可以打开文件看一看,应该是满屏紧凑,没有空行,没有@LINK跳转的,就像这样:- P' B, v9 D  C& Q/ L* ]

    4 \" C3 a6 a' R' Z1 o$ t# E8 q$ ~6 W3 t: n) j: x

      Z2 L' j, a" B( s" w# w1 J1 {! e6 |. x# p7 t( Q
    6 W  p1 q5 B. C  B% ~
    到了这里,就可以开始正式进行第三步了。这里用到的是tab2opf.py这个工具,该工具基于py2,所以要用py2来执行。从书伴直接下载的tab2opf虽然没问题,但是根据我的经验,把253行的print df给注释掉,速度会提升许多,而且出错的机率也会减少。除此之外,由于词典的不规范及其他特殊原因,我们上述生成的xxx_stripped.txt难免会有几个或十几个错误行(MDX词典本身的问题),因此,最好加一个异常处理的块,遇到错误行直接提示一下就跳过,免得程序中止运行,你们可以参照下图修改,注意红色箭头的地方。
    ' z3 P4 Y, U6 b- ]( J1 o* q8 F. N3 @3 \/ z1 Z3 D

    ) s  O% ?' i0 Y3 z4 w2 W; v, a& @( [$ k: Z  B
    : K' e. [5 D# T4 x- y9 F
    ( X% j) E6 f" ~" T. j: R
    然后执行命令:python2 tab2opf.py -utf xxx_stripped.txt# {6 g8 M0 ]7 T6 K" P0 v
    0 M  ^- e( |% _; H+ R
    执行完毕后会生成一个opf文件和一堆html文件,如下图所示:
    ! v/ y9 J1 ]7 O& Y. \* U) n! o1 b) u7 s

    + L$ D$ i" I8 v9 p6 W5 t7 _8 T9 P7 h4 n, W

    ' y3 Q& t" X, E% c/ K3 n
    6 ?' W1 R8 ?2 r% D4 k在进行下一步之前,我们还得写好CSS,我的电脑配置不行,打开太大的HTML文件很卡很卡,因此我提取一些意项较多的词条来单独修改建议"go", "take", "in", "the"等,这里我提取“go”词条,复制"go"词条所在的一整块<idx:entry> </idx:entry>,然后加上头和尾(头尾可在任意一个html文件中复制即可),保存为html即可。如图所示:+ I6 O* Y0 h: p

    - h" c) K7 _: t% c, f  u7 c( i; K) U1 n  q# n0 ?1 Q

    $ ^9 L4 I" \5 ^; l! l) v- _( `0 g" i& K' q; X; H. ~  _

    " z  s6 }! S: V( A3 o( O' u因为我们要测试css,所以再添加一个head标签并在其中用link标签引用一个css文件,然后就可以写css了。2 A5 `( ~" B* K
      S0 z4 x% L2 `4 T9 F. O

    3 j0 B8 q+ k! a$ _
    2 i; H* O# q* W0 h! |) J4 f
    ; K! g( ]! p) D0 y# i' {7 M1 H. A3 {- R
    MOBI的字典只能生成v7版本,该版本对CSS的支持极其有限,margin只支持left其他方向都不支持,即使是看起来有效的margin-left,也不过是在转化过程中替换为blockquote而已。所以只考虑粗体、斜体、下划线和颜色即可,当然不管这里用什么颜色,Kindle上都是浅灰色。
    8 \) u) k2 S+ P/ o" [) G5 F( l- n" e. ?& l
    这是我修改完毕后的效果。
    + a1 y+ {+ q  B7 I! J1 {( |; L1 L2 Y9 X

    ( o- z+ [5 ?& M
    + c" u' y! F7 V6 g* |- U
    1 r' t: ~  y8 u6 x' E! a! i/ d9 B) w+ G) |
    css满意后,那就可以给所有的html文件批量添加link引用了,这里notepad++可以单独完成,就不写脚本了。方法如下:2 a1 ~+ s$ i, j$ R8 R- l
    ; d4 P: S; K$ D' {  `/ u
    打开任意一个html,Ctrl + F,然后切换到文件查找选项卡,下面注意选择正则表达式,如图所示:
    3 w* h) n6 a! y0 g( }/ I% o. q* N* P7 F# q! g2 n. \" \2 K

    - Q4 l, z" H6 z1 b
    5 w- P& Z) |5 w, ]
    # j5 L) u" p% F$ o
    5 O  Z. r! J) a
    6 Z6 k) D' E- c! w$ R查找目标: (<html.*?>)
    & @1 x, P" R$ h8 \; x7 v
    0 q5 O+ Y5 N- |7 T& B替换为:\1<head><link rel="stylesheet" type="text/css" href="test.css" /></head>
    ' i/ {& N( }, e+ u5 ?/ Q: v6 [7 Y) v' E: r/ W- {, `2 D
    文件类型:*.html
    . W* y) F" F( `7 }$ f$ ^9 s2 [. i$ C( ~( k0 [! v) z
    目录:即html文件所在的目录
    5 }! [* @  T& s& }! s; Z* ]2 u& R$ D9 w. @0 c; b* n7 M! A6 T* f
    0 F& n" d+ v& D$ _0 b0 k1 L
    & [* L8 I# R$ F/ x2 y* t) ]
    然后点击文件中替换即可,这样,所有HTML都添加了CSS引用了。# P2 M9 e+ Q3 e& Y# _$ I
    - z) B- Q: O; E+ S
    现在到了另一个重要时刻了:为即将生成的Kindle词典添加变形词,原理就是检测forms-en.txt里面的单词然后提取出变形词添加进去,上面说过了,此处不再赘言。, a* k5 o5 f8 E* t6 ?5 c% w

    2 Z$ f0 j# E% d; ]  d9 Q  @代码很长,不贴了。用法很简单:Add_Infl.py html文件所在的目录  e1 t3 g9 C- [5 D

    ( R+ H# B- Z' W, u- T. o$ `
    $ ?3 _- D0 h- r4 K8 B; N/ D- z1 U% z1 h/ P+ _  Z& M. z4 K- L

    / K' @0 Z1 C& u  c0 [2 @1 y
    ) c0 P$ y+ n. |3 T文件在此,解压后其他文件和文件夹勿动,以免程序不能正常运行。6 D& Z% G9 y( L' q" J+ h! F+ ?" d
    6 Q6 l2 t6 X. k4 j

    : u' f+ r" i4 |- N+ i& q, B
    ! k( t. P- g" L然后会在目录下生成一个名为OK的新目录,新的HTML文件即在此。, ^7 k0 t2 _& \0 \  _) d/ B% M/ C

    , r5 a- R3 m6 V最后就是把之前的opf和css复制进去,然后用mobigen.exe生成即可,mobigen.exe -unicode xxxx.opf
    3 P" ]8 O" v, l7 V
    7 B% ?, K1 x: c& R( A+ t' n如果你想修改生成后的词典名称,打开opf,修改这一行即可# b5 ~* J8 {5 G- z0 u2 k
    2 B' L: B8 m( h5 e. K/ D

    ( [( V5 D) a% J$ a$ x$ Z0 \& S
    9 x) H, v9 D' g2 h7 P2 e" b. K% R
    ; R# D8 B9 \6 r4 R$ v$ s$ f6 m" j0 f
    完。
    + {9 W. J; {/ k% Q* T% y1 E3 H* y, T% ?
    三、结束8 p+ i1 a3 R/ E

    $ f- o' `1 R, I) i第一次写这种教程帖,步骤、截图等等都很繁琐,几次我都差点晕了。简单看了几遍,算不上流畅但也不至于晦涩。若诸位有什么问题或发现什么错误也可以在下面回复,希望能有更多优秀的Kindle词典出现。8 {; b8 J8 N* m( h6 n
    $ m8 [6 v( T; [- T" n. 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的每日心情
    奋斗
    2023-4-1 06:34
  • 签到天数: 1049 天

    [LV.10]以坛为家III

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

    本版积分规则

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

    GMT+8, 2024-6-6 16:17 , Processed in 0.060822 second(s), 11 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2023, Tencent Cloud.

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