Esempio n. 1
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);
        }
Esempio n. 2
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var startPosition = slice.Start;
            // Go to escape character
            var c = slice.NextChar();
            int line;
            int column;

            if (c.IsAsciiPunctuation())
            {
                processor.Inline = new LiteralInline()
                {
                    Content = new StringSlice(slice.Text, slice.Start, slice.Start),
                    Span    = { Start = processor.GetSourcePosition(startPosition, out line, out column) },
                    Line    = line,
                    Column  = column,
                    IsFirstCharacterEscaped = true,
                };
                processor.Inline.Span.End = processor.Inline.Span.Start + 1;
                slice.SkipChar();
                return(true);
            }

            // A backslash at the end of the line is a [hard line break]:
            if (c == '\n' || c == '\r')
            {
                var newLine = c == '\n' ? NewLine.LineFeed : NewLine.CarriageReturn;
                if (c == '\r' && slice.PeekChar() == '\n')
                {
                    newLine = NewLine.CarriageReturnLineFeed;
                }
                var inline = new LineBreakInline()
                {
                    IsHard      = true,
                    IsBackslash = true,
                    Span        = { Start = processor.GetSourcePosition(startPosition, out line, out column) },
                    Line        = line,
                    Column      = column,
                };
                processor.Inline = inline;

                if (processor.TrackTrivia)
                {
                    inline.NewLine = newLine;
                }

                inline.Span.End = inline.Span.Start + 1;
                slice.SkipChar(); // Skip \n or \r alone
                if (newLine == NewLine.CarriageReturnLineFeed)
                {
                    slice.SkipChar(); // Skip \r\n
                }
                return(true);
            }

            return(false);
        }
Esempio n. 3
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var text = slice.Text;

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

            // Sligthly faster to perform our own search for opening characters
            var nextStart = processor.Parsers.IndexOfOpeningCharacter(text, slice.Start + 1, slice.End);
            //var nextStart = str.IndexOfAny(processor.SpecialCharacters, slice.Start + 1, slice.Length - 1);
            int length;

            if (nextStart < 0)
            {
                nextStart = slice.End + 1;
                length    = nextStart - slice.Start;
            }
            else
            {
                // Remove line endings if the next char is a new line
                length = nextStart - slice.Start;
                if (text[nextStart] == '\n')
                {
                    int end = nextStart - 1;
                    while (length > 0 && text[end].IsSpace())
                    {
                        length--;
                        end--;
                    }
                }
            }

            // The LiteralInlineParser is always matching (at least an empty string)
            var endPosition = slice.Start + length - 1;

            processor.Inline = new LiteralInline()
            {
                Content = length > 0 ? new StringSlice(slice.Text, slice.Start, endPosition) : StringSlice.Empty,
                Span    = new SourceSpan(startPosition, processor.GetSourcePosition(endPosition)),
                Line    = line,
                Column  = column,
            };

            slice.Start = nextStart;

            // Call only PostMatch if necessary
            if (PostMatch != null)
            {
                PostMatch(processor, ref slice);
            }

            return(true);
        }
Esempio n. 4
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)
        {
            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);
        }
Esempio n. 6
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            int    match;
            string literal;

            if (!TryParse(ref slice, out literal, out match))
            {
                return(false);
            }

            var startPosition = slice.Start;

            if (literal != null)
            {
                var matched = slice;
                matched.End = slice.Start + match - 1;
                int line;
                int column;
                processor.Inline = new HtmlEntityInline()
                {
                    Original   = matched,
                    Transcoded = new StringSlice(literal),
                    Span       = new SourceSpan(processor.GetSourcePosition(startPosition, out line, out column), processor.GetSourcePosition(matched.End)),
                    Line       = line,
                    Column     = column
                };
                slice.Start = slice.Start + match;
                return(true);
            }

            return(false);
        }
Esempio n. 7
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) },
Esempio n. 8
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)
                },
Esempio n. 9
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            bool matchFound = slice.MatchLowercase(matchingText);

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

                processor.Inline = new MatchingTextInline
                {
                    Span =
                    {
                        Start = inlineStart,
                        End   = inlineStart + matchingText.Length
                    },
                    Line         = line,
                    Column       = column,
                    MatchingText = matchingText
                };

                slice.Start = inlineStart + matchingText.Length;
            }

            return(matchFound);
        }
Esempio n. 10
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            // Hard line breaks are for separating inline content within a block. Neither syntax for hard line breaks works at the end of a paragraph or other block element:
            if (!(processor.Block is ParagraphBlock))
            {
                return(false);
            }

            var startPosition         = slice.Start;
            var hasDoubleSpacesBefore = slice.PeekCharExtra(-1).IsSpace() && slice.PeekCharExtra(-2).IsSpace();

            slice.NextChar(); // Skip \n

            int line;
            int column;

            processor.Inline = new LineBreakInline
            {
                Span   = { Start = processor.GetSourcePosition(startPosition, out line, out column) },
                IsHard = EnableSoftAsHard || (slice.Start != 0 && hasDoubleSpacesBefore),
                Line   = line,
                Column = column
            };
            processor.Inline.Span.End = processor.Inline.Span.Start;
            return(true);
        }
Esempio n. 11
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            foreach (var p in _typographMapping.Mappings)
            {
                foreach (var f in p.Value)
                {
                    var m = f(slice);

                    if (m == null)
                    {
                        continue;
                    }

                    m.Span.Start = processor.GetSourcePosition(slice.Start, out int line, out int column);
                    m.Line       = line;
                    m.Column     = column;
                    m.Span.End   = m.Span.Start + m.Match.Length - 1;

                    slice.Start += m.Match.Length;
                    return(true);
                }
            }

            return(false);
        }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var startPosition = processor.GetSourcePosition(slice.Start, out int line, out int column);
            var saved         = slice;

            if (LinkHelper.TryParseLabel(ref slice, out string label, out SourceSpan labelSpan))
            {
                string alertClass;
                switch (label.ToLower())
                {
                case "!note":
                    alertClass = "note";
                    break;

                case "!warning":
                    alertClass = "warning";
                    break;

                case "!tip":
                    alertClass = "tip";
                    break;

                case "!important":
                    alertClass = "important";
                    break;

                case "!caution":
                    alertClass = "caution";
                    break;

                default:
                    slice = saved;
                    return(false);
                }

                processor.Inline = new AlertInline()
                {
                    AlertClass = alertClass,
                    Span       = new SourceSpan(startPosition, processor.GetSourcePosition(slice.Start - 1)),
                    Line       = line,
                    Column     = column
                };
                return(true);
            }

            return(false);
        }
Esempio n. 13
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var text = slice.Text;

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

            // Slightly faster to perform our own search for opening characters
            var nextStart = processor.Parsers.IndexOfOpeningCharacter(text, slice.Start + 1, slice.End);
            //var nextStart = str.IndexOfAny(processor.SpecialCharacters, slice.Start + 1, slice.Length - 1);
            int length;

            if (nextStart < 0)
            {
                nextStart = slice.End + 1;
                length    = nextStart - slice.Start;
            }
            else
            {
                // Remove line endings if the next char is a new line
                length = nextStart - slice.Start;
                if (!processor.TrackTrivia)
                {
                    var nextText = text[nextStart];
                    if (nextText == '\n' || nextText == '\r')
                    {
                        int end = nextStart - 1;
                        while (length > 0 && text[end].IsSpace())
                        {
                            length--;
                            end--;
                        }
                    }
                }
            }

            // The LiteralInlineParser is always matching (at least an empty string)
            var endPosition = slice.Start + length - 1;

            if (processor.Inline is { } previousInline &&
                !previousInline.IsContainer &&
                processor.Inline is LiteralInline previousLiteral &&
                ReferenceEquals(previousLiteral.Content.Text, slice.Text) &&
                previousLiteral.Content.End + 1 == slice.Start)
            {
                previousLiteral.Content.End = endPosition;
                previousLiteral.Span.End    = processor.GetSourcePosition(endPosition);
            }
Esempio n. 14
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);
        }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            string match;

            // Previous char must be a space
            if (!slice.PeekCharExtra(-1).IsWhiteSpaceOrZero())
            {
                return(false);
            }

            // Try to match an existing emoji
            var startPosition = slice.Start;

            if (!textMatchHelper.TryMatch(slice.Text, slice.Start, slice.Length, out match))
            {
                return(false);
            }

            string emoji = match;

            if (EnableSmiley)
            {
                // If we have a smiley, we decode it to emoji
                if (!SmileyToEmoji.TryGetValue(match, out emoji))
                {
                    emoji = match;
                }
            }

            // Decode the eomji to unicode
            string unicode;

            if (!EmojiToUnicode.TryGetValue(emoji, out unicode))
            {
                // Should not happen but in case
                return(false);
            }

            // Move the cursor to the character after the matched string
            slice.Start += match.Length;

            // Push the EmojiInline
            int line;
            int column;

            processor.Inline = new EmojiInline(unicode)
            {
                Span =
                {
                    Start = processor.GetSourcePosition(startPosition, out line, out column),
                },
                Line   = line,
                Column = column,
                Match  = match
            };
            processor.Inline.Span.End = processor.Inline.Span.Start + match.Length - 1;

            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);
        }
Esempio n. 17
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);
        }
Esempio n. 18
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var nextChar = slice.PeekChar();

            if (nextChar != '{')
            {
                return(false);
            }

            var start = slice.Start;

            slice.NextChar();
            nextChar = slice.NextChar();

            var contentBuilder = processor.StringBuilders.Get();

            while (nextChar != '}')
            {
                contentBuilder.Append(nextChar);
                nextChar = slice.NextChar();
            }

            if (slice.PeekChar() != ']')
            {
                processor.StringBuilders.Release(contentBuilder);
                return(false);
            }

            slice.NextChar();
            slice.NextChar();

            processor.Inline = new CodeInclude
            {
                DisplayName = contentBuilder.ToString(),
                Span        = new SourceSpan(processor.GetSourcePosition(
                                                 start, out var line, out var column),
                                             processor.GetSourcePosition(slice.End)),
                Line   = line,
                Column = column
            };

            return(true);
        }
    }
Esempio n. 19
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);
        }
Esempio n. 20
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)
                },
Esempio n. 21
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);
        }
Esempio n. 22
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);
        }
Esempio n. 23
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            HtmlAttributes attributes;
            var            startPosition = slice.Start;

            if (TryParse(ref slice, out attributes))
            {
                var inline = processor.Inline;

                // If the current object to attach is either a literal or delimiter
                // try to find a suitable parent, otherwise attach the html attributes to the block
                if (inline is LiteralInline)
                {
                    while (true)
                    {
                        inline = inline.Parent;
                        if (!(inline is DelimiterInline))
                        {
                            break;
                        }
                    }
                }
                var objectToAttach = inline == null || inline == processor.Root ? (MarkdownObject)processor.Block : inline;

                // If the current block is a Paragraph, but only the HtmlAttributes is used,
                // Try to attach the attributes to the following block
                var paragraph = objectToAttach as ParagraphBlock;
                if (paragraph != null && paragraph.Inline.FirstChild == null && processor.Inline == null && slice.IsEmptyOrWhitespace())
                {
                    var parent           = paragraph.Parent;
                    var indexOfParagraph = parent.IndexOf(paragraph);
                    if (indexOfParagraph + 1 < parent.Count)
                    {
                        objectToAttach = parent[indexOfParagraph + 1];
                        // We can remove the paragraph as it is empty
                        paragraph.RemoveAfterProcessInlines = true;
                    }
                }

                var currentHtmlAttributes = objectToAttach.GetAttributes();
                attributes.CopyTo(currentHtmlAttributes, true, false);

                // Update the position of the attributes
                int line;
                int column;
                currentHtmlAttributes.Span.Start = processor.GetSourcePosition(startPosition, out line, out column);
                currentHtmlAttributes.Line       = line;
                currentHtmlAttributes.Column     = column;
                currentHtmlAttributes.Span.End   = currentHtmlAttributes.Span.Start + slice.Start - startPosition - 1;

                // We don't set the processor.Inline as we don't want to add attach attributes to a particular entity
                return(true);
            }

            return(false);
        }
Esempio n. 24
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            string link;
            bool   isEmail;
            var    saved = slice;
            int    line;
            int    column;

            if (LinkHelper.TryParseAutolink(ref slice, out link, out isEmail))
            {
                processor.Inline = new AutolinkInline()
                {
                    IsEmail = isEmail,
                    Url     = link,
                    Span    = new SourceSpan(processor.GetSourcePosition(saved.Start, out line, out column), processor.GetSourcePosition(slice.Start - 1)),
                    Line    = line,
                    Column  = column
                };
            }
            else if (EnableHtmlParsing)
            {
                slice = saved;
                string htmlTag;
                if (!HtmlHelper.TryParseHtmlTag(ref slice, out htmlTag))
                {
                    return(false);
                }

                processor.Inline = new HtmlInline()
                {
                    Tag    = htmlTag,
                    Span   = new SourceSpan(processor.GetSourcePosition(saved.Start, out line, out column), processor.GetSourcePosition(slice.Start - 1)),
                    Line   = line,
                    Column = column
                };
            }
            else
            {
                return(false);
            }

            return(true);
        }
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            // Previous char must be a whitespace or a punctuation
            var previousChar = slice.PeekCharExtra(-1);

            if (!previousChar.IsWhiteSpaceOrZero() && ValidPreviousCharacters.IndexOf(previousChar) == -1)
            {
                return(false);
            }

            var pendingEmphasis = _listOfCharCache.Get();

            try
            {
                // Check that an autolink is possible in the current context
                if (!IsAutoLinkValidInCurrentContext(processor, pendingEmphasis))
                {
                    return(false);
                }

                var startPosition = slice.Start;
                // Parse URL
                var match = AutoEmailBare.Match(slice.Text, slice.Start, slice.Length);
                if (!match.Success)
                {
                    return(false);
                }

                // Remove <...>
                if (slice.CurrentChar == '<')
                {
                    if (slice[match.Length] != '>')
                    {
                        return(false);
                    }
                    // Remove trailing >
                    slice.Start++;
                }

                var email = match.Groups[1].Value;
                slice.Start += match.Length;

                var inline = new LinkInline()
                {
                    Span =
                    {
                        Start = processor.GetSourcePosition(startPosition, out var line, out var column),
                    },
                    Line       = line,
                    Column     = column,
                    Url        = "mailto:" + email,
                    IsClosed   = true,
                    IsAutoLink = true,
                };
Esempio n. 26
0
        public override Boolean Match(InlineProcessor processor, ref StringSlice slice)
        {
            var startPosition = processor.GetSourcePosition(slice.Start, out int line, out int column);
            var last          = slice.PeekCharExtra(-1);
            var current       = slice.CurrentChar;

            if (current != '[' || last == '\\')
            {
                return(false);
            }

            // Link reference
            if (LinkHelper.TryParseLabel(ref slice, out String label, out SourceSpan labelSpan))
            {
                if (processor.Document.ContainsLinkReferenceDefinition(label))
                {
                    return(false);
                }
            }

            // Explicit link
            if (slice.CurrentChar.IsOneOf('[', '(', ':'))
            {
                return(false);
            }

            // Shorthand
            processor.Inline = new LinkInline(label, "")
            {
                LabelSpan = processor.GetSourcePositionFromLocalSpan(labelSpan),
                IsImage   = false,
                Span      = new SourceSpan(
                    startPosition,
                    processor.GetSourcePosition(slice.Start - 1)),
                Line     = line,
                Column   = column,
                IsClosed = true,
            }.AppendChild(new LiteralInline(label));

            return(true);
        }
Esempio n. 27
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var startPosition = slice.Start;
            // Go to escape character
            var c = slice.NextChar();
            int line;
            int column;

            if (c.IsAsciiPunctuation())
            {
                processor.Inline = new LiteralInline()
                {
                    Content = new StringSlice(slice.Text, slice.Start, slice.Start),
                    Span    = { Start = processor.GetSourcePosition(startPosition, out line, out column) },
                    Line    = line,
                    Column  = column,
                    IsFirstCharacterEscaped = true,
                };
                processor.Inline.Span.End = processor.Inline.Span.Start + 1;
                slice.NextChar();
                return(true);
            }

            // A backslash at the end of the line is a [hard line break]:
            if (c == '\n')
            {
                processor.Inline = new LineBreakInline()
                {
                    IsHard      = true,
                    IsBackslash = true,
                    Span        = { Start = processor.GetSourcePosition(startPosition, out line, out column) },
                    Line        = line,
                    Column      = column
                };
                processor.Inline.Span.End = processor.Inline.Span.Start + 1;
                slice.NextChar();
                return(true);
            }
            return(false);
        }
        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);
        }
Esempio n. 30
0
        private bool MatchXrefShortcut(InlineProcessor processor, ref StringSlice slice)
        {
            if (!slice.CurrentChar.IsAlpha())
            {
                return(false);
            }

            var saved = slice;
            int line;
            int column;

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

            while (!c.IsZero())
            {
                //Meet line ends or whitespaces
                if (c.IsWhiteSpaceOrZero() || StopCharacters.Contains(c))
                {
                    break;
                }

                var nextChar = slice.PeekCharExtra(1);
                if (ContinuableCharacters.Contains(c) && (nextChar.IsWhiteSpaceOrZero() || StopCharacters.Contains(nextChar) || ContinuableCharacters.Contains(nextChar)))
                {
                    break;
                }

                href.Append(c);
                c = slice.NextChar();
            }


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

            var htmlAttributes = xrefInline.GetAttributes();

            var sourceContent = href.Insert(0, '@');

            htmlAttributes.AddPropertyIfNotExist("data-throw-if-not-resolved", "False");
            htmlAttributes.AddPropertyIfNotExist("data-raw-source", sourceContent.ToString());
            processor.Inline = xrefInline;

            return(true);
        }