Example #1
0
        // "+++ <name>" with optional trailing whitespace
        internal virtual bool IsOpeningLine(BlockProcessor blockProcessor)
        {
            StringSlice line = blockProcessor.Line;

            if (line.NextChar() != '+' ||
                line.NextChar() != '+' ||
                line.NextChar() != ' ')
            {
                return(false);
            }

            for (int i = 0; i < _nameLength; i++)
            {
                if (line.NextChar() != _name[i])
                {
                    return(false);
                }
            }

            // Nothing other than whitespace after the name. A multipart block's name may begin with the name of another
            // multipart block, this ensures we don't confuse such blocks.
            line.NextChar();
            line.TrimEnd();

            return(line.CurrentChar == '\0');
        }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (slice.CurrentChar == '$' && slice.PeekChar(1) == '(')
            {
                slice.NextChar();
                slice.NextChar();

                int start = slice.Start;
                int end   = start;

                while (slice.CurrentChar != ')')
                {
                    end = slice.Start;
                    slice.NextChar();
                }

                processor.GetSourcePosition(slice.Start, out int line, out int column);

                processor.Inline = new VariableInline
                {
                    Line         = line,
                    Column       = column,
                    VariableName = new StringSlice(slice.Text, start, end)
                };

                slice.NextChar();

                return(true);
            }

            return(false);
        }
Example #3
0
        private static bool MatchPath(ref StringSlice slice, ref string path)
        {
            if (slice.CurrentChar != '(')
            {
                return(false);
            }

            slice.NextChar();
            SkipWhitespace(ref slice);

            string includedFilePath;

            if (slice.CurrentChar == '<')
            {
                includedFilePath = TryGetStringBeforeChars(new char[] { ')', '>' }, ref slice, breakOnWhitespace: true);
            }
            else
            {
                includedFilePath = TryGetStringBeforeChars(new char[] { ')' }, ref slice, breakOnWhitespace: true);
            };

            if (includedFilePath == null)
            {
                return(false);
            }

            if (includedFilePath.Length >= 1 && includedFilePath.First() == '<' && slice.CurrentChar == '>')
            {
                includedFilePath = includedFilePath.Substring(1, includedFilePath.Length - 1).Trim();
            }

            if (slice.CurrentChar == ')')
            {
                path = includedFilePath;
                slice.NextChar();
                return(true);
            }
            else
            {
                var title = TryGetStringBeforeChars(new char[] { ')' }, ref slice, breakOnWhitespace: false);
                if (title == null)
                {
                    return(false);
                }
                else
                {
                    if (title.Length >= 2 && title.First() == '\'' && title.Last() == '\'')
                    {
                        title = title.Substring(1, title.Length - 2).Trim();
                    }
                    else if (title.Length >= 2 && title.First() == '\"' && title.Last() == '\"')
                    {
                        title = title.Substring(1, title.Length - 2).Trim();
                    }
                    path = includedFilePath;
                    slice.NextChar();
                    return(true);
                }
            }
        }
Example #4
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            // A tasklist is either
            // [ ]
            // or [x] or [X]

            if (!(processor.Block !.Parent is ListItemBlock listItemBlock))
            {
                return(false);
            }

            var startingPosition = slice.Start;
            var c = slice.NextChar();

            if (!c.IsSpace() && c != 'x' && c != 'X')
            {
                return(false);
            }
            if (slice.NextChar() != ']')
            {
                return(false);
            }
            // Skip last ]
            slice.SkipChar();

            // Create the TaskList
            var taskItem = new TaskList()
            {
                Span    = { Start = processor.GetSourcePosition(startingPosition, out int line, out int column) },
Example #5
0
        private bool MatchBookMarkQuery(BlockProcessor processor, ref StringSlice slice, ref CodeSnippet codeSnippet)
        {
            if (slice.CurrentChar != '#')
            {
                return(false);
            }

            var queryChar = slice.CurrentChar;
            var query     = StringBuilderCache.Local();
            var c         = slice.NextChar();

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

            var queryString = query.ToString().Trim();

            CodeRange codeRange;

            if (TryGetLineRange(queryString, out codeRange))
            {
                codeSnippet.BookMarkRange = codeRange;
            }
            else
            {
                codeSnippet.TagName = queryString;
            }

            return(true);
        }
Example #6
0
        private bool MatchTitle(BlockProcessor processor, ref StringSlice slice, ref CodeSnippet codeSnippet)
        {
            if (slice.CurrentChar != '"')
            {
                return(false);
            }

            var title     = StringBuilderCache.Local();
            var c         = slice.NextChar();
            var hasEscape = false;

            while (c != '\0' && (c != '"' || hasEscape))
            {
                if (c == '\\' && !hasEscape)
                {
                    hasEscape = true;
                }
                else
                {
                    title.Append(c);
                    hasEscape = false;
                }
                c = slice.NextChar();
            }

            codeSnippet.Title = title.ToString().Trim();

            if (c == '"')
            {
                slice.NextChar();
                return(true);
            }

            return(false);
        }
Example #7
0
        /// <summary>
        /// Splits a slice into an IEnumerable of slices split on newlines
        /// </summary>
        /// <param name="slice">The slice to split</param>
        /// <returns>The line split into lines</returns>
        public static IEnumerable <StringSlice> SplitSliceToLines(StringSlice slice)
        {
            var sliceStart = slice.Start;

            while (!slice.IsEmpty)
            {
                if (slice.CurrentChar == '\n')
                {
                    slice.NextChar();
                    yield return(new StringSlice(slice.Text, sliceStart, slice.Start - 1));

                    sliceStart = slice.Start;
                    continue;
                }

                if (slice.CurrentChar == '\r' && slice.PeekChar(1) == '\n')
                {
                    slice.Start += 2;
                    yield return(new StringSlice(slice.Text, sliceStart, slice.Start - 1));

                    sliceStart = slice.Start;
                    continue;
                }

                slice.NextChar();
            }

            if (sliceStart != slice.Start)
            {
                yield return(new StringSlice(slice.Text, sliceStart, slice.Start - 1));
            }
        }
Example #8
0
        private bool TryMatchAttributeValue(ref StringSlice slice, out string value, string extensionName, string attributeName, Action <string> logError)
        {
            value = string.Empty;
            var c = slice.CurrentChar;

            if (c != '"')
            {
                logError($"Invalid attribute \"{attributeName}\". Values must be enclosed in double quotes.");
                return(false);
            }
            var b = StringBuilderCache.Local();

            c = slice.NextChar();
            while (c != '"')
            {
                if (c.IsZero())
                {
                    logError($"Invalid attribute \"{attributeName}\". Values must be terminated with a double quote.");
                    return(false);
                }
                b.Append(c);
                c = slice.NextChar();
            }
            slice.NextChar();
            value = b.ToString();
            return(true);
        }
Example #9
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            bool matchFound;
            char previous;

            matchFound = false;
            previous   = slice.PeekCharExtra(-1);

            if (!previous.IsWhiteSpaceOrZero())
            {
                return(false);
            }

            char current;
            int  start;
            int  end;

            slice.NextChar();

            current = slice.CurrentChar;
            start   = slice.Start;
            end     = start;

            StringBuilder ep  = new StringBuilder();
            StringBuilder num = new StringBuilder();

            while (current != ',')
            {
                end = slice.Start;
                ep.Append(current);
                current = slice.NextChar();
            }

            current = slice.NextChar();

            while (current != '}')
            {
                end = slice.Start;
                num.Append(current);
                current = slice.NextChar();
            }

            current = slice.NextChar();

            if (current.IsWhiteSpaceOrZero())
            {
                int inlineStart;
                inlineStart = processor.GetSourcePosition(slice.Start, out int line, out int column);

                processor.Inline = new Caps()
                {
                    Span = { Start = inlineStart, End = inlineStart + (end - start) + 1 }, Line = line, Column = column, CapEpisode = new StringSlice(ep.ToString()), CapNumber = new StringSlice(num.ToString())
                };

                matchFound = true;
            }

            return(matchFound);
        }
Example #10
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);
        }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (!slice.PeekCharExtra(-1).IsWhiteSpaceOrZero())
            {
                return(false); //require whitespace/nothing before
            }

            var key     = String.Empty;
            var issue   = String.Empty;
            var current = slice.CurrentChar;

            //read as many uppercase characters as required - project key
            while (current.IsAlphaUpper())
            {
                key    += current;
                current = slice.NextChar();
            }

            //require a '-' between key and issue number
            if (!current.Equals('-'))
            {
                return(false);
            }

            current = slice.NextChar();

            //read as many numbers as required - issue number
            while (current.IsDigit())
            {
                issue  += current;
                current = slice.NextChar();
            }

            if (!current.IsWhiteSpaceOrZero()) //must be followed by whitespace
            {
                return(false);
            }

            int line;
            int column;

            processor.Inline = new JiraLink() //create the link at the relevant position
            {
                Span =
                {
                    Start = processor.GetSourcePosition(slice.Start, out line, out column)
                },
                Line   = line,
                Column = column,
                Issue  = issue,
                Key    = key
            };

            processor.Inline.Span.End = processor.Inline.Span.Start + issue.Length + key.Length + 1; //+1 for the '-'

            return(true);
        }
Example #12
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            bool matchFound;
            char next;

            matchFound = false;

            next = slice.PeekCharExtra(1);

            if (next == '<')
            {
                char current;
                int  start;
                int  end;

                slice.NextChar();
                slice.NextChar(); // skip the opening pair

                current = slice.CurrentChar;
                start   = slice.Start;
                end     = start;

                while (current != '\0' && current != '>')
                {
                    end++;
                    current = slice.NextChar();
                }

                if (end > start && current == '>' && slice.PeekCharExtra(1) == '>')
                {
                    int inlineStart;

                    end--;
                    inlineStart = processor.GetSourcePosition(slice.Start, out int line, out int column);

                    processor.Inline = new KeyboardInline
                    {
                        Span =
                        {
                            Start = inlineStart,
                            End   = inlineStart + (end - start)
                        },
                        Line   = line,
                        Column = column,
                        Text   = new StringSlice(slice.Text, start, end)
                    };

                    slice.NextChar();
                    slice.NextChar(); // skip the closing characters

                    matchFound = true;
                }
            }

            return(matchFound);
        }
Example #13
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            // Allow preceding whitespace or `(`
            var pc = slice.PeekCharExtra(-1);

            if (!pc.IsWhiteSpaceOrZero() && pc != '(')
            {
                return(false);
            }

            var current = slice.CurrentChar;

            var startKey = slice.Start;
            var endKey   = slice.Start;

            //read as many uppercase characters as required - project key
            while (current.IsAlphaUpper())
            {
                endKey  = slice.Start;
                current = slice.NextChar();
            }

            //require a '-' between key and issue number
            if (!current.Equals('-'))
            {
                return(false);
            }

            current = slice.NextChar(); // skip -

            //read as many numbers as required - issue number
            if (!current.IsDigit())
            {
                return(false);
            }

            var startIssue = slice.Start;
            var endIssue   = slice.Start;

            while (current.IsDigit())
            {
                endIssue = slice.Start;
                current  = slice.NextChar();
            }

            if (!current.IsWhiteSpaceOrZero() && current != ')') //can be followed only by a whitespace or `)`
            {
                return(false);
            }

            var jiraLink = new JiraLink() //create the link at the relevant position
            {
                Span =
                {
                    Start = processor.GetSourcePosition(slice.Start, out int line, out int column)
                },
Example #14
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            // A tasklist is either
            // [ ]
            // or [x] or [X]

            var listItemBlock = processor.Block.Parent as ListItemBlock;

            if (listItemBlock == null)
            {
                return(false);
            }

            var startingPosition = slice.Start;
            var c = slice.NextChar();

            if (!c.IsSpace() && c != 'x' && c != 'X')
            {
                return(false);
            }
            if (slice.NextChar() != ']')
            {
                return(false);
            }
            // Skip last ]
            slice.NextChar();

            // Create the TaskList
            int line;
            int column;
            var taskItem = new TaskList()
            {
                Span    = { Start = processor.GetSourcePosition(startingPosition, out line, out column) },
                Line    = line,
                Column  = column,
                Checked = !c.IsSpace()
            };

            taskItem.Span.End = taskItem.Span.Start + 2;
            processor.Inline  = taskItem;

            // Add proper class for task list
            if (!string.IsNullOrEmpty(ListItemClass))
            {
                listItemBlock.GetAttributes().AddClass(ListItemClass);
            }

            var listBlock = (ListBlock)listItemBlock.Parent;

            if (!string.IsNullOrEmpty(ListClass))
            {
                listBlock.GetAttributes().AddClass(ListClass);
            }

            return(true);
        }
Example #15
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            bool matchFound;
            char previous;

            matchFound = false;

            previous = slice.PeekCharExtra(-1);

            if (previous.IsWhiteSpaceOrZero() || previous == '(' || previous == '[')
            {
                char current;
                int  start;
                int  end;

                slice.NextChar(); // skip the # starting character

                current = slice.CurrentChar;
                start   = slice.Start;
                end     = start;

                // read as many digits as we can find, incrementing the slice length as we go
                while (current.IsDigit())
                {
                    end     = slice.Start;
                    current = slice.NextChar();
                }

                // once we've ran out of digits, check to see what the next character is
                // to make sure this is a valid issue and nothing something random like #001Alpha
                if (current.IsWhiteSpaceOrZero() || current == ')' || current == ']')
                {
                    int inlineStart;

                    inlineStart = processor.GetSourcePosition(slice.Start, out int line, out int column);

                    // and if we got here, then we've got a valid reference, so create our AST node
                    // and assign it to the processor
                    processor.Inline = new MantisLink
                    {
                        Span =
                        {
                            Start = inlineStart,
                            End   = inlineStart + (end - start) + 1    // add one to the length to account for the # starting character
                        },
                        Line        = line,
                        Column      = column,
                        IssueNumber = new StringSlice(slice.Text, start, end)
                    };

                    matchFound = true;
                }
            }

            return(matchFound);
        }
Example #16
0
        /// <summary>
        /// Parses a column header equivalent to the regexp: <code>\s*:\s*[delimiterChar]+\s*:\s*</code>
        /// </summary>
        /// <param name="slice">The text slice.</param>
        /// <param name="delimiterChar">The delimiter character (either `-` or `=`). If `\0`, it will detect the character (either `-` or `=`)</param>
        /// <param name="align">The alignment of the column.</param>
        /// <returns>
        ///   <c>true</c> if parsing was successfull
        /// </returns>
        public static bool ParseColumnHeaderDetect(ref StringSlice slice, ref char delimiterChar, out TableColumnAlign?align)
        {
            align = null;

            slice.TrimStart();
            var  c        = slice.CurrentChar;
            bool hasLeft  = false;
            bool hasRight = false;

            if (c == ':')
            {
                hasLeft = true;
                slice.NextChar();
            }

            slice.TrimStart();
            c = slice.CurrentChar;

            // if we want to automatically detect
            if (delimiterChar == '\0')
            {
                if (c == '=' || c == '-')
                {
                    delimiterChar = c;
                }
                else
                {
                    return(false);
                }
            }

            // We expect at least one `-` delimiter char
            if (slice.CountAndSkipChar(delimiterChar) == 0)
            {
                return(false);
            }

            slice.TrimStart();
            c = slice.CurrentChar;

            if (c == ':')
            {
                hasRight = true;
                slice.NextChar();
            }
            slice.TrimStart();

            align = hasLeft && hasRight
                ? TableColumnAlign.Center
                : hasRight ? TableColumnAlign.Right : hasLeft ? TableColumnAlign.Left : (TableColumnAlign?)null;

            return(true);
        }
Example #17
0
    /// <summary>
    /// Tries to match the specified slice.
    /// </summary>
    /// <param name="processor">The parser processor.</param>
    /// <param name="slice">The text slice.</param>
    /// <returns><c>true</c> if this parser found a match; <c>false</c> otherwise</returns>
    public override bool Match(InlineProcessor processor, ref StringSlice slice)
    {
        var c             = slice.CurrentChar;
        var startPosition = processor.GetSourcePosition(slice.Start, out var line, out var column);

        var isImage = false;

        if (c == '!')
        {
            isImage = true;
            c       = slice.NextChar();
            if (c != LinkOpenChar)
            {
                return(false);
            }
        }

        switch (c)
        {
        case LinkOpenChar:
            if (slice.PeekChar() != LinkOpenChar)
            {
                return(false);
            }
            var saved           = slice;
            var currentPosition = slice.Start;
            if (TryParseLink(ref slice, out var title, out var display, out var hasDisplay, out var autoDisplay, out var endPosition))
            {
                processor.Inline = new WikiLinkDelimiterInline(this)
                {
                    Type        = DelimiterType.Open,
                    AutoDisplay = autoDisplay,
                    Display     = display,
                    HasDisplay  = hasDisplay,
                    Title       = title,
                    IsImage     = isImage,
                    Span        = new SourceSpan(startPosition, processor.GetSourcePosition(slice.Start - 1)),
                    Line        = line,
                    Column      = column,
                };
                slice = saved;
                if (endPosition == currentPosition)
                {
                    slice.NextChar();
                    slice.NextChar();
                }
                else
                {
                    slice.Start = endPosition;
                    slice.NextChar();
                }
            }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var  _isMatch = false;
            int  _start, _end;
            var  _url = "";
            char _current;
            var  _fullSlice = slice.ToString().ToLower().TrimStart(OpeningCharacters);

            if (!slice.PeekCharExtra(-1).IsWhiteSpaceOrZero())
            {
                return(_isMatch);
            }

            if (_configuration.BaseUrls.Where(u => _fullSlice.StartsWith(u)).Count() == 0)
            {
                return(_isMatch);
            }

            _start   = slice.Start;
            _end     = _start;
            _current = slice.NextChar();

            while (_current != ']')
            {
                _url    += _current;
                _end     = slice.Start;
                _current = slice.NextChar();
            }

            if (_current == ']')
            {
                slice.NextChar();

                var _inlineStart = processor.GetSourcePosition(slice.Start, out int _line, out int _column);

                processor.Inline = new EmbeddedGist
                {
                    Span =
                    {
                        Start = _inlineStart,
                        End   = _inlineStart + (_end - _start) + 1
                    },
                    Line   = _line,
                    Column = _column,
                    Url    = _url
                };

                _isMatch = true;
            }

            return(_isMatch);
        }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (slice.PeekCharExtra(1) != 'S' ||
                slice.PeekCharExtra(2) != 'c' ||
                slice.PeekCharExtra(3) != 'r' ||
                slice.PeekCharExtra(4) != 'i' ||
                slice.PeekCharExtra(5) != 'p' ||
                slice.PeekCharExtra(6) != 't' ||
                slice.PeekCharExtra(7) != 'C' ||
                slice.PeekCharExtra(8) != 's' ||
                slice.PeekCharExtra(9) != ' ')
            {
                return(false);
            }

            var  content = String.Empty;
            var  issue   = String.Empty;
            char current;
            int  counter = 1;   //Account for the `
            bool loop    = true;

            for (int i = 0; i < slice.End && loop; i++)
            {
                current = slice.NextChar();
                counter++;

                if (current == '`')
                {
                    loop = false;
                }
                else
                {
                    content += current;
                }
            }
            slice.NextChar();
            counter++;
            int line;
            int column;

            processor.Inline = new ScriptCsInline()
            {
                Script = content.Substring(9)
            };
            processor.Inline.Span = new SourceSpan()
            {
                Start = processor.GetSourcePosition(slice.Start, out line, out column)
            };
            processor.Inline.Line     = line;
            processor.Inline.Span.End = processor.Inline.Span.Start + counter;
            return(true);
        }
Example #20
0
        public void TestStringLineGroupWithModifiedStart()
        {
            var line1 = new StringSlice("  ABC");
            line1.NextChar();
            line1.NextChar();

            var line2 = new StringSlice("  DEF ");
            line2.Trim();

            var text = new StringLineGroup(4) {line1, line2};

            var result = ToString(text.ToCharIterator());
            TextAssert.AreEqual("ABC\nDEF", result);
        }
Example #21
0
        /// <summary>
        /// Tries to open a section tag using the slice
        /// </summary>
        /// <param name="processor">The processor</param>
        /// <param name="slice">The slice</param>
        /// <returns>The result of the match</returns>
        public override ParserState TryOpenBlock(Processor processor, ref StringSlice slice)
        {
            var tagStart = slice.Start - processor.CurrentTags.StartTag.Length;
            var index    = slice.Start;

            while (slice[index].IsWhitespace())
            {
                index++;
            }

            var match = slice[index];

            if (match == OpeningTagDelimiter)
            {
                slice.Start = index + 1; // Skip delimiter

                while (slice.CurrentChar.IsWhitespace())
                {
                    slice.NextChar();
                }

                var startIndex = slice.Start;

                // Take characters until closing tag
                while (!slice.IsEmpty && !slice.Match(processor.CurrentTags.EndTag))
                {
                    slice.NextChar();
                }

                var sectionName          = slice.ToString(startIndex, slice.Start).TrimEnd();
                var contentStartPosition = slice.Start + processor.CurrentTags.EndTag.Length;

                var sectionTag = new SectionToken
                {
                    SectionName          = sectionName,
                    StartPosition        = tagStart,
                    ContentStartPosition = contentStartPosition,
                    Parser   = this,
                    IsClosed = false
                };

                processor.CurrentToken = sectionTag;

                slice.Start = contentStartPosition;

                return(ParserState.Break);
            }

            return(ParserState.Continue);
        }
        protected StringSlice ReadUntil(StringSlice slice, char until, out int end)
        {
            char current = slice.CurrentChar;
            int  start   = slice.Start;

            end = start;
            slice.NextChar();
            while (current != until || current.IsWhiteSpaceOrZero())
            {
                end     = slice.Start;
                current = slice.NextChar();
            }
            return(new StringSlice(slice.Text, start, end));
        }
Example #23
0
        /// <summary>
        /// Returns the next character in the line being processed. Update <see cref="Start"/> and <see cref="Column"/>.
        /// </summary>
        /// <returns>The next character or `\0` if end of line is reached</returns>
        public char NextChar()
        {
            var c = Line.CurrentChar;

            if (c == '\t')
            {
                Column = CharHelper.AddTab(Column);
            }
            else
            {
                Column++;
            }
            return(Line.NextChar());
        }
Example #24
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            bool matchFound;
            char previous;

            matchFound = false;
            previous   = slice.PeekCharExtra(-1);

            if (previous.IsWhiteSpaceOrZero() || previous == '(' || previous == '[')
            {
                char current;
                int  start;
                int  end;

                slice.NextChar();

                current = slice.CurrentChar;
                start   = slice.Start;
                end     = start;

                while (current.IsDigit())
                {
                    end     = slice.Start;
                    current = slice.NextChar();
                }

                if (current.IsWhiteSpaceOrZero() || current == ')' || current == ']')
                {
                    int inlineStart;

                    inlineStart = processor.GetSourcePosition(slice.Start, out int line, out int column);

                    processor.Inline = new Mention
                    {
                        Span =
                        {
                            Start = inlineStart,
                            End   = inlineStart + (end - start) + 1
                        },
                        Line     = line,
                        Column   = column,
                        Username = new StringSlice(slice.Text, start, end)
                    };

                    matchFound = true;
                }
            }

            return(matchFound);
        }
Example #25
0
        /// <summary>
        /// Try to create a block close tag
        /// </summary>
        /// <param name="processor">The processor</param>
        /// <param name="slice">the slice</param>
        /// <param name="token">the current block tag</param>
        /// <returns>If the close was successful</returns>
        public override bool TryClose(Processor processor, ref StringSlice slice, BlockToken token)
        {
            var sectionTag = (SectionToken)token;

            while (slice.CurrentChar.IsWhitespace())
            {
                slice.NextChar();
            }

            var blockStart = slice.Start - processor.CurrentTags.StartTag.Length;

            slice.Start = slice.Start + 1; // Skip the slash

            while (slice.CurrentChar.IsWhitespace())
            {
                slice.NextChar();
            }

            var startIndex = slice.Start;

            // Take characters until closing tag
            while (!slice.IsEmpty && !slice.Match(processor.CurrentTags.EndTag))
            {
                slice.NextChar();
            }

            var sectionName = slice.ToString(startIndex, slice.Start).TrimEnd();

            if (sectionTag.SectionName == sectionName)
            {
                var tagEnd = slice.Start + processor.CurrentTags.EndTag.Length;

                var endTag = new SectionEndToken
                {
                    SectionName        = sectionName,
                    EndPosition        = tagEnd,
                    ContentEndPosition = blockStart,
                    IsClosed           = true
                };

                processor.CurrentToken = endTag;

                slice.Start += processor.CurrentTags.EndTag.Length;
                return(true);
            }

            throw new StubbleException($"Cannot close Block '{sectionName}' at {blockStart}. There is already an unclosed Block '{sectionTag.SectionName}'");
        }
Example #26
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var previous = slice.PeekCharExtra(-1);

            //if (!previous.IsWhiteSpaceOrZero()) return false;

            slice.NextChar();

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

            var current = slice.NextChar();
            var start   = slice.Start;
            var end     = start;

            while (current.IsDigit())
            {
                end     = slice.Start;
                current = slice.NextChar();
            }

            if (!current.IsWhiteSpaceOrZero() && current.IsDigit())
            {
                return(false);
            }
            var inlineStart = processor.GetSourcePosition(slice.Start, out var line, out var column);

            if (!int.TryParse(new StringSlice(slice.Text, start, end).ToString(), out var parsedId))
            {
                return(false);
            }

            processor.Inline = new LinkToParsedModel
            {
                Span =
                {
                    Start = inlineStart,
                    End   = inlineStart + (end - start) + 1
                },
                Line   = line,
                Column = column,
                Id     = parsedId,
            };

            return(true);
        }
Example #27
0
        private BlockState TryParseTagType7(BlockProcessor state, StringSlice line, int startColumn, int startPosition)
        {
            var builder = StringBuilderCache.Local();
            var c       = line.CurrentChar;
            var result  = BlockState.None;

            if ((c == '/' && HtmlHelper.TryParseHtmlCloseTag(ref line, builder)) || HtmlHelper.TryParseHtmlTagOpenTag(ref line, builder))
            {
                // Must be followed by whitespace only
                bool hasOnlySpaces = true;
                c = line.CurrentChar;
                while (true)
                {
                    if (c == '\0')
                    {
                        break;
                    }
                    if (!c.IsWhitespace())
                    {
                        hasOnlySpaces = false;
                        break;
                    }
                    c = line.NextChar();
                }

                if (hasOnlySpaces)
                {
                    result = CreateHtmlBlock(state, HtmlBlockType.NonInterruptingBlock, startColumn, startPosition);
                }
            }

            builder.Length = 0;
            return(result);
        }
Example #28
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            // Allow preceding whitespace
            var pc = slice.PeekCharExtra(-1);

            if (!pc.IsWhiteSpaceOrZero())
            {
                return(false);
            }

            var current = slice.CurrentChar;

            var start = slice.Start;
            var end   = slice.Start;

            // Read allowed characters
            while (current.IsAlphaNumeric() || current == '-' || current == '_' || current == '#')
            {
                end     = slice.Start;
                current = slice.NextChar();
            }

            var tag = new Hashtag
            {
                Span =
                {
                    Start = processor.GetSourcePosition(slice.Start, out var line, out var column)
                },
Example #29
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);
        }
Example #30
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (!slice.Match(m_StartTag))
            {
                return(false);
            }

            var rawContent = new StringBuilder();

            var current = slice.CurrentChar;

            while (!rawContent.ToString().EndsWith(m_EndTag))
            {
                if (slice.IsEmpty)
                {
                    return(false);
                }

                rawContent.Append(current);
                current = slice.NextChar();
            }

            processor.Inline = new ProtectedTagsData(rawContent.ToString());

            return(true);
        }