示例#1
0
        private static Inline HandleOpenerCloser(Subject subj, InlineTag singleCharTag, InlineTag doubleCharTag)
        {
            bool canOpen, canClose;
            var  c         = subj.Buffer[subj.Position];
            var  numdelims = ScanEmphasisDelimiters(subj, c, out canOpen, out canClose);

            if (canClose)
            {
                // walk the stack and find a matching opener, if there is one
                var istack = InlineStack.FindMatchingOpener(subj.LastPendingInline, InlineStack.InlineStackPriority.Emphasis, c, numdelims, canOpen, out canClose);
                if (istack != null)
                {
                    var useDelims = MatchInlineStack(istack, subj, numdelims, null, singleCharTag, doubleCharTag);

                    if (useDelims > 0)
                    {
                        // if the closer was not fully used, move back a char or two and try again.
                        if (useDelims < numdelims)
                        {
                            subj.Position = subj.Position - numdelims + useDelims;

                            // use recursion only if it will not be very deep.
                            // however it cannot be used if the single char will not be parsed.
                            if (numdelims < 10)
                            {
                                return(HandleOpenerCloser(subj, singleCharTag, doubleCharTag));
                            }
                        }

                        return(null);
                    }
                }
            }

            var inlText = new Inline(subj.Buffer, subj.Position - numdelims, numdelims, subj.Position - numdelims, subj.Position, c);

            if (canOpen || canClose)
            {
                var istack = new InlineStack();
                istack.DelimiterCount = numdelims;
                istack.Delimiter      = c;
                istack.StartingInline = inlText;
                istack.Priority       = InlineStack.InlineStackPriority.Emphasis;
                istack.Flags          = (canOpen ? InlineStack.InlineStackFlags.Opener : 0)
                                        | (canClose ? (InlineStack.InlineStackFlags.Closer | InlineStack.InlineStackFlags.CloserOriginally) : 0);

                InlineStack.AppendStackEntry(istack, subj);
            }

            return(inlText);
        }
示例#2
0
        private static Inline HandleRightSquareBracket(Subject subj, bool supportPlaceholderBrackets)
        {
            // move past ']'
            subj.Position++;

            bool canClose;
            var  istack = InlineStack.FindMatchingOpener(subj.LastPendingInline, InlineStack.InlineStackPriority.Links, '[', 1, false, out canClose);

            if (istack != null)
            {
                // if the opener is "inactive" then it means that there was a nested link
                if (istack.DelimiterCount == -1)
                {
                    InlineStack.RemoveStackEntry(istack, subj, istack);
                    return(new Inline("]", subj.Position - 1, subj.Position));
                }

                var endpos = subj.Position;

                // try parsing details for '[foo](/url "title")' or '[foo][bar]'
                //var details = ParseLinkDetails(subj);
                var details = ParseLinkDetails(subj, supportPlaceholderBrackets);

                // try lookup of the brackets themselves
                if (details == null || details == Reference.SelfReference)
                {
                    var startpos = istack.StartPosition;
                    var label    = new StringPart(subj.Buffer, startpos, endpos - startpos - 1);

                    details = LookupReference(subj.DocumentData, label);
                }

                if (details == Reference.InvalidReference)
                {
                    details = null;
                }

                MatchSquareBracketStack(istack, subj, details);
                return(null);
            }

            var inlText = new Inline("]", subj.Position - 1, subj.Position);

            if (canClose)
            {
                // note that the current implementation will not work if there are other inlines with priority
                // higher than Links.
                // to fix this the parsed link details should be added to the closer element in the stack.

                throw new NotSupportedException("It is not supported to have inline stack priority higher than Links.");

                ////istack = new InlineStack();
                ////istack.Delimiter = '[';
                ////istack.StartingInline = inlText;
                ////istack.StartPosition = subj.Position;
                ////istack.Priority = InlineStack.InlineStackPriority.Links;
                ////istack.Flags = InlineStack.InlineStackFlags.Closer;

                ////InlineStack.AppendStackEntry(istack, subj);
            }

            return(inlText);
        }