Пример #1
0
        static List <TextElement> ParseCommand(string text)
        {
            var elems   = new List <TextElement>();
            var element = new TextElement
            {
                Speed = 1
            };
            var state   = ParseState.PlainText;
            var cmdName = new StringBuilder();
            var cmdArgs = new StringBuilder();

            for (int i = 0; i < text.Length; i++)
            {
                var c  = text[i];
                var nc = i < text.Length - 1 ? text[i + 1] : default(char);
                switch (state)
                {
                case ParseState.PlainText:
                    // コマンドはじまりか?
                    if (c == '$')
                    {
                        // エスケープか?
                        if (nc == '$')
                        {
                            // そのまま出力して1個飛ばす
                            i++;
                        }
                        else
                        {
                            // コマンドをはじめる
                            state = ParseState.Name;
                            cmdName.Clear();
                            cmdArgs.Clear();
                            continue;
                        }
                    }
                    element.Text = c.ToString();

                    elems.Add(element);
                    element.Nod      = false;
                    element.WaitTime = 0;
                    break;

                case ParseState.Name:
                    if (c == '=')
                    {
                        // 引数開始
                        state = ParseState.Argument;
                        continue;
                    }

                    if (c == ';')
                    {
                        // コマンド終了
                        state = ParseState.PlainText;
                        DoCommand(ref elems, ref element, cmdName.ToString(), cmdArgs.ToString());
                        continue;
                    }

                    cmdName.Append(c);
                    break;

                case ParseState.Argument:
                    if (c == ';')
                    {
                        // コマンド終了
                        state = ParseState.PlainText;
                        DoCommand(ref elems, ref element, cmdName.ToString(), cmdArgs.ToString());
                        continue;
                    }

                    cmdArgs.Append(c);
                    break;

                default:
                    throw new InvalidOperationException("Invalid parse state");
                }
            }

            return(elems);
        }
Пример #2
0
        static void DoCommand(ref List <TextElement> list, ref TextElement elem, string name, string args)
        {
            switch (name.ToLower())
            {
            case "b":
            case "bold":
                elem.Bold = true;
                break;

            case "i":
            case "italic":
                elem.Italic = true;
                break;

            case "c":
            case "col":
            case "color":
                elem.Color = args;
                break;

            case "v":
            case "voice":
                elem.Voice = args;
                break;

            case "!b":
            case "!bold":
                elem.Bold = false;
                break;

            case "!i":
            case "!italic":
                elem.Italic = false;
                break;

            case "!c":
            case "!col":
            case "!color":
                elem.Color = null;
                break;

            case "!sz":
            case "!size":
                elem.Size = 0;
                break;

            case "!spd":
            case "!speed":
                elem.Speed = 1;
                break;

            case "sz":
            case "size":
                int size;
                if (!int.TryParse(args.Trim(), out size))
                {
                    throw new FormatException("サイズには整数値のみ指定できます");
                }

                elem.Size = size;
                break;

            case "r":
            case "rest":
                elem.Bold     = false;
                elem.Italic   = false;
                elem.Color    = null;
                elem.Nod      = false;
                elem.Speed    = 1;
                elem.WaitTime = 0;
                elem.Size     = 0;
                elem.Voice    = null;
                break;

            case "w":
            case "wait":
                float wait;
                if (!float.TryParse(args.Trim(), out wait))
                {
                    throw new FormatException("待機時間には実数値のみ指定できます");
                }

                elem.WaitTime = wait;
                break;

            case "nod":
                elem.Nod = true;
                break;

            case "spd":
            case "speed":
                float spd;
                if (!float.TryParse(args.Trim(), out spd))
                {
                    throw new FormatException("文字送り速度には実数値のみ指定できます");
                }

                elem.Speed = spd;
                break;

            case "var":
            case "variable":
                foreach (var c in GetVariable(args))
                {
                    elem.Text = c.ToString();
                    list.Add(elem);
                    elem.Nod      = false;
                    elem.WaitTime = 0;
                }
                break;

            default:
                var raw = new StringBuilder().Append('$').Append(name);
                if (!string.IsNullOrEmpty(args))
                {
                    raw.Append('=').Append(args);
                }
                raw.Append(';');
                foreach (var c in raw.ToString())
                {
                    elem.Text = c.ToString();
                    list.Add(elem);
                    elem.Nod      = false;
                    elem.WaitTime = 0;
                }
                break;
            }
        }