掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 36|回复: 0

[工具] MDX/MDD一键转Android版GoldenDict可用格式

[复制链接]

该用户从未签到

发表于 昨天 04:30 | 显示全部楼层 |阅读模式
最近整理了一套自己一直在用的词典转换脚本,主要用于把 **MDict/MDX 词典转换成适合 Android GoldenDict 使用的 StarDict + DSL 资源词典**。$ s; t+ V' J4 B' \
) A+ g7 U4 T. K" v  a8 W% I
脚本名称:
8 k4 q; [: |3 K7 p) j% i0 I  E+ |: w$ u8 q' v9 z8 z: }' {3 o9 a# Z
```text
/ H5 W; o4 o# Z. l1 Zmdxtogd.py6 e, q) O& o+ [" y
```  s' j9 U0 g) x' [: o. s! E( v7 n

$ I4 }( t2 ^5 n( |; q4 b配置文件:: \, A) s- m* h4 q4 {5 D/ k
& H7 |( ?& r, }& ], i
```text/ k! j6 X  `% P5 u- O( I$ S
config.txt
, \) K. R* y" m) o' t) \7 G```- \' i% _! o$ X0 u

% s2 G0 o/ L: E目前支持的输入格式包括:9 H' V( ^0 V( b
$ c) w/ x# k: Z) Y/ p$ x) @
```text
) k, d( X' ^: [# ~7 rMDX2 K" U1 e- L4 F- d4 H
Tabfile; ^6 e6 P/ k) W( V% F
MDict Textfile
" ^6 ~6 |  P) O- H( @8 H```
' ^) _/ a! M9 I7 q; ^# F* ~0 S0 Y  W$ `# V" }, Q
其中 MDict Textfile 指类似下面这种格式:
/ j. ]2 d4 ~& V- ?/ H. g5 e+ D
! L  o4 h7 P. g```text) ?, W2 L6 r9 ^' s4 C
词条1* c. Q1 X8 P, p1 l- G/ l4 G  [7 f: Q
内容第一行2 R3 x1 Z& D; x) u6 W2 X
内容第二行
2 g4 C& v! B1 P2 B( s) c</>' [' K9 L# M) o( |6 f
词条2  v  j+ n+ q/ h, ~# i. `4 p! N6 K+ J
内容
: x1 q+ }  [' |) z</>2 ^. h; {8 h; P, V) Z) j# x
```% y2 w5 F" Q4 J1 ?7 `" C
9 w; \9 ?/ O  E# U
程序会先统一转成 Tabfile。正文中的实际换行会转换为字面量 `\n`,因此每个词条在 Tabfile 中始终只占一行,之后再继续进行资源路径替换和 StarDict 转换。; B' O' M2 V3 _$ z: Q

) q3 V. Z* O: p9 B/ i6 L" v" V## 一、主要功能9 p: f% {' y  i  V, F
! K! U* ~5 B% L. R( C) `5 h' w
### 1. 支持 MDX + 多个 MDD
. I# q0 c+ y  A$ ?. C
. _" e! K8 `! Z1 h: c如果输入:
- z+ |/ |! o: \
) _* Z. l5 X3 d```text  Z; r( f* I( g5 A+ w
词典.mdx4 I5 S% l# @: X8 u" {& b! o
```1 T, k1 J2 @; m* Y6 b& e3 }$ Q

0 B5 d7 E7 q4 b6 m程序会自动寻找同目录下的:
& w! }0 z  {& ?9 H& ^. A0 W/ i3 e5 d5 w7 Y5 g9 e
```text
" |3 ~; d% Q* [1 I词典.mdd
9 c4 I0 E+ d% W( `! E. U8 K3 W词典.1.mdd3 t1 D  X( k4 }: u
词典.2.mdd- C4 v3 n& X8 x# B$ d4 E. z' J
……7 ^: F! d1 ^. G) b8 t
```' O0 H/ f0 b4 @' L
/ Y$ p3 {" {3 F9 Z
无需在配置文件中逐个填写。) H/ W/ s4 E' U; T+ Q6 H' X" e" Z
' |, {- J2 `3 `6 j$ |8 J
MDD 中的图片、CSS、JS、字体、音频等资源会解包并重新整理,然后生成 Android GoldenDict 使用的:- k9 R6 j0 ~- H' S
( f% B' S9 @2 U  T! E# i
```text6 K* M" }. @/ r5 _( ?
词典.dsl( I) M5 b+ X2 o' s/ h. J
词典.dsl.files.zip
% }, c4 u6 a" g```
% I. n( b7 @: @5 ^: c% N" P# M0 `2 z; G, v) G3 R  l
DSL 使用 UTF-8 with BOM。$ r0 C/ T; H5 k; _

/ B+ Q, Z4 e! q---
" e9 H& p  Y6 {" c% G  _2 I" d* C; o* ]0 O" ]8 e
### 2. 支持本地资源8 ^- o( V& v; i, ^( F. l9 C3 M; R
0 I: B" {* I* T# k8 Z! I
有些 MDX 中引用的 CSS、图片或字体并不在 MDD 里,而是直接放在词典文件旁边,例如:5 X, i6 g% y# I2 f8 l9 H& ]
8 B* W7 N; G" m9 `1 r
```text0 F( V2 _# O  h
词典.mdx
. F8 }7 E' {9 q6 B: O- L! D# wmecd.css
- v% z% p: E  z' I6 @# X3 P1 P/ h! simages/; `% E' t5 r0 P6 Z% A, i1 G
fonts/
# _2 Z5 y1 d9 P```* k& \! Y% U$ d0 y( h& [! |, q
- y3 w( B1 c) e6 w
程序也会尝试解析这些实际被引用到的本地资源,并纳入相同的资源重写流程。
& j3 c: n- A$ A: g8 t
1 f4 U& s' m2 t2 V( r& }CSS 内部继续引用的图片、字体等资源,也会进一步解析。
& c: L. c6 S# M% A2 D* X' {, _3 V; S. V- {7 ~; s% \( X! w: f
---- _! Z6 H: B( @4 G; P+ L
0 d9 r% |9 {$ c: D. G, t: |, m
### 3. 资源包支持两种目录方式7 h" D# N' @1 y3 K1 b$ p  [8 K1 s

& k5 I) C3 b# K  A% c4 m配置:
# q! ^& |; M  m7 ]" Z) t$ n* i) }
+ @+ t3 s* z/ x& X4 F9 O# B```text7 m( j( o1 T  {8 ^
resource_layout = root( S3 ?' r( h1 R; E
```5 n& V! V. _; W& S* v. J& ]
8 e# s  l* ~5 [7 e9 ]+ f) B% F
表示把资源全部放到 `.dsl.files.zip` 根目录。
, T8 [% d$ U7 k& y4 V
/ j1 c% P  q# Y) ~如果存在同名文件,会自动重命名,并同步修改正文/CSS/JS 中的引用。
6 K3 T7 m; m# e% B; d- X9 @1 |$ u, s+ k% B2 i; q9 o0 Q1 M
也可以:
, [# Q( V$ b5 |; G7 ?1 c  Z3 y1 p6 G! j. W# r' B0 {
```text$ t8 E- S2 w) W
resource_layout = original5 t5 A- ~6 R5 Y% n8 B/ l- v# @
```) Y4 O/ y5 K6 s' b& j, T) A4 D

) M# G/ u% h5 q* n保留 MDD 原来的目录结构,例如:. M% g  U" Q( g% b

6 Z0 ~: h3 q" v0 ?```text
5 ?# z+ q2 X) x' Iimages/a.png
2 ]0 k1 P7 j* [1 Scss/style.css) g8 B: Q/ }1 G' ?7 G% [4 _
fonts/font.woff2- |3 R( y2 R9 q! v3 g: M$ z& p% }
```
0 i6 Y" S0 d/ S- K; e7 a5 Y4 n0 [0 {/ `9 w8 p/ e
对于资源特别多的词典,我个人更推荐 `original`,管理和排查都比较方便。
! y- s( n' g$ G& U6 y9 }7 c  W4 n$ U
---3 x. S% }5 i+ z/ J% ^8 I# g8 Y

! d- g; ?; O; u$ {) T# v### 4. CSS 可以放 ZIP,也可以独立放文件夹$ m1 C2 I) Z9 F( h! S
' R8 b; d8 @, i7 U! t7 ^
```text- w: U7 Y& e: K+ G
css_storage = zip
9 z  e  k1 s9 S4 q0 }$ o% }```
9 j$ q) }5 Y& Z/ U  L+ Y2 i0 d
. r/ K( {' G5 O, Y& _$ cCSS 放入:' V" h! w4 Y5 R

8 G, O3 m3 `- `! _( ?! W. J9 }0 q```text
& L" a; f7 Y! V% [6 j5 E; W/ A- A( a词典.dsl.files.zip
8 u- Q" r4 l& a1 j7 m```
5 L  y$ V/ M( ?# r; d6 c% \5 [+ ~) }  L& h
或者:
- {2 H; A9 b% p# Y: f; b
/ S: ?+ c- C8 y; L; {: h```text
9 j5 ]& G4 @( A/ z) p; {css_storage = folder, B6 j; W3 Q" N, P5 `
```6 v$ n( Z( N& Z

: S9 F/ k; V  \) r/ A3 aCSS 作为独立文件,与正式词典文件放在同一目录。* C9 h) {3 V* [; G4 r! a* q
( Y0 M6 d& C9 w* g) x. {/ g" y6 \
---
) D9 @  {( e2 ]
2 S6 z8 L* {: D% J) i) h; A: s! ]## 二、自动处理 Android GoldenDict 资源路径* p# s! c! ?5 }3 y

  B- W. Q4 J' y( ?程序会根据 DSL 在 Android GoldenDict 中的实际安装路径,计算 DSL resource ID,并把类似:, Y( Z) K& s# E$ Y

; m- e, O) ~  K```text9 U( h  u' T1 j) d' E
images/a.png( s2 \, c/ y( ~
../fonts/font.woff2
, z4 |  d6 d5 {! W4 E- E5 {- d- rmecd.css+ {& d3 Q9 n7 g% m& F3 F
```
* |; a* m) H% `0 L
% Q) ~6 b: ~; B5 B8 d改写成 Android GoldenDict 能访问的资源地址。/ U8 U$ j$ M$ Q( {# {' c$ J" |
- ~; t5 A" ^/ B+ B4 |& G+ c
例如:
1 s- _4 K6 ]. `! F" u1 n& M- T3 K
8 m8 y! ]7 j5 M1 D! M```text) s4 F! F. q( Z9 i: @
content://mobi.goldendict.android/resource/<DSL_ID>/images/a.png
8 g! s5 D" B9 N, M```& x+ c8 W( L' V" h( d
8 x; t7 j4 H/ T
DSL resource ID 使用 DSL 相对于 GoldenDict 根目录的路径计算。
' g: L1 u; U4 C( O! h- T. [  a- m5 i/ u: _/ m' z
例如:
# o% w- ~3 y& n# l- x5 ]+ J
, W; m" i7 U$ C" b% ]7 C```text) C) ]  V) O/ |
/storage/emulated/0/GoldenDict/ENG/ENG-ZHO/词典名/词典名.dsl
; Y7 V& d+ F3 B$ T8 c5 H) O: Y* M5 U```+ a/ p( e/ ]! ^

3 J4 S- O- k8 |实际参与计算的是:
. g, Y9 }/ q/ p( l; E1 j
" e% j, @. M8 H7 Q3 r% a3 [% p```text9 E8 n9 z" D- G9 d% t
ENG/ENG-ZHO/词典名/词典名.dsl3 x( t0 j! O. X. `9 g
```$ Y& _  `. ?2 J5 S$ w; ]8 r

, _! [* g# m$ T$ B  X8 h0 Q---
3 l# {  f1 A5 d* I6 T; m. l
( l1 L/ g$ B* y; V## 三、自动识别词典语言
6 e* s$ F& D, t  W/ ?3 z+ L" d3 @7 }% Q0 S
配置文件中强烈建议填写:
. }" f) y4 G, g" ^2 T+ Y$ ?( m( Z0 S# }6 z* |
```text
) D1 k. E$ N% G/ e6 t% J+ h- `INDEX_LANGUAGE =
6 G4 |4 c6 A, O6 Z3 PCONTENTS_LANGUAGE =
$ g. q- B5 O8 ]5 x" p2 ^8 z```% U! G8 d$ v/ G; u' g+ C$ j- X

5 [" b$ j+ Y# f& t0 U1 Y不过写法比较宽松。! |( \* y- @" a# f5 [" w; N

; v7 d; r) o/ C! R6 _" I3 q) }例如英语可以写:. W, K4 v9 o5 \
6 U/ O0 ^. K2 l+ S) `: D: j1 a
```text
* y9 x& J; _4 b9 \eng
2 z& E* ]$ r& Sen
/ C6 c/ y5 I! C# GEnglish
8 j/ B7 f6 k( @0 s6 o: Tenglish
8 X; S9 Z' P+ V9 P" F+ X9 l. u7 F3 N英语# \: C- {3 P. T* V2 Y1 Z
英文
/ y) e/ g" V2 S0 k7 o& k
& u: ^! ^8 [/ v$ z" P```3 U9 R" r9 L, ?' r6 i4 j4 R9 O% o

+ J# L- W& m! Y$ i- T$ p  v中文可以写:
' }; s! l5 u; c  ?# v" H& t1 F9 N2 }/ L
```text# Y8 Q  L) [* D/ `) G; k. j2 c
zho
2 E, a2 g  {* |, ]! Jzh
8 m4 @8 W! ^9 ^; o" h% D) Fchi
7 V7 n* |1 B% B; p! bChinese- U* d. p# N% @( K! M, R5 l
中文
) O1 ]! R; F) _* ]2 _汉语
( t' g9 }7 R$ g漢語& F! B7 c4 @$ g3 @" U4 i
& d3 R: c- y9 [& D( w1 i, Q3 j
% X0 `+ @( H0 N5 r  L, k$ U( t7 d5 i

6 E* b9 q% Y. q```
3 Z$ T; E* a8 Q  d) [) M' {
( M9 e( X( H8 n. m程序内部会统一转换成标准代码。
4 ?. E8 i% ^" N4 f" M+ Q& W
/ h/ v3 w: t0 d  o# w例如:
' J! z& J* T$ B1 i( N
& Q) }$ `" C& M2 k: X) Z& [```text0 d/ C& P) c# y" S- Y2 [5 d: {
INDEX_LANGUAGE = 英
( o6 @2 w* i3 |3 A6 T4 e& ACONTENTS_LANGUAGE = 汉
/ Y) X9 _  _3 d% A0 s```* N8 m4 u2 U( z  d
2 j) n' B; {4 z4 c
会统一识别成:* N" F' `7 ?  \% W# e
' F( ?8 I( \( B5 b
```text
7 P1 b( ?# r8 z, y3 g  Eeng → zho  d: F) U7 O( S) H
```* Y6 z8 t& q* f" N1 T

$ d( q$ J/ \' z) _& t1 I1 H1 {DSL 中则自动生成:
8 ~( B- v& T2 U5 F# k# ~0 B' p5 \
9 O0 A( |7 J: a; Q" Q```text
8 N) ?1 d, g, W. s# n5 l$ E#INDEX_LANGUAGE "English") f# |- a% g: _, F" K7 ]3 v6 ]* v1 t
#CONTENTS_LANGUAGE "Chinese"( C7 c0 p) \5 q: n8 p6 a  {% b
```: \7 l# {6 D" W7 |! |

% ^$ M; V; m, t; ?7 }如果没有填写,程序还会尝试从词典文件名判断,例如:
5 l' |1 T1 x1 S3 E3 Y9 L1 h6 o
4 c. s7 s; C- I1 `" W2 b( v! k& i```text, m0 J0 n& y+ L. {4 l& D& o
xx英汉词典- q' l' h4 I# B+ g0 J
→ eng / zho
2 ~# E$ s4 V6 V, w6 T9 i. M9 v9 n1 v3 a- k$ P9 Z3 Z
xx汉英词典
$ v. z( b% p; K" f- b→ zho / eng( W' M/ U9 |1 l) M5 r
2 m6 Z7 @/ d6 S  f/ R4 K0 |
英英词典. x, I3 ?0 P+ m2 W
→ eng / eng8 }0 d* k  E4 y7 T$ l

4 m: p5 ^( g+ \# G! O' j" h+ H0 XPOR-ZH
" k( @. A6 O; X→ por / zho" s! A' Z1 u- ?3 Z. w6 P
```
3 j- M2 U; V1 F/ [( Z; B5 e% `0 w7 c* a* q: u: H# a3 K6 A
无法可靠判断时使用:
8 K1 ~* Q  w7 J, Q  \$ i, _9 A4 R( \+ D! N
```text
6 y7 M* \- j0 ^2 kUnk / Unk
/ a4 f# q% L- R6 P1 p```0 a5 o& _, O6 T- v4 I$ v

* W8 E6 ^  [. N; A3 \% g3 \( i9 E建议还是手工填写,自动判断主要作为兜底。
! C( \; |) M- ]( u: N0 D
, T/ }; ^' m) x6 E! }; o  u4 y---7 {; m( h: [$ J8 j, e# t6 |' ?, d

& y' L; Z# d: \9 P, ^## 四、StarDict 的语言也会自动处理8 v2 }, H+ C6 L

# z) n( X& J& o这是专门针对 GoldenDict 做的一项处理。
, Y6 O8 @' V9 `: S4 L) v7 a
3 u, Q+ m+ J1 P0 ~/ L* i6 dStarDict 本身没有 DSL 那样的:' [0 {3 p& A+ G& H$ i) l, @
3 G, h4 b! D0 y( p# k
```text
8 w! F# F/ E# U# }#INDEX_LANGUAGE
: t/ \# R" s1 j#CONTENTS_LANGUAGE
% ^6 E( y8 U! P. X2 X$ m```1 J6 {5 [7 v' |" z9 G7 H

8 ?# R% z$ M& N' q, y) S. {% `GoldenDict 可以根据 StarDict 文件名中的语言对判断语言。
8 _4 {. G% \# ], }, _* r# T2 i4 e5 J& B- W1 r$ g9 L3 ]# v
因此,例如:4 @/ `; N$ ?- e) N' O
, z3 t8 `, L2 |" ]6 a
```text
# e- C  s7 I( \INDEX_LANGUAGE = eng$ L7 V6 N) N+ D( R
CONTENTS_LANGUAGE = zho
& P9 B3 f$ V6 c! H% O8 m& W& O```; U1 z* g0 |* f/ l! ~* m- J

, a3 E- R9 O2 y* T; YStarDict 自动生成:
; y; Y: Y, [- h) ]( R
. _; J) a+ o% z$ ````text3 k6 @( E& a" W2 p: j! k
词典名.en-zh.ifo9 p7 |! U& v# N
词典名.en-zh.idx/ V3 I7 E4 e. w8 x
词典名.en-zh.dict
, }$ S5 b- H/ X3 h9 U5 E词典名.en-zh.dict.dz
. A9 {3 t* ^4 l, N0 t1 H```
% d* W1 r- M8 h
: L7 E6 P$ Q* H  x+ Z% [这样 GoldenDict 可以识别为:3 F2 x2 d% m, n& Q2 _# H4 B

. i$ K  h7 |' O' M) C* m```text* x3 e* Q2 E& c" {9 u
English → Chinese
7 o1 h  n. _5 ~. L/ f1 c" p: @8 f```
9 |- N  a. ]+ P# l8 s4 C9 o
. o6 f* s% H% u& s* q但是 `.ifo` 内仍然保持:
0 p4 C3 d( o* V8 m2 v7 q
7 @4 v; i# Z- i/ {; ?" X```text* g( M+ M6 ~3 C9 G
bookname=词典名  Y/ g2 g+ S0 w" n& Y) a
```( I$ ?6 U+ \% x1 v0 h

8 m$ U$ _; S" J$ j8 k# j因此词典在 GoldenDict 中显示的仍然是原来的词典名,不会显示成:/ S4 U/ [( e2 [2 X& \% }+ N
! X$ f3 Z, I! |
```text9 g; t) q2 B) E$ w4 e" }% s
词典名.en-zh; u9 q! t( k% ^- H! F8 T4 H4 n
```
9 D# k/ y! ~' t8 N0 d" s% p8 y
4 K: Q/ `% C) Q$ ~$ c+ v类似地:
2 {5 V# W9 I; C7 i# J
1 m0 D5 y6 p. e, ````text$ M# E2 z- d+ K0 {
zho → eng& z8 H8 X1 _4 _' a9 s2 H) Q6 Q  M
生成 .zh-en.*; S+ u/ ?5 O& _! Z4 ~4 r
1 ^" ]$ t0 {  T& m8 R3 M: t, s
eng → eng0 {9 ?! a! c4 g
生成 .en-en.*# F, _/ B9 u% A" _

2 }5 b: l0 |: `fra → zho" ~+ M6 ~6 y" o! G! j: Q# K
生成 .fr-zh.*
! G8 u7 U  q4 y```2 F- C) f* r. W& v8 z9 x
/ R. w# W2 b8 ]8 t: s
如果某一端语言无法确定,则不会强行添加错误的语言后缀。8 X2 S0 ?& b+ Y$ e0 y

4 A$ Q0 ?0 L9 Y( `) g" V3 u---
1 q* o& l( p' d  |5 G' n& p" b  V! U" O, @2 r# {
## 五、Android 目录自动生成
0 K2 g% t( B3 o6 d* [
% ^3 c' k+ x8 C如果不填写:1 w& i5 X2 ^( U8 G0 D$ W
4 Z) @, d  Y1 o. h4 S0 Y; I6 u
```text: u2 q  w) E# @! W  y
install_dir =
7 ^4 Y0 A$ E, X: O```  r/ y! N# p5 u$ Y& y( ~  p

4 \/ D$ ^* n( B" C. ~6 M* S- K程序会按照语言自动生成目录。
0 q+ m" g- M) i& H. B4 ]/ L7 X0 h
( `: ?  a( q" Y/ M) m, \例如:# J9 Z$ x6 c1 G  x2 x: ]& A

- _5 |$ g$ u% t3 G, I- }% m( ~, s2 B```text+ b+ i: `" \& s# _
INDEX_LANGUAGE = eng3 l0 Z3 ?5 y" ]7 k! X) ?
CONTENTS_LANGUAGE = zho
9 T1 H7 {  h& p4 t$ {```
8 q! R" }6 S) h4 v  M, m) ^6 Z
) h: q: w7 o* m% @( n* G, e) ^默认得到:
) |+ o& {9 G: l, y, _# G) D% _' a0 s3 Y) J
```text
6 k+ L0 i4 J5 y# i" \$ C  K3 V; M+ N# ZENG/ENG-ZHO/词典名* N/ c: ?$ z% T! Q. x) W
```
% u2 X6 u0 S8 w  p& \9 z" d. {$ b# I6 i% [  [6 l' D. u
最终 Android 位置类似:, z/ m  {; Q% f0 M: h# d
) \# ]% Y* J/ {" ?9 o
```text
. z( T- [7 Z4 M, E8 _% u# c/storage/emulated/0/GoldenDict/
3 g' l# J8 o: k6 G6 E# M! y└─ ENG/1 m! f: R8 w( w
   └─ ENG-ZHO/9 J! t+ G' Q, `& S/ H- a1 n
      └─ 词典名/" y. }- o* U3 f5 D5 o
```
( t- z7 m- Q4 N' f+ Z
! k! S( M; o# V这样词典多了以后,可以按照:
% E- `( T+ C6 Y3 X0 `5 ~' C, w4 ~" ]& F! x3 s) P8 ]. m
```text
! W+ f( G% g3 w0 S- G; B/ r源语言
5 U/ c1 T+ N  V1 i→ 语言方向" P, ^1 |% w, p* z7 p2 {
→ 具体词典- Q3 n, B3 `& X
```
! L" ^6 u0 k# g, O
' J* D- r6 |/ ?来分类。9 D: L! n: R: h7 m( K

% u# S4 B; g6 o' w" r8 Z6 B转换完成后还会自动生成:
' M" u7 o- P+ k1 D. |( I6 ~4 W) Z
```text& {3 F0 t. n- }8 W
GoldenDict安装位置.txt
$ W( B3 V" n; X" ?: b8 |7 M```! t) Y' u$ u1 M. Y& f4 p

* |# \" q3 z" w& y9 o里面直接写明应该把正式词典文件复制到 Android 的哪个目录。7 g5 a% n- O  }5 ?' z& p% F
3 U/ ?. G! [' ?. d# g' H3 L
---: X) b0 f/ K1 D- J9 t  @

  P; F+ ^# c6 c: s## 六、自动处理词典图标
- c9 q$ \) G7 [& U+ S" [) l
, f; X# R" z6 f如果 MDX/Textfile/Tabfile 同目录存在同名图片:
' f) `; G1 ~: r
% |2 x' e2 o; p+ O8 y```text* R9 s1 ]/ `; p. B  ^) F: ?
词典.png
" `9 J$ f2 \9 ]! b' M% }! L词典.jpg' e( m  X# K$ ~$ v3 b; ?' q
词典.jpeg
* U3 l0 V) W( ]+ q/ ~" C" q- B词典.bmp" s" k. m  x4 X4 ]# l* M
```7 e3 v0 I1 Q& v. g& [

+ f0 D: R% Q5 l2 H5 o程序会自动找到并转换为:
$ a" g7 d( o, X' _
  A. ]: Y! N% U. x. j. n```text2 i) d& ^4 ^0 Z' E: _* m
词典.bmp
8 g, P- ?& Q' e7 C2 B```2 T3 g$ q& N4 z6 k9 q
! I8 r. @* J* S7 \( V
尺寸:( _1 `# a+ k' V9 X

% Q0 Q' u, x5 B) D" X: g; d) q2 ~```text! e+ O+ o1 ~% @4 l4 |
48 × 642 V; ?* a3 f. f9 T
```* M2 X! j5 `% _1 d* ^; i6 Z
9 J1 j2 q4 I4 q# L
用于 GoldenDict 词典图标。! r. ~) N3 H, U" c6 e2 O
: s* g: j6 E2 D  _
图片会保持原始宽高比缩放,并居中到 48×64 画布,避免直接拉伸变形。( F7 [0 d5 v) m6 ]; B. K
' z( A/ }  d. p( |
图像转换需要:. J2 v9 C5 D5 T- n7 V0 y

! M7 C2 [! A: w" a; W```text* {8 P: {7 J% \+ G$ p) I, [
Pillow
0 z8 e9 \9 J6 j; Z# y# d1 y```
; c: i% R' f! O4 l& l$ S1 }% Z0 _
可以安装:/ v  o6 y) w1 t8 p( O
8 e- E. v6 B+ y' N# X
```bat
; p& m! U( S# \, O% M; ]python -m pip install Pillow
/ ?7 U- h% g1 ]```- [$ \( s6 w6 m5 e1 D9 I* H0 }' B

, P1 H/ J; u- J# E. v% V% o---1 r2 f6 G; V" {0 H2 T$ J8 H
+ k. G" L# B% j2 ]: |
## 七、最终 Tabfile 会保留下来! Y6 U  W1 c, \) ^& H+ \
; @7 J6 x( y$ [1 f
程序完成各种:/ K; c5 y6 n( U
: u- B: \7 N. p9 e4 p
```text
) p+ z' y( T0 g$ yentry://
- Y; d) z) E: ~' H1 l  v/ j图片路径" _" Z2 M! \5 {6 \
CSS路径
% `8 I1 O% I6 B  t5 s7 jJS路径
/ o+ l2 i/ P: W2 L7 o  W& H字体路径0 [1 U$ g! Y$ ~
其它资源路径. }% }$ O" }: A' J$ V8 l1 s
```
- `" f7 e, t" T" i9 C1 Q! P
% q( C7 a* L, i: Y替换以后,会保留:
. }2 |8 a7 {! E, t* d0 v# E  m- h, {, }8 l
```text
7 W- D0 d# K% E! e0 c+ U8 s词典名.android.txt4 k8 |: O9 S! o9 d+ E+ l
```/ {) g: k" u$ y' p# `4 e# @
+ u0 ~! G# `# C
这是最终送入 StarDict 转换前的 Tabfile。' S) }3 _: c& _
' d1 `$ N7 `' f" ]; F$ [6 n
因此,如果转换完成后还想手工修改正文,可以直接编辑这个文件。/ u. S1 k) i* T5 v& O

  C! g( z5 l4 x7 R. S$ [同时程序会生成:0 N. C* ?: w+ ]" B+ D; G% Z
/ J' V, g7 }, m! A# D
```text
% o2 Y) h3 _5 b4 T5 n' Amakestardict.bat
* l. {4 x7 o; _, z, [_makestardict.py
# X, }* c  w. T9 Z+ V: K: |```
6 L/ d& C$ z( x+ M; m, l6 O3 I% ]* B; t8 \' P' O6 e
修改完:. @0 W' {$ b& a

/ q1 K: e2 r4 h. g```text
' X1 z+ A9 d% k; B$ Q; v8 k词典名.android.txt
9 A% W/ ?) T* r, ~6 d```/ @' j* \9 e' M
  P9 S& q  W/ z0 w) F' ?8 u' {& N
以后直接双击:
6 U# x$ ^" I! O4 v' N( k1 P8 G4 t# g$ d0 W9 F7 I
```text
; o7 |$ `7 W* k: |, g% Ymakestardict.bat
/ D1 N' T0 R. O% @8 t```/ C1 \8 H# \9 W/ a9 A& o2 s8 Z
, D# g# V# o* u. o( P  Y
即可重新生成 StarDict,不需要重新跑 MDX/MDD 解包和资源转换过程。& t. ^+ ^; C( g5 R7 t
* s9 I) J5 M, P9 O
重新生成时同样会保持:3 ~5 b) B8 H, }* P9 b3 o

7 ?- Y- w6 S' f0 ], W```text
3 H/ b/ c+ @. t词典名.en-zh.*( @# a! F3 z1 i) [
```& v- b1 J* Y& i& w* P) I. }
  r( Z: j  H7 o# H5 N
这样的语言标记。: |% ^4 D& g2 r  ?% H

$ [% a3 ]5 @1 h0 Y( x# e---& K9 m0 h% }& n4 N- Y
5 \4 V& h: q* Q) \2 E
## 八、StarDict 的 `.dict` 与 `.dict.dz`
2 t# q7 }2 _" Z" P, e
4 k5 q' P' T7 N8 ~5 g. m! k5 i0 F2 I配置:' C4 M4 N  H" d' c7 H, L

' I' }! P  |! }; P- \```text$ i: h, n/ j% t$ p
stardict_dictzip = true
1 q; ?) W: ?( Y4 {' u```% E  Q6 p  N; L; j" Y

* W5 y6 q* k; U( l( t会同时保留:& A9 ?- A0 b2 C0 G

, g6 J2 X3 Z* \( |/ I5 h```text) n: l" J1 L2 Q# S
词典名.en-zh.dict. u3 F( L) q* U9 m
词典名.en-zh.dict.dz- X) }9 R% H' ]! `$ ^
```
9 g% z- o4 N, o( v$ h0 f: D1 f( i% T1 {
如果:, N+ T' t& i. b8 z; ]; V( [

: L5 G- A2 Q2 d' S" B, V! b: I```text
+ D( `  g, s1 Z; a% V! Xstardict_dictzip = false
( R  e, f1 Y8 O4 O3 w4 b% ^) e  Q```( T* b+ Z/ {$ g& N4 X) ?% D
- [/ O! {0 l- R5 `% ?: J
则只生成:9 n' D: W- ?0 m4 P+ Y& R

. v6 n; h* O, a```text$ r5 |. U2 c+ V1 L& ~6 V
词典名.en-zh.dict- x7 T+ r4 C4 P) K1 L6 k! }: x; a8 x
```4 o& `$ l3 e, d2 V
5 P8 [# N, j6 n4 e* W/ [9 d$ K/ W) P( y
生成 `.dict.dz` 需要:8 e  ^) j( e) J& T8 J! b9 `$ `$ I* W1 {

8 p! o$ `5 D% Z. o4 k0 ]) v6 e# ]```bat6 {* t# ^$ J/ z8 W
python -m pip install python-idzip6 w1 y1 i! P% d" P" L+ [
```
( V1 l6 A0 m# y: O& [
6 M1 P1 I& ]* S+ d7 o! b4 l---/ H0 e* Y* q8 B; {9 l" k! }# }

5 E" T, w1 S0 r0 N* @7 n4 G- S## 九、配置文件尽量简化
0 r6 R* L; o5 B% ]! x# K3 f
5 z& K) m% }4 r4 @目前 `config.txt` 采用普通文本:' z5 |/ [+ ?2 t0 ?0 M3 k4 u% ^

9 ~+ b+ G. z- ^9 M7 h- \```text9 A' a. F. s) [$ K: L9 _
key = value
, k) ~$ G( r  `+ d4 {```
3 g4 b: D) u- d7 z8 V4 R% J2 ]! m
不使用 JSON,方便直接打开修改。/ G5 j0 O8 t$ c) F+ u

8 ^& \! w8 u8 H, Z! c最基本可以只写:
' b+ H, O. R' T  E5 \
* Q# R8 y9 [6 T1 x1 Q```text. O) m# p0 z- D9 A, I. I0 R! A
source_file = ./词典.mdx; k, Y# o, f5 S# S) K% F( }+ P) ]
```0 Y! T; D8 o& L9 ~

7 j( t4 V# Y! c3 q# M$ }/ F5 q推荐再填写:
0 C: R( q/ ]  B& x% C3 I+ _
/ f3 t- ^* @! n6 k! B2 \7 K2 L```text1 y  R' ^1 p0 p; Y2 d7 Z' Z+ z
INDEX_LANGUAGE = eng
1 `3 \6 a- W9 QCONTENTS_LANGUAGE = zho
  S9 ~: A% L# l```. u, `  n" e' C0 G8 Z! `) I3 g# m

: b( t# U& |6 y7 F( l其它项目一般都有默认值。
+ Y& H- Q8 n, d3 V! k
/ w, O  M" w$ b0 r. u一个常用示例:' f+ h8 e; f. d4 V' U1 p2 T
4 B8 ^, r! |: K, C$ z  g* p
```text
3 g5 J, q' f( x! c9 E  O6 @/ @source_file = ./外研社英汉多功能词典.mdx9 r3 S: ]' C2 \4 _8 O, `6 l
input_type = auto
" V+ m- f* `2 S. R3 s
# Z* `2 \% l0 [3 EINDEX_LANGUAGE = 英
3 j) R$ ~) p2 X' ACONTENTS_LANGUAGE = 汉' c: c5 F: p9 ~/ s$ ~
# a6 t5 E+ [6 r- C- d
dictionary_name =0 C1 Q+ f5 J& J' E. D
output_dir =
4 K0 P8 \8 d- F2 ^$ p( w6 a; S+ p& l6 ]
device_goldendict_root = /storage/emulated/0/GoldenDict
  U% I3 W; g' I( E( c, N' D$ u& y3 ginstall_dir =
/ f9 `0 C& F* _, d' ^5 B, n. @( W/ q9 t3 [6 ~1 {
css_storage = zip
1 F" C" T, t  aresource_layout = original; y9 a! |, `2 ^2 Z0 N# T' C, S7 _  h
" T0 e/ L2 B# K) d
local_resource_dirs = .
0 ^& w9 _& c" r- E( r1 _local_resource_recursive = true9 p7 z( R+ f/ o2 _' V. |( s: |
! d$ n8 A' J  e$ m6 `7 p& L
rewrite_inside_resources = true+ f1 S8 l* a; R. \1 R
3 ]2 f  E& s2 @& P7 T- Q/ w) h7 ~
stardict_dictzip = true
# R, l  ?, W5 y  E0 e  a. k9 vstardict_html = true  x3 m  l8 L; K. Q

- Y3 Q# F# {$ A! u! Dkeep_raw_tabfile = false2 e' d) ^; D' h4 N7 z; S! B
```
3 S9 r8 G. h1 q1 ?! f' I
, f! C3 {' @+ T! d其中:- r7 r: e& v5 v  J

( y! c6 V$ T  d9 X- h- g# \```text
/ Z0 z$ y6 `2 f4 Idictionary_name =
  s- F* i2 Y& uoutput_dir =
) e" y" k$ b1 v! e* f, i0 P$ R! J```; P" f: H7 Z9 B" N

: C" t  T! ^( |: \留空时会自动根据输入文件名生成。
+ U; |4 |' n8 J6 M1 q) F+ `- A+ u2 h+ m( L8 I  G  ?  E; P
---
7 F3 E& D& t4 D, r1 J( d  s; E6 v' r/ W$ E7 W: w1 _- O
## 十、两种运行方式
( E, Q) F0 U# `& [* T
4 I7 q8 ~! u$ Y9 V* O### 方法 1:使用 config.txt
. Z$ _" W6 |; P: S! N2 F7 D+ e: z9 T, Z* @* ]3 z6 z3 C) `) u7 C
```bat  h* f4 s7 A4 I+ k# b. |6 e
python mdxtogd.py7 v8 i+ d# f2 V
```5 ^  m9 u9 ~& M
+ o6 X8 L" [6 ^: u- J
程序默认读取当前目录的:
6 V5 p: E# V: n4 o, a% a3 B& C. ]% E# N
```text
  n( G3 D* q4 K9 Z  y2 u5 o7 Fconfig.txt3 Y$ N8 c* k4 E5 F" {
```5 X5 Y  z1 A% a3 {4 ^/ v6 a
8 {6 R- a5 b' u0 |+ P, E0 F3 L8 H! Q
---" Y- {( Y( w2 y# @6 \& k: q- [

6 s) T0 r$ f; S* p# T1 F### 方法 2:直接指定输入和输出
/ z9 @# |. Z9 C2 y: B! H
5 a4 g6 a  ~% P, z```bat3 v- m- L% l5 ]7 L
python mdxtogd.py xx/词典.mdx yy/新词典名称.ifo2 [6 {. c4 ~: o3 y, ~/ p
```
, [7 u% {' P3 [4 ?- X& T
7 E  Z2 e2 w7 o& {+ M+ ^Tabfile/Textfile 也可以:
# L" P6 W2 Q' z- ]# m" ~3 o" W; r# v, ?8 P2 I: Y6 G2 U9 j
```bat
/ u/ e% k5 g4 f7 z4 V; a/ upython mdxtogd.py dict.tab out/NewDict.ifo5 \" |. n; W7 o& a2 m6 T( y
python mdxtogd.py dict.txt out/NewDict.ifo
: v9 R+ a! c/ x# d( j8 t```/ i3 l& N; z! a7 ^9 `0 C

* T+ g, ?* B3 x! N1 X如果语言是:
4 g" s6 R8 i6 F4 i/ l( S8 f7 y
$ r( i7 y7 f' L; T, b5 p, {```text* @# [2 E9 S& p2 r8 ^
eng → zho( l! @2 k7 [; k: h- b5 I) t! x8 ?
```
8 M5 {# [; J/ c5 ^5 `
+ M9 ?, p( m3 T2 Q: Y# I0 q最终 StarDict 会自动生成:: Q5 e7 B! X7 Y2 z, b2 Q: c1 \

  i6 H4 A% N9 j" f0 E```text
) r9 Z' u7 r  h$ J' \0 Oout/NewDict.en-zh.ifo
4 v/ J$ F- e, {& H1 W9 Fout/NewDict.en-zh.idx5 {* n) u, {, ~1 f( n
out/NewDict.en-zh.dict
: N: y4 R+ Y6 V3 R$ H, B8 kout/NewDict.en-zh.dict.dz
" n7 A1 S7 g. c# i- _```
; X$ w6 w, ^  Y: p% L8 p$ K9 B& b) \4 [8 G' X
而 DSL 和图标仍然保持:
. N" B5 D  c3 p
1 w& y7 d$ `  T* {```text
1 x3 h- `' j1 A; H2 f* qNewDict.dsl* Z/ M' y7 S% [- N9 {( I  n# {' V$ G
NewDict.dsl.files.zip
7 c- F, n* t* QNewDict.bmp2 U- W4 [: G  Y3 ~: X
```7 k3 _7 f& d9 M3 ]

  J1 S+ F- u4 U5 a! x---$ N% i( k2 k+ E& B1 \! E) r$ _1 k) Y) W
* ^8 Z$ k7 b6 y+ k. k8 w1 I# s3 o/ C
## 十一、主要依赖
- X& `: z7 |  w, ~$ ^% o6 G& h& O5 {
核心需要:
9 J; C: ~7 N: c* Z% Q0 C8 ?. p9 A1 _$ |  P0 {
```text
) o0 Q. q" [8 gPython
- B5 o  G* z$ {8 G2 _; nPyGlossary
9 W" k8 l  `- E8 N& p1 Jmdict-utils6 O9 O" M4 \2 V; K% [
```- E" d' k; E5 w' ~+ x
; [, s6 D/ }# ]1 U- [
建议同时安装:
6 p8 @/ \) {9 U7 ~9 u
& u9 F+ l, j4 [```text1 [  D! d1 i% u, M
Pillow
% C; x; K, M4 b) l6 Lpython-idzip" P9 i2 u, f3 b3 \
```. h0 F8 F9 B* r* ?
: x( y! H: Y! u/ ~! X, |* x, a: N
例如:
: ]5 U* D+ i* I, I& M3 |* G; o/ z1 U; d2 U3 R1 k1 C% G* a
```bat
5 r7 Q$ p- M# q7 ?1 Spython -m pip install pyglossary mdict-utils Pillow python-idzip
  l$ h, U$ h6 f6 \2 ^" m! o- D- \```, a) L9 i/ ~) z  K- z5 C) R% A0 V4 L

, X* n: x/ G5 \4 ^$ _部分 PyGlossary 插件可能还会提示缺少 `lxml`,如果希望一起安装:
  T2 X& p4 n( N  u
. ~' l, w4 h( Z- _```bat
1 T/ ^( N9 K! V0 R* mpython -m pip install lxml
/ K8 l4 O1 X0 |% {) \! g4 ]```3 P( k- B: }+ n

" n" n5 I7 O0 D: l---
1 R1 a6 b1 A9 `& y* ~/ N
* Q% _# r; J/ I/ n5 X## 十二、输出目录示例
- Q# ?' A' s5 F+ u8 Y6 G' W2 v. G; C2 z  C) ?2 ~% B/ i/ o( B, u
例如:8 n, E. c& }0 h( S, r
8 r4 ^7 x+ B4 l& O# A! v% U
```text4 U: a6 b8 X' b: F) h2 Q
外研社英汉多功能词典/3 |) {" C" L# O! M1 e5 ?2 `
```
0 G  m9 }+ e' B, N# B
" B0 F$ [3 B1 y( O转换工作目录大致如下:0 {  a6 Y' V$ I! ?1 @, q4 W$ \. h$ q

0 W9 _  n- ^- I- s* z```text
9 l9 W) d7 e4 s8 ]) b1 _( B/ P8 I外研社英汉多功能词典/- Q7 E1 r  K$ O8 j. u! j
├─ 外研社英汉多功能词典/
' m/ j& C4 s& M0 d, `- J│  ├─ 外研社英汉多功能词典.dsl
! A3 a' D8 f1 v3 v* U│  ├─ 外研社英汉多功能词典.dsl.files.zip6 I, W9 T. x4 r- e! Q: E
│  ├─ 外研社英汉多功能词典.en-zh.ifo
/ {" h' b4 d7 }0 S+ N$ c- V│  ├─ 外研社英汉多功能词典.en-zh.idx
( p) S; j1 L; l- f│  ├─ 外研社英汉多功能词典.en-zh.dict
6 o2 V4 l$ v5 ]! J" h│  ├─ 外研社英汉多功能词典.en-zh.dict.dz9 X0 n' U/ \6 H. d6 {+ `
│  └─ 外研社英汉多功能词典.bmp6 i& I; W1 K0 C- R; E: e9 y" x

  n# N- i1 K. l' P! K2 P" n: |├─ 外研社英汉多功能词典.android.txt5 o7 M5 {/ d2 A6 e& Q# g+ f* E
├─ makestardict.bat
4 q+ }. Q9 s, ^2 ]) Q├─ _makestardict.py, w8 M5 g  y/ W/ g" B% |7 p5 v
├─ GoldenDict安装位置.txt
* b- L: W4 h4 N& N└─ conversion_report.json. g2 P2 W; z" p! G1 D7 ^
```! j' c- W: S% B0 d" M. }

) e' q: [6 @5 v* v8 `) xAndroid 端只需要复制内层正式词典目录中的文件。
7 T! V' M# L  q. f' S
$ R% j, M' a; B3 q/ N* d# O---
+ n: p* I4 D4 {! N, y# ~
! Z( Z- E! W/ W2 X## 十三、一些说明
0 w  K" T/ _5 H6 A: ?, u& \# R6 U8 j* A. {/ ~2 `! T$ N
这套脚本主要是按我自己在 Android GoldenDict 上实际使用词典的需求逐步整理出来的,因此重点不是做一个通用格式转换器,而是尽量把:
% u' O  d5 ^6 n1 q" I% U0 z6 _; n9 p* r! B2 m
```text* I  V! m3 L( }$ Z1 X# X
MDX/MDD: s% L8 n7 H0 v# J% F
1 t: B; a/ N6 ]. Q1 V
资源整理0 e) U9 _: K* N! ]: ?: f9 {
. ^4 S! m7 V+ h% |& _
Android GoldenDict DSL资源
# E3 z  ?+ ]3 d8 t+ P% G9 {* R! D
7 N; E% D' i0 h" T7 z# tStarDict
- T- S% V! @4 u9 y$ G2 h
) v  O% K2 J; S8 R+ ?语言识别, D  D* }' i  n$ N4 F
( ]0 l9 |+ m+ O- \
目录部署4 n+ Z9 c, [+ B
```
$ X+ Q3 w5 H1 t  E0 R) Z" C2 x4 z- r+ X9 G
这一整套过程自动化。
0 B( q& G1 X; C' `; u! n2 O  ]$ O7 \; f$ V+ h
不同 MDX 的 HTML/CSS/JS 写法差异很大,因此不敢保证所有词典都能完全无修改直接转换。如果碰到特殊资源路径、特殊脚本、特殊 MDD 结构等问题,也欢迎反馈具体词典结构或报错信息,后续可以继续完善。$ D) P( {: [' e" V9 ]" D$ e

' q! h( z2 r! D" x) J0 k6 n建议第一次转换新词典后,重点检查:( [1 t5 }+ y7 s1 P/ N% O+ W

' ]8 w7 s6 o: ~( u```text  e8 P3 H% R4 h2 n7 |! `2 g* F
conversion_report.json- G# J1 ]: }$ m
GoldenDict安装位置.txt; N( ~8 g+ |8 h* i& @+ S
词典名.android.txt2 y0 u. W3 E! i( O8 D; ~$ B
```! E) J) w8 U- [- g

& C* N5 E* L. J+ u/ A/ |如果有:
7 k+ }! i  H: i) x# K4 x
# k8 C. f2 s0 g2 l1 F```text
- \$ p' j! @: E, s2 ^& f$ z4 f⚠️ 未解析本地资源
5 |1 d/ R, N: @8 a3 M```5 S0 w3 ~5 ?) H+ g

2 H2 T" ~' v+ `最好先确认对应资源到底是在 MDD、本地文件夹,还是原词典引用本身已经失效。$ X9 [+ `, z0 B3 i* c
6 H4 I: X1 P4 R; h1 f. @& ^
目前我自己主要用于 Android GoldenDict 的 MDX → StarDict + DSL resource 转换,欢迎大家测试、改进和反馈。
* X$ P: d# v, I
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2026-9-14 22:23 , Processed in 0.028234 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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