예제 #1
0
        public void PrintShape(string type, int[] param)
        {
            ConsoleShapePart part = ConsoleShapePart.CreateShape(type, param, userStyle.Color, userStyle.ButtonColor, false);

            printBuffer.Append(part);
        }
예제 #2
0
        private static AConsoleDisplayPart tagAnalyze(HtmlAnalzeState state, StringStream st)
        {
            bool   endTag = (st.Current == '/');
            string tag;

            if (endTag)
            {
                st.ShiftNext();
                int found = st.Find('>');
                if (found < 0)
                {
                    st.CurrentPosition = st.RowString.Length;
                    return(null);                   //戻り先でエラーを出す
                }
                tag = st.Substring(st.CurrentPosition, found).Trim();
                st.CurrentPosition += found;
                FontStyle endStyle = FontStyle.Strikeout;
                switch (tag.ToLower())
                {
                case "b": endStyle = FontStyle.Bold; goto case "s";

                case "i": endStyle = FontStyle.Italic; goto case "s";

                case "u": endStyle = FontStyle.Underline; goto case "s";

                case "s":
                    if ((state.FontStyle & endStyle) == FontStyle.Regular)
                    {
                        throw new CodeEE("</" + tag + ">の前に<" + tag + ">がありません");
                    }
                    state.FontStyle ^= endStyle;
                    return(null);

                case "p":
                    if ((!state.FlagP) || (state.FlagPClosed))
                    {
                        throw new CodeEE("</p>の前に<p>がありません");
                    }
                    state.FlagPClosed = true;
                    return(null);

                case "nobr":
                    if ((!state.FlagNobr) || (state.FlagNobrClosed))
                    {
                        throw new CodeEE("</nobr>の前に<nobr>がありません");
                    }
                    state.FlagNobrClosed = true;
                    return(null);

                case "font":
                    if (state.FonttagList.Count == 0)
                    {
                        throw new CodeEE("</font>の前に<font>がありません");
                    }
                    state.FonttagList.RemoveAt(state.FonttagList.Count - 1);
                    return(null);

                case "button":
                    if (state.CurrentButtonTag == null || !state.CurrentButtonTag.IsButtonTag)
                    {
                        throw new CodeEE("</button>の前に<button>がありません");
                    }
                    state.CurrentButtonTag = null;
                    state.FlagButton       = true;
                    return(null);

                case "nonbutton":
                    if (state.CurrentButtonTag == null || state.CurrentButtonTag.IsButtonTag)
                    {
                        throw new CodeEE("</nonbutton>の前に<nonbutton>がありません");
                    }
                    state.CurrentButtonTag = null;
                    state.FlagButton       = true;
                    return(null);

                default:
                    throw new CodeEE("終了タグ</" + tag + ">は解釈できません");
                }
                //goto error;
            }
            //以降は開始タグ

            bool           tempUseMacro = LexicalAnalyzer.UseMacro;
            WordCollection wc           = null;

            try
            {
                LexicalAnalyzer.UseMacro = false;                //一時的にマクロ展開をやめる
                tag = LexicalAnalyzer.ReadSingleIdentifier(st);
                LexicalAnalyzer.SkipWhiteSpace(st);
                if (st.Current != '>')
                {
                    wc = LexicalAnalyzer.Analyse(st, LexEndWith.GreaterThan, LexAnalyzeFlag.AllowAssignment | LexAnalyzeFlag.AllowSingleQuotationStr);
                }
            }
            finally
            {
                LexicalAnalyzer.UseMacro = tempUseMacro;
            }
            if (string.IsNullOrEmpty(tag))
            {
                goto error;
            }
            IdentifierWord word;
            FontStyle      newStyle = FontStyle.Strikeout;

            switch (tag.ToLower())
            {
            case "b": newStyle = FontStyle.Bold; goto case "s";

            case "i": newStyle = FontStyle.Italic; goto case "s";

            case "u": newStyle = FontStyle.Underline; goto case "s";

            case "s":
                if (wc != null)
                {
                    throw new CodeEE("<" + tag + ">タグにに属性が設定されています");
                }
                if ((state.FontStyle & newStyle) != FontStyle.Regular)
                {
                    throw new CodeEE("<" + tag + ">が二重に使われています");
                }
                state.FontStyle |= newStyle;
                return(null);

            case "br":
                if (wc != null)
                {
                    throw new CodeEE("<" + tag + ">タグにに属性が設定されています");
                }
                state.FlagBr = true;
                return(null);

            case "nobr":
                if (wc != null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されています");
                }
                if (!state.LineHead)
                {
                    throw new CodeEE("<nobr>が行頭以外で使われています");
                }
                if (state.FlagNobr)
                {
                    throw new CodeEE("<nobr>が2度以上使われています");
                }
                state.FlagNobr = true;
                return(null);

            case "p":
            {
                if (wc == null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                }
                if (!state.LineHead)
                {
                    throw new CodeEE("<p>が行頭以外で使われています");
                }
                if (state.FlagNobr)
                {
                    throw new CodeEE("<p>が2度以上使われています");
                }
                word = wc.Current as IdentifierWord;
                wc.ShiftNext();
                OperatorWord op = wc.Current as OperatorWord;
                wc.ShiftNext();
                LiteralStringWord attr = wc.Current as LiteralStringWord;
                wc.ShiftNext();
                if (!wc.EOL || word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                {
                    goto error;
                }
                if (!word.Code.Equals("align", StringComparison.OrdinalIgnoreCase))
                {
                    throw new CodeEE("<p>タグの属性名" + word.Code + "は解釈できません");
                }
                string attrValue = Unescape(attr.Str);
                switch (attrValue.ToLower())
                {
                case "left":
                    state.Alignment = DisplayLineAlignment.LEFT;
                    break;

                case "center":
                    state.Alignment = DisplayLineAlignment.CENTER;
                    break;

                case "right":
                    state.Alignment = DisplayLineAlignment.RIGHT;
                    break;

                default:
                    throw new CodeEE("属性値" + attr.Str + "は解釈できません");
                }
                state.FlagP = true;
                return(null);
            }

            case "img":
            {
                if (wc == null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                }
                string attrValue = null;
                string src       = null;
                string srcb      = null;
                int    height    = 0;
                int    width     = 0;
                int    ypos      = 0;
                while (wc != null && !wc.EOL)
                {
                    word = wc.Current as IdentifierWord;
                    wc.ShiftNext();
                    OperatorWord op = wc.Current as OperatorWord;
                    wc.ShiftNext();
                    LiteralStringWord attr = wc.Current as LiteralStringWord;
                    wc.ShiftNext();
                    if (word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                    {
                        goto error;
                    }
                    attrValue = Unescape(attr.Str);
                    if (word.Code.Equals("src", StringComparison.OrdinalIgnoreCase))
                    {
                        if (src != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        src = attrValue;
                    }
                    else if (word.Code.Equals("srcb", StringComparison.OrdinalIgnoreCase))
                    {
                        if (srcb != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        srcb = attrValue;
                    }
                    else if (word.Code.Equals("height", StringComparison.OrdinalIgnoreCase))
                    {
                        if (height != 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        if (!int.TryParse(attrValue, out height))
                        {
                            throw new CodeEE("<" + tag + ">タグのheight属性の属性値が数値として解釈できません");
                        }
                    }
                    else if (word.Code.Equals("width", StringComparison.OrdinalIgnoreCase))
                    {
                        if (width != 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        if (!int.TryParse(attrValue, out width))
                        {
                            throw new CodeEE("<" + tag + ">タグのwidth属性の属性値が数値として解釈できません");
                        }
                    }
                    else if (word.Code.Equals("ypos", StringComparison.OrdinalIgnoreCase))
                    {
                        if (ypos != 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        if (!int.TryParse(attrValue, out ypos))
                        {
                            throw new CodeEE("<" + tag + ">タグのypos属性の属性値が数値として解釈できません");
                        }
                    }
                    else
                    {
                        throw new CodeEE("<" + tag + ">タグの属性名" + word.Code + "は解釈できません");
                    }
                }
                if (src == null)
                {
                    throw new CodeEE("<" + tag + ">タグにsrc属性が設定されていません");
                }
                return(new ConsoleImagePart(src, srcb, height, width, ypos));
            }

            case "shape":
            {
                if (wc == null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                }
                int[]  param  = null;
                string type   = null;
                int    color  = -1;
                int    bcolor = -1;
                while (!wc.EOL)
                {
                    word = wc.Current as IdentifierWord;
                    wc.ShiftNext();
                    OperatorWord op = wc.Current as OperatorWord;
                    wc.ShiftNext();
                    LiteralStringWord attr = wc.Current as LiteralStringWord;
                    wc.ShiftNext();
                    if (word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                    {
                        goto error;
                    }
                    string attrValue = Unescape(attr.Str);
                    switch (word.Code.ToLower())
                    {
                    case "color":
                        if (color >= 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        color = stringToColorInt32(attrValue);
                        break;

                    case "bcolor":
                        if (bcolor >= 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        bcolor = stringToColorInt32(attrValue);
                        break;

                    case "type":
                        if (type != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        type = attrValue;
                        break;

                    case "param":
                        if (param != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        {
                            string[] tokens = attrValue.Split(',');
                            param = new int[tokens.Length];
                            for (int i = 0; i < tokens.Length; i++)
                            {
                                if (!int.TryParse(tokens[i], out param[i]))
                                {
                                    throw new CodeEE("<" + tag + ">タグの" + word.Code + "属性の属性値が数値として解釈できません");
                                }
                            }
                            break;
                        }

                    default:
                        throw new CodeEE("<" + tag + ">タグの属性名" + word.Code + "は解釈できません");
                    }
                }
                if (param == null)
                {
                    throw new CodeEE("<" + tag + ">タグにparam属性が設定されていません");
                }
                if (type == null)
                {
                    throw new CodeEE("<" + tag + ">タグにtype属性が設定されていません");
                }
                Color c = Config.ForeColor;
                Color b = Config.FocusColor;
                if (color >= 0)
                {
                    c = Color.FromArgb(color >> 16, (color >> 8) & 0xFF, color & 0xFF);
                }
                if (bcolor >= 0)
                {
                    b = Color.FromArgb(bcolor >> 16, (bcolor >> 8) & 0xFF, bcolor & 0xFF);
                }
                return(ConsoleShapePart.CreateShape(type, param, c, b, color >= 0));
            }

            case "button":
            case "nonbutton":
            {
                if (state.CurrentButtonTag != null)
                {
                    throw new CodeEE("<button>又は<nonbutton>が入れ子にされています");
                }
                HtmlAnalzeStateButtonTag buttonTag = new HtmlAnalzeStateButtonTag();
                bool   isButton  = tag.ToLower() == "button";
                string attrValue = null;
                string value     = null;
                //if (wc == null)
                //	throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                while (wc != null && !wc.EOL)
                {
                    word = wc.Current as IdentifierWord;
                    wc.ShiftNext();
                    OperatorWord op = wc.Current as OperatorWord;
                    wc.ShiftNext();
                    LiteralStringWord attr = wc.Current as LiteralStringWord;
                    wc.ShiftNext();
                    if (word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                    {
                        goto error;
                    }
                    attrValue = Unescape(attr.Str);
                    if (word.Code.Equals("value", StringComparison.OrdinalIgnoreCase))
                    {
                        if (!isButton)
                        {
                            throw new CodeEE("<" + tag + ">タグにvalue属性が設定されています");
                        }
                        if (value != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        value = attrValue;
                    }
                    else if (word.Code.Equals("title", StringComparison.OrdinalIgnoreCase))
                    {
                        if (buttonTag.ButtonTitle != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        buttonTag.ButtonTitle = attrValue;
                    }
                    else if (word.Code.Equals("pos", StringComparison.OrdinalIgnoreCase))
                    {
                        //throw new NotImplCodeEE();
                        int pos = 0;
                        if (buttonTag.PointXisLocked)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        if (!int.TryParse(attrValue, out pos))
                        {
                            throw new CodeEE("<" + tag + ">タグのpos属性の属性値が数値として解釈できません");
                        }
                        buttonTag.PointX         = pos;
                        buttonTag.PointXisLocked = true;
                    }
                    else
                    {
                        throw new CodeEE("<" + tag + ">タグの属性名" + word.Code + "は解釈できません");
                    }
                }
                if (isButton)
                {
                    //if (value == null)
                    //	throw new CodeEE("<" + tag + ">タグにvalue属性が設定されていません");
                    int intValue = 0;
                    buttonTag.ButtonIsInteger = (int.TryParse(value, out intValue));
                    buttonTag.ButtonValueInt  = intValue;
                    buttonTag.ButtonValueStr  = value;
                }
                buttonTag.IsButton     = value != null;
                buttonTag.IsButtonTag  = isButton;
                state.CurrentButtonTag = buttonTag;
                state.FlagButton       = true;
                return(null);
            }

            case "font":
            {
                if (wc == null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                }
                HtmlAnalzeStateFontTag font = new HtmlAnalzeStateFontTag();
                while (!wc.EOL)
                {
                    word = wc.Current as IdentifierWord;
                    wc.ShiftNext();
                    OperatorWord op = wc.Current as OperatorWord;
                    wc.ShiftNext();
                    LiteralStringWord attr = wc.Current as LiteralStringWord;
                    wc.ShiftNext();
                    if (word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                    {
                        goto error;
                    }
                    string attrValue = Unescape(attr.Str);
                    switch (word.Code.ToLower())
                    {
                    case "color":
                        if (font.Color >= 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        font.Color = stringToColorInt32(attrValue);
                        break;

                    case "bcolor":
                        if (font.BColor >= 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        font.BColor = stringToColorInt32(attrValue);
                        break;

                    case "face":
                        if (font.FontName != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        font.FontName = attrValue;
                        break;

                    //case "pos":
                    //	{
                    //		//throw new NotImplCodeEE();
                    //		if (font.PointXisLocked)
                    //			throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                    //		int pos = 0;
                    //		if (!int.TryParse(attrValue, out pos))
                    //			throw new CodeEE("<font>タグのpos属性の属性値が数値として解釈できません");
                    //		font.PointX = pos;
                    //		font.PointXisLocked = true;
                    //		break;
                    //	}
                    default:
                        throw new CodeEE("<" + tag + ">タグの属性名" + word.Code + "は解釈できません");
                    }
                }
                //他のfontタグの内側であるなら未設定項目については外側のfontタグの設定を受け継ぐ(posは除く)
                if (state.FonttagList.Count > 0)
                {
                    HtmlAnalzeStateFontTag oldFont = state.FonttagList[state.FonttagList.Count - 1];
                    if (font.Color < 0)
                    {
                        font.Color = oldFont.Color;
                    }
                    if (font.BColor < 0)
                    {
                        font.BColor = oldFont.BColor;
                    }
                    if (font.FontName == null)
                    {
                        font.FontName = oldFont.FontName;
                    }
                }
                state.FonttagList.Add(font);
                return(null);
            }

            default:
                goto error;
            }


error:
            throw new CodeEE("html文字列\"" + st.RowString + "\"のタグ解析中にエラーが発生しました");
        }