private static LayoutBox BuildLayoutTree(Style.StyledNode styleNode) { var display = styleNode.GetDisplay(); BoxType boxType; switch (display) { case Style.Display.Block: boxType = new BlockNode(styleNode); break; case Style.Display.Inline: boxType = new InlineNode(styleNode); break; default: throw new LayoutException("Root node has display: none."); } var root = new LayoutBox(boxType); foreach (var child in styleNode.Children) { switch (child.GetDisplay()) { case Style.Display.Block: root.Children.Add(BuildLayoutTree(child)); break; case Style.Display.Inline: root.GetInlineContainer().Children.Add(BuildLayoutTree(child)); break; } } return(root); }
/// <summary> /// RUN /// </summary> /// <returns><c>true</c> if one or more nodes has been parsed.</returns> private bool ParseRun(RunParsingMode mode, IInlineContainer container, bool setLineNumber) { ParseStart(); var parsedAny = false; while (!NeedsTerminate()) { // Read more InlineNode inline = null; if ((inline = ParseExpandable()) != null) { goto NEXT; } switch (mode) { case RunParsingMode.Run: // RUN if ((inline = ParseInline()) != null) { goto NEXT; } break; case RunParsingMode.ExpandableText: // EXPANDABLE_TEXT if ((inline = ParsePartialPlainText()) != null) { goto NEXT; } break; case RunParsingMode.ExpandableUrl: // EXPANDABLE_URL if ((inline = ParseUrlText()) != null) { goto NEXT; } break; default: throw new ArgumentOutOfRangeException(nameof(mode), mode, null); } break; NEXT: parsedAny = true; // Remember that ParsePartialText stops whenever there's a susceptable termination of PLAIN_TEXT // So we need to marge the consequent PlainText objects. if (inline is PlainText newtext) { if (container.Inlines.LastNode is PlainText lastText) { lastText.Content += newtext.Content; lastText.ExtendLineInfo(lineNumber, linePosition); continue; } } container.Inlines.Add(inline); } // Note that the content of RUN should not be empty. if (parsedAny) { ParseSuccessful((Node)container, setLineNumber); return(true); } else { Fallback(); return(false); } }