Exemple #1
0
        // Parse reference.  Assumes string begins with '[' character.
        // Modify refmap if a reference is encountered.
        // Return 0 if no reference found, otherwise position of subject
        // after reference is parsed.
        public static int ParseReference(Subject subj)
        {
            string title;
            var    startPos = subj.Position;

            // parse label:
            var lab = ParseReferenceLabel(subj);

            if (lab == null || lab.Value.Length > Reference.MaximumReferenceLabelLength)
            {
                goto INVALID;
            }

            if (!Scanner.HasNonWhitespace(lab.Value))
            {
                goto INVALID;
            }

            // colon:
            if (peek_char(subj) == ':')
            {
                subj.Position++;
            }
            else
            {
                goto INVALID;
            }

            // parse link url:
            spnl(subj);
            var matchlen = Scanner.scan_link_url(subj.Buffer, subj.Position, subj.Length);

            if (matchlen == 0)
            {
                goto INVALID;
            }

            var url = subj.Buffer.Substring(subj.Position, matchlen);

            url            = CleanUrl(url);
            subj.Position += matchlen;

            // parse optional link_title
            var beforetitle = subj.Position;

            spnl(subj);
            matchlen = Scanner.scan_link_title(subj.Buffer, subj.Position, subj.Length);
            if (matchlen > 0)
            {
                title          = subj.Buffer.Substring(subj.Position, matchlen);
                title          = CleanTitle(title);
                subj.Position += matchlen;
            }
            else
            {
                subj.Position = beforetitle;
                title         = string.Empty;
            }

            // parse final spaces and newline:
            while (peek_char(subj) == ' ')
            {
                subj.Position++;
            }

            if (peek_char(subj) == '\n')
            {
                subj.Position++;
            }
            else if (peek_char(subj) != '\0')
            {
                goto INVALID;
            }

            // insert reference into refmap
            AddReference(subj.ReferenceMap, lab.Value, url, title);

            return(subj.Position);

INVALID:
            subj.Position = startPos;
            return(0);
        }
Exemple #2
0
        // Parse a link or the link portion of an image, or return a fallback.
        static Reference ParseLinkDetails(Subject subj)
        {
            int    n;
            int    sps;
            int    endlabel, starturl, endurl, starttitle, endtitle, endall;
            string url, title;

            endlabel = subj.Position;

            var c = peek_char(subj);

            if (c == '(' &&
                ((sps = Scanner.scan_spacechars(subj.Buffer, subj.Position + 1, subj.Length)) > -1) &&
                ((n = Scanner.scan_link_url(subj.Buffer, subj.Position + 1 + sps, subj.Length)) > -1))
            {
                // try to parse an explicit link:
                starturl   = subj.Position + 1 + sps; // after (
                endurl     = starturl + n;
                starttitle = endurl + Scanner.scan_spacechars(subj.Buffer, endurl, subj.Length);
                // ensure there are spaces btw url and title
                endtitle = (starttitle == endurl) ? starttitle :
                           starttitle + Scanner.scan_link_title(subj.Buffer, starttitle, subj.Length);
                endall = endtitle + Scanner.scan_spacechars(subj.Buffer, endtitle, subj.Length);
                if (endall < subj.Length && subj.Buffer[endall] == ')')
                {
                    subj.Position = endall + 1;
                    url           = subj.Buffer.Substring(starturl, endurl - starturl);
                    url           = CleanUrl(url);
                    title         = subj.Buffer.Substring(starttitle, endtitle - starttitle);
                    title         = CleanTitle(title);

                    return(new Reference()
                    {
                        Title = title, Url = url
                    });
                }
            }
            else if (c == '[' || c == ' ' || c == '\n')
            {
                var label = ParseReferenceLabel(subj);
                if (label != null)
                {
                    if (label.Value.Length == 0)
                    {
                        return(Reference.SelfReference);
                    }

                    var details = LookupReference(subj.ReferenceMap, label.Value);
                    if (details != null)
                    {
                        return(details);
                    }

                    // rollback the subject but return InvalidReference so that the caller knows not to
                    // parse 'foo' from [foo][bar].
                    subj.Position = endlabel;
                    return(Reference.InvalidReference);
                }
            }

            // rollback the subject position because didn't match anything.
            subj.Position = endlabel;
            return(null);
        }