///// <summary> ///// Writes the attached <see cref="HtmlAttributes"/> on the specified <see cref="MarkdownObject"/>. ///// </summary> ///// <param name="obj">The object.</param> ///// <returns></returns> //public NormalizeRenderer WriteAttributes(MarkdownObject obj) //{ // if (obj == null) throw new ArgumentNullException(nameof(obj)); // return WriteAttributes(obj.TryGetAttributes()); //} ///// <summary> ///// Writes the specified <see cref="HtmlAttributes"/>. ///// </summary> ///// <param name="attributes">The attributes to render.</param> ///// <returns>This instance</returns> //public NormalizeRenderer WriteAttributes(HtmlAttributes attributes) //{ // if (attributes == null) // { // return this; // } // if (attributes.Id != null) // { // Write(" id=\"").WriteEscape(attributes.Id).Write("\""); // } // if (attributes.Classes != null && attributes.Classes.Count > 0) // { // Write(" class=\""); // for (int i = 0; i < attributes.Classes.Count; i++) // { // var cssClass = attributes.Classes[i]; // if (i > 0) // { // Write(" "); // } // WriteEscape(cssClass); // } // Write("\""); // } // if (attributes.Properties != null && attributes.Properties.Count > 0) // { // foreach (var property in attributes.Properties) // { // Write(" ").Write(property.Key); // if (property.Value != null) // { // Write("=").Write("\""); // WriteEscape(property.Value); // Write("\""); // } // } // } // return this; //} /// <summary> /// Writes the lines of a <see cref="LeafBlock"/> /// </summary> /// <param name="leafBlock">The leaf block.</param> /// <param name="writeEndOfLines">if set to <c>true</c> write end of lines.</param> /// <returns>This instance</returns> public NormalizeRenderer WriteLeafRawLines(LeafBlock leafBlock, bool writeEndOfLines, bool indent = false) { if (leafBlock == null) { ThrowHelper.ArgumentNullException_leafBlock(); } if (leafBlock.Lines.Lines != null) { var lines = leafBlock.Lines; var slices = lines.Lines; for (int i = 0; i < lines.Count; i++) { if (!writeEndOfLines && i > 0) { WriteLine(); } if (indent) { Write(" "); } Write(ref slices[i].Slice); if (writeEndOfLines) { WriteLine(); } } } return(this); }
/// <summary> /// Writes the lines of a <see cref="LeafBlock"/> /// </summary> /// <param name="leafBlock">The leaf block.</param> /// <param name="writeEndOfLines">if set to <c>true</c> write end of lines.</param> /// <param name="escape">if set to <c>true</c> escape the content for HTML</param> /// <param name="softEscape">Only escape < and &</param> /// <returns>This instance</returns> public HtmlRenderer WriteLeafRawLines(LeafBlock leafBlock, bool writeEndOfLines, bool escape, bool softEscape = false) { if (leafBlock == null) { ThrowHelper.ArgumentNullException_leafBlock(); } if (leafBlock.Lines.Lines != null) { var lines = leafBlock.Lines; var slices = lines.Lines; for (int i = 0; i < lines.Count; i++) { if (!writeEndOfLines && i > 0) { WriteLine(); } if (escape) { WriteEscape(ref slices[i].Slice, softEscape); } else { Write(ref slices[i].Slice); } if (writeEndOfLines) { WriteLine(); } } } return(this); }
/// <summary> /// Writes the lines of a <see cref="LeafBlock"/> /// </summary> /// <param name="leafBlock">The leaf block.</param> /// <returns>This instance</returns> public void WriteLeafRawLines(LeafBlock leafBlock) { if (leafBlock is null) { ThrowHelper.ArgumentNullException_leafBlock(); } if (leafBlock.Lines.Lines != null) { var lines = leafBlock.Lines; var slices = lines.Lines; for (int i = 0; i < lines.Count; i++) { var slice = slices[i].Slice; Write(ref slice); WriteLine(slice.NewLine); } } }
/// <summary> /// Processes the inline of the specified <see cref="LeafBlock"/>. /// </summary> /// <param name="leafBlock">The leaf block.</param> public void ProcessInlineLeaf(LeafBlock leafBlock) { if (leafBlock is null) { ThrowHelper.ArgumentNullException_leafBlock(); } // clear parser states Array.Clear(ParserStates, 0, ParserStates.Length); Root = new ContainerInline() { IsClosed = false }; leafBlock.Inline = Root; Inline = null; Block = leafBlock; BlockNew = null; LineIndex = leafBlock.Line; previousSliceOffset = 0; previousLineIndexForSliceOffset = 0; lineOffsets.Clear(); var text = leafBlock.Lines.ToSlice(lineOffsets); leafBlock.Lines.Release(); int previousStart = -1; while (!text.IsEmpty) { // Security check so that the parser can't go into a crazy infinite loop if one extension is messing if (previousStart == text.Start) { ThrowHelper.InvalidOperationException($"The parser is in an invalid infinite loop while trying to parse inlines for block [{leafBlock.GetType().Name}] at position ({leafBlock.ToPositionText()}"); } previousStart = text.Start; var c = text.CurrentChar; var textSaved = text; var parsers = Parsers.GetParsersForOpeningCharacter(c); if (parsers != null) { for (int i = 0; i < parsers.Length; i++) { text = textSaved; if (parsers[i].Match(this, ref text)) { goto done; } } } parsers = Parsers.GlobalParsers; if (parsers != null) { for (int i = 0; i < parsers.Length; i++) { text = textSaved; if (parsers[i].Match(this, ref text)) { goto done; } } } text = textSaved; // Else match using the default literal inline parser LiteralInlineParser.Match(this, ref text); done: var nextInline = Inline; if (nextInline != null) { if (nextInline.Parent is null) { // Get deepest container var container = FindLastContainer(); if (!ReferenceEquals(container, nextInline)) { container.AppendChild(nextInline); } if (container == Root) { if (container.Span.IsEmpty) { container.Span = nextInline.Span; } container.Span.End = nextInline.Span.End; } } } else { // Get deepest container var container = FindLastContainer(); Inline = container.LastChild is LeafInline ? container.LastChild : container; if (Inline == Root) { Inline = null; } } //if (DebugLog != null) //{ // DebugLog.WriteLine($"** Dump: char '{c}"); // leafBlock.Inline.DumpTo(DebugLog); //} } if (TrackTrivia) { if (!(leafBlock is HeadingBlock)) { var newLine = leafBlock.NewLine; leafBlock.Inline.AppendChild(new LineBreakInline { NewLine = newLine }); } } Inline = null; //if (DebugLog != null) //{ // DebugLog.WriteLine("** Dump before Emphasis:"); // leafBlock.Inline.DumpTo(DebugLog); //} // PostProcess all inlines PostProcessInlines(0, Root, null, true); //TransformDelimitersToLiterals(); //if (DebugLog != null) //{ // DebugLog.WriteLine(); // DebugLog.WriteLine("** Dump after Emphasis:"); // leafBlock.Inline.DumpTo(DebugLog); //} }