掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 16|回复: 0

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

[复制链接]

该用户从未签到

发表于 昨天 04:30 | 显示全部楼层 |阅读模式
最近整理了一套自己一直在用的词典转换脚本,主要用于把 **MDict/MDX 词典转换成适合 Android GoldenDict 使用的 StarDict + DSL 资源词典**。
2 ]% ]" _9 W- o8 y; @: u. |
# t) Q9 E& e/ s) B3 l; f脚本名称:( q/ ]$ J. w$ }8 `

" U- {0 E: P0 |, ^: L% P. z```text* D7 n3 S( ^  Z+ ?$ E( X. d
mdxtogd.py: |4 k% a) X( Z7 G
```
1 _* K! C0 v4 w! |. c4 ~, D
6 q7 r* P6 \. r9 g5 R" `$ H& K6 r配置文件:* S3 I# i" J2 F4 G
+ X4 h# u" [! k2 \, p, S
```text
/ b- u" e5 R1 A* P6 Yconfig.txt; G( B  T8 k4 z9 \1 H: w
```
7 O( u3 H% w7 o7 o, g7 m' h( @: W* }, }. z
目前支持的输入格式包括:
+ K; F' ^* v' k% |  ?2 m6 Z/ ~0 Y- s( g  l9 l5 c
```text! k' l( r  K- l7 {; t
MDX
  ]$ k8 [3 ~: n! zTabfile4 B$ r) d- Q. _
MDict Textfile
! Y8 A/ ~. U; `; @```
' }3 M0 Z; E  [& D% ]# i8 N1 m' Q0 l8 D' F7 d
其中 MDict Textfile 指类似下面这种格式:
6 B: }; r/ _$ x2 M4 V* K5 d0 ]5 B& C1 l3 y3 U
```text
. @- _. v' X9 q5 y; a/ O词条1! M, q: n) W: A3 ]2 i/ x& b! V
内容第一行
: }$ o3 O' X! n' h. a内容第二行+ B' |; ^  ~3 J; D" s; I4 r
</>
# Y% c) |- M3 b5 W词条2% s! _$ M1 b3 H9 W
内容
9 h, A3 `4 K- J$ z1 f" Q, S; j* @</>
( k7 _; ]: h. X: b3 k0 V% K```
+ K* X& W# |+ c/ U- J
/ [# c6 j* _& W3 ~) J程序会先统一转成 Tabfile。正文中的实际换行会转换为字面量 `\n`,因此每个词条在 Tabfile 中始终只占一行,之后再继续进行资源路径替换和 StarDict 转换。
* t1 C5 G$ d5 S# D+ O
( z+ i& k3 K# h2 Y7 {) F1 K## 一、主要功能
& ~. \# k0 a# z6 n! e7 ^0 o1 T0 \- [  z+ p2 j4 A+ T0 ^8 s
### 1. 支持 MDX + 多个 MDD
( l, H! b% Q8 @, x1 {& H& i, g! Y* T6 v+ d* x) W- _( l
如果输入:
$ ?; r2 F" {/ L+ T# K2 n& B: C# q+ w- \  l# {/ t. E
```text
' Y1 k" H8 w5 R- J% @  ?词典.mdx# I/ W7 k- ?8 |4 o$ h. A8 A
```
  T6 v3 P  P" i+ `- `3 ]& _' q3 }$ L, y. b: S: K; H
程序会自动寻找同目录下的:6 M! \/ e& T( E
3 g1 y7 r  J4 k; t* L, H. @
```text
- U# ?2 h7 U/ C+ W3 ^8 n* N词典.mdd5 V4 v; F3 k& E. O2 Q
词典.1.mdd0 z3 J, y; x/ ?) w
词典.2.mdd# x5 a  Z. h- B! e' M3 b  n
……- G1 Q) y# S" P- _
```/ u+ M' f  e( u) Z) X' A5 N, N
. L: m/ T8 s/ n
无需在配置文件中逐个填写。8 R# a. ~+ K( [- _% z; _: D: g

  S! O' N/ u7 G+ s5 \' r' Y9 B4 q( lMDD 中的图片、CSS、JS、字体、音频等资源会解包并重新整理,然后生成 Android GoldenDict 使用的:
8 k$ D5 y: [0 N2 p. T7 n, o4 c6 h! f* [9 O5 {/ h
```text
7 u8 ?# ?. w3 d( X词典.dsl7 P9 G" q$ o% }4 h3 i2 j
词典.dsl.files.zip, f1 R) o" a+ ]! ~/ E% w' i. Y  {$ E
```
+ T9 ]0 p: n& j9 x8 H* u% L1 `
. t. B* C  g4 j+ d0 H4 Y' RDSL 使用 UTF-8 with BOM。' u! Z4 y3 T' R- r% T1 i
5 P, v5 e9 N% E: `: m. t
---
4 p' R4 o  x6 l6 U, E3 ], w
7 A: J; u# N% V' |' [### 2. 支持本地资源: M9 N/ Z& J' u
# F0 F2 J% U$ X' t# K- j. e
有些 MDX 中引用的 CSS、图片或字体并不在 MDD 里,而是直接放在词典文件旁边,例如:
9 g# M8 ^# P* S2 n8 e1 X2 f0 E
) G) C2 \5 t# j' i```text5 }$ y% g7 u1 Y/ f
词典.mdx
4 `) g. I4 X; E& Xmecd.css
) ]( x7 F+ `( l3 pimages/  h+ E5 t( J+ {# E" ?" k  t
fonts/+ e5 t- v6 e/ c2 ^9 C
```' \+ v# [$ Y7 B' U# I' D) Q

; ~* E8 l( V, Q8 L. V' E# V% A. t程序也会尝试解析这些实际被引用到的本地资源,并纳入相同的资源重写流程。. y+ T7 v, _0 A

# a6 Y" ?, O9 ]( |/ `CSS 内部继续引用的图片、字体等资源,也会进一步解析。" I6 p' h- N# K' I* Q, k

! j% i* J6 s, z---7 x' s% w- Q1 V' C& T0 d$ C+ ]- A
  Z6 _! D' N' M4 z. k, l" U
### 3. 资源包支持两种目录方式
. d( k# N: {: J
1 ^+ `+ k, i8 U6 W- J+ Y+ E* ~# K, b配置:( ~5 T9 a6 c9 a7 o/ f5 ]
1 V$ K6 @" c" Y- J" i- [% P6 o. H. T
```text- T% D5 [1 f, F9 K( \
resource_layout = root$ g# m! K, J6 g9 ?; R4 ]$ ~
```
& B8 B/ M: A/ H' t% `
( K: Y. U+ |1 G) \) J表示把资源全部放到 `.dsl.files.zip` 根目录。7 U" f. h$ `, [- ?) @
+ w" y! f9 m- Y7 s& I8 c6 `% J
如果存在同名文件,会自动重命名,并同步修改正文/CSS/JS 中的引用。
* N' @/ y$ P, j, ~6 U7 }2 Z. N4 e. S; ^
也可以:
* j1 s# W2 Z# e; L, K6 r0 B  p6 K2 \4 t: w
```text( T  t4 c0 Z2 P" T1 p1 G* r7 `
resource_layout = original
( n* F, p: e. e3 k1 y```
! o) Q) m, c0 y" K* l$ E0 d( O7 S" |% \/ `4 X4 e- N
保留 MDD 原来的目录结构,例如:4 C2 l) e* P1 R0 D% D+ X( b" |
$ X: {6 N) T0 |
```text
; A, `- T3 {# [& O, U( `5 i) qimages/a.png& z+ G4 e; P" Q# E' }
css/style.css0 {! s& f1 q$ Q
fonts/font.woff21 z+ p4 L- j9 |5 ~; P) |8 {
```$ M8 C1 l0 _7 W# B! k, ^3 {
. G: J/ O' L4 [5 ]
对于资源特别多的词典,我个人更推荐 `original`,管理和排查都比较方便。: X& n& s( L; S* y: o+ i, b; o% ~) ~

0 Q+ o& p9 o! ~0 i) j/ P& L/ d---# {' |/ O8 z% o* ^2 I

$ }  W/ l3 f) w% \3 A# I### 4. CSS 可以放 ZIP,也可以独立放文件夹
5 }2 v. \% K1 s1 N$ O0 B' C; C
0 L- c5 X) R- `3 ?- y```text' L+ J4 H3 }% v$ f# S; M' M5 a
css_storage = zip3 N6 w9 h" }! U4 Y) P0 l3 I# p
```
3 |: J& v* R% X$ v* ^1 z8 ^! t; H+ m; c) w3 p& e- l
CSS 放入:5 }5 u# T+ W) a, P3 e& }$ s
- Z( ~; w2 E, Q! ^9 z7 H
```text$ q' x# A( D' F! r5 T# U' s
词典.dsl.files.zip* [0 n0 D$ o" n  ^# \
```: M% q1 \# e/ U9 `) m

0 R) S+ I, D9 ^. S. y/ V. y或者:7 ]( o' W/ q; H/ a

6 n" u& F6 c& t1 y" A& x1 o```text
3 D' ^! m. G9 M/ d, D3 r* [css_storage = folder
2 S8 p; Z8 s" A```
5 I5 G* Y. M7 f; s- N
  Q0 T( K, `) b- pCSS 作为独立文件,与正式词典文件放在同一目录。
; t0 O7 @' v. j1 V: R; x/ R& y6 V1 k* L0 o' z' U2 C- K8 [! l: e+ ~! @
---
) A" v* u  W/ j/ B6 g) \3 m( W3 `# M
! Z0 n" @; r3 t. e+ Z& _' P& z## 二、自动处理 Android GoldenDict 资源路径
1 g: E4 n4 d8 L- a' c, N+ b. S& P. [" C& B
程序会根据 DSL 在 Android GoldenDict 中的实际安装路径,计算 DSL resource ID,并把类似:$ p1 g6 l6 H) T
) e/ N, }7 Z+ V- o- U6 ]1 H
```text
8 e$ b0 U+ X3 S1 x+ {; c" Z5 [images/a.png# J8 I# D0 X) h$ A: d. O+ k
../fonts/font.woff20 V, y$ _7 ^& u; i
mecd.css4 @! {4 s9 @- ?/ F9 f) }4 ^7 ^
```
: V% r/ b4 |' l* o) u2 U7 \0 _9 X4 L8 k. c
改写成 Android GoldenDict 能访问的资源地址。" e7 F% O7 ^+ b% \& q4 Z

1 u" D2 Y# N; [' m& g例如:
# g+ G* j: d& b+ k8 X& V; T  k; Q
- X' H, N% @7 b* s* u# I' c```text3 R+ ?3 |. y0 z6 q, c5 [8 `& u9 _
content://mobi.goldendict.android/resource/<DSL_ID>/images/a.png9 {) x  J/ }6 L
```
! f) j5 c, a; ^8 o. H$ _1 o
6 e3 P& B3 T- g- H1 HDSL resource ID 使用 DSL 相对于 GoldenDict 根目录的路径计算。
5 u$ j1 t( M% G
3 k" S; I. b5 g0 @" j' Z; ]例如:! R  K* e! `- g; U" N

8 b! ?  g/ O  m" k" l```text
  E2 m5 M! n# T# }5 o& s% l/storage/emulated/0/GoldenDict/ENG/ENG-ZHO/词典名/词典名.dsl
! [! F# i9 s( i  w```
6 _# ], u' T3 I5 `1 F/ ~" j& ^# v+ H" F  T
实际参与计算的是:' ?, K' p" z; x6 ?0 g& B
# {2 y# J) R+ n- X6 y
```text) b, x7 |2 _* v! Y
ENG/ENG-ZHO/词典名/词典名.dsl- m2 x: [# I$ @! e& Y3 H5 h
```: Q  ~" o* W0 z% [8 H% f3 T7 x
* c( x3 n0 B# o- o
---& V! v6 r, {( d3 L

/ n* C1 Z' U( h$ A/ m8 \$ U& J/ U## 三、自动识别词典语言! c! M8 R4 X/ M3 z- g9 I1 H$ }
& s1 p0 T9 S6 ]- f: r9 x
配置文件中强烈建议填写:
2 n# N( d/ W! y" g5 D
( E: }7 _7 q, ^- [- c0 Q- D```text7 Q( I% I* V" l1 K2 c  b
INDEX_LANGUAGE =
- f1 ^; L! a% L% YCONTENTS_LANGUAGE =; \6 ?( y5 W$ s8 @
```" k' n( G* J+ ?  u& w" O

( U8 s, d. T" c8 [: W$ T不过写法比较宽松。& N6 F5 Z+ ]5 l
* K" F1 E( G7 ~( a
例如英语可以写:$ l/ ]) u( D! z: N* d
# D. ?" B8 g' h* z8 e2 @
```text
/ q/ Z1 P4 L, T  k7 P. Ceng
6 D8 z2 V+ x; t6 k% Qen
# Q3 P4 o6 G' t" s, n( R' OEnglish  f( k+ k- E/ K3 s0 v' r  @1 {! p: L
english
4 e6 Q$ y. S3 o0 @2 b4 o4 T' L, A英语
- E/ s: \/ W6 `$ Y/ m5 ]' N英文
7 y/ T5 L- s4 W* R! M6 D
! b- Q1 V6 {+ O```
# ^9 P. i( J- J! ]5 o: z! ]# i: F
# [4 Z* B2 U( F中文可以写:# D* d4 @% x6 n) ]1 g
5 @# ~; A+ R2 \. L# N$ `1 K
```text
( p/ Y2 V7 z# D! {7 Zzho
: ], n+ p$ b# Y1 S# y/ o6 tzh
/ N- s% W+ Z& M4 vchi
# t8 I; I/ W' f5 z% I; A9 gChinese
& Z/ T9 N1 Q8 u1 Q9 \4 a中文
# P$ o  j1 v9 J2 h/ R$ o  V汉语
& s8 [! u# B* Y+ V' R/ i漢語
9 g8 n/ ^# Z: `1 q$ B4 a) a6 ], A2 I& Q3 y& B* h- m. h- M
  o9 _5 u4 t# O6 l, Y) W
+ C+ k" c* ^8 r, q: p
```
+ u6 i* u$ E! T* `4 f
- Y$ ]4 G: B# r7 W) ^  |程序内部会统一转换成标准代码。
' u- {" E. B) \- l" d+ E/ C
+ Q6 U# ]. c$ w. @+ w例如:/ E4 Y; r/ k! F( Z+ C* x$ g
% [3 {" a* S3 r( a: |
```text5 T& i" k% E( Y# |: L
INDEX_LANGUAGE = 英
- P( G/ c8 ]: o. I8 fCONTENTS_LANGUAGE = 汉- ~/ V0 S7 z, X' e
```
  [; Z$ A/ ~2 H/ M4 z, X
) [* y( V( B  t1 P7 X9 Y6 i7 x2 Z' g会统一识别成:8 j: q0 m" u$ c  {( k

% G% y3 [5 u: h3 q2 U) a9 g- F& F```text
( j6 O5 o5 L. t4 deng → zho
! n% A+ `7 S+ X+ C$ K4 Q, _```& z6 \3 s' ^9 e2 E* P, j

4 X# S) R' ]# ^; U% tDSL 中则自动生成:
5 Q* |; g# t$ ]4 S- N6 R3 G
2 ^3 O' b! N2 B+ F, N# f' b```text
. F! p. C1 _1 u( b5 Z: Z. \#INDEX_LANGUAGE "English"
, ~) G; y6 X0 x. e8 V#CONTENTS_LANGUAGE "Chinese"
2 {! w2 t2 G+ L9 `  t0 j; {```
! q- c. Q6 M( h' @0 s. ]9 `0 q' M& b4 U5 n& Z( i0 c2 T6 z& c
如果没有填写,程序还会尝试从词典文件名判断,例如:5 p" l3 B! ?- H' K. p. d- p

) Z, t8 R  e5 |) O9 a```text
" D% p. K& K* @8 Lxx英汉词典
7 j" A  x3 Z  R3 b7 }→ eng / zho
2 |+ o6 J# `; H6 x5 P5 \/ O$ v8 F- x* E
xx汉英词典) ?6 g; W8 ~! g8 |3 D7 ]& W( G
→ zho / eng( E6 N4 B$ a: g% X7 |1 J4 [
1 y& c" J( m* B1 T9 f$ E, b9 O1 [7 K
英英词典8 c- C+ J7 a1 l
→ eng / eng
: D( H1 E4 T1 m7 l8 z" O7 L4 i2 ?; G8 V& q) _4 ^7 s
POR-ZH
" V  t$ }+ _6 ]0 s2 e7 ?→ por / zho# V4 P+ y1 g& D# C
```& o! x0 H3 q8 M( @! ^" i: z, [

/ d8 {" F2 ?7 ~0 D无法可靠判断时使用:
, m0 f( e/ ^  ~& u# I9 Q  a. u7 p8 B3 t# z1 c3 s
```text
: h3 p: x+ n6 u6 I, sUnk / Unk/ D( ]2 W4 @7 B9 D" o" b" Z
```
0 e% g( v1 f, O3 S- G1 `$ r( ]  y8 B" l# o& |: T' h' K
建议还是手工填写,自动判断主要作为兜底。
0 @; h0 B3 l+ V1 C) ~0 N4 A
4 {; Q) z. k1 S& n) ?9 E---! a/ o& T* w5 S
4 U4 V) C$ h# y2 @# I
## 四、StarDict 的语言也会自动处理# T, C0 l/ l7 f

8 Y+ f, F# x/ {这是专门针对 GoldenDict 做的一项处理。7 l" b9 O% J: t- }" @6 z( N

* f9 D  [6 Z( M/ \StarDict 本身没有 DSL 那样的:7 e' t, g/ ]. M, h- v) [

# \6 f. A$ U2 U  _3 T( g0 `: r```text
- S! g7 }2 c. v, a! g. |#INDEX_LANGUAGE
* U7 l: \7 D7 a* m- @#CONTENTS_LANGUAGE
, Z: D1 g& o7 U2 O/ H! e```+ h5 P1 ~  U& M$ P; ?& \. Q

0 w; z# K' l  j8 ?GoldenDict 可以根据 StarDict 文件名中的语言对判断语言。8 R- H; a9 F. }* k5 o+ D7 T
( u& p" Z+ g. D* B
因此,例如:6 E: G$ I" q. R  J

. |# g, y' H3 D```text0 }+ O1 R; T# d& g4 z: m
INDEX_LANGUAGE = eng
7 v9 c. [* A) z. X' O2 y' OCONTENTS_LANGUAGE = zho
* B; R) l4 i; ^  |: [```8 Z8 E. Q# ?" s% ?/ ?" X6 ~
: V6 X9 C. H8 ?
StarDict 自动生成:
: Q: E$ G3 H% j* x9 q! g
" s! w& r+ @; r6 \0 m& ~4 k) b```text, m  l4 U. d3 U# f4 p1 |
词典名.en-zh.ifo
+ H, Z4 \2 }$ n* C9 ]词典名.en-zh.idx
, D3 a: W; A; z6 u词典名.en-zh.dict1 J4 h. |$ }1 N- m
词典名.en-zh.dict.dz
6 ?. Y# m+ H) c1 v) z6 J```
, L/ n- h0 J, |
+ \$ M3 [6 ~" g: `这样 GoldenDict 可以识别为:
. T" U9 f3 W: c# I. }5 V2 [7 R" E9 U% y  h1 i* U
```text
' ?, F0 J$ L! FEnglish → Chinese; N2 z+ u4 `, X% u2 U
```6 |9 {7 y! |6 i+ i9 s  O$ s: q

& ?9 j7 Q5 l2 q: @/ H但是 `.ifo` 内仍然保持:- d- A$ o9 Q) O& l  R. T

/ p. p/ k( S& ?: z```text
# [2 `7 O! _5 U& P5 ~9 ]bookname=词典名
" H* u5 c  [( r" Q3 S  U```" g8 G! O! N) `6 ?
# n, w# K1 P1 c% S5 n& |
因此词典在 GoldenDict 中显示的仍然是原来的词典名,不会显示成:- i, `: G3 D+ d% u: \; D

3 Q/ L9 m, [6 K" j5 Y0 O* S6 F```text) ^0 N- ]3 P3 E: ?
词典名.en-zh
3 C0 o$ h, Y# [5 H```: k8 T6 I) p% @7 t% h1 G
; {8 t  l7 s: ]  a/ z' [4 v
类似地:
6 X4 G0 {- c% C2 F& c" v- I0 V3 j
```text
6 g* _7 |, Q9 g+ v8 ~zho → eng
5 L: ?+ O; F. a9 R; a! c8 Y生成 .zh-en.*, C5 V) ~/ L) s( `7 K( }7 f

' |+ O. F( I. \) oeng → eng
! p; W: d; j& }* ^生成 .en-en.*- u1 ]8 g* p' J8 y1 o

2 `) I5 E& ~( o; J& D+ Tfra → zho: A0 R$ J6 e3 i2 H
生成 .fr-zh.*# u; ~0 m7 R- B3 A
```
( h8 |, Z; o- R, U% b' g" g/ T: W& J( n7 f" b3 u# F% n! V! V
如果某一端语言无法确定,则不会强行添加错误的语言后缀。9 O3 Q- m8 v- h: J1 O4 W; f

* t# P; v! ?0 b) G, s---
$ D: A, l2 @9 p( j& {8 ], ?0 @  Z- v/ C$ M' }
## 五、Android 目录自动生成
% {; y& A* A- Z( y3 a; n- {0 E- z8 m1 ]; t7 B2 E  K
如果不填写:
9 J# s5 A8 s9 D
5 A. T) s! r$ M. b# `8 K! }1 S' f```text/ m" Y5 P/ F( ~! K0 Z
install_dir =
, E' d' W/ m( B```
8 U) B- l! ]; j  i1 i2 @. _6 F2 b! {  Z3 R& N2 o
程序会按照语言自动生成目录。+ z, b+ O( Q* t4 \: C

; D0 R7 p' @3 ]4 h例如:
% H, K" K" t; [: c* T1 c) n' x. b; z- _0 d% M9 M" U
```text
6 f$ K5 C+ J* `, C# t9 z" oINDEX_LANGUAGE = eng
* c+ d  `- O8 \8 SCONTENTS_LANGUAGE = zho
/ l  l0 ~, T1 H0 w) I) m```
' ~, `2 _3 I7 r2 u8 I
- @: l% z5 ^8 P- F/ X8 @# {默认得到:. Z  d+ |* C1 P6 W6 n& w8 e, U
. z/ e6 y* ^0 `7 @
```text
# J" Y! `7 i7 o# P3 jENG/ENG-ZHO/词典名: y  ]/ ]$ @4 t, C  o4 `
```& j2 |; h/ P2 o. G" ?+ _. |

% R6 k7 k. q) X7 e4 B& r1 L最终 Android 位置类似:5 w4 e2 y& j, i9 Y  w8 T
+ J9 l! B! q3 m& g) P7 {3 _
```text
6 }$ a6 ~9 F. @" a/ @$ S9 {, |& a. N9 r7 O/storage/emulated/0/GoldenDict/
7 B" Q4 R( U/ l: I* q; z! V└─ ENG/  [- S7 |' Y( e; h5 W/ O
   └─ ENG-ZHO/
5 |/ X2 t+ r+ y$ c" U8 d      └─ 词典名/
7 l# w$ w+ o/ v7 `8 J- Q; t```7 L5 C# ~2 s% E% B9 g. ?7 A
  }6 }& D6 I9 D9 ~  M
这样词典多了以后,可以按照:* s! f  Y6 S6 @8 j( ?- p! d
( L. t# R" ]1 l! s4 v! b3 j
```text7 [2 e. j5 i; o* y7 X' J
源语言
( N" T, g& M7 w% N→ 语言方向0 `( ?: Y) Z7 H; h* X2 C, f% w
→ 具体词典" ?' y" |' b; V% a8 P) e4 A0 {& B
```5 c. W  V' t6 }4 V  P6 [0 B' W

3 U, j) b1 C. Y* M- z2 {& J( P& c来分类。' |' G& d0 F- N! k6 M. S$ ~. S; j
6 I7 y0 f! O: W* j) t4 o
转换完成后还会自动生成:
& s8 N4 q4 r/ [: E* |+ D. l/ O1 ]0 i( k2 r2 s: Z( S
```text1 I/ O% _/ L$ k$ Q: P1 ?
GoldenDict安装位置.txt
4 D" }: ]8 Y! O! f3 E; ?0 e. e```' t7 |" \3 ~9 Z3 s! M- x

8 |6 d3 ?5 l; K# {; P6 e里面直接写明应该把正式词典文件复制到 Android 的哪个目录。1 j' o: C* ?" p2 [5 w, g( ?

! L# ^" l  l  s, h, U# b) O---
$ E+ [* Q1 ~- |  c  Y* [
2 x5 I, M& Q3 u1 C' N9 p## 六、自动处理词典图标, Z: [' `0 `% m' k

# f, ^# k7 s0 j如果 MDX/Textfile/Tabfile 同目录存在同名图片:3 B1 @  c; X- V

4 }$ `. H3 G; W# F# u; r```text6 ~, I1 k8 s5 R5 l9 q0 q7 H7 b  ^' l
词典.png
! `% N* _% U: }8 @# b! b- U词典.jpg) j$ A% x% [) q+ a3 @
词典.jpeg
9 k. Y0 c) e$ \$ N词典.bmp
! l& X( I! N: ]! L7 }* w```" O; Q! y7 f2 c/ K6 u

; D, Z+ Q7 ~8 h' s程序会自动找到并转换为:
; F; r  S9 G! o4 T8 y  U3 p! h  O9 T2 ~+ g
```text/ ?, v' p) r! f
词典.bmp
% t- D4 `+ I; U  V```
3 {! i4 N' |6 T7 K0 S# {) {
7 N1 k9 I0 F" {* y& ?3 s尺寸:$ [! |9 J+ u/ `: J9 |0 r" a% y

$ ^# _" \+ N$ j7 R& j) X```text% s" f9 [- [, u4 Z+ |
48 × 64
  Z. c' ~- \$ a# P& h* w0 u/ J! Q```
1 r6 W3 f# H( {* k; |
' k6 A  P  n* _+ R8 A: }用于 GoldenDict 词典图标。3 T* f% M+ \% c4 `) g

! f. ~2 n" O8 k$ T$ Q$ ]& M图片会保持原始宽高比缩放,并居中到 48×64 画布,避免直接拉伸变形。8 R; M" @  R7 c" Y2 \7 {2 X
6 ^& U0 m2 T' e: X
图像转换需要:' {6 l( T; X! R- [9 x

6 B. g& R/ I7 S- f( M1 E2 |```text
7 D% O% a, x* c5 U) l6 N+ dPillow# e: q' q! J+ t& a) R
```
2 g: q* }6 @6 e9 G3 J6 f- a
! _* b. E: |+ Z3 U* {, B可以安装:
+ [/ F) T% R3 m9 n) \# |
+ D0 L3 K! d7 _```bat9 l: i4 D) K! P' j, Y' X/ D
python -m pip install Pillow8 |3 Y3 ?+ F. \9 Y- C
```: ~3 b6 ?# L" {7 V& T
; _7 b* [0 \1 o& F
---, B% z( l- b# ^' b% o
4 z$ x9 {$ K( p+ B* l/ _
## 七、最终 Tabfile 会保留下来
5 \( `5 l" v( P+ ^3 K  `* v- Z# e: }) A; l$ K3 _; A' ^- Y+ p: Q& K
程序完成各种:
* o) s% r8 p/ S: r: ~8 P# k1 K4 ?, u1 {
```text
/ x$ W7 B, D" j" J; jentry://
; o* X, n+ Q, V/ ~9 Z" n图片路径
5 H+ i8 l2 L5 m, r5 V8 n- S' q: qCSS路径2 J+ |9 G; w$ w4 u1 o
JS路径6 N1 u- r5 R1 l: n  P/ z
字体路径! u3 {- F) M% y4 E
其它资源路径6 Y1 b9 v6 |( y) v
```* k. r0 a* Q1 i. j/ C) J) W& a
  I) V' a" t9 z  Q& R
替换以后,会保留:0 g1 \+ y/ v/ x8 Y; H7 S. q+ H
/ H/ S( J. I; U
```text
& C( H  \1 q+ ~" H4 ~) n9 C词典名.android.txt' M. l% Q$ o$ @$ l' H6 k
```
8 F8 ~1 W% n( C3 H5 ?  M3 ^
! w# h6 Z6 r# L- H这是最终送入 StarDict 转换前的 Tabfile。
6 h2 j: a1 f$ i2 U" m' i* o9 v( R8 y/ i
因此,如果转换完成后还想手工修改正文,可以直接编辑这个文件。
5 s( p8 K7 Y& X$ b# B" @) a
3 p* O6 G. s; Q同时程序会生成:
: |: h& }3 G# i6 n% m5 _5 h) V( W1 m0 D' u
```text
, e' S2 D  y( N5 i$ m; b) D1 p' xmakestardict.bat8 l1 Y- w8 ~' H1 Z5 O- p: c
_makestardict.py
' a: T- y/ `! [' m# N9 j```/ Z* V2 U/ E1 A8 l0 o
& N- }3 H4 |+ J
修改完:
) q8 ~" {$ E* {; Z0 H# \
4 v/ f4 H$ h% [, m' N$ ````text) I: C3 w- ~2 O
词典名.android.txt
: j, C2 e. y9 f8 A```9 I% g# o" \7 q& B
3 r; `' q8 ~: E% [9 |2 h! b4 \
以后直接双击:2 t: o5 L  Q6 c
3 `" x! n# q( A& C
```text& L8 w3 a* i- |7 R
makestardict.bat
+ L5 }$ S/ w, i# M```; A6 d: B9 T( q! w' H
" B" M  o* o+ m5 T9 W: ]. b
即可重新生成 StarDict,不需要重新跑 MDX/MDD 解包和资源转换过程。3 x1 D: G. I8 \' Y: Y
( f. F- S, _/ v+ F" t* n
重新生成时同样会保持:2 t, p2 v- T$ N% i8 s  p4 b- W
7 m' S) A3 c5 b! Y% q% r
```text
3 U& R7 C7 b; Y2 f% b- P词典名.en-zh.*
0 }  {' O3 Z! ~$ l1 R+ ````
8 x  r" G1 K( r4 S- d  h3 x5 ]! ~# Q, N" K* J
这样的语言标记。
+ p3 t' N$ J0 y; Q. K5 D. ^( l' d2 Z6 P0 q1 ~' t" d+ K
---
6 D; }8 G' F7 b! q3 Y1 B- r: [
) v" m8 J. Z! ]6 ~" ?## 八、StarDict 的 `.dict` 与 `.dict.dz`
& _8 U; {9 n* L* I4 L: g
& W$ c* @( j- X$ `, r3 Q配置:
$ r: T5 B% l4 B' T/ o/ N% N" H7 m8 T7 \7 e  d4 Y6 ]$ O. l5 X+ r# N
```text3 c  ?1 u% f5 \& O! X( P1 @# w
stardict_dictzip = true
5 h1 W: ^& E1 |% x5 e% v$ v```$ x, F: o5 {1 }5 `! W# B* u
2 o9 G1 S, G" d# C: ?7 f" N  K. ]
会同时保留:* N- h# i1 f: v: o# g3 X" h

' q+ f  U8 u( U* W7 Q```text! R5 B% z, k6 e  j3 u" S( L& u
词典名.en-zh.dict, l2 o" o. c6 E" n: P, m
词典名.en-zh.dict.dz
4 ]& S/ t1 S: `! z```
& C5 K7 T7 K, y# o8 X: f: ~; u) m) G
如果:
. K" u- q3 J0 q+ t- Z9 ~, @  J1 g% V
```text
; U( c- {# q" g: b) Estardict_dictzip = false
- z' f# |6 D3 O```
! H8 R+ o: s2 c) \: q- j1 X" \2 b. v
- ~* B, d8 \+ n' U6 f则只生成:
' B6 T, V2 Q8 L& r! q( l! N: Q* d& V6 K+ B6 m9 P
```text/ U) [; r' J! Y( u6 @; W# O
词典名.en-zh.dict
1 o3 T7 q& w* k# _, H1 F8 T```$ V! V! R3 }: M; [+ _
9 M% g9 v! }' ^0 z
生成 `.dict.dz` 需要:" E9 N7 _2 Q7 R$ X1 ]! u

  l9 F: j' I4 N```bat
2 I" q1 Q, ~$ o% z6 |python -m pip install python-idzip
3 N( u2 h9 h5 Y5 q```
; J2 F3 L$ y9 w6 z& c& e' ~
; e0 r4 q0 D9 d+ N; V' H, d6 x---
4 N0 {2 [, }' w, F+ K- {  Z
, j, I0 P5 z. ~7 k+ F; l+ U# J8 B7 j## 九、配置文件尽量简化
0 l8 t: s) q% a6 o7 _8 P" N
1 V" J% g% b( j2 y, Y- y7 |2 {目前 `config.txt` 采用普通文本:
4 N: X$ J/ g9 @6 ?/ T9 Z6 G; H4 \" R/ J6 r5 V+ ^7 z( J$ q* \
```text
2 k& Y7 b& ~* c. J) M! Q% skey = value! q' p& |2 G3 t8 i) K! W9 c# w
```4 `) J* Q; {9 G! y$ Z) T
/ H" I% V( H, d3 P
不使用 JSON,方便直接打开修改。
( _% ^( O' E! c$ ?  z5 G! @: @3 ^; j- r
最基本可以只写:, |% C" g) F+ ~

* y/ O8 k, l# P" @6 T/ V% Q2 T```text
2 j0 U( ~- K8 A+ \7 qsource_file = ./词典.mdx: l; N1 i7 B6 V2 `+ ?& c2 `9 h, D+ a2 F- I
```
. X) J  Q) G6 u4 o6 U1 ]+ G" g. g0 n# e; S3 M9 [- F& m
推荐再填写:
4 c4 F1 E7 L  F& H5 Z0 S) _
. M. Y# i  w$ K3 u) ^0 }```text7 Z  U& B; ~( Y3 I$ _, E8 S
INDEX_LANGUAGE = eng
4 k1 r6 ~* X3 D0 p3 K* CCONTENTS_LANGUAGE = zho  n" W7 j4 h; o. w- h
```/ |9 R- S1 a% d5 z7 `  d2 e

/ \2 m( q/ h7 z3 N0 I- z其它项目一般都有默认值。: I- v" n' I1 E
' g7 G  j- [/ H+ t
一个常用示例:
( C3 i: Z2 |3 Z3 w. m, N8 b
7 B; J7 R; d: }9 S```text! b& N& R) {3 N  R! B3 u) r; @% M: E
source_file = ./外研社英汉多功能词典.mdx
2 D3 s/ x$ `# T& r4 S8 p% U0 S+ C* Uinput_type = auto
$ p+ g7 J: C; ]% v5 o2 P
5 H* |2 ]9 e$ n+ Q" ~INDEX_LANGUAGE = 英+ e3 k; [: m$ g/ O( h1 n
CONTENTS_LANGUAGE = 汉
7 }- |% [' F& I9 U2 R
- e4 I& A( l9 v, ~% @! Adictionary_name =9 q; y6 K* f: M
output_dir =* a) z! {) W- t/ o" ~- G
3 I5 d" ]! B0 ?5 x) L2 U8 a
device_goldendict_root = /storage/emulated/0/GoldenDict5 A! T3 F# V3 x! M7 F  x
install_dir =
0 `) t0 r3 x( S  t) H
6 F, N  E( e1 R4 Jcss_storage = zip
  L5 n) k1 z- i) Mresource_layout = original( J7 m, x0 a5 ~! z; t

; ]; m$ ~+ U4 y9 G2 m+ Qlocal_resource_dirs = .& R7 C4 t1 J, s) |4 c
local_resource_recursive = true
* E& T% O+ m4 W1 \' P2 m' S' B7 }# {+ z( B; G2 ^  Y% {1 s
rewrite_inside_resources = true8 J: P0 Q, V" b" r# Z* b# b" g

( Q* \7 ^# ?& R3 C! l8 @8 istardict_dictzip = true
! b- Y% h% V7 ^! G7 L7 `7 c  X( Lstardict_html = true/ O8 P, v( ~% k1 M& P6 q" g1 N
# X- K0 I  j! i. `' L
keep_raw_tabfile = false. _' c0 ?. V! z5 Z* g
```
* M+ l' U% P9 s7 c
, _. p. S' T* Y6 z" X0 `其中:
' L9 w* Z5 O" Z$ W& D
9 C6 K3 k0 {) |5 [& C+ i5 Q1 e```text8 j; T5 {! y7 P6 R( h! N' @
dictionary_name =2 L( S: o0 y. t2 A# O
output_dir =
& Z7 [4 L( z# m3 Q3 D, V```
9 M# Z4 p6 |! S8 O3 S* O! q" ~$ Q) u! l
留空时会自动根据输入文件名生成。- F5 s: k9 A. P& `9 G

/ q1 N# q7 Y8 O, G7 v4 v6 {8 w& L: [---
" x! u/ n- s, n2 j- E6 H' B
2 Q: H9 A4 k4 M1 E: F/ M+ d## 十、两种运行方式
! T2 T+ G) n% R( _
4 [( J) V. s) {% K### 方法 1:使用 config.txt
; O. ~. C/ \  W+ h0 _  q) g5 N4 D7 R" E% \+ P. A
```bat5 ?1 ~# [* C9 p& C+ N9 _
python mdxtogd.py
/ W8 h: U' _3 w5 |! O- l```
% F, z6 {- ]0 b) U* q9 J+ H% J  v: l% o9 q
程序默认读取当前目录的:: W) u6 D8 e7 p. J% j8 m

" L. c/ S5 G' S, M```text; A: R1 _3 F* O# j5 l, K5 \
config.txt
3 R8 G" }# ]5 ]+ X1 P0 Z0 p6 S# @```2 @0 V+ @7 n' Q4 X1 J4 f* u
9 M2 j, D' H8 p& \: T3 P6 U
---0 T- U; B5 ]3 w
- y+ t+ J- ^" U
### 方法 2:直接指定输入和输出4 j2 _. S1 p. ^) P: J4 [0 F

- m( E+ H- D$ E2 I```bat
, }9 u0 U! u0 ~python mdxtogd.py xx/词典.mdx yy/新词典名称.ifo
4 I* k: t2 ], s4 F$ r```
0 ]8 k. ^3 `1 b, r, T: q' v
7 W" R( |9 p! BTabfile/Textfile 也可以:
: P" v3 _0 a! z5 d" r
3 w, r5 r2 E8 k- b9 v, O```bat0 W. o+ U5 A7 \
python mdxtogd.py dict.tab out/NewDict.ifo5 o* a# ~, b# Y; s# Z9 _! k
python mdxtogd.py dict.txt out/NewDict.ifo- C) R/ n7 a# _" X& C/ S; Z& i
```
; y. o. e9 x. r$ K% O
/ s, e! h9 ]: n如果语言是:
2 R, g  G  n5 R8 x; _# W
/ D6 F$ H- P' X. A% U4 c2 M```text2 b- ]& P9 O! }- S0 ^
eng → zho
4 i9 W- t- B  L```4 X( ?6 U9 V& l8 p! {+ k
1 v" \7 P$ }" b
最终 StarDict 会自动生成:
4 F9 ?) t( n4 D8 K/ l* \( z) A
% ^+ C6 R4 S+ n  S```text( [( p" g3 T& e) X
out/NewDict.en-zh.ifo
2 t/ i7 _9 y8 `8 Mout/NewDict.en-zh.idx
0 K4 o& J' N0 L8 \: E. yout/NewDict.en-zh.dict4 M( Z9 ~. }( x! \* ^6 h6 D
out/NewDict.en-zh.dict.dz
, m" a/ U9 s% R5 U" G% x```
# D' s5 E% ^5 |  g1 [! v  D4 n
2 L: R4 t0 F0 [9 _  r" x. g而 DSL 和图标仍然保持:, v  [( w9 l/ F' t3 C9 _, u8 s+ E
. `$ K) j/ {- Y
```text
( ]+ D) @$ ^; E, l/ {: J5 hNewDict.dsl
5 l9 Y) R, `  [( n( u! b! oNewDict.dsl.files.zip6 K4 e2 _- k+ i0 L/ Q7 |& g+ y
NewDict.bmp
3 X8 o" H* d/ }5 ^; A1 O( u; d```' Z0 g7 j* y8 ?: [8 |4 ?- t( W* n

# L! T% m+ n9 ]% z3 [---
4 B( O3 z5 A. \& l* E+ j$ }8 y
* d. y* `  c( J6 h( }9 f## 十一、主要依赖( H, a2 d9 \/ j, Y# g# h$ P
4 \* Z/ e+ c1 y
核心需要:
" v5 I: q) B7 E+ g6 V  P7 y
, V, s  M8 Y, T4 W/ n```text! z3 p: a$ G/ K) B! J5 P- g
Python
, ]0 }# ]6 y0 K: S! y, @$ x! }PyGlossary: F0 X) P) T3 s) ~) t
mdict-utils
' j/ e6 ^0 r) Z% A```
. a% e. ]- \( N4 a6 U" K$ C- \% w$ D/ H
建议同时安装:
& J  Q) h# [7 K3 I1 g* K  O
1 D/ s* R& h8 d```text# g2 I1 a' y( |. M' l4 ]; r4 N) X  I
Pillow
9 F5 M! D! P, |# S* N; {python-idzip' z: g" H2 j6 w9 y
```" _9 B" \/ p* v

- b3 p/ X0 \/ t& N' @  H5 i' I5 t例如:
9 ]. B" J2 w+ {  G- z, P2 V& Z' d' |
+ \* J' X/ s9 V7 w1 u```bat
; I- H: M0 Z" A; fpython -m pip install pyglossary mdict-utils Pillow python-idzip' A7 i: k4 Q2 ~+ E0 Z9 [* \+ }; n  s- S
```# o( O0 D8 E+ j6 a3 E) G0 }& g
& u4 G/ c5 Z0 F. c$ V
部分 PyGlossary 插件可能还会提示缺少 `lxml`,如果希望一起安装:
. ^; k) k- e! T; Q" e- H7 e8 n6 U) E/ n* [
```bat% E/ ~  S9 F& y1 J7 I! h
python -m pip install lxml
' @8 P2 D: O: P2 P& p$ Z. p```
& K+ e) E2 V, {" q( [+ J. {8 _9 Z; u% ~" A+ h7 e4 z
---
+ n  U; ^3 _; N+ S; K. X
( O* N( e3 a  n- |2 t  s* ~& ^## 十二、输出目录示例1 I2 T! s/ `) N% K5 z+ \& l* S
/ ]) L; v. l0 b5 A- `& f, y
例如:
) [' m% B1 j& ]/ d; c; f9 X! Z( s( f2 B" D% R
```text2 V. F/ p  }: F" V2 G
外研社英汉多功能词典/0 u- {& r- V" _' t3 `
```
) M7 i- c2 X9 K# Z* a( Y* e! H7 `% @$ F9 z" r
转换工作目录大致如下:: `6 c5 V# `5 i, s/ k

7 I7 X  O, V/ y& ]* p# _8 n: p```text% P! Y% ~" |, G. P4 U
外研社英汉多功能词典/4 k' d5 [* X( s6 ]8 g2 _, T
├─ 外研社英汉多功能词典/
- m% A! Y1 h; |3 Z9 b4 D│  ├─ 外研社英汉多功能词典.dsl. D: s1 y& f5 I0 f2 u5 H: _, z
│  ├─ 外研社英汉多功能词典.dsl.files.zip
% h5 B2 G" Y+ G( l9 Z  G: z│  ├─ 外研社英汉多功能词典.en-zh.ifo4 Y* X9 i! r: j2 M
│  ├─ 外研社英汉多功能词典.en-zh.idx
8 S6 ?8 k' b7 k" v│  ├─ 外研社英汉多功能词典.en-zh.dict
, L. m7 o% H7 E, k5 @  `8 `│  ├─ 外研社英汉多功能词典.en-zh.dict.dz; E0 o. I0 O, Z+ h! U
│  └─ 外研社英汉多功能词典.bmp" y, N6 z+ L% `7 G8 `
+ ]$ g8 H5 T* {' F. g6 }( U
├─ 外研社英汉多功能词典.android.txt: x1 v! E5 V1 e0 c2 N" N
├─ makestardict.bat
$ {5 u- B7 O0 U. I4 F4 A8 w├─ _makestardict.py
* Q6 N, [' W1 u; }9 Q$ \- ~" N├─ GoldenDict安装位置.txt; s% O4 T3 M1 C, h
└─ conversion_report.json
7 i- b( \1 q- h6 I7 B```' B$ \8 _/ i! N8 }8 z1 g
+ J/ d! }; ^5 s8 J
Android 端只需要复制内层正式词典目录中的文件。
6 V! z3 a8 {  }( n. Y
; |6 x' k  l& O. O- K---
( r' ?  q8 ]& Y! J6 q1 k9 \( \1 X# Q8 b$ K7 y/ }2 W0 D
## 十三、一些说明' q( Y' a8 v$ {" y$ J1 v
& S5 N. [% r3 j
这套脚本主要是按我自己在 Android GoldenDict 上实际使用词典的需求逐步整理出来的,因此重点不是做一个通用格式转换器,而是尽量把:% U$ R& z* f2 b# q; o

# m# w9 N# w. e  P7 s" T```text  Z3 q7 m6 ^/ I7 a8 w* M% Y9 R( g& R3 W
MDX/MDD- B4 h* l2 f2 R: d( ?* M2 ^

3 K) u0 p6 y. L3 M7 M6 }资源整理3 y" C8 ~7 N: I/ M0 j: A$ \5 ?% K

6 j) Q/ S/ ~( ?* ?Android GoldenDict DSL资源$ H5 {/ O% P  ~0 C3 E  w* M
2 g; i; t9 ^$ k; V/ w; v
StarDict! `  F5 P6 D) }1 _% J
8 ?) Y! m% {) G3 g. ?5 r4 ?
语言识别
4 K0 _+ k" k& g! P" Q) T4 @: w3 O! {( z/ a5 F
目录部署
1 v" B( g; \0 d) \( b7 v, f```, {7 S! N" V8 ?4 W8 ~+ G
+ `+ l* C5 x* S2 c  H. }" Q$ a+ y
这一整套过程自动化。/ e0 o  m8 a3 Q6 O3 w
! ]* r4 O/ F% V+ s
不同 MDX 的 HTML/CSS/JS 写法差异很大,因此不敢保证所有词典都能完全无修改直接转换。如果碰到特殊资源路径、特殊脚本、特殊 MDD 结构等问题,也欢迎反馈具体词典结构或报错信息,后续可以继续完善。% P" \" C7 T' `8 {9 c
) ], a3 G5 |& L8 [, a
建议第一次转换新词典后,重点检查:4 L3 Y' }9 ?/ j# K8 L
6 ]0 O& k$ |& Q6 J8 i3 [
```text
  O7 B) z$ r8 Vconversion_report.json2 `3 N8 v4 I' o7 Q
GoldenDict安装位置.txt
- D* |$ D3 M6 o) l5 e2 E% N+ A, ^, c词典名.android.txt/ M& V: G% c- E
```1 U) |! l$ k  }, Z$ B: S, c

; ]6 ~8 K8 B1 q5 P$ }1 l, m如果有:
+ Z" z0 L4 l& Z9 S- ^) W
1 v& W! q5 _5 Y; h```text# Z' Y& L: `# \2 _8 h7 M$ |
⚠️ 未解析本地资源! b4 i- e3 c* X3 B4 A' r: }  ]
```. Q# t3 s- S0 @3 \0 D

0 q* U0 e3 M  s4 m, q6 b4 L最好先确认对应资源到底是在 MDD、本地文件夹,还是原词典引用本身已经失效。
- N0 e) e" S4 \6 f9 L+ e
( ]# A! F$ ?  N4 x" v" k; K目前我自己主要用于 Android GoldenDict 的 MDX → StarDict + DSL resource 转换,欢迎大家测试、改进和反馈。0 z! Y  ^; d7 K0 y8 q
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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