コード例 #1
0
        private bool TryProcessLinkOrImage(InlineProcessor inlineState, ref StringSlice text)
        {
            LinkDelimiterInline openParent = null;

            foreach (var parent in inlineState.Inline.FindParentOfType <LinkDelimiterInline>())
            {
                openParent = parent;
                break;
            }

            if (openParent != null)
            {
                // If we do find one, but it’s not active,
                // we remove the inactive delimiter from the stack,
                // and return a literal text node ].
                if (!openParent.IsActive)
                {
                    inlineState.Inline = new LiteralInline()
                    {
                        Content = new StringSlice("["),
                        Span    = openParent.Span,
                        Line    = openParent.Line,
                        Column  = openParent.Column,
                    };
                    openParent.ReplaceBy(inlineState.Inline);
                    return(false);
                }

                // If we find one and it’s active,
                // then we parse ahead to see if we have
                // an inline link/image, reference link/image,
                // compact reference link/image,
                // or shortcut reference link/image
                var parentDelimiter = openParent.Parent;
                switch (text.CurrentChar)
                {
                case '(':
                    string     url;
                    string     title;
                    SourceSpan linkSpan;
                    SourceSpan titleSpan;
                    if (LinkHelper.TryParseInlineLink(ref text, out url, out title, out linkSpan, out titleSpan))
                    {
                        // Inline Link
                        var link = new LinkInline()
                        {
                            Url       = HtmlHelper.Unescape(url),
                            Title     = HtmlHelper.Unescape(title),
                            IsImage   = openParent.IsImage,
                            LabelSpan = openParent.LabelSpan,
                            UrlSpan   = inlineState.GetSourcePositionFromLocalSpan(linkSpan),
                            TitleSpan = inlineState.GetSourcePositionFromLocalSpan(titleSpan),
                            Span      = new SourceSpan(openParent.Span.Start, inlineState.GetSourcePosition(text.Start - 1)),
                            Line      = openParent.Line,
                            Column    = openParent.Column,
                        };

                        openParent.ReplaceBy(link);
                        // Notifies processor as we are creating an inline locally
                        inlineState.Inline = link;

                        // Process emphasis delimiters
                        inlineState.PostProcessInlines(0, link, null, false);

                        // If we have a link (and not an image),
                        // we also set all [ delimiters before the opening delimiter to inactive.
                        // (This will prevent us from getting links within links.)
                        if (!openParent.IsImage)
                        {
                            MarkParentAsInactive(parentDelimiter);
                        }

                        link.IsClosed = true;

                        return(true);
                    }
                    break;

                default:

                    var    labelSpan        = SourceSpan.Empty;
                    string label            = null;
                    bool   isLabelSpanLocal = true;
                    // Handle Collapsed links
                    if (text.CurrentChar == '[')
                    {
                        if (text.PeekChar(1) == ']')
                        {
                            label            = openParent.Label;
                            labelSpan        = openParent.LabelSpan;
                            isLabelSpanLocal = false;
                            text.NextChar();     // Skip [
                            text.NextChar();     // Skip ]
                        }
                    }
                    else
                    {
                        label = openParent.Label;
                    }

                    if (label != null || LinkHelper.TryParseLabel(ref text, true, out label, out labelSpan))
                    {
                        if (isLabelSpanLocal)
                        {
                            labelSpan = inlineState.GetSourcePositionFromLocalSpan(labelSpan);
                        }

                        if (ProcessLinkReference(inlineState, label, labelSpan, openParent, inlineState.GetSourcePosition(text.Start - 1)))
                        {
                            // Remove the open parent
                            openParent.Remove();
                            if (!openParent.IsImage)
                            {
                                MarkParentAsInactive(parentDelimiter);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                        return(true);
                    }
                    break;
                }

                // We have a nested [ ]
                // firstParent.Remove();
                // The opening [ will be transformed to a literal followed by all the childrens of the [

                var literal = new LiteralInline()
                {
                    Span    = openParent.Span,
                    Content = new StringSlice(openParent.IsImage ? "![" : "[")
                };

                inlineState.Inline = openParent.ReplaceBy(literal);
                return(false);
            }

            return(false);
        }