예제 #1
0
        internal void RenderImg(Markdown m, StringBuilder b, string alt_text, List <string> specialAttributes)
        {
            HtmlTag tag = new HtmlTag("img");

            // encode url
            StringBuilder sb = m.GetStringBuilder();

            Utils.SmartHtmlEncodeAmpsAndAngles(sb, Url);
            tag.attributes["src"] = sb.ToString();

            // encode alt text
            if (!String.IsNullOrEmpty(alt_text))
            {
                sb.Length = 0;
                Utils.SmartHtmlEncodeAmpsAndAngles(sb, alt_text);
                tag.attributes["alt"] = sb.ToString();
            }

            // encode title
            if (!String.IsNullOrEmpty(Title))
            {
                sb.Length = 0;
                Utils.SmartHtmlEncodeAmpsAndAngles(sb, Title);
                tag.attributes["title"] = sb.ToString();
            }
            if (specialAttributes.Any())
            {
                LinkDefinition.HandleSpecialAttributes(specialAttributes, sb, tag);
            }
            tag.closed = true;

            m.OnPrepareImage(tag, m.RenderingTitledImage);

            tag.RenderOpening(b);
        }
예제 #2
0
        public void DoubleQuoteTitle()
        {
            r = LinkDefinition.ParseLinkDefinition("[id]: url.com \"my title\"", false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.ID, "id");
            Assert.AreEqual(r.Url, "url.com");
            Assert.AreEqual(r.Title, "my title");
        }
예제 #3
0
        public void ParenthesizedTitle()
        {
            r = LinkDefinition.ParseLinkDefinition("[id]: url.com (my title)", false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.ID, "id");
            Assert.AreEqual(r.Url, "url.com");
            Assert.AreEqual(r.Title, "my title");
        }
예제 #4
0
        public void NoTitle()
        {
            r = LinkDefinition.ParseLinkDefinition("[id]: url.com", false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.ID, "id");
            Assert.AreEqual(r.Url, "url.com");
            Assert.AreEqual(r.Title, null);
        }
예제 #5
0
        public void MultiLine()
        {
            r = LinkDefinition.ParseLinkDefinition("[id]:\n\t     http://www.site.com \n\t      (my title)", false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.ID, "id");
            Assert.AreEqual(r.Url, "http://www.site.com");
            Assert.AreEqual(r.Title, "my title");
        }
예제 #6
0
        public void AngleBracketedUrl()
        {
            r = LinkDefinition.ParseLinkDefinition("[id]: <url.com> (my title)", false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.ID, "id");
            Assert.AreEqual(r.Url, "url.com");
            Assert.AreEqual(r.Title, "my title");
        }
예제 #7
0
 public LinkInfo(LinkDefinition def, string link_text, List<string> specialAttributes )
 {
     this.Definition = def;
     this.LinkText = link_text;
     this.SpecialAttributes = new List<string>();
     if(specialAttributes != null)
     {
         this.SpecialAttributes.AddRange(specialAttributes);
     }
 }
예제 #8
0
        public void AngleBracketedUrl()
        {
            string str = "[id]: <url.com> (my title)";
            r = LinkDefinition.ParseLinkDefinition(str, false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.id, "id");
            Assert.AreEqual(r.url, "url.com");
            Assert.AreEqual(r.title, "my title");
        }
예제 #9
0
 public LinkInfo(LinkDefinition def, string link_text, List <string> specialAttributes)
 {
     this.Definition        = def;
     this.LinkText          = link_text;
     this.SpecialAttributes = new List <string>();
     if (specialAttributes != null)
     {
         this.SpecialAttributes.AddRange(specialAttributes);
     }
 }
예제 #10
0
        public void DoubleQuoteTitle()
        {
            string str = "[id]: url.com \"my title\"";
            r = LinkDefinition.ParseLinkDefinition(str, false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.id, "id");
            Assert.AreEqual(r.url, "url.com");
            Assert.AreEqual(r.title, "my title");
        }
예제 #11
0
        public void NoTitle()
        {
            string str = "[id]: url.com";
            r = LinkDefinition.ParseLinkDefinition(str, false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.Id, "id");
            Assert.AreEqual(r.Url, "url.com");
            Assert.AreEqual(r.Title, string.Empty);
        }
예제 #12
0
        public void MultiLine()
        {
            string str = "[id]:\n\t     http://www.site.com \n\t      (my title)";
            r = LinkDefinition.ParseLinkDefinition(str, false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.id, "id");
            Assert.AreEqual(r.url, "http://www.site.com");
            Assert.AreEqual(r.title, "my title");
        }
예제 #13
0
        public void NoTitle()
        {
            string str = "[id]: url.com";
            r = LinkDefinition.ParseLinkDefinition(str, false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.id, "id");
            Assert.AreEqual(r.url, "url.com");
            Assert.AreEqual(r.title, null);
        }
예제 #14
0
        internal void RenderLink(Markdown m, StringBuilder b, string link_text, List <string> specialAttributes)
        {
            if (this.Url.StartsWith("mailto:"))
            {
                b.Append("<a href=\"");
                Utils.HtmlRandomize(b, this.Url);
                b.Append('\"');
                if (!String.IsNullOrEmpty(this.Title))
                {
                    b.Append(" title=\"");
                    Utils.SmartHtmlEncodeAmpsAndAngles(b, this.Title);
                    b.Append('\"');
                }
                b.Append('>');
                Utils.HtmlRandomize(b, link_text);
                b.Append("</a>");
            }
            else
            {
                HtmlTag tag = new HtmlTag("a");

                // encode url
                StringBuilder sb = m.GetStringBuilder();
                Utils.SmartHtmlEncodeAmpsAndAngles(sb, this.Url);
                tag.attributes["href"] = sb.ToString();

                // encode title
                if (!String.IsNullOrEmpty(this.Title))
                {
                    sb.Length = 0;
                    Utils.SmartHtmlEncodeAmpsAndAngles(sb, this.Title);
                    tag.attributes["title"] = sb.ToString();
                }

                if (specialAttributes.Any())
                {
                    LinkDefinition.HandleSpecialAttributes(specialAttributes, sb, tag);
                }

                // Do user processing
                m.OnPrepareLink(tag);

                // Render the opening tag
                tag.RenderOpening(b);

                b.Append(link_text);                      // Link text already escaped by SpanFormatter
                b.Append("</a>");
            }
        }
예제 #15
0
        // Parse just the link target
        // For reference link definition, this is the bit after "[id]: thisbit"
        // For inline link, this is the bit in the parens: [link text](thisbit)
        internal static LinkDefinition ParseLinkTarget(StringScanner p, string id, bool ExtraMode)
        {
            // Skip whitespace
            p.SkipWhitespace();

            // End of string?
            if (p.eol)
            {
                return(null);
            }

            // Create the link definition
            var r = new LinkDefinition(id);

            // Is the url enclosed in angle brackets
            if (p.SkipChar('<'))
            {
                // Extract the url
                p.Mark();

                // Find end of the url
                while (p.current != '>')
                {
                    if (p.eof)
                    {
                        return(null);
                    }
                    p.SkipEscapableChar(ExtraMode);
                }

                string url = p.Extract();
                if (!p.SkipChar('>'))
                {
                    return(null);
                }

                // Unescape it
                r.url = Utils.UnescapeString(url.Trim(), ExtraMode);

                // Skip whitespace
                p.SkipWhitespace();
            }
            else
            {
                // Find end of the url
                p.Mark();
                int paren_depth = 1;
                while (!p.eol)
                {
                    char ch = p.current;
                    if (char.IsWhiteSpace(ch))
                    {
                        break;
                    }
                    if (id == null)
                    {
                        if (ch == '(')
                        {
                            paren_depth++;
                        }
                        else if (ch == ')')
                        {
                            paren_depth--;
                            if (paren_depth == 0)
                            {
                                break;
                            }
                        }
                    }

                    p.SkipEscapableChar(ExtraMode);
                }

                r.url = Utils.UnescapeString(p.Extract().Trim(), ExtraMode);
            }

            p.SkipLinespace();

            // End of inline target
            if (p.DoesMatch(')'))
            {
                return(r);
            }

            bool bOnNewLine = p.eol;
            int  posLineEnd = p.position;

            if (p.eol)
            {
                p.SkipEol();
                p.SkipLinespace();
            }

            // Work out what the title is delimited with
            char delim;

            switch (p.current)
            {
            case '\'':
            case '\"':
                delim = p.current;
                break;

            case '(':
                delim = ')';
                break;

            default:
                if (bOnNewLine)
                {
                    p.position = posLineEnd;
                    return(r);
                }
                else
                {
                    return(null);
                }
            }

            // Skip the opening title delimiter
            p.SkipForward(1);

            // Find the end of the title
            p.Mark();
            while (true)
            {
                if (p.eol)
                {
                    return(null);
                }

                if (p.current == delim)
                {
                    if (delim != ')')
                    {
                        int savepos = p.position;

                        // Check for embedded quotes in title

                        // Skip the quote and any trailing whitespace
                        p.SkipForward(1);
                        p.SkipLinespace();

                        // Next we expect either the end of the line for a link definition
                        // or the close bracket for an inline link
                        if ((id == null && p.current != ')') ||
                            (id != null && !p.eol))
                        {
                            continue;
                        }

                        p.position = savepos;
                    }

                    // End of title
                    break;
                }

                p.SkipEscapableChar(ExtraMode);
            }

            // Store the title
            r.title = Utils.UnescapeString(p.Extract(), ExtraMode);

            // Skip closing quote
            p.SkipForward(1);

            // Done!
            return(r);
        }
예제 #16
0
        // Process [link] and ![image] directives
        Token ProcessLinkOrImageOrFootnote()
        {
            // Link or image?
            TokenType token_type = SkipChar('!') ? TokenType.img : TokenType.link;

            // Opening '['
            if (!SkipChar('['))
            {
                return(null);
            }

            // Is it a foonote?
            var savepos = position;

            if (m_Markdown.ExtraMode && token_type == TokenType.link && SkipChar('^'))
            {
                SkipLinespace();

                // Parse it
                string id;
                if (SkipFootnoteID(out id) && SkipChar(']'))
                {
                    // Look it up and create footnote reference token
                    int footnote_index = m_Markdown.ClaimFootnote(id);
                    if (footnote_index >= 0)
                    {
                        // Yes it's a footnote
                        return(CreateToken(TokenType.footnote, new FootnoteReference(footnote_index, id)));
                    }
                }

                // Rewind
                position = savepos;
            }

            if (DisableLinks && token_type == TokenType.link)
            {
                return(null);
            }

            bool ExtraMode = m_Markdown.ExtraMode;

            // Find the closing square bracket, allowing for nesting, watching for
            // escapable characters
            Mark();
            int depth = 1;

            while (!eof)
            {
                char ch = current;
                if (ch == '[')
                {
                    depth++;
                }
                else if (ch == ']')
                {
                    depth--;
                    if (depth == 0)
                    {
                        break;
                    }
                }

                this.SkipEscapableChar(ExtraMode);
            }

            // Quit if end
            if (eof)
            {
                return(null);
            }

            // Get the link text and unescape it
            string link_text = Utils.UnescapeString(Extract(), ExtraMode);

            // The closing ']'
            SkipForward(1);

            // Save position in case we need to rewind
            savepos = position;

            // Inline links must follow immediately
            if (SkipChar('('))
            {
                // Extract the url and title
                var link_def = LinkDefinition.ParseLinkTarget(this, null, m_Markdown.ExtraMode);
                if (link_def == null)
                {
                    return(null);
                }

                // Closing ')'
                SkipWhitespace();
                if (!SkipChar(')'))
                {
                    return(null);
                }

                // Create the token
                return(CreateToken(token_type, new LinkInfo(link_def, link_text)));
            }

            // Optional space or tab
            if (!SkipChar(' '))
            {
                SkipChar('\t');
            }

            // If there's line end, we're allow it and as must line space as we want
            // before the link id.
            if (eol)
            {
                SkipEol();
                SkipLinespace();
            }

            // Reference link?
            string link_id = null;

            if (current == '[')
            {
                // Skip the opening '['
                SkipForward(1);

                // Find the start/end of the id
                Mark();
                if (!Find(']'))
                {
                    return(null);
                }

                // Extract the id
                link_id = Extract();

                // Skip closing ']'
                SkipForward(1);
            }
            else
            {
                // Rewind to just after the closing ']'
                position = savepos;
            }

            // Link id not specified?
            if (string.IsNullOrEmpty(link_id))
            {
                // Use the link text (implicit reference link)
                link_id = Utils.NormalizeLineEnds(link_text);

                // If the link text has carriage returns, normalize
                // to spaces
                if (!object.ReferenceEquals(link_id, link_text))
                {
                    while (link_id.Contains(" \n"))
                    {
                        link_id = link_id.Replace(" \n", "\n");
                    }
                    link_id = link_id.Replace("\n", " ");
                }
            }

            // Find the link definition abort if not defined
            var def = m_Markdown.GetLinkDefinition(link_id);

            if (def == null)
            {
                return(null);
            }

            // Create a token
            return(CreateToken(token_type, new LinkInfo(def, link_text)));
        }
예제 #17
0
 // Add a link definition
 internal void AddLinkDefinition(LinkDefinition link)
 {
     // Store it
     m_LinkDefinitions[link.id]=link;
 }
예제 #18
0
 // Add a link definition
 public void AddLinkDefinition(LinkDefinition link)
 {
     // Store it
     m_LinkDefinitions[link.id]=link;
 }
예제 #19
0
 public LinkInfo(LinkDefinition def, string link_text)
 {
     this.def = def;
     this.link_text = link_text;
 }
예제 #20
0
 // Add a link definition
 internal void AddLinkDefinition(LinkDefinition link)
 {
     // Store it
     m_LinkDefinitions[link.id] = link;
     m_FoundLinks.Add(new LinkInfo(link, null));
 }
예제 #21
0
 // Add a link definition
 internal void AddLinkDefinition(LinkDefinition link)
 {
     // Store it
     _mLinkDefinitions[link.ID] = link;
 }
예제 #22
0
파일: LinkInfo.cs 프로젝트: KittyMac/LD36
 public LinkInfo(LinkDefinition def, string link_text)
 {
     this.def       = def;
     this.link_text = link_text;
 }
예제 #23
0
 public void Setup()
 {
     r=null;
 }
예제 #24
0
 // Add a link definition
 internal void AddLinkDefinition(LinkDefinition link)
 {
     // Store it
     m_LinkDefinitions[link.id] = link;
 }
예제 #25
0
 // Add a link definition
 public void AddLinkDefinition(LinkDefinition link)
 {
     // Store it
     m_LinkDefinitions[link.id] = link;
 }
예제 #26
0
        internal void RenderLink(Markdown m, StringBuilder b, string link_text, List <string> specialAttributes)
        {
            if (this.Url.StartsWith("mailto:"))
            {
                b.Append("<a href=\"");
                Utils.HtmlRandomize(b, this.Url);
                b.Append('\"');
                if (!String.IsNullOrEmpty(this.Title))
                {
                    b.Append(" title=\"");
                    Utils.SmartHtmlEncodeAmpsAndAngles(b, this.Title);
                    b.Append('\"');
                }
                b.Append('>');
                Utils.HtmlRandomize(b, link_text);
                b.Append("</a>");
            }
            else
            {
                HtmlTag tag = new HtmlTag("a");

                var url = this.Url;

                if (m.DocNetMode && m.ConvertLocalLinks)
                {
                    // A few requirements before we can convert local links:
                    //   1. Link contains .md
                    //   2. Link is relative
                    //   3. Link is included in the index
                    var index = url.LastIndexOf(".md", StringComparison.OrdinalIgnoreCase);
                    if (index >= 0)
                    {
                        var linkProcessor = m.LocalLinkProcessor;
                        if (linkProcessor != null)
                        {
                            url = linkProcessor(url);
                        }
                        else
                        {
                            Uri uri;
                            if (Uri.TryCreate(url, UriKind.Relative, out uri))
                            {
                                url = String.Concat(url.Substring(0, index), ".htm", url.Substring(index + ".md".Length));
                            }
                        }
                    }
                }

                // encode url
                StringBuilder sb = m.GetStringBuilder();
                Utils.SmartHtmlEncodeAmpsAndAngles(sb, url);
                tag.attributes["href"] = sb.ToString();

                // encode title
                if (!String.IsNullOrEmpty(this.Title))
                {
                    sb.Length = 0;
                    Utils.SmartHtmlEncodeAmpsAndAngles(sb, this.Title);
                    tag.attributes["title"] = sb.ToString();
                }

                if (specialAttributes.Any())
                {
                    LinkDefinition.HandleSpecialAttributes(specialAttributes, sb, tag);
                }

                // Do user processing
                m.OnPrepareLink(tag);

                // Render the opening tag
                tag.RenderOpening(b);

                b.Append(link_text);                      // Link text already escaped by SpanFormatter
                b.Append("</a>");
            }
        }
예제 #27
0
 // Add a link definition
 internal void AddLinkDefinition(LinkDefinition link)
 {
     // Store it
     m_LinkDefinitions[link.id]=link;
     m_FoundLinks.Add(new LinkInfo(link, null));
 }
예제 #28
0
        public void SingleQuoteTitle()
        {
            string str = "[id]: url.com \'my title\'";
            r = LinkDefinition.ParseLinkDefinition(str, false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.Id, "id");
            Assert.AreEqual(r.Url, "url.com");
            Assert.AreEqual(r.Title, "my title");
        }
예제 #29
0
		// Parse just the link target
		// For reference link definition, this is the bit after "[id]: thisbit"
		// For inline link, this is the bit in the parens: [link text](thisbit)
		internal static LinkDefinition ParseLinkTarget(StringScanner p, string id, bool ExtraMode)
		{
			// Skip whitespace
			p.SkipWhitespace();

			// End of string?
			if (p.eol)
				return null;

			// Create the link definition
			var r = new LinkDefinition(id);

			// Is the url enclosed in angle brackets
			if (p.SkipChar('<'))
			{
				// Extract the url
				p.Mark();

				// Find end of the url
				while (p.current != '>')
				{
					if (p.eof)
						return null;
					p.SkipEscapableChar(ExtraMode);
				}

				string url = p.Extract();
				if (!p.SkipChar('>'))
					return null;

				// Unescape it
				r.url = Utils.UnescapeString(url.Trim(), ExtraMode);

				// Skip whitespace
				p.SkipWhitespace();
			}
			else
			{
				// Find end of the url
				p.Mark();
				int paren_depth = 1;
				while (!p.eol)
				{
					char ch=p.current;
					if (char.IsWhiteSpace(ch))
						break;
					if (id == null)
					{
						if (ch == '(')
							paren_depth++;
						else if (ch == ')')
						{
							paren_depth--;
							if (paren_depth==0)
								break;
						}
					}

					p.SkipEscapableChar(ExtraMode);
				}

				r.url = Utils.UnescapeString(p.Extract().Trim(), ExtraMode);
			}

			p.SkipLinespace();

			// End of inline target
			if (p.DoesMatch(')'))
				return r;

			bool bOnNewLine = p.eol;
			int posLineEnd = p.position;
			if (p.eol)
			{
				p.SkipEol();
				p.SkipLinespace();
			}

			// Work out what the title is delimited with
			char delim;
			switch (p.current)
			{
				case '\'':  
				case '\"':
					delim = p.current;
					break;

				case '(':
					delim = ')';
					break;

				default:
					if (bOnNewLine)
					{
						p.position = posLineEnd;
						return r;
					}
					else
						return null;
			}

			// Skip the opening title delimiter
			p.SkipForward(1);

			// Find the end of the title
			p.Mark();
			while (true)
			{
				if (p.eol)
					return null;

				if (p.current == delim)
				{

					if (delim != ')')
					{
						int savepos = p.position;

						// Check for embedded quotes in title

						// Skip the quote and any trailing whitespace
						p.SkipForward(1);
						p.SkipLinespace();

						// Next we expect either the end of the line for a link definition
						// or the close bracket for an inline link
						if ((id == null && p.current != ')') ||
							(id != null && !p.eol))
						{
							continue;
						}

						p.position = savepos;
					}

					// End of title
					break;
				}

				p.SkipEscapableChar(ExtraMode);
			}

			// Store the title
			r.title = Utils.UnescapeString(p.Extract(), ExtraMode);

			// Skip closing quote
			p.SkipForward(1);

			// Done!
			return r;
		}
예제 #30
0
        public void ParenthesizedTitle()
        {
            string str = "[id]: url.com (my title)";
            r = LinkDefinition.ParseLinkDefinition(str, false);

            Assert.IsNotNull(r);
            Assert.AreEqual(r.id, "id");
            Assert.AreEqual(r.url, "url.com");
            Assert.AreEqual(r.title, "my title");
        }