///// <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);
        }
Exemple #2
0
 /// <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 &lt; and &amp;</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);
 }
Exemple #3
0
 /// <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);
         }
     }
 }
Exemple #4
0
        /// <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);
            //}
        }