Tidy.Core.Lexer.InferredTag C# (CSharp) Метод

InferredTag() публичный Метод

public InferredTag ( string name ) : Node
name string
Результат Node
        public virtual Node InferredTag(string name)
        {
            Node node = NewNode(Node.START_TAG, Lexbuf, Txtstart, Txtend, name);
            node.Isimplicit = true;
            return node;
        }

Usage Example

Пример #1
0
            /*
            element is node created by the lexer
            upon seeing the start tag, or by the
            parser when the start tag is inferred
            */
            public virtual void Parse(Lexer lexer, Node element, short mode)
            {
                Node node;
                bool checkstack;
                int istackbase = 0;
                TagCollection tt = lexer.Options.TagTable;

                checkstack = true;

                if ((element.Tag.Model & ContentModel.EMPTY) != 0)
                {
                    return;
                }

                if (element.Tag == tt.TagForm && element.IsDescendantOf(tt.TagForm))
                {
                    Report.Warning(lexer, element, null, Report.ILLEGAL_NESTING);
                }

                /*
                InlineDup() asks the lexer to insert inline emphasis tags
                currently pushed on the istack, but take care to avoid
                propagating inline emphasis inside OBJECT or APPLET.
                For these elements a fresh inline stack context is created
                and disposed of upon reaching the end of the element.
                They thus behave like table cells in this respect.
                */
                if ((element.Tag.Model & ContentModel.OBJECT) != 0)
                {
                    istackbase = lexer.Istackbase;
                    lexer.Istackbase = lexer.Istack.Count;
                }

                if ((element.Tag.Model & ContentModel.MIXED) == 0)
                {
                    lexer.InlineDup(null);
                }

                mode = Lexer.IGNORE_WHITESPACE;

                while (true)
                {
                    node = lexer.GetToken(mode);
                    if (node == null)
                    {
                        break;
                    }

                    /* end tag for this element */
                    if (node.Type == Node.END_TAG && node.Tag != null &&
                        (node.Tag == element.Tag || element.Was == node.Tag))
                    {
                        if ((element.Tag.Model & ContentModel.OBJECT) != 0)
                        {
                            /* pop inline stack */
                            while (lexer.Istack.Count > lexer.Istackbase)
                            {
                                lexer.PopInline(null);
                            }
                            lexer.Istackbase = istackbase;
                        }

                        element.Closed = true;
                        Node.TrimSpaces(lexer, element);
                        Node.TrimEmptyElement(lexer, element);
                        return;
                    }

                    if (node.Tag == tt.TagHtml || node.Tag == tt.TagHead || node.Tag == tt.TagBody)
                    {
                        if (node.Type == Node.START_TAG || node.Type == Node.START_END_TAG)
                        {
                            Report.Warning(lexer, element, node, Report.DISCARDING_UNEXPECTED);
                        }

                        continue;
                    }

                    if (node.Type == Node.END_TAG)
                    {
                        if (node.Tag == null)
                        {
                            Report.Warning(lexer, element, node, Report.DISCARDING_UNEXPECTED);

                            continue;
                        }
                        if (node.Tag == tt.TagBr)
                        {
                            node.Type = Node.START_TAG;
                        }
                        else if (node.Tag == tt.TagP)
                        {
                            Node.CoerceNode(lexer, node, tt.TagBr);
                            Node.InsertNodeAtEnd(element, node);
                            node = lexer.InferredTag("br");
                        }
                        else
                        {
                            /*
                            if this is the end tag for an ancestor element
                            then infer end tag for this element
                            */
                            Node parent;
                            for (parent = element.Parent; parent != null; parent = parent.Parent)
                            {
                                if (node.Tag != parent.Tag) continue;
                                if ((element.Tag.Model & ContentModel.OPT) == 0)
                                {
                                    Report.Warning(lexer, element, node, Report.MISSING_ENDTAG_BEFORE);
                                }

                                lexer.UngetToken();

                                if ((element.Tag.Model & ContentModel.OBJECT) != 0)
                                {
                                    /* pop inline stack */
                                    while (lexer.Istack.Count > lexer.Istackbase)
                                    {
                                        lexer.PopInline(null);
                                    }
                                    lexer.Istackbase = istackbase;
                                }

                                Node.TrimSpaces(lexer, element);
                                Node.TrimEmptyElement(lexer, element);
                                return;
                            }
                            /* special case </tr> etc. for stuff moved in front of table */
                            if (lexer.Exiled && node.Tag.Model != 0 && (node.Tag.Model & ContentModel.TABLE) != 0)
                            {
                                lexer.UngetToken();
                                Node.TrimSpaces(lexer, element);
                                Node.TrimEmptyElement(lexer, element);
                                return;
                            }
                        }
                    }

                    /* mixed content model permits text */
                    if (node.Type == Node.TEXT_NODE)
                    {
                        bool iswhitenode = node.Type == Node.TEXT_NODE && node.End <= node.Start + 1 &&
                                           lexer.Lexbuf[node.Start] == (sbyte) ' ';

                        if (lexer.Options.EncloseBlockText && !iswhitenode)
                        {
                            lexer.UngetToken();
                            node = lexer.InferredTag("p");
                            Node.InsertNodeAtEnd(element, node);
                            ParseTag(lexer, node, Lexer.MIXED_CONTENT);
                            continue;
                        }

                        if (checkstack)
                        {
                            checkstack = false;

                            if ((element.Tag.Model & ContentModel.MIXED) == 0)
                            {
                                if (lexer.InlineDup(node) > 0)
                                {
                                    continue;
                                }
                            }
                        }

                        Node.InsertNodeAtEnd(element, node);
                        mode = Lexer.MIXED_CONTENT;
                        /*
                        HTML4 strict doesn't allow mixed content for
                        elements with %block; as their content model
                        */
                        lexer.Versions &= ~ HtmlVersion.Html40Strict;
                        continue;
                    }

                    if (Node.InsertMisc(element, node))
                    {
                        continue;
                    }

                    /* allow PARAM elements? */
                    if (node.Tag == tt.TagParam)
                    {
                        if (((element.Tag.Model & ContentModel.PARAM) != 0) &&
                            (node.Type == Node.START_TAG || node.Type == Node.START_END_TAG))
                        {
                            Node.InsertNodeAtEnd(element, node);
                            continue;
                        }

                        /* otherwise discard it */
                        Report.Warning(lexer, element, node, Report.DISCARDING_UNEXPECTED);
                        continue;
                    }

                    /* allow AREA elements? */
                    if (node.Tag == tt.TagArea)
                    {
                        if ((element.Tag == tt.TagMap) &&
                            (node.Type == Node.START_TAG || node.Type == Node.START_END_TAG))
                        {
                            Node.InsertNodeAtEnd(element, node);
                            continue;
                        }

                        /* otherwise discard it */
                        Report.Warning(lexer, element, node, Report.DISCARDING_UNEXPECTED);
                        continue;
                    }

                    /* ignore unknown start/end tags */
                    if (node.Tag == null)
                    {
                        Report.Warning(lexer, element, node, Report.DISCARDING_UNEXPECTED);
                        continue;
                    }

                    /*
                    Allow ContentModel.INLINE elements here.

                    Allow ContentModel.BLOCK elements here unless
                    lexer.excludeBlocks is yes.

                    LI and DD are special cased.

                    Otherwise infer end tag for this element.
                    */

                    if ((node.Tag.Model & ContentModel.INLINE) == 0)
                    {
                        if (node.Type != Node.START_TAG && node.Type != Node.START_END_TAG)
                        {
                            Report.Warning(lexer, element, node, Report.DISCARDING_UNEXPECTED);
                            continue;
                        }

                        if (element.Tag == tt.TagTd || element.Tag == tt.TagTh)
                        {
                            /* if parent is a table cell, avoid inferring the end of the cell */

                            if ((node.Tag.Model & ContentModel.HEAD) != 0)
                            {
                                MoveToHead(lexer, element, node);
                                continue;
                            }

                            if ((node.Tag.Model & ContentModel.LIST) != 0)
                            {
                                lexer.UngetToken();
                                node = lexer.InferredTag("ul");
                                Node.AddClass(node, "noindent");
                                lexer.ExcludeBlocks = true;
                            }
                            else if ((node.Tag.Model & ContentModel.DEFLIST) != 0)
                            {
                                lexer.UngetToken();
                                node = lexer.InferredTag("dl");
                                lexer.ExcludeBlocks = true;
                            }

                            /* infer end of current table cell */
                            if ((node.Tag.Model & ContentModel.BLOCK) == 0)
                            {
                                lexer.UngetToken();
                                Node.TrimSpaces(lexer, element);
                                Node.TrimEmptyElement(lexer, element);
                                return;
                            }
                        }
                        else if ((node.Tag.Model & ContentModel.BLOCK) != 0)
                        {
                            if (lexer.ExcludeBlocks)
                            {
                                if ((element.Tag.Model & ContentModel.OPT) == 0)
                                    Report.Warning(lexer, element, node, Report.MISSING_ENDTAG_BEFORE);

                                lexer.UngetToken();

                                if ((element.Tag.Model & ContentModel.OBJECT) != 0)
                                    lexer.Istackbase = istackbase;

                                Node.TrimSpaces(lexer, element);
                                Node.TrimEmptyElement(lexer, element);
                                return;
                            }
                        }
                            /* things like list items */
                        else
                        {
                            if ((element.Tag.Model & ContentModel.OPT) == 0 && !element.Isimplicit)
                                Report.Warning(lexer, element, node, Report.MISSING_ENDTAG_BEFORE);

                            if ((node.Tag.Model & ContentModel.HEAD) != 0)
                            {
                                MoveToHead(lexer, element, node);
                                continue;
                            }

                            lexer.UngetToken();

                            if ((node.Tag.Model & ContentModel.LIST) != 0)
                            {
                                if (element.Parent != null && element.Parent.Tag != null &&
                                    element.Parent.Tag.Parser == ParseList)
                                {
                                    Node.TrimSpaces(lexer, element);
                                    Node.TrimEmptyElement(lexer, element);
                                    return;
                                }

                                node = lexer.InferredTag("ul");
                                Node.AddClass(node, "noindent");
                            }
                            else if ((node.Tag.Model & ContentModel.DEFLIST) != 0)
                            {
                                if (element.Parent.Tag == tt.TagDl)
                                {
                                    Node.TrimSpaces(lexer, element);
                                    Node.TrimEmptyElement(lexer, element);
                                    return;
                                }

                                node = lexer.InferredTag("dl");
                            }
                            else if ((node.Tag.Model & ContentModel.TABLE) != 0 ||
                                     (node.Tag.Model & ContentModel.ROW) != 0)
                            {
                                node = lexer.InferredTag("table");
                            }
                            else if ((element.Tag.Model & ContentModel.OBJECT) != 0)
                            {
                                /* pop inline stack */
                                while (lexer.Istack.Count > lexer.Istackbase)
                                {
                                    lexer.PopInline(null);
                                }
                                lexer.Istackbase = istackbase;
                                Node.TrimSpaces(lexer, element);
                                Node.TrimEmptyElement(lexer, element);
                                return;
                            }
                            else
                            {
                                Node.TrimSpaces(lexer, element);
                                Node.TrimEmptyElement(lexer, element);
                                return;
                            }
                        }
                    }

                    /* parse known element */
                    if (node.Type == Node.START_TAG || node.Type == Node.START_END_TAG)
                    {
                        if ((node.Tag.Model & ContentModel.INLINE) != 0)
                        {
                            if (checkstack && !node.Isimplicit)
                            {
                                checkstack = false;

                                if (lexer.InlineDup(node) > 0)
                                    continue;
                            }

                            mode = Lexer.MIXED_CONTENT;
                        }
                        else
                        {
                            checkstack = true;
                            mode = Lexer.IGNORE_WHITESPACE;
                        }

                        /* trim white space before <br> */
                        if (node.Tag == tt.TagBr)
                        {
                            Node.TrimSpaces(lexer, element);
                        }

                        Node.InsertNodeAtEnd(element, node);

                        if (node.Isimplicit)
                        {
                            Report.Warning(lexer, element, node, Report.INSERTING_TAG);
                        }

                        ParseTag(lexer, node, Lexer.IGNORE_WHITESPACE);
                        continue;
                    }

                    /* discard unexpected tags */
                    if (node.Type == Node.END_TAG)
                        lexer.PopInline(node);
                    /* if inline end tag */

                    Report.Warning(lexer, element, node, Report.DISCARDING_UNEXPECTED);
                }

                if ((element.Tag.Model & ContentModel.OPT) == 0)
                {
                    Report.Warning(lexer, element, node, Report.MISSING_ENDTAG_FOR);
                }

                if ((element.Tag.Model & ContentModel.OBJECT) != 0)
                {
                    /* pop inline stack */
                    while (lexer.Istack.Count > lexer.Istackbase)
                    {
                        lexer.PopInline(null);
                    }
                    lexer.Istackbase = istackbase;
                }

                Node.TrimSpaces(lexer, element);
                Node.TrimEmptyElement(lexer, element);
            }
All Usage Examples Of Tidy.Core.Lexer::InferredTag