Ejemplo n.º 1
0
        public void Setup()
        {
            parser = new ReferenceInlineParser();
            Mock <InlineProcessor> mockProcessor = new Mock <InlineProcessor>(new MarkdownDocument(), new InlineParserList(new InlineParser[0]), false, new MarkdownParserContext());

            processor = mockProcessor.Object;
        }
Ejemplo n.º 2
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            var previousChar = slice.PeekCharExtra(-1);

            if (!IsValidPreviousCharacter(previousChar))
            {
                return(false);
            }

            List <char> pendingEmphasis;

            if (!IsAutoLinkValidInCurrentContext(processor, out pendingEmphasis))
            {
                return(false);
            }

            int charactersConsumedInReference;
            var ticketUri = GetTicketUri(slice, out charactersConsumedInReference);

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

            AddTicketLink(processor, slice, charactersConsumedInReference, ticketUri);
            slice.Start += charactersConsumedInReference;

            return(true);
        }
Ejemplo n.º 3
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)
                },
        private void HeadingBlock_ProcessInlinesEnd(InlineProcessor processor, Inline?inline)
        {
            var identifiers = processor.Document.GetData(DeepLinkKey) as HashSet <string>;

            if (identifiers is null)
            {
                identifiers = new HashSet <string>();
                processor.Document.SetData(DeepLinkKey, identifiers);
            }

            var headingBlock = (HeadingBlock)processor.Block !;

            if (headingBlock.Inline is null)
            {
                return;
            }

            // If id is already set, don't try to modify it
            var attributes = processor.Block !.GetAttributes();

            if (attributes.Id != null)
            {
                return;
            }

            // Use internally a HtmlRenderer to strip links from a heading
            var stripRenderer = rendererCache.Get();

            stripRenderer.Render(headingBlock.Inline);
            var headingText = stripRenderer.Writer.ToString() !;

            rendererCache.Release(stripRenderer);

            headingText = $"{Filename}-{headingText}";

            // Urilize the link
            headingText = (options & DeepLinkOptions.GitHub) != 0
                ? LinkHelper.UrilizeAsGfm(headingText)
                : LinkHelper.Urilize(headingText, (options & DeepLinkOptions.AllowOnlyAscii) != 0);

            // If the heading is empty, use the word "section" instead
            var baseHeadingId = string.IsNullOrEmpty(headingText) ? "section" : headingText;

            // Add a trailing -1, -2, -3...etc. in case of collision
            int index         = 0;
            var headingId     = baseHeadingId;
            var headingBuffer = StringBuilderCache.Local();

            while (!identifiers.Add(headingId))
            {
                index++;
                headingBuffer.Append(baseHeadingId);
                headingBuffer.Append('-');
                headingBuffer.Append(index);
                headingId            = headingBuffer.ToString();
                headingBuffer.Length = 0;
            }

            attributes.Id = $"{headingId}";
        }
        public void ExtractCiteUrl_ExtractsCiteUrlIfSuccessful()
        {
            // Arrange
            const string dummyUrl = "dummyLink";
            var          dummyAuthorLinkInline = new LinkInline();
            var          dummyCiteLinkInline   = new LinkInline(dummyUrl, null);
            var          dummyContainerInline  = new ContainerInline();

            dummyContainerInline.
            AppendChild(dummyAuthorLinkInline).
            AppendChild(dummyCiteLinkInline);
            LeafBlock       dummyCitationBlock   = _mockRepository.Create <LeafBlock>(null).Object;
            InlineProcessor dummyInlineProcessor = MarkdigTypesFactory.CreateInlineProcessor();

            dummyInlineProcessor.ProcessInlineLeaf(dummyCitationBlock); // Sets InlineProcessor.Block to dummyCitationBlock
            dummyCitationBlock.Inline = dummyContainerInline;           // Replace container created in ProcessInlineLeaf
            FlexiQuoteBlock dummyFlexiQuoteBlock = CreateFlexiQuoteBlock();

            dummyFlexiQuoteBlock.Add(dummyCitationBlock);
            Mock <FlexiQuoteBlockFactory> mockTestSubject = CreateMockFlexiQuoteBlockFactory();

            mockTestSubject.Setup(m => m.NormalizeCiteLinkIndex(2, dummyFlexiQuoteBlock)).Returns(1);

            // Act
            mockTestSubject.Object.ExtractCiteUrl(dummyInlineProcessor, null);

            // Assert
            _mockRepository.VerifyAll();
            Assert.Equal(dummyUrl, dummyFlexiQuoteBlock.CiteUrl);
        }
Ejemplo n.º 6
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (!ExtensionsHelper.MatchStart(ref slice, StartString, true))
            {
                return(false);
            }

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

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

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

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

            return(true);
        }
Ejemplo n.º 7
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();
            var context     = new InclusionContext();

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

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

            return(true);
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        public void DocumentOnProcessInlinesBegin_DoesNotReplaceExistingLinkReferenceDefinitions()
        {
            // Arrange
            const string     dummyLinkLabelContent = "dummyLinkLabelContent";
            InlineProcessor  dummyInlineProcessor  = MarkdigTypesFactory.CreateInlineProcessor();
            FlexiFigureBlock dummyFlexiFigureBlock = CreateFlexiFigureBlock(linkLabelContent: dummyLinkLabelContent);

            dummyInlineProcessor.Document.SetData(FlexiFigureBlockFactory.REFERENCE_LINKABLE_FLEXI_FIGURE_BLOCKS_KEY,
                                                  new List <FlexiFigureBlock> {
                dummyFlexiFigureBlock
            });
            var dummyLinkReferenceDefinition = new LinkReferenceDefinition();

            dummyInlineProcessor.Document.SetLinkReferenceDefinition(dummyLinkLabelContent, dummyLinkReferenceDefinition);
            FlexiFigureBlockFactory testSubject = CreateFlexiFigureBlockFactory();

            // Act
            testSubject.DocumentOnProcessInlinesBegin(dummyInlineProcessor, null);

            // Assert
            Dictionary <string, LinkReferenceDefinition> linkReferenceDefinitions =
                (dummyInlineProcessor.Document.GetData(typeof(LinkReferenceDefinitionGroup)) as LinkReferenceDefinitionGroup)?.Links;

            Assert.Single(linkReferenceDefinitions);
            Assert.Same(dummyLinkReferenceDefinition, linkReferenceDefinitions.Values.First()); // Doesn't get replaced
        }
Ejemplo 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);
        }
Ejemplo n.º 12
0
        private InlineProcessor BuidProcessor()
        {
            var p  = new WikiLinkParser();
            var pr = new InlineProcessor(new StringBuilderCache(), new MarkdownDocument(), new InlineParserList(Enumerable.Empty <InlineParser>()), false);

            return(pr);
        }
Ejemplo n.º 13
0
        public void DocumentOnProcessInlinesBegin_CreatesAndAddsALinkReferenceDefinitionForEachReferenceLinkableFlexiFigureBlock()
        {
            // Arrange
            const string     dummyLinkLabelContent = "dummyLinkLabelContent";
            const string     dummyID               = "dummyID";
            const string     dummyName             = "dummyName";
            FlexiFigureBlock dummyFlexiFigureBlock = CreateFlexiFigureBlock(name: dummyName, linkLabelContent: dummyLinkLabelContent, id: dummyID);
            InlineProcessor  dummyInlineProcessor  = MarkdigTypesFactory.CreateInlineProcessor();

            dummyInlineProcessor.Document.SetData(FlexiFigureBlockFactory.REFERENCE_LINKABLE_FLEXI_FIGURE_BLOCKS_KEY, new List <FlexiFigureBlock> {
                dummyFlexiFigureBlock
            });
            FlexiFigureBlockFactory testSubject = CreateFlexiFigureBlockFactory();

            // Act
            testSubject.DocumentOnProcessInlinesBegin(dummyInlineProcessor, null);

            // Assert
            Dictionary <string, LinkReferenceDefinition> linkReferenceDefinitions = (dummyInlineProcessor.Document.GetData(typeof(LinkReferenceDefinitionGroup)) as LinkReferenceDefinitionGroup)?.Links;

            Assert.Single(linkReferenceDefinitions);
            LinkReferenceDefinition resultLinkReferenceDefinition = linkReferenceDefinitions.Values.First();

            Assert.Equal(dummyLinkLabelContent, resultLinkReferenceDefinition.Label);
            Assert.Equal($"#{dummyID}", resultLinkReferenceDefinition.Url);
            Assert.Equal(dummyName, resultLinkReferenceDefinition.Title);
        }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
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);
        }
Ejemplo n.º 16
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);
        }
Ejemplo n.º 17
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);
        }
Ejemplo n.º 18
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);
        }
Ejemplo n.º 19
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) },
Ejemplo n.º 20
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);
        }
Ejemplo n.º 22
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            // First, some definitions.
            // A delimiter run is a sequence of one or more delimiter characters that is not preceded or followed by the same delimiter character
            // The amount of delimiter characters in the delimiter run may exceed emphasisDesc.MaximumCount, as that is handeled in `ProcessEmphasis`

            var delimiterChar = slice.CurrentChar;
            var emphasisDesc  = emphasisMap ![delimiterChar] !;
Ejemplo n.º 23
0
        public override bool Match(InlineProcessor processor, ref StringSlice slice)
        {
            if (slice.Start != 0 && !slice.PeekCharExtra(-1).IsWhitespace())
            {
                return(false);
            }
            string match;

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

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

            var builder = new StringBuilder();

            while (slice.CurrentChar.IsDigit() && !slice.IsEmpty)
            {
                builder.Append(slice.CurrentChar);
                slice.Start++;
            }

            var index = builder.Length > 0 ? int.Parse(builder.ToString()) : 0;

            if (index == 0)
            {
                //If we failed to parse index, abort
                slice.Start -= builder.Length;
                slice.Start -= match.Length;
                return(false);
            }

            builder.Clear();

            if (slice.CurrentChar == '(')
            {
                slice.Start++;

                while (slice.CurrentChar != ')' && !slice.IsEmpty)
                {
                    builder.Append(slice.CurrentChar);
                    slice.Start++;
                }

                if (!slice.IsEmpty)
                {
                    slice.Start++;
                }
            }

            var extra = builder.ToString();

            processor.Inline = new EntityLinkInline(match, index, extra);

            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);
        }
Ejemplo n.º 25
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);
        }
Ejemplo n.º 26
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);
        }
Ejemplo n.º 27
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)
                },
Ejemplo n.º 28
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);
        }
Ejemplo n.º 29
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);
        }
Ejemplo n.º 30
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);
        }