public void PrintShape(string type, int[] param) { ConsoleShapePart part = ConsoleShapePart.CreateShape(type, param, userStyle.Color, userStyle.ButtonColor, false); printBuffer.Append(part); }
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 + "\"のタグ解析中にエラーが発生しました"); }