-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy pathkanji_stroke_color.py
206 lines (167 loc) · 6.54 KB
/
kanji_stroke_color.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# -*- coding: utf-8 ; mode: Python -*-
# © 2012 Roland Sieker <[email protected]>
#
# Provenance: This file started out as files written by Damien Elmes
# <[email protected]>, and Cayenne Boyer. I think there isn't much of
# their code left, but anyway.
#
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
"""
Show colored stroke order diagrams.
Add-on for Anki2 to show colored stroke order diagrams for kanji. The
diagrams have to be provided as svg is the right directories.
"""
# Usually Python comes with 'batteries included', that is, with the
# Python standard library. Unfortunately, this is not the case for a
# typical Anki install. So bring along some files that are
# missing. Make sure we find them.
from aqt import mw # We need this early to get to the path
# These *are* available with standard Anki
import os
import re
import sys
# The rest of the anki componets.
from anki import hooks
# Add the path, but only once. (Other add-ons by YT contain
# similar code.)
if not [pe for pe in sys.path if 'batteries' in pe]:
sys.path.append(os.path.join(mw.pm.addonFolder(), "batteries"))
# Now this should work. Include module to search for file names.
import glob
__version__ = '2.1.0'
kanji_size = 200
"""The size the svg is scaled to"""
rest_size = 120
"""Size used for the other variants."""
kanji_directory = 'stroke-order-kanji'
"""Where the kanji are stored.
Where the kanji svgs are stored in the add-ons folder, before they are
copied to the media folder.
"""
variant_display_names = {
'': 'title="Standard"', 'Jinmei': 'title="Jinmei"',
'Kaisho': 'title="Kaisho"'}
"""Mapping file name variants to display variants."""
def ascii_basename(c, var=''):
u"""
An SVG filename in ASCII using the same format KanjiVG uses.
May raise TypeError for some kinds of invalid
character/variant combinations
"""
code = '%05x' % ord(c)
# except TypeError: # character not a character
if not var:
return code + u'.svg'
else:
return u'{0}-{1}.svg'.format(code, var)
def character_basename(c, var=''):
u"""
An SVG filename that uses the unicode character
There are two exceptions:
* non-alphanumeric characters use the ascii_filename
* lower-case letters get an extra underscore at the end.
to avoid some (potential) file system problems.
"""
if not c.isalnum():
return ascii_basename(c, var)
if c.islower():
# This should trigger only for romaji, for kanji isupper()
# and islower() are both False.
c = c + u'_'
if not var:
return u'{0}.svg'.format(c)
else:
return u'{0}-{1}.svg'.format(c, var)
# I don't know how to do a lamba with the *args. So unroll the four.
def kanji_svg_jinmei(txt, *args):
u"""
Display the text as colored stroke order diagram.
Display the text as colored stroke order svg diagram. This version
uses the Jinmei (人名 or name, i guess) variant, if available.
"""
return kanji_svg_var(txt, variant='Jinmei')
def kanji_svg_kaisho(txt, *args):
u"""
Display the text as colored stroke order diagram.
Display the text as colored stroke order svg diagram. This version
uses the Kaisho (楷書 or square style) variant, if available.
"""
return kanji_svg_var(txt, variant='Kaisho')
def kanji_svg_kyoukasho(txt, *args):
u"""
Display the text as colored stroke order diagram.
Display the text as colored stroke order svg diagram. This version
uses the standard version, which is, as far as i know, schoolbook
or 教科書/kyoukasho style.
"""
return kanji_svg_var(txt)
def kanji_svg_rest(txt, *args):
"""
Display the text as colored stroke order diagrams.
Display the text as colored stroke order svg diagrams. This
version shows all the diagrams that are not the standard, in a
smaller size, wraped in a div, or nothing if there is only one
variant.
"""
return kanji_svg_var(txt, show_rest=True)
def kanji_svg_var(txt, variant='', show_rest=False):
"""
Replace kanji with SVG
For each character in txt, check if there is an svg to
display and replace txt with this svg image.
"""
rtxt = u''
size = kanji_size
if show_rest:
size = rest_size
for c in txt:
# Try to get the variant
fn_title_list = get_file_names_titles(c, variant, show_rest)
for fname, title_attr in fn_title_list:
rtxt += u'''<embed width="{size}" height="{size}" \
{title} src="{fname}" />''' .format(
fname=fname, size=size, title=title_attr)
# (The title_attr brings along the title="', the others
# parameters don't)
if not fn_title_list and not show_rest:
rtxt += c
if show_rest and rtxt:
rtxt = u'<div class="strokevariants">' + rtxt + u'</div>'
return rtxt
def get_file_names_titles(c, variant, show_rest):
""" Return the file names of the svgs we should show. """
name_title_list = []
if not show_rest:
fname = os.path.join(mw.addonManager.addonsFolder(),
kanji_directory, character_basename(c, variant))
if variant and not os.path.exists(fname):
# Maybe we can save this by using the standard version.
fname = os.path.join(mw.addonManager.addonsFolder(),
kanji_directory, character_basename(c))
if os.path.exists(fname):
try:
title = variant_display_names[variant]
except KeyError:
title = ''
name_title_list.append((fname, title))
else:
# The true show-all style, show stroke order variants.
# (We cheat a bit, this can't work for upper-case romaji
# letters and for non-alphanumeric characters. There aren't
# any variants for those, so no harm, no foul.)
for fname in glob.glob(os.path.join(
mw.addonManager.addonsFolder(),
kanji_directory, c + u'-*.svg')):
try:
title = re.search(
u'/{0}-([^/]+).svg$'.format(re.escape(c)), fname).group(1)
except AttributeError:
# Shouldn't happen. We just got the names that match
# this pattern.
title = ''
name_title_list.append((fname, title))
return name_title_list
hooks.addHook('fmod_kanjiColor', kanji_svg_kyoukasho)
hooks.addHook('fmod_kanjiColorJinmei', kanji_svg_jinmei)
hooks.addHook('fmod_kanjiColorKaisho', kanji_svg_kaisho)
hooks.addHook('fmod_kanjiColorRest', kanji_svg_rest)