public override bool CanInterrupt(BlockProcessor processor, Block block) { return(!(block is ParagraphBlock)); }
public override BlockState TryContinue(BlockProcessor processor, Block block) { var htmlBlock = (HtmlBlock)block; return(MatchEnd(processor, htmlBlock)); }
private BlockState TryParseTagType16(BlockProcessor state, StringSlice line, int startColumn, int startPosition) { char c; c = line.CurrentChar; if (c == '!') { c = line.NextChar(); if (c == '-' && line.PeekChar() == '-') { return(CreateHtmlBlock(state, HtmlBlockType.Comment, startColumn, startPosition)); // group 2 } if (c.IsAlphaUpper()) { return(CreateHtmlBlock(state, HtmlBlockType.DocumentType, startColumn, startPosition)); // group 4 } if (c == '[' && line.Match("CDATA[", 1)) { return(CreateHtmlBlock(state, HtmlBlockType.CData, startColumn, startPosition)); // group 5 } return(BlockState.None); } if (c == '?') { return(CreateHtmlBlock(state, HtmlBlockType.ProcessingInstruction, startColumn, startPosition)); // group 3 } var hasLeadingClose = c == '/'; if (hasLeadingClose) { c = line.NextChar(); } var tag = new char[10]; var count = 0; for (; count < tag.Length; count++) { if (!c.IsAlphaNumeric()) { break; } tag[count] = Char.ToLowerInvariant(c); c = line.NextChar(); } if ( !(c == '>' || (!hasLeadingClose && c == '/' && line.PeekChar() == '>') || c.IsWhitespace() || c == '\0')) { return(BlockState.None); } if (count == 0) { return(BlockState.None); } var tagName = new string(tag, 0, count); var tagIndex = Array.BinarySearch(HtmlTags, tagName, StringComparer.Ordinal); if (tagIndex < 0) { return(BlockState.None); } // Cannot start with </script </pre or </style if ((tagIndex == 49 || tagIndex == 50 || tagIndex == 53)) { if (c == '/' || hasLeadingClose) { return(BlockState.None); } return(CreateHtmlBlock(state, HtmlBlockType.ScriptPreOrStyle, startColumn, startPosition)); } return(CreateHtmlBlock(state, HtmlBlockType.InterruptingBlock, startColumn, startPosition)); }
private BlockState MatchEnd(BlockProcessor state, HtmlBlock htmlBlock) { state.GoToColumn(state.ColumnBeforeIndent); // Early exit if it is not starting by an HTML tag var line = state.Line; var result = BlockState.Continue; int index; switch (htmlBlock.Type) { case HtmlBlockType.Comment: index = line.IndexOf(EndOfComment); if (index >= 0) { htmlBlock.UpdateSpanEnd(index + EndOfComment.Length); result = BlockState.Break; } break; case HtmlBlockType.CData: index = line.IndexOf(EndOfCDATA); if (index >= 0) { htmlBlock.UpdateSpanEnd(index + EndOfCDATA.Length); result = BlockState.Break; } break; case HtmlBlockType.ProcessingInstruction: index = line.IndexOf(EndOfProcessingInstruction); if (index >= 0) { htmlBlock.UpdateSpanEnd(index + EndOfProcessingInstruction.Length); result = BlockState.Break; } break; case HtmlBlockType.DocumentType: index = line.IndexOf('>'); if (index >= 0) { htmlBlock.UpdateSpanEnd(index + 1); result = BlockState.Break; } break; case HtmlBlockType.ScriptPreOrStyle: index = line.IndexOf("</script>", 0, true); if (index >= 0) { htmlBlock.UpdateSpanEnd(index + "</script>".Length); result = BlockState.Break; } else { index = line.IndexOf("</pre>", 0, true); if (index >= 0) { htmlBlock.UpdateSpanEnd(index + "</pre>".Length); result = BlockState.Break; } else { index = line.IndexOf("</style>", 0, true); if (index >= 0) { htmlBlock.UpdateSpanEnd(index + "</style>".Length); result = BlockState.Break; } } } break; case HtmlBlockType.InterruptingBlock: if (state.IsBlankLine) { result = BlockState.BreakDiscard; } break; case HtmlBlockType.NonInterruptingBlock: if (state.IsBlankLine) { result = BlockState.BreakDiscard; } break; } // Update only if we don't have a break discard if (result != BlockState.BreakDiscard) { htmlBlock.Span.End = line.End; } return(result); }