예제 #1
0
        /// <summary>
        /// TMLをパースする
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public Document Parse(Stream stream, string filename = "")
        {
            filename_ = filename;
            var setting = new XmlReaderSettings
            {
                IgnoreComments   = true,
                IgnoreWhitespace = true,
                ConformanceLevel = ConformanceLevel.Fragment,
            };

            reader_ = XmlTextReader.Create(new StreamReader(stream), setting);
            var styleParser = new StyleParser();

            Document root = new Document();

            root.Tag = "document";
            root.SetClass("");
            Stack <Element> stack = new Stack <Element>();

            stack.Push(root);

            while (reader_.Read())
            {
                try {
                    switch (reader_.NodeType)
                    {
                    case XmlNodeType.Text:
                        var text = new Text()
                        {
                            Value = convertSpaces(reader_.Value)
                        };
                        text.Parent = stack.Peek();
                        text.Tag    = "text";
                        stack.Peek().Children.Add(text);
                        break;

                    case XmlNodeType.Element:
                        if (reader_.Name == "style")
                        {
                            reader_.Read();
                            if (reader_.NodeType != XmlNodeType.Text)
                            {
                                throw new InnerError("must be text");
                            }
                            styleParser.ParseStyleSheet(root.StyleSheet, reader_.Value);
                            reader_.Read();
                            if (reader_.NodeType != XmlNodeType.EndElement)
                            {
                                throw new InnerError("must be close tag");
                            }
                        }
                        else
                        {
                            ConstructorInfo constructor;
                            if (!TypeByTag.TryGetValue(reader_.Name, out constructor))
                            {
                                throw new InnerError("unknown tag name " + reader_.Name);
                            }
                            var element = (Element)constructor.Invoke(null);

                            stack.Peek().Children.Add(element);
                            element.Tag = reader_.Name;
                            element.SetClass("");
                            element.Parent = stack.Peek();
                            stack.Push(element);
                            element.Parse(this, reader_);

                            if (reader_.IsEmptyElement)
                            {
                                stack.Pop();
                            }
                        }

                        break;

                    case XmlNodeType.EndElement:
                        stack.Pop();
                        break;

                    default:
                        throw new InnerError("invalid element type " + reader_.NodeType);
                    }
                } catch (InnerError ex) {
                    var lineInfo = (IXmlLineInfo)reader_;
                    ErrorCount++;
                    if (errors_ == null)
                    {
                        errors_ = new List <string> ();
                    }
                    errors_.Add(filename_ + ":" + lineInfo.LineNumber + ":" + lineInfo.LinePosition + " " + ex.Message);
                    throw new ParserException(ex.Message, filename_, lineInfo.LineNumber, lineInfo.LinePosition);
                }
            }

            // Logger.Log(root.Dump());

            root.ApplyStyle(root.StyleSheet);

            return(root);
        }
예제 #2
0
 public void SetUp()
 {
     Tml.Logger.Enable = true;
     parser            = new StyleParser();
 }