summaryrefslogtreecommitdiff
path: root/engine/python3/kana.py
blob: 10e1b968c9cf500c93e9c13924b2b8e6a904cc25 (plain)
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
# vim:set et sts=4 sw=4:
# -*- coding: utf-8 -*-
#
# ibus-anthy - The Anthy engine for IBus
#
# Copyright (c) 2007-2008 Peng Huang <shawn.p.huang@gmail.com>
# Copyright (c) 2010-2014 Takao Fujiwara <takao.fujiwara1@gmail.com>
# Copyright (c) 2007-2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import sys

from tables import *
import segment

_UNFINISHED_HIRAGANA = set('かきくけこさしすせそたちつてとはひふへほ')

class KanaSegment(segment.Segment):
    _prefs = None
    _kana_typing_rule_section = None
    _kana_voiced_consonant_rule = None

    def __init__(self, enchars='', jachars=''):
        if not jachars:
            jachars = self.__get_kana_typing_rule(enchars, '')
        super(KanaSegment, self).__init__(enchars, jachars)

    @classmethod
    def INIT_KANA_TYPING_RULE(cls, prefs):
        cls._prefs = prefs
        if prefs == None:
            cls._kana_typing_rule_section = None
            return
        if cls._kana_typing_rule_section == None:
            cls._init_kana_typing_method()
        if cls._kana_voiced_consonant_rule == None and \
           cls._kana_typing_rule_section != None:
            cls._init_kana_voiced_consonant_rule()

    @classmethod
    def _init_kana_typing_method(cls, method=None):
        prefs = cls._prefs
        if method == None:
            method = prefs.get_value('kana_typing_rule', 'method')
        if method == None:
            method = 'jp'
        cls._kana_typing_rule_section = 'kana_typing_rule/' + method
        if cls._kana_typing_rule_section not in prefs.sections():
            cls._kana_typing_rule_section = None

    @classmethod
    def _init_kana_voiced_consonant_rule(cls):
        prefs = cls._prefs
        # Create kana_voiced_consonant_rule dynamically.
        # E.g. 't' + '@' on jp kbd becomes Hiragana GA
        # 't' + '[' on us kbd becomes Hiragana GA
        # If the customized table provides U+309b with other chars,
        # it needs to be detected dynamically.
        cls._kana_voiced_consonant_rule = {}
        section = cls._kana_typing_rule_section
        for gkey in prefs.keys(section):
            value = prefs.get_value(section, gkey)
            key = prefs.typing_from_config_key(gkey)
            if key == '':
                continue
            if value == chr(0x309b):
                for no_voiced, voiced in \
                        list(kana_voiced_consonant_no_rule.items()):
                    rule = no_voiced + key
                    cls._kana_voiced_consonant_rule[rule] = voiced
            if value == chr(0x309c):
                for no_voiced, voiced in \
                        list(kana_semi_voiced_consonant_no_rule.items()):
                    rule = no_voiced + key
                    cls._kana_voiced_consonant_rule[rule] = voiced

    @classmethod
    def RESET(cls, prefs, section, name, value):
        cls._prefs = prefs
        if section == 'kana_typing_rule' and name == 'method' and \
           value != None:
            cls._kana_typing_rule_section = None
            cls._kana_voiced_consonant_rule = None
            cls._init_kana_typing_method(value)
        elif section.startswith('kana_typing_rule/'):
            # Probably it's better to restart ibus by manual
            # instead of saving the emitted values from config.
            cls._kana_voiced_consonant_rule = None

    def __get_kana_typing_rule(self, enchars, retval=None):
        prefs = self._prefs
        value = None
        section = self._kana_typing_rule_section
        if section != None:
            # Need to send Unicode to typing_to_config_key instead of UTF-8
            # not to separate U+A5
            gkey = prefs.typing_to_config_key(enchars)
            if gkey == '':
                return None
            enchars = gkey
            if enchars in prefs.keys(section):
                value = prefs.str(prefs.str(prefs.get_value(section, enchars)))
            else:
                prefs.set_no_key_warning(True)
                value = prefs.get_value_direct(section, enchars)
                prefs.set_no_key_warning(False)
                if value != None:
                    value = prefs.str(prefs.str(value))
            if value == '':
                value = None
            if value == None:
                value = retval 
        else:
            value = kana_typing_rule_static.get(enchars, retval)
        return value

    def is_finished(self):
        return not (self._jachars in _UNFINISHED_HIRAGANA)

    def append(self, enchar):
        if enchar == '\0' or enchar == '':
            return []
        if self._jachars:
            text = self._jachars + enchar
            if self._kana_voiced_consonant_rule != None:
                jachars = self._kana_voiced_consonant_rule.get(text, None)
            if jachars:
                self._enchars = self._enchars + enchar
                self._jachars = jachars
                return []
            return [KanaSegment(enchar)]
        self._enchars = self._enchars + enchar
        self._jachars = self.__get_kana_typing_rule(self._enchars, '')
        return []

    def prepend(self, enchar):
        if enchar == '\0' or enchar == '':
            return []
        if self._enchars == '':
            self._enchars = enchar
            self._jachars = self.__get_kana_typing_rule(self._enchars, '')
            return []
        return [KanaSegment(enchar)]

    def pop(self, index=-1):
        if index == -1:
            index = len(self._enchars) - 1
        if index < 0 or index >= len(self._enchars):
            raise IndexError('Out of bound')
        if self.is_finished():
            self._enchars = ''
            self._jachars = ''
        else:
            enchars = list(self._enchars)
            del enchars[index]
            self._enchars = ''.join(enchars)
            self._jachars = self.__get_kana_typing_rule(self._enchars, '')