private void WriteNote(HtmlRenderer renderer, QuoteSectionNoteBlock obj)
        {
            var syntax      = SectionNoteType.GetSyntax($"[!{obj.NoteTypeString}]");
            var noteHeading = $"<h5><i class=\"{syntax.Icon}\"></i> {syntax.Text}</h5>";

            renderer.Write("<div").Write($" class=\"alert alert-{syntax.AlertClass}\"").WriteAttributes(obj).WriteLine(">");
            var savedImplicitParagraph = renderer.ImplicitParagraph;

            renderer.ImplicitParagraph = false;
            renderer.WriteLine(noteHeading);
            renderer.WriteChildren(obj);
            renderer.ImplicitParagraph = savedImplicitParagraph;
            renderer.WriteLine("</div>");
        }
        private bool TryParseFromLine(BlockProcessor processor, QuoteSectionNoteBlock block)
        {
            int originalColumn = processor.Column;

            block.QuoteType = QuoteSectionNoteType.MarkdownQuote;

            if (processor.CurrentChar != '[')
            {
                return(false);
            }

            var stringBuilder = StringBuilderCache.Local();
            var c             = processor.CurrentChar;

            var hasEscape = false;

            while (c != '\0' && (c != ']' || hasEscape))
            {
                if (c == '\\' && !hasEscape)
                {
                    hasEscape = true;
                }
                else
                {
                    stringBuilder.Append(c);
                    hasEscape = false;
                }
                c = processor.NextChar();
            }

            stringBuilder.Append(c);
            var infoString = stringBuilder.ToString().Trim();

            if (c == '\0')
            {
                processor.GoToColumn(originalColumn);
                return(false);
            }

            if (c == ']')
            {
                // "> [!NOTE] content" is invalid, go to end to see it.
                processor.NextChar();
                while (processor.CurrentChar.IsSpaceOrTab())
                {
                    processor.NextChar();
                }
                var isNoteVideoDiv = infoString.StartsWith("[!div", StringComparison.OrdinalIgnoreCase) ||
                                     infoString.StartsWith("[!Video", StringComparison.OrdinalIgnoreCase) ||
                                     SectionNoteType.IsNoteType(infoString);
                if (processor.CurrentChar != '\0' && isNoteVideoDiv)
                {
                    processor.GoToColumn(originalColumn);
                    return(false);
                }
            }

            if (SectionNoteType.IsNoteType(infoString))
            {
                block.QuoteType      = QuoteSectionNoteType.DFMNote;
                block.NoteTypeString = infoString.Substring(2, infoString.Length - 3).ToLowerInvariant();
                return(true);
            }

            if (infoString.StartsWith("[!div", StringComparison.OrdinalIgnoreCase))
            {
                block.QuoteType = QuoteSectionNoteType.DFMSection;
                string attribute = infoString.Substring(5, infoString.Length - 6).Trim();
                if (attribute.Length >= 2 && attribute.First() == '`' && attribute.Last() == '`')
                {
                    block.SectionAttributeString = attribute.Substring(1, attribute.Length - 2).Trim();
                }
                if (attribute.Length >= 1 && attribute.First() != '`' && attribute.Last() != '`')
                {
                    block.SectionAttributeString = attribute;
                }
                return(true);
            }

            if (infoString.StartsWith("[!Video", StringComparison.OrdinalIgnoreCase))
            {
                string link = infoString.Substring(7, infoString.Length - 8);
                if (link.StartsWith(" http://") || link.StartsWith(" https://"))
                {
                    block.QuoteType = QuoteSectionNoteType.DFMVideo;
                    block.VideoLink = link.Trim();
                    return(true);
                }
            }

            processor.GoToColumn(originalColumn);
            return(false);
        }