public async void RenderNode(INode node, ITextContainer parentContainer) { var element = node as IElement; if (element != null) { PushTag(element); foreach (var child in node.ChildNodes) { if (child is IText) { var text = child.TextContent ?? string.Empty; if (TagStack.Contains("pre", StringComparer.OrdinalIgnoreCase) == false) { // Not in pre, replace all line break to empty. text = text.Replace("\r", string.Empty).Replace("\n", string.Empty); } if (string.IsNullOrEmpty(text) == false) { parentContainer.Add(new Run { Text = text }); } } else { var childElement = child as IElement; if (childElement != null) { var elementRender = ElementRenders.GetRender(childElement.TagName); if (elementRender != null) { elementRender.RenderElement(childElement, parentContainer, this); } else { if (Debugger.IsAttached) { Debugger.Break(); } await new MessageDialog(string.Format("{0} can't render", childElement.TagName)).ShowAsync(); } } } } PopTag(element); } }
/// <summary> /// Parses the given document to find all tags between the beginning of the document and the specified /// end line. /// </summary> /// <remarks> /// The <paramref name="p_pctCompleteTagCallback" /> is called whenever a complete tag has been parsed. /// A complete tag is a tag whose opening and closing tags have been found (for example, <b>..</b>). /// The stack that is returned contains all the unclosed tags found, and so represents where in the /// document heirarchy the line falls. /// </remarks> /// <param name="p_docDocument">The document to parse.</param> /// <param name="p_intEndLine">The line of the document at which to stop parsing.</param> /// <param name="p_pctCompleteTagCallback">The method to call whenever a complete tag is parsed.</param> /// <returns>A stack containing all the unclosed tags found.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if <paramref name="p_intEndLine" /> is greater than /// or equal to the <see cref="IDocument.TotalNumberOfLines" /> of <paramref name="p_docDocument" />. /// </exception> public static TagStack ParseTags(IDocument p_docDocument, Int32 p_intEndLine, ParsedTag p_pctCompleteTagCallback, ParsedTag p_pctUnclosedTagCallback) { if (p_intEndLine >= p_docDocument.TotalNumberOfLines) { throw new ArgumentOutOfRangeException("p_intEndLine", p_intEndLine, "The given end line paramater is outside of the range of lines in the given document."); } //parse the buffer var stkTags = new TagStack(); for (var i = 0; i <= p_intEndLine; i++) { var strLine = p_docDocument.GetText(p_docDocument.GetLineSegment(i)); var intLineNum = i; var intLastOpenPos = strLine.LastIndexOf('<'); if (intLastOpenPos < 0) { continue; } var intLastClosePos = strLine.LastIndexOf('>'); if ((intLastClosePos > -1) && (intLastOpenPos > intLastClosePos)) { var stbLines = new StringBuilder(strLine); //there is an open tag on this line - read lines until it is closed. for (; i <= p_intEndLine; i++) { var strNextLine = p_docDocument.GetText(p_docDocument.GetLineSegment(i)); intLastClosePos = strLine.LastIndexOf('>'); stbLines.Append(strNextLine); if (intLastClosePos < 0) { i--; break; } } strLine = stbLines.ToString(); } var mclLineTags = rgxTagContents.Matches(strLine); foreach (Match mtcTag in mclLineTags) { var strTag = mtcTag.Groups[1].Value.Trim(); var strTagName = rgxTagName.Match(strTag).Groups[1].Value; if (strTag.StartsWith("/")) { if (stkTags.Contains(strTagName)) { while (!stkTags.Peek().Equals(strTagName)) { var tpsTag = stkTags.Pop(); var tlcStart = new TextLocation(tpsTag.Column, tpsTag.LineNumber); var tlcEnd = new TextLocation(tpsTag.Column + tpsTag.Name.Length, tpsTag.LineNumber); if (p_pctUnclosedTagCallback != null) { p_pctUnclosedTagCallback(p_docDocument, tpsTag.Name, tlcStart, tlcEnd); } } var tpsCompleteTag = stkTags.Pop(); if (p_pctCompleteTagCallback != null) { var tlcStart = new TextLocation(tpsCompleteTag.Column, tpsCompleteTag.LineNumber); var intEndFoldPos = mtcTag.Groups[1].Index; var tlcEnd = new TextLocation(intEndFoldPos, intLineNum); p_pctCompleteTagCallback(p_docDocument, strTagName, tlcStart, tlcEnd); } } } else { if (!strTag.EndsWith("/")) { stkTags.Push(strTagName, intLineNum, mtcTag.Groups[1].Index); } } } } return(stkTags); }