1
# -*- coding: utf-8 -*-
2
# Copyright: Damien Elmes <anki@ichi2.net>
3
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
6
from subprocess import Popen, PIPE
7
from anki.utils import findTag, stripHTML
8
from anki.hooks import addHook
11
srcField = "Expression"
14
class KakasiController(object):
16
# add our pre-packaged kakasi to the path
17
if sys.platform == "win32":
18
dir = os.path.dirname(sys.argv[0])
19
os.environ['PATH'] += ";" + dir + "\\kakasi\\bin"
20
shareDir = dir + "\\kakasi\\share\\kakasi\\"
21
os.environ['ITAIJIDICT'] = shareDir + "\\itaijidict"
22
os.environ['KANWADICT'] = shareDir + "\\kanwadict"
23
elif sys.platform.startswith("darwin"):
24
dir = os.path.dirname(os.path.abspath(__file__))
25
dir = os.path.abspath(dir + "/../../../../..")
27
# don't add kakasi to the path on powerpc, it's buggy
28
# and loop until this works, since processor() is buggy
31
proc = platform.processor()
37
os.environ['PATH'] += ":" + dir + "/kakasi"
38
os.environ['ITAIJIDICT'] = dir + "/kakasi/itaijidict"
39
os.environ['KANWADICT'] = dir + "/kakasi/kanwadict"
42
# we don't launch kakasi until it's actually required
45
if not self.available():
46
from errno import ENOENT
47
raise OSError(ENOENT, 'Kakasi not available')
48
# don't convert kana to hiragana
49
p = Popen("kakasi -isjis -osjis -u -JH -p", shell=True,
50
bufsize=-1, stdin=PIPE, stdout=PIPE)
51
(self.kin, self.kout) = (p.stdin, p.stdout)
59
def toFurigana(self, kanji):
61
kanji = self.formatForKakasi(kanji)
63
self.kin.write(kanji.encode("sjis", "ignore")+'\n')
65
return unicode(self.kout.readline().rstrip('\n'), "sjis")
69
def formatForKakasi(self, text):
70
"Strip characters kakasi can't handle."
71
# kakasi is line based
72
text = text.replace("\n", " ")
73
text = text.replace(u'\uff5e', "~")
74
text = text.replace("<br>", "---newline---")
75
text = text.replace("<br />", "---newline---")
76
text = stripHTML(text)
77
text = text.replace("---newline---", "<br>")
81
if sys.platform in ("win32",):
82
executable = 'kakasi.exe'
85
for d in os.environ['PATH'].split(os.pathsep):
86
if os.path.exists(os.path.join(d, executable)):
91
##########################################################################
93
kakasi = KakasiController()
94
if not kakasi.available():
97
def onFocusLost(fact, field):
100
if field.name != srcField:
102
if not findTag(modelTag, fact.model.tags):
109
tmp = kakasi.toFurigana(field.value)
110
if tmp != field.value:
113
addHook('fact.focusLost', onFocusLost)