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

            var slice        = processor.Line;
            var NestedColumn = (NestedColumnBlock)block;

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, new string(':', NestedColumn.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-nested-column", "NestedColumn have some invalid chars in the ending.", block);
            }

            block.UpdateSpanEnd(slice.End);

            return(BlockState.BreakDiscard);
        }
Example #2
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())
            {
                Logger.LogWarning($"Row has some invalid chars in the ending.");
            }

            block.UpdateSpanEnd(slice.End);

            return(BlockState.BreakDiscard);
        }
Example #3
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);
        }
Example #4
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);
        }
Example #5
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);
        }
Example #6
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);
            }
        }
Example #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)))
            {
                ExtensionsHelper.ResetLineIndent(processor);
                return(BlockState.Continue);
            }

            ExtensionsHelper.SkipSpaces(ref slice);

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

            var c = ExtensionsHelper.SkipSpaces(ref slice);

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

            block.UpdateSpanEnd(slice.End);
            monikerRange.Closed = true;

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

            var slice      = processor.Line;
            var renderZone = (RenderZoneBlock)block;

            ExtensionsHelper.SkipSpaces(ref slice);

            if (!ExtensionsHelper.MatchStart(ref slice, new string(':', renderZone.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-render-zone", $"Zone render has some invalid chars in the ending.");
            }

            block.UpdateSpanEnd(slice.End);
            renderZone.Closed = true;

            return(BlockState.BreakDiscard);
        }
Example #9
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);
        }
Example #10
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);
        }
Example #11
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);
        }
Example #12
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);
        }
Example #13
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);
        }