/* create style element using rules from dictionary */ private void CreateStyleElement(Lexer lexer, Node doc) { Style style; if (lexer.Styles == null && NiceBody(lexer, doc)) { return; } Node node = lexer.NewNode(Node.START_TAG, null, 0, 0, "style"); node.Isimplicit = true; /* insert type attribute */ var av = new AttVal(null, null, '"', "type", "text/css"); av.Dict = AttributeTable.DefaultAttributeTable.FindAttribute(av); node.Attributes = av; Node body = doc.FindBody(lexer.Options.TagTable); lexer.Txtstart = lexer.Lexsize; if (body != null) { CleanBodyAttrs(lexer, body); } for (style = lexer.Styles; style != null; style = style.Next) { lexer.AddCharToLexer(' '); lexer.AddStringLiteral(style.Tag); lexer.AddCharToLexer('.'); lexer.AddStringLiteral(style.TagClass); lexer.AddCharToLexer(' '); lexer.AddCharToLexer('{'); lexer.AddStringLiteral(style.Properties); lexer.AddCharToLexer('}'); lexer.AddCharToLexer('\n'); } lexer.Txtend = lexer.Lexsize; Node.InsertNodeAtEnd(node, lexer.NewNode(Node.TEXT_NODE, lexer.Lexbuf, lexer.Txtstart, lexer.Txtend)); /* now insert style element into document head doc is root node. search its children for html node the head node should be first child of html node */ Node head = doc.FindHead(lexer.Options.TagTable); if (head != null) { Node.InsertNodeAtEnd(head, node); } }
public static Node ParseDocument(Lexer lexer) { Node doctype = null; TagCollection tt = lexer.Options.TagTable; Node document = lexer.NewNode(); document.Type = Node.ROOT_NODE; while (true) { Node node = lexer.GetToken(Lexer.IGNORE_WHITESPACE); if (node == null) { break; } /* deal with comments etc. */ if (Node.InsertMisc(document, node)) { continue; } if (node.Type == Node.DOC_TYPE_TAG) { if (doctype == null) { Node.InsertNodeAtEnd(document, node); doctype = node; } else { Report.Warning(lexer, document, node, Report.DISCARDING_UNEXPECTED); } continue; } if (node.Type == Node.END_TAG) { Report.Warning(lexer, document, node, Report.DISCARDING_UNEXPECTED); //TODO? continue; } Node html; if (node.Type != Node.START_TAG || node.Tag != tt.TagHtml) { lexer.UngetToken(); html = lexer.InferredTag("html"); } else { html = node; } Node.InsertNodeAtEnd(document, html); ParseHtml.Parse(lexer, html, 0); // TODO? break; } return document; }
public static Node ParseXmlDocument(Lexer lexer) { Node document = lexer.NewNode(); document.Type = Node.ROOT_NODE; Node doctype = null; lexer.Options.XmlTags = true; while (true) { Node node = lexer.GetToken(Lexer.IGNORE_WHITESPACE); if (node == null) { break; } /* discard unexpected end tags */ if (node.Type == Node.END_TAG) { Report.Warning(lexer, null, node, Report.UNEXPECTED_ENDTAG); continue; } /* deal with comments etc. */ if (Node.InsertMisc(document, node)) { continue; } if (node.Type == Node.DOC_TYPE_TAG) { if (doctype == null) { Node.InsertNodeAtEnd(document, node); doctype = node; } else { Report.Warning(lexer, document, node, Report.DISCARDING_UNEXPECTED); } // TODO continue; } /* if start tag then parse element's content */ if (node.Type == Node.START_TAG) { Node.InsertNodeAtEnd(document, node); ParseXmlElement(lexer, node, Lexer.IGNORE_WHITESPACE); } } if (doctype != null && !lexer.CheckDocTypeKeyWords(doctype)) { Report.Warning(lexer, doctype, null, Report.DTYPE_NOT_UPPER_CASE); } /* ensure presence of initial <?XML version="1.0"?> */ if (lexer.Options.XmlPi) { lexer.FixXmlPi(document); } return document; }
/* This maps <p>hello<em> world</em> to <p>hello <em>world</em> Trims initial space, by moving it before the start tag, or if this element is the first in parent's content, then by discarding the space */ public static void TrimInitialSpace(Lexer lexer, Node element, Node text) { // GLP: Local fix to Bug 119789. Remove this comment when parser.c is updated. // 31-Oct-00. if (text.Type == TEXT_NODE && text.Textarray[text.Start] == (byte) ' ' && (text.Start < text.End)) { if (((element.Tag.Model & ContentModel.INLINE) != 0) && (element.Tag.Model & ContentModel.FIELD) == 0 && element.Parent.Content != element) { Node prev = element.Prev; if (prev != null && prev.Type == TEXT_NODE) { if (prev.Textarray[prev.End - 1] != (byte) ' ') { prev.Textarray[prev.End++] = (byte) ' '; } ++element.Start; } /* create new node */ else { Node node = lexer.NewNode(); // Local fix for bug 228486 (GLP). This handles the case // where we need to create a preceeding text node but there are // no "slots" in textarray that we can steal from the current // element. Therefore, we create a new textarray containing // just the blank. When Tidy is fixed, this should be removed. if (element.Start >= element.End) { node.Start = 0; node.End = 1; node.Textarray = new byte[1]; } else { node.Start = element.Start++; node.End = element.Start; node.Textarray = element.Textarray; } node.Textarray[node.Start] = (byte) ' '; node.Prev = prev; if (prev != null) { prev.Next = node; } node.Next = element; element.Prev = node; node.Parent = element.Parent; } } /* discard the space in current node */ ++text.Start; } }