public override BlockState TryOpen(BlockProcessor processor) { if (processor.IsCodeIndent) { return(BlockState.None); } var column = processor.Column; var sourcePosition = processor.Start; var quoteChar = processor.CurrentChar; var c = processor.NextChar(); if (c.IsSpaceOrTab()) { processor.NextColumn(); } var rawNewBlock = new QuoteSectionNoteBlock(this) { Line = processor.LineIndex, QuoteChar = quoteChar, Column = column, Span = new SourceSpan(sourcePosition, processor.Line.End), }; TryParseFromLine(processor, rawNewBlock); processor.NewBlocks.Push(rawNewBlock); if (rawNewBlock.QuoteType == QuoteSectionNoteType.DFMVideo) { return(BlockState.BreakDiscard); } else { return(BlockState.Continue); } }
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 hasExcape = false; while (c != '\0' && (c != ']' || hasExcape)) { if (c == '\\' && !hasExcape) { hasExcape = true; } else { stringBuilder.Append(c); hasExcape = 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)) || IsNoteType(infoString); if (processor.CurrentChar != '\0' && isNoteVideoDiv) { _context.LogWarning("invalid-note-section", "Text in the first line of Note/Section/Video is not valid. Will be rendererd to <blockquote>"); processor.GoToColumn(originalColumn); return(false); } } if (IsNoteType(infoString)) { block.QuoteType = QuoteSectionNoteType.DFMNote; block.NoteTypeString = infoString.Substring(2, infoString.Length - 3); 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); }