Esempio n. 1
0
        /// <summary>
        /// htmlから表示行の作成
        /// </summary>
        /// <param name="str">htmlテキスト</param>
        /// <param name="sm"></param>
        /// <param name="console">実際の表示に使わないならnullにする</param>
        /// <returns></returns>
        public static ConsoleDisplayLine[] Html2DisplayLine(string str, StringMeasure sm, EmueraConsole console)
        {
            List <AConsoleDisplayPart> cssList    = new List <AConsoleDisplayPart>();
            List <ConsoleButtonString> buttonList = new List <ConsoleButtonString>();
            StringStream    st = new StringStream(str);
            int             found;
            bool            hasComment = str.IndexOf("<!--") >= 0;
            bool            hasReturn  = str.IndexOf('\n') >= 0;
            HtmlAnalzeState state      = new HtmlAnalzeState();

            while (!st.EOS)
            {
                found = st.Find('<');
                if (hasReturn)
                {
                    int rFound = st.Find('\n');
                    if (rFound >= 0 && (found > rFound || found < 0))
                    {
                        found = rFound;
                    }
                }
                if (found < 0)
                {
                    string txt = Unescape(st.Substring());
                    cssList.Add(new ConsoleStyledString(txt, state.GetSS()));
                    if (state.FlagPClosed)
                    {
                        throw new CodeEE("</p>の後にテキストがあります");
                    }
                    if (state.FlagNobrClosed)
                    {
                        throw new CodeEE("</nobr>の後にテキストがあります");
                    }
                    break;
                }
                else if (found > 0)
                {
                    string txt = Unescape(st.Substring(st.CurrentPosition, found));
                    cssList.Add(new ConsoleStyledString(txt, state.GetSS()));
                    state.LineHead      = false;
                    st.CurrentPosition += found;
                }
                //コメントタグのみ特別扱い
                if (hasComment && st.CurrentEqualTo("<!--"))
                {
                    st.CurrentPosition += 4;
                    found = st.Find("-->");
                    if (found < 0)
                    {
                        throw new CodeEE("コメンdト終了タグ\"-->\"がみつかりません");
                    }
                    st.CurrentPosition += found + 3;
                    continue;
                }
                if (hasReturn && st.Current == '\n')                //テキスト中の\nは<br>として扱う
                {
                    state.FlagBr = true;
                    st.ShiftNext();
                }
                else                //タグ解析
                {
                    st.ShiftNext();
                    AConsoleDisplayPart part = tagAnalyze(state, st);
                    if (st.Current != '>')
                    {
                        throw new CodeEE("タグ終端'>'が見つかりません");
                    }
                    if (part != null)
                    {
                        cssList.Add(part);
                    }
                    st.ShiftNext();
                }

                if (state.FlagBr)
                {
                    state.LastButtonTag = state.CurrentButtonTag;
                    if (cssList.Count > 0)
                    {
                        buttonList.Add(cssToButton(cssList, state, console));
                    }
                    buttonList.Add(null);
                }
                if (state.FlagButton && cssList.Count > 0)
                {
                    buttonList.Add(cssToButton(cssList, state, console));
                }
                state.FlagBr        = false;
                state.FlagButton    = false;
                state.LastButtonTag = state.CurrentButtonTag;
            }
            //</nobr></p>は省略許可
            if (state.CurrentButtonTag != null || state.FontStyle != FontStyle.Regular || state.FonttagList.Count > 0)
            {
                throw new CodeEE("閉じられていないタグがあります");
            }
            if (cssList.Count > 0)
            {
                buttonList.Add(cssToButton(cssList, state, console));
            }

            foreach (ConsoleButtonString button in buttonList)
            {
                if (button != null && button.PointXisLocked)
                {
                    if (!state.FlagNobr)
                    {
                        throw new CodeEE("<nobr>が設定されていない行ではpos属性は使用できません");
                    }
                    if (state.Alignment != DisplayLineAlignment.LEFT)
                    {
                        throw new CodeEE("alignがleftでない行ではpos属性は使用できません");
                    }
                    break;
                }
            }
            ConsoleDisplayLine[] ret = PrintStringBuffer.ButtonsToDisplayLines(buttonList, sm, state.FlagNobr, false);

            foreach (ConsoleDisplayLine dl in ret)
            {
                dl.SetAlignment(state.Alignment);
            }
            return(ret);
        }