예제 #1
0
        /// <summary>
        /// This function can be called by any element parsing. Given a start and stopping point this will
        /// parse all found elements out of the range.
        /// </summary>
        /// <returns> A list of parsed inlines. </returns>
        public static List <MarkdownInline> ParseInlineChildren(string markdown, int startingPos, int maxEndingPos, bool ignoreLinks = false)
        {
            int currentParsePosition = startingPos;

            var inlines = new List <MarkdownInline>();

            while (currentParsePosition < maxEndingPos)
            {
                // Find the next inline element.
                var parseResult = FindNextInlineElement(markdown, currentParsePosition, maxEndingPos, ignoreLinks);

                // If the element we found doesn't start at the position we are looking for there
                // is text between the element and the start of the parsed element. We need to wrap
                // it into a text run.
                if (parseResult.Start != currentParsePosition)
                {
                    var textRun = TextRunInline.Parse(markdown, currentParsePosition, parseResult.Start);
                    inlines.Add(textRun);
                }

                // Add the parsed element.
                inlines.Add(parseResult.ParsedElement);

                // Update the current position.
                currentParsePosition = parseResult.End;
            }

            return(inlines);
        }
예제 #2
0
        /// <summary>
        /// Finds the next inline element by matching trip chars and verifying the match.
        /// </summary>
        /// <param name="markdown"> The markdown text to parse. </param>
        /// <param name="start"> The position to start parsing. </param>
        /// <param name="end"> The position to stop parsing. </param>
        /// <param name="ignoreLinks"> Indicates whether to parse links. </param>
        /// <returns>Returns the next element</returns>
        private static InlineParseResult FindNextInlineElement(string markdown, int start, int end, bool ignoreLinks)
        {
            // Search for the next inline sequence.
            for (int pos = start; pos < end; pos++)
            {
                // IndexOfAny should be the fastest way to skip characters we don't care about.
                pos = markdown.IndexOfAny(_tripCharacters, pos, end - pos);
                if (pos < 0)
                {
                    break;
                }

                // Find the trigger(s) that matched.
                char currentChar = markdown[pos];
                foreach (InlineTripCharHelper currentTripChar in _triggerList)
                {
                    // Check if our current char matches the suffix char.
                    if (currentChar == currentTripChar.FirstChar)
                    {
                        // Don't match if the previous character was a backslash.
                        if (pos > start && markdown[pos - 1] == '\\')
                        {
                            continue;
                        }

                        // If we are here we have a possible match. Call into the inline class to verify.
                        InlineParseResult parseResult = null;
                        switch (currentTripChar.Method)
                        {
                        case InlineParseMethod.BoldItalic:
                            parseResult = BoldItalicTextInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.Comment:
                            parseResult = CommentInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.LinkReference:
                            parseResult = LinkAnchorInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.Bold:
                            parseResult = BoldTextInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.Italic:
                            parseResult = ItalicTextInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.MarkdownLink:
                            if (!ignoreLinks)
                            {
                                parseResult = MarkdownLinkInline.Parse(markdown, pos, end);
                            }

                            break;

                        case InlineParseMethod.AngleBracketLink:
                            if (!ignoreLinks)
                            {
                                parseResult = HyperlinkInline.ParseAngleBracketLink(markdown, pos, end);
                            }

                            break;

                        case InlineParseMethod.Url:
                            if (!ignoreLinks)
                            {
                                parseResult = HyperlinkInline.ParseUrl(markdown, pos, end);
                            }

                            break;

                        case InlineParseMethod.RedditLink:
                            if (!ignoreLinks)
                            {
                                parseResult = HyperlinkInline.ParseRedditLink(markdown, pos, end);
                            }

                            break;

                        case InlineParseMethod.PartialLink:
                            if (!ignoreLinks)
                            {
                                parseResult = HyperlinkInline.ParsePartialLink(markdown, pos, end);
                            }

                            break;

                        case InlineParseMethod.Email:
                            if (!ignoreLinks)
                            {
                                parseResult = HyperlinkInline.ParseEmailAddress(markdown, start, pos, end);
                            }

                            break;

                        case InlineParseMethod.Strikethrough:
                            parseResult = StrikethroughTextInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.Superscript:
                            parseResult = SuperscriptTextInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.Subscript:
                            parseResult = SubscriptTextInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.Code:
                            parseResult = CodeInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.Image:
                            parseResult = ImageInline.Parse(markdown, pos, end);
                            break;

                        case InlineParseMethod.Emoji:
                            parseResult = EmojiInline.Parse(markdown, pos, end);
                            break;
                        }

                        if (parseResult != null)
                        {
                            return(parseResult);
                        }
                    }
                }
            }

            // If we didn't find any elements we have a normal text block.
            // Let us consume the entire range.
            return(new InlineParseResult(TextRunInline.Parse(markdown, start, end), start, end));
        }