public override bool CanInterrupt(BlockProcessor processor, Block block)
 {
     return(!(block is ParagraphBlock));
 }
Exemple #2
0
        public override BlockState TryContinue(BlockProcessor processor, Block block)
        {
            var htmlBlock = (HtmlBlock)block;

            return(MatchEnd(processor, htmlBlock));
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        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);
        }