示例#1
0
        /// <summary>
        /// Build automaton from word string
        /// </summary>
        /// <param name="word">Word string</param>
        /// <param name="keyboard">Keyboard</param>
        /// <returns>Automaton</returns>
        public virtual InputAutomaton ToAutomaton(string s, InputKeyboard keyboard)
        {
            // Start state
            InputAutomaton start   = new InputAutomaton();
            InputAutomaton current = start;
            string         c;

            for (int i = 0; i < s.Length; i++)
            {
                InputAutomaton next;

                // Get next input character (Hiragana, Alphabet, Number, Sign)
                c = s.Substring(i, 1);

                // Convert the input character to Katakana, Large alphabet, Hankaku.
                // In old version, As SJIS does not have Hiragana of "ヴ", we converted that to Katakana
                c = c.Hira2Kana();
                c = c.Zenkaku2Hankaku();

                next = new InputAutomaton();

                if (CreateAutomaton(current, c, next, InputCustomDefaultV1.Ope_NO_CUSTOM))
                {
                    current = next;
                }
            }

            return(start);
        }
        /// <summary>
        /// Build automaton from word string
        /// </summary>
        /// <param name="word">Word string</param>
        /// <param name="keyboard">Keyboard</param>
        /// <returns>Automaton</returns>
        public virtual InputAutomaton ToAutomaton(string s, InputKeyboard keyboard)
        {
            var plane = GetPlane(keyboard, "Default");

            // Start state
            InputAutomaton start   = new InputAutomaton();
            InputAutomaton current = start;
            string         c;

            // Make automaton
            for (int i = 0; i < s.Length; i++)
            {
                InputAutomaton next;

                // Get next input character
                c = s.Substring(i, 1);

                next    = new InputAutomaton();
                current = ProcessNormal(plane, s, current, ref c, ref i, next);

                current = next;
            }

            return(start);
        }
示例#3
0
        /// <summary>
        /// Build automaton from word string
        /// </summary>
        /// <param name="word">Word string</param>
        /// <param name="keyboard">Keyboard</param>
        /// <returns>Automaton</returns>
        public virtual InputAutomaton ToAutomaton(string s, InputKeyboard keyboard)
        {
            // Start state
            InputAutomaton start = new InputAutomaton();
            InputAutomaton current = start;
            string         c, c_conv;

            var s_conv = s.Kana2Hira();

            s_conv = s.Zenkaku2Hankaku(true, true);

            // Make automaton
            for (int i = 0; i < s.Length; i++)
            {
                InputAutomaton next;

                // Get next input character
                c      = s.Substring(i, 1);
                c_conv = s_conv.Substring(i, 1);

                // Use original
                next = new InputAutomaton();
                current.SetConnect(c_conv[0], new InputAutomaton.Connect()
                {
                    Automaton = next,
                    Flags     = InputCustomDefaultV1.Ope_NO_CUSTOM,
                    Character = c,
                });
                current = next;
            }

            return(start);
        }
        /// <summary>
        /// Process normal character
        /// </summary>
        /// <param name="plane">Plane</param>
        /// <param name="s">String</param>
        /// <param name="current">Current automaton</param>
        /// <param name="c">Char</param>
        /// <param name="index">Index</param>
        /// <param name="next">Next automaton</param>
        /// <returns></returns>
        internal InputAutomaton ProcessNormal(int plane, string s, InputAutomaton current, ref string c, ref int index, InputAutomaton next)
        {
            BitFlag custom = InputCustomDefaultV1.Ope_NO_CUSTOM;

            // Add automaton
            CreateAutomaton(plane, current, c, next, custom);

            return(current);
        }
示例#5
0
        /// <summary>
        /// Build string from automaton.
        /// </summary>
        /// <param name="root">Root state</param>
        /// <param name="current">Current State</param>
        /// <param name="inputCustom">Input custom (do not modify)</param>
        /// <param name="pos">Return current position</param>
        /// <param name="nextCharacter">Return next valid character.</param>
        /// <returns>If nextCharacter is -1, Return only next character, otherwise, return all the string.</returns>
        public virtual string FromAutomaton(InputAutomaton root, InputAutomaton current, IInputCustom custom, ref int pos, ref int nextCharacter)
        {
            var result = new StringBuilder();

            pos = 0;

            InputAutomaton automaton = root;

            while (!(automaton.IsAccept()))
            {
                bool found = false;
                KeyValuePair <int, InputAutomaton.Connect> select = new KeyValuePair <int, InputAutomaton.Connect>();
                foreach (var i in automaton.GetConnect())
                {
                    // Use first connection because no need to consider customization
                    int            c             = i.Key;
                    bool           valid         = false;
                    InputAutomaton automaton_tmp = automaton.Input(c, ref valid, null);
                    if (current == automaton_tmp)
                    {
                        select = i;
                        found  = true;
                    }
                }

                if (!found)
                {
                    // Found no route, use the first route
                    select = automaton.GetConnect().First();
                }

                int    c2        = select.Key;
                string addstring = select.Value.Character;

                // In CPU mode, use only first key
                if (nextCharacter != -1)
                {
                    nextCharacter = c2;
                    break;
                }

                // Go to next automaton
                bool valid2 = false;
                result.Append(addstring);
                automaton = automaton.Input(c2, ref valid2, null);
                if (current == automaton)
                {
                    pos = result.Length;
                }
            }

            return(result.ToString());
        }
        /// <summary>
        /// Build string from automaton.
        /// </summary>
        /// <param name="root">Root state</param>
        /// <param name="current">Current State</param>
        /// <param name="inputCustom">Input custom (do not modify)</param>
        /// <param name="pos">Return current position</param>
        /// <param name="nextCharacter">Return next valid character.</param>
        /// <returns>If nextCharacter is -1, Return only next character, otherwise, return all the string.</returns>
        public virtual string FromAutomaton(InputAutomaton root, InputAutomaton current, IInputCustom custom, ref int pos, ref int nextCharacter)
        {
            var result = new StringBuilder();

            pos = 0;

            InputAutomaton automaton = root;

            while (!(automaton.IsAccept()))
            {
                int    c         = '\0';
                string addstring = "";

                // If we have perfect input custom, use that
                foreach (var i in automaton.GetConnect())
                {
                    if (custom.IsSet(i.Value.Flags))
                    {
                        c         = i.Key;
                        addstring = i.Value.Character;
                        break;
                    }
                }

                if (c == '\0')
                {
                    // Found no route, use the first route
                    c         = automaton.GetConnect().First().Key;
                    addstring = automaton.GetConnect().First().Value.Character;
                }

                // In CPU mode, use only first key
                if (nextCharacter != -1)
                {
                    nextCharacter = c;
                    break;
                }

                // Go to next automaton
                bool valid = false;
                result.Append(addstring);
                automaton = automaton.Input(c, ref valid, null);
                if (current == automaton)
                {
                    pos = result.Length;
                }
            }

            return(result.ToString());
        }
示例#7
0
        /// <summary>
        /// Create new automaton
        /// </summary>
        /// <param name="current"></param>
        /// <param name="c"></param>
        /// <param name="next"></param>
        /// <param name="customAdd"></param>
        internal bool CreateAutomaton(InputAutomaton current, string c, InputAutomaton next, BitFlag customAdd)
        {
            // Previous automaton
            InputAutomaton prev = current;

            if (!_kanamap.ContainsKey(c))
            {
                // Input is not supported
                return(false);
            }

            var kanamap = _kanamap[c];

            if (VersionHelper.WTVersion == 404)
            {
                // There is a bug in the version 405
                // To be compatible with that, we add ぱ/ぴ/ぺ with Shift Handakuten
                if ((_imAuthor == "Denasu System") &&
                    (_imName == "JISかな") &&
                    (c == "パ" || c == "ピ" || c == "ペ"))
                {
                    kanamap = new List <KeyStroke>();
                    foreach (var j in _kanamap[c])
                    {
                        kanamap.Add(j);

                        if (j.Stroke.Count() == 2 &&
                            ((j.Stroke[0] & (int)WTKeyCode.Shift) != (int)WTKeyCode.Shift) &&
                            (j.Stroke[1] & (int)WTKeyCode.Shift) != (int)WTKeyCode.Shift)
                        {
                            kanamap.Add(new KeyStroke()
                            {
                                Custom = j.Custom,
                                Input  = j.Input,
                                Stroke = new int[2]
                                {
                                    j.Stroke[0] | (int)WTKeyCode.Shift,
                                    j.Stroke[1] | (int)WTKeyCode.Shift,
                                }
                            });
                        }
                    }
                }
            }

            foreach (var j in kanamap)
            {
                if (j.Stroke.Count() == 0)
                {
                    continue;
                }

                current = prev;

                // Create new automaton for each stroke
                for (var k = 0; k < j.Stroke.Count(); k++)
                {
                    if (j.Stroke[k] == (int)WTKeyCode.NoKey)
                    {
                        continue;
                    }

                    if (k + 1 == j.Stroke.Count())
                    {
                        // The last alphabet
                        InputAutomaton.Connect connect = new InputAutomaton.Connect()
                        {
                            Automaton = next,
                            Flags     = j.Custom.Or(customAdd),
                            Character = j.Input,
                        };
                        current.SetConnect(j.Stroke[k], connect);
                        current = next;
                    }
                    else
                    {
                        InputAutomaton.Connect connect = current.GetConnect(j.Stroke[k]);
                        if (connect == null)
                        {
                            // Create a automaton with Flags
                            connect = new InputAutomaton.Connect()
                            {
                                Automaton = new InputAutomaton(),
                                Flags     = j.Custom.Or(customAdd),
                                Character = "",
                            };
                            current.SetConnect(j.Stroke[k], connect);
                            current = connect.Automaton;
                        }
                        else
                        {
                            // To make it deterministic, use existing automaton
                            connect.Flags = connect.Flags.Or(j.Custom);

                            current = connect.Automaton;
                        }
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Create new automaton
        /// </summary>
        /// <param name="plane">Plane</param>
        /// <param name="current">Current Automaton</param>
        /// <param name="c">char</param>
        /// <param name="next">Next Automaton</param>
        /// <param name="customAdd">Custom to add</param>
        internal void CreateAutomaton(int plane, InputAutomaton current, string c, InputAutomaton next, BitFlag customAdd)
        {
            // Previous automaton
            InputAutomaton prev = current;

            if (!_strokemap[plane].ContainsKey(c))
            {
                // Input is not supported
                return;
            }

            // For all the stroke for c (e.g. "か"->ka, ca)
            foreach (var stroke in _strokemap[plane][c])
            {
                if (stroke.Stroke.Count() == 0)
                {
                    continue;
                }

                current = prev;

                // Create new automaton for each stroke
                for (var alphabet = 0; alphabet < stroke.Stroke.Count(); alphabet++)
                {
                    if (stroke.Stroke[alphabet] == (int)WTKeyCode.NoKey)
                    {
                        // Unknown
                        continue;
                    }

                    if (alphabet + 1 == stroke.Stroke.Count())
                    {
                        // The last alphabet
                        current.SetConnect(stroke.Stroke[alphabet], new InputAutomaton.Connect()
                        {
                            Automaton = next,
                            Flags     = stroke.Custom.Or(customAdd),
                            Character = stroke.Input.Substring(alphabet, 1),
                        });
                        current = next;
                    }
                    else
                    {
                        // Middle alphabet

                        InputAutomaton.Connect connect = current.GetConnect(stroke.Stroke[alphabet]);
                        if (connect == null)
                        {
                            // This automaton doesn't have the connection for this alphabet

                            // Create a new connection for this alphabet
                            connect = new InputAutomaton.Connect()
                            {
                                Automaton = new InputAutomaton(),
                                Flags     = stroke.Custom.Or(customAdd),
                                Character = stroke.Input.Substring(alphabet, 1),
                            };

                            // Connect
                            current.SetConnect(stroke.Stroke[alphabet], connect);
                            current = connect.Automaton;
                        }
                        else
                        {
                            // This automaton already have a connection for this alphabet

                            // To make it deterministic, use existing automaton
                            connect.Flags = connect.Flags.Or(stroke.Custom);

                            current = connect.Automaton;
                        }
                    }
                }
            }
        }