Beispiel #1
0
        public override BlockState TryContinue(BlockProcessor processor, Block block)
        {
            if (processor.IsBlankLine)
            {
                return(BlockState.Continue);
            }

            var slice = processor.Line;
            var Row   = (RowBlock)block;

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, new string(':', Row.ColonCount)))
            {
                return(BlockState.Continue);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, EndString, false))
            {
                return(BlockState.Continue);
            }

            var c = ExtensionsHelper.SkipSpaces(ref slice);

            if (!c.IsZero())
            {
                _context.LogWarning("invalid-row", $"Row has some invalid chars in the ending.");
            }

            block.UpdateSpanEnd(slice.End);

            return(BlockState.BreakDiscard);
        }
Beispiel #2
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (!ExtensionsHelper.MatchStart(ref slice, StartString, true))
            {
                return(false);
            }

            var text = ExtensionsHelper.TryGetStringBeforeChars(new char[] { '\"', '\n' }, ref slice);

            if (text == null || text.IndexOf('\n') != -1)
            {
                return(false);
            }

            if (!ExtensionsHelper.MatchStart(ref slice, EndString, true))
            {
                return(false);
            }

            processor.Inline = new NolocInline()
            {
                Text = text
            };

            return(true);
        }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
            {
                return(false);
            }
            else
            {
                if (slice.CurrentChar == '-')
                {
                    slice.NextChar();
                }
            }

            var includeFile = new InclusionInline();
            var context     = new InclusionContext();

            if (!ExtensionsHelper.MatchLink(ref slice, ref context))
            {
                return(false);
            }

            includeFile.Context = context;
            processor.Inline    = includeFile;

            return(true);
        }
Beispiel #4
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            if (processor.IsCodeIndent)
            {
                return(BlockState.None);
            }

            // Sample: [!code-javascript[Main](../jquery.js?name=testsnippet#tag "title")]
            var slice = processor.Line;

            if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
            {
                return(BlockState.None);
            }

            var codeSnippet = new CodeSnippet(this);

            MatchLanguage(processor, ref slice, ref codeSnippet);

            if (!MatchName(processor, ref slice, ref codeSnippet))
            {
                return(BlockState.None);
            }

            if (!MatchPath(processor, ref slice, ref codeSnippet))
            {
                return(BlockState.None);
            }

            MatchQuery(processor, ref slice, ref codeSnippet);

            MatchTitle(processor, ref slice, ref codeSnippet);

            ExtensionsHelper.SkipWhitespace(ref slice);
            if (slice.CurrentChar == ')')
            {
                slice.NextChar();
                ExtensionsHelper.SkipWhitespace(ref slice);
                if (slice.CurrentChar == ']')
                {
                    var codeSnippetEnd = slice.Start;
                    slice.NextChar();
                    ExtensionsHelper.SkipWhitespace(ref slice);
                    if (slice.CurrentChar == '\0')
                    {
                        // slice finished its task, re-use it for Raw content
                        slice.Start        = processor.Line.Start;
                        slice.End          = codeSnippetEnd;
                        codeSnippet.Raw    = slice.ToString();
                        codeSnippet.Column = processor.Column;
                        codeSnippet.Line   = processor.LineIndex;

                        processor.NewBlocks.Push(codeSnippet);
                        return(BlockState.BreakDiscard);
                    }
                }
            }

            return(BlockState.None);
        }
Beispiel #5
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var startPosition = processor.GetSourcePosition(slice.Start, out var line, out var column);

            if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
            {
                return(false);
            }

            if (slice.CurrentChar == '-')
            {
                slice.NextChar();
            }

            string title = null, path = null;

            if (!ExtensionsHelper.MatchLink(ref slice, ref title, ref path) || !ExtensionsHelper.MatchInclusionEnd(ref slice))
            {
                return(false);
            }

            processor.Inline = new InclusionInline
            {
                Title            = title,
                IncludedFilePath = path,
                Line             = line,
                Column           = column,
                Span             = new SourceSpan(startPosition, processor.GetSourcePosition(slice.Start - 1)),
                IsClosed         = true,
            };

            return(true);
        }
Beispiel #6
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
            {
                return(false);
            }
            else
            {
                if (slice.CurrentChar == '-')
                {
                    slice.NextChar();
                }
            }

            var    includeFile = new InclusionInline();
            string title = null, path = null;

            if (!ExtensionsHelper.MatchLink(ref slice, ref title, ref path))
            {
                return(false);
            }

            includeFile.Title            = title;
            includeFile.IncludedFilePath = path;
            processor.Inline             = includeFile;

            return(true);
        }
Beispiel #7
0
        public override BlockState TryContinue(BlockProcessor processor, Block block)
        {
            if (processor.IsBlankLine)
            {
                return(BlockState.Continue);
            }

            var slice        = processor.Line;
            var monikerRange = (MonikerRangeBlock)block;

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, new string(':', monikerRange.ColonCount)))
            {
                return(BlockState.Continue);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, "moniker-end", false))
            {
                return(BlockState.Continue);
            }

            var c = ExtensionsHelper.SkipSpaces(ref slice);

            if (!c.IsZero())
            {
                Logger.LogWarning($"MonikerRange have some invalid chars in the ending.");
            }

            block.UpdateSpanEnd(slice.End);

            return(BlockState.BreakDiscard);
        }
Beispiel #8
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            var slice          = processor.Line;
            var column         = processor.Column;
            var sourcePosition = processor.Start;

            if (processor.IsCodeIndent ||
                !ExtensionsHelper.MatchStart(ref slice, ":::"))
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            var extensionName = "triple-colon";
            ITripleColonExtensionInfo    extension;
            IDictionary <string, string> attributes;
            HtmlAttributes htmlAttributes;
            IDictionary <string, string> renderProperties;
            Action <string> logError = (string message) => _context.LogError(
                $"invalid-{extensionName}",
                $"Invalid {extensionName} on line {processor.LineIndex}. \"{slice.Text}\" is invalid. {message}",
                null,
                line: processor.LineIndex);

            if (!TryMatchIdentifier(ref slice, out extensionName) ||
                !_extensions.TryGetValue(extensionName, out extension) ||
                !extension.TryValidateAncestry(processor.CurrentContainer, logError) ||
                !TryMatchAttributes(ref slice, out attributes, extensionName, extension.SelfClosing, logError) ||
                !extension.TryProcessAttributes(attributes, out htmlAttributes, out renderProperties, logError))
            {
                return(BlockState.None);
            }

            var block = new TripleColonBlock(this)
            {
                Closed           = false,
                Column           = column,
                Line             = processor.LineIndex,
                Span             = new SourceSpan(sourcePosition, slice.End),
                Extension        = extension,
                RenderProperties = renderProperties
            };

            if (htmlAttributes != null)
            {
                block.SetData(typeof(HtmlAttributes), htmlAttributes);
            }

            processor.NewBlocks.Push(block);

            if (extension.SelfClosing)
            {
                return(BlockState.BreakDiscard);
            }

            return(BlockState.ContinueDiscard);
        }
Beispiel #9
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
            {
                return(false);
            }

            var href      = StringBuilderCache.Local();
            var c         = slice.CurrentChar;
            var saved     = slice;
            var startChar = '\0';
            int line;
            int column;

            if (c == '\'' || c == '"')
            {
                startChar = c;
                c         = slice.NextChar();
            }

            while (c != startChar && c != '>')
            {
                href.Append(c);
                c = slice.NextChar();
            }

            if (startChar != '\0')
            {
                if (c != startChar)
                {
                    return(false);
                }

                c = slice.NextChar();
            }

            if (c != '>')
            {
                return(false);
            }
            slice.NextChar();

            var xrefInline = new XrefInline
            {
                Href   = href.ToString().Trim(),
                Span   = new SourceSpan(processor.GetSourcePosition(saved.Start, out line, out column), processor.GetSourcePosition(slice.Start - 1)),
                Line   = line,
                Column = column
            };

            var htmlAttributes = xrefInline.GetAttributes();

            htmlAttributes.AddPropertyIfNotExist("data-throw-if-not-resolved", "True");
            processor.Inline = xrefInline;

            return(true);
        }
Beispiel #10
0
        public override BlockState TryContinue(BlockProcessor processor, Block block)
        {
            var slice = processor.Line;

            if (processor.IsBlankLine)
            {
                return(BlockState.Continue);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, ":::"))
            {
                ExtensionsHelper.ResetLineIndent(processor);
                return(BlockState.Continue);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            var extensionName = ((TripleColonBlock)block).Extension.Name;

            if (!ExtensionsHelper.MatchStart(ref slice, extensionName) || !ExtensionsHelper.MatchStart(ref slice, "-end"))
            {
                ExtensionsHelper.ResetLineIndent(processor);
                return(BlockState.Continue);
            }

            var c = ExtensionsHelper.SkipSpaces(ref slice);

            var endingTripleColons = ((TripleColonBlock)block).EndingTripleColons;

            if (endingTripleColons && !ExtensionsHelper.MatchStart(ref slice, ":::"))
            {
                _context.LogWarning(
                    $"invalid-{extensionName}",
                    $"Invalid {extensionName} on line {block.Line}. \"{slice.Text}\" is invalid. Missing ending \":::{extensionName}-end:::\"",
                    block);
                return(BlockState.Continue);
            }

            if (!c.IsZero() && !endingTripleColons)
            {
                _context.LogWarning(
                    $"invalid-{extensionName}",
                    $"Invalid {extensionName} on line {block.Line}. \"{slice.Text}\" is invalid. Invalid character after \"::: {extensionName}-end\": \"{c}\"",
                    block);
            }

            block.UpdateSpanEnd(slice.End);
            block.IsOpen = false;
            (block as TripleColonBlock).Closed = true;

            return(BlockState.BreakDiscard);
        }
Beispiel #11
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            if (processor.IsCodeIndent)
            {
                return(BlockState.None);
            }

            // [!include[<title>](<filepath>)]
            var column  = processor.Column;
            var line    = processor.Line;
            var command = line.ToString();

            if (!ExtensionsHelper.MatchStart(ref line, StartString, false))
            {
                return(BlockState.None);
            }
            else
            {
                if (line.CurrentChar == '+')
                {
                    line.NextChar();
                }
            }

            string title = null, path = null;

            if (!ExtensionsHelper.MatchLink(ref line, ref title, ref path) || !ExtensionsHelper.MatchInlcusionEnd(ref line))
            {
                return(BlockState.None);
            }

            while (line.CurrentChar.IsSpaceOrTab())
            {
                line.NextChar();
            }
            if (line.CurrentChar != '\0')
            {
                return(BlockState.None);
            }

            processor.NewBlocks.Push(new InclusionBlock(this)
            {
                Title            = title,
                IncludedFilePath = path,
                Line             = processor.LineIndex,
                Column           = column,
            });

            return(BlockState.BreakDiscard);
        }
Beispiel #12
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            if (processor.IsCodeIndent)
            {
                return(BlockState.None);
            }

            var slice = processor.Line;

            if (ExtensionsHelper.IsEscaped(slice))
            {
                return(BlockState.None);
            }

            var column         = processor.Column;
            var sourcePosition = processor.Start;
            var colonCount     = 0;

            var c = slice.CurrentChar;

            while (c == Colon)
            {
                c = slice.NextChar();
                colonCount++;
            }

            if (colonCount < 3)
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
            {
                return(BlockState.None);
            }

            processor.NewBlocks.Push(new RowBlock(this)
            {
                ColonCount = colonCount,
                Column     = column,
                Span       = new SourceSpan(sourcePosition, slice.End),
            });

            return(BlockState.ContinueDiscard);
        }
Beispiel #13
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            if (processor.IsCodeIndent)
            {
                return(BlockState.None);
            }

            // [!include[<title>](<filepath>)]
            var column      = processor.Column;
            var line        = processor.Line;
            var command     = line.ToString();
            var includeFile = new InclusionBlock(this);

            if (!ExtensionsHelper.MatchStart(ref line, StartString, false))
            {
                return(BlockState.None);
            }
            else
            {
                if (line.CurrentChar == '+')
                {
                    line.NextChar();
                }
            }

            var context = new InclusionContext();

            if (!ExtensionsHelper.MatchLink(ref line, ref context))
            {
                return(BlockState.None);
            }

            while (line.CurrentChar.IsSpaceOrTab())
            {
                line.NextChar();
            }
            if (line.CurrentChar != '\0')
            {
                return(BlockState.None);
            }

            includeFile.Context = context;
            processor.NewBlocks.Push(includeFile);

            return(BlockState.BreakDiscard);
        }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (!ExtensionsHelper.MatchStart(ref slice, ":::"))
            {
                return(false);
            }

            if (!TripleColonBlockParser.TryMatchIdentifier(ref slice, out var extensionName) ||
                !_extensions.TryGetValue(extensionName, out var extension))
            {
                return(false);
            }

            var inline = new TripleColonInline(this)
            {
                Closed = false,
                Column = 0,
                Line   = processor.LineIndex,
                Span   = new SourceSpan(processor.LineIndex, slice.End),
            };

            var logError   = new Action <string>(message => _context.LogError($"invalid-{extensionName}", message, inline));
            var logWarning = new Action <string>(message => _context.LogWarning($"invalid-{extensionName}", message, inline));

            if (!TripleColonBlockParser.TryMatchAttributes(ref slice, out var attributes, extension.SelfClosing, logError) ||
                !extension.TryProcessAttributes(attributes, out var htmlAttributes, out var renderProperties, logError, logWarning, inline))
            {
                return(false);
            }

            inline.Extension        = extension;
            inline.Attributes       = attributes;
            inline.RenderProperties = renderProperties;

            if (htmlAttributes != null)
            {
                inline.SetData(typeof(HtmlAttributes), htmlAttributes);
            }

            processor.Inline = inline;

            return(true);
        }
Beispiel #15
0
        private bool TryMatchAttributes(ref StringSlice slice, out IDictionary <string, string> attributes, string extensionName, bool selfClosing, Action <string> logError)
        {
            attributes = EmptyAttributes;
            while (true)
            {
                ExtensionsHelper.SkipSpaces(ref slice);
                if (slice.CurrentChar.IsZero() || (selfClosing && ExtensionsHelper.MatchStart(ref slice, ":::")))
                {
                    return(true);
                }

                if (!TryMatchIdentifier(ref slice, out var attributeName))
                {
                    logError("Invalid attribute.");
                    return(false);
                }
                if (attributes.ContainsKey(attributeName))
                {
                    logError($"Attribute \"{attributeName}\" specified multiple times.");
                    return(false);
                }

                var value = string.Empty;

                ExtensionsHelper.SkipSpaces(ref slice);
                if (slice.CurrentChar == '=')
                {
                    slice.NextChar();
                    ExtensionsHelper.SkipSpaces(ref slice);
                    if (!TryMatchAttributeValue(ref slice, out value, extensionName, attributeName, logError))
                    {
                        return(false);
                    }
                }

                if (attributes == EmptyAttributes)
                {
                    attributes = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                }
                attributes.Add(attributeName, value);
            }
        }
Beispiel #16
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            if (processor.IsCodeIndent)
            {
                return(BlockState.None);
            }

            var slice          = processor.Line;
            var column         = processor.Column;
            var sourcePosition = processor.Start;
            var colonCount     = 0;

            var c = slice.CurrentChar;

            while (c == Colon)
            {
                c = slice.NextChar();
                colonCount++;
            }

            if (colonCount < 3)
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, "moniker", false))
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, "range=\"", false))
            {
                return(BlockState.None);
            }

            var range = StringBuilderCache.Local();

            c = slice.CurrentChar;

            while (c != '\0' && c != '"')
            {
                range.Append(c);
                c = slice.NextChar();
            }

            if (c != '"')
            {
                _context.LogWarning("invalid-moniker-range", "MonikerRange does not have ending charactor (\").");
                return(BlockState.None);
            }

            c = slice.NextChar();
            while (c.IsSpace())
            {
                c = slice.NextChar();
            }

            if (!c.IsZero())
            {
                _context.LogWarning("invalid-moniker-range", $"MonikerRange have some invalid chars in the starting.");
            }

            var monikerRange = new MonikerRangeBlock(this)
            {
                Closed       = false,
                MonikerRange = range.ToString(),
                ColonCount   = colonCount,
                Column       = column,
                Span         = new SourceSpan(sourcePosition, slice.End),
            };

            monikerRange.GetAttributes().AddPropertyIfNotExist("range", monikerRange.MonikerRange);

            processor.NewBlocks.Push(monikerRange);

            return(BlockState.ContinueDiscard);
        }
Beispiel #17
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            if (processor.IsCodeIndent)
            {
                return(BlockState.None);
            }

            var slice = processor.Line;

            if (ExtensionsHelper.IsEscaped(slice))
            {
                return(BlockState.None);
            }

            var column         = processor.Column;
            var sourcePosition = processor.Start;
            var colonCount     = 0;

            var c = slice.CurrentChar;

            while (c == Colon)
            {
                c = slice.NextChar();
                colonCount++;
            }

            if (colonCount < 3)
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, "render=\"", false))
            {
                return(BlockState.None);
            }

            var range = StringBuilderCache.Local();

            c = slice.CurrentChar;

            while (c != '\0' && c != '"')
            {
                range.Append(c);
                c = slice.NextChar();
            }

            if (c != '"')
            {
                _context.LogWarning("invalid-render-zone", "Zone render does not have ending character (\").");
                return(BlockState.None);
            }

            c = slice.NextChar();
            while (c.IsSpace())
            {
                c = slice.NextChar();
            }

            if (!c.IsZero())
            {
                _context.LogWarning("invalid-render-zone", $"Zone render has some invalid chars in the beginning.");
            }

            // Check the blockprocessor context to see if we are already inside of a zone
            // container. If so, break.
            var containerBlock = processor.CurrentContainer;

            do
            {
                if (processor.CurrentContainer.GetType() == typeof(RenderZoneBlock))
                {
                    _context.LogError("invalid-render-zone", "Zone render cannot be nested.");
                    return(BlockState.None);
                }
                containerBlock = containerBlock.Parent;
            } while (containerBlock != null);

            processor.NewBlocks.Push(new RenderZoneBlock(this)
            {
                Closed     = false,
                ColonCount = colonCount,
                Column     = column,
                Span       = new SourceSpan(sourcePosition, slice.End),
                Target     = range.ToString(),
            });

            return(BlockState.ContinueDiscard);
        }
Beispiel #18
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            var slice          = processor.Line;
            var sourcePosition = processor.Start;

            if (processor.IsCodeIndent ||
                !ExtensionsHelper.MatchStart(ref slice, ":::"))
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            var             extensionName = "triple-colon";
            Action <string> logError      = (string message) => _context.LogError(
                $"invalid-{extensionName}",
                $"{message}",
                null,
                line: processor.LineIndex);
            Action <string> logWarning = (string message) => _context.LogWarning(
                $"invalid-{extensionName}",
                $"{message}",
                null,
                line: processor.LineIndex);

            var block = new TripleColonBlock(this)
            {
                Closed = false,
                Column = processor.Column,
                Line   = processor.LineIndex,
                Span   = new SourceSpan(sourcePosition, slice.End),
            };

            if (!TryMatchIdentifier(ref slice, out extensionName) ||
                !_extensions.TryGetValue(extensionName, out var extension) ||
                !extension.TryValidateAncestry(processor.CurrentContainer, logError) ||
                !TryMatchAttributes(ref slice, out var attributes, extensionName, extension.SelfClosing, logError) ||
                !extension.TryProcessAttributes(attributes, out var htmlAttributes, out var renderProperties, logError, logWarning, block))
            {
                return(BlockState.None);
            }

            block.Extension        = extension;
            block.Attributes       = attributes;
            block.RenderProperties = renderProperties;

            if (htmlAttributes != null)
            {
                block.SetData(typeof(HtmlAttributes), htmlAttributes);
            }

            processor.NewBlocks.Push(block);

            if (extension.GetType() == typeof(ImageExtension) &&
                htmlAttributes != null &&
                ImageExtension.RequiresClosingTripleColon(attributes))
            {
                block.EndingTripleColons = true;
                return(BlockState.ContinueDiscard);
            }

            if (extension.SelfClosing)
            {
                return(BlockState.BreakDiscard);
            }

            return(BlockState.ContinueDiscard);
        }
Beispiel #19
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            if (processor.IsCodeIndent)
            {
                return(BlockState.None);
            }

            var slice = processor.Line;

            if (ExtensionsHelper.IsEscaped(slice))
            {
                return(BlockState.None);
            }

            var column         = processor.Column;
            var sourcePosition = processor.Start;
            var colonCount     = 0;

            var c = slice.CurrentChar;

            while (c == Colon)
            {
                c = slice.NextChar();
                colonCount++;
            }

            if (colonCount < 3)
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, "moniker", false))
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, "range=\"", false))
            {
                return(BlockState.None);
            }

            var range = StringBuilderCache.Local();

            c = slice.CurrentChar;

            while (c != '\0' && c != '"')
            {
                range.Append(c);
                c = slice.NextChar();
            }

            if (c != '"')
            {
                return(BlockState.None);
            }

            c = slice.NextChar();
            while (c.IsSpace())
            {
                c = slice.NextChar();
            }

            if (!c.IsZero())
            {
                Logger.LogWarning($"MonikerRange have some invalid chars in the starting.");
            }

            processor.NewBlocks.Push(new MonikerRangeBlock(this)
            {
                MonikerRange = range.ToString(),
                ColonCount   = colonCount,
                Column       = column,
                Span         = new SourceSpan(sourcePosition, slice.End),
            });

            return(BlockState.ContinueDiscard);
        }
Beispiel #20
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            if (processor.IsBlankLine)
            {
                return(BlockState.Continue);
            }

            var slice = processor.Line;

            if (ExtensionsHelper.IsEscaped(slice))
            {
                return(BlockState.None);
            }

            var column         = processor.Column;
            var sourcePosition = processor.Start;
            var colonCount     = 0;

            ExtensionsHelper.SkipSpaces(ref slice);

            var columnWidth = StringBuilderCache.Local();
            var c           = slice.CurrentChar;

            while (c == Colon)
            {
                c = slice.NextChar();
                colonCount++;
            }

            if (colonCount < 3)
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
            {
                return(BlockState.None);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

            if (ExtensionsHelper.MatchStart(ref slice, "span=\"", false))
            {
                c = slice.CurrentChar;

                while (c != '"')
                {
                    columnWidth.Append(c);
                    c = slice.NextChar();
                }

                if (!ExtensionsHelper.MatchStart(ref slice, "\"", false))
                {
                    return(BlockState.None);
                }
            }
            else
            {
                columnWidth.Append("1"); // default span is one
            }

            while (c.IsSpace())
            {
                c = slice.NextChar();
            }

            if (!ExtensionsHelper.MatchStart(ref slice, ":::", false)) //change
            {
                return(BlockState.None);
            }

            if (!c.IsZero())
            {
                Logger.LogWarning($"NestedColumn have some invalid chars in the starting.");
            }

            processor.NewBlocks.Push(new NestedColumnBlock(this)
            {
                ColumnWidth = columnWidth.ToString(),
                ColonCount  = colonCount,
                Column      = column,
                Span        = new SourceSpan(sourcePosition, slice.End),
            });

            return(BlockState.ContinueDiscard);
        }