internal void RenderLink(Markdown m, StringBuilder b, string link_text)
		{
			if (url.StartsWith("mailto:"))
			{
				b.Append("<a href=\"");
				Utils.HtmlRandomize(b, url);
				b.Append('\"');
				//if (!String.IsNullOrEmpty(title))
				if (null != title && title != System.String.Empty)
				{
					b.Append(" title=\"");
					Utils.SmartHtmlEncodeAmpsAndAngles(b, 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, url);
				tag.attributes["href"] = sb.ToString();

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

				// 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>");
			}
		}
示例#2
0
        public bool IsTagReallySafe(HtmlTag tag)
        {
            switch (tag.name)
            {
                case "B":
                case "UL":
                case "LI":
                case "I":
                    return tag.attributes.Count == 0;

                case "A":
                case "a":
                    return tag.closing && tag.attributes.Count == 0;
            }

            return false;
        }
        internal MarkdownInHtmlMode GetMarkdownMode(HtmlTag tag)
        {
            // Get the markdown attribute
            string strMarkdownMode;
            if (!m_markdown.ExtraMode || !tag.attributes.TryGetValue("markdown", out strMarkdownMode))
            {
                if (m_bMarkdownInHtml)
                    return MarkdownInHtmlMode.Deep;
                else
                    return MarkdownInHtmlMode.NA;
            }

            // Remove it
            tag.attributes.Remove("markdown");

            // Parse mode
            if (strMarkdownMode == "1")
                return (tag.Flags & HtmlTagFlags.ContentAsSpan)!=0 ? MarkdownInHtmlMode.Span : MarkdownInHtmlMode.Block;

            if (strMarkdownMode == "block")
                return MarkdownInHtmlMode.Block;

            if (strMarkdownMode == "deep")
                return MarkdownInHtmlMode.Deep;

            if (strMarkdownMode == "span")
                return MarkdownInHtmlMode.Span;

            return MarkdownInHtmlMode.Off;
        }
示例#4
0
        internal void RenderVideo(Markdown m, StringBuilder b, string alt_text)
        {
            HtmlTag tag = new HtmlTag("video");
            tag.attributes ["controls"] = "controls";
            // encode url
            StringBuilder sb = m.GetStringBuilder();
            Utils.SmartHtmlEncodeAmpsAndAngles(sb, url);

            HtmlTag source = new HtmlTag("source");
            source.attributes["src"] = sb.ToString();
            m.OnPrepareVideoSource(source);

            // 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();
            }

            tag.closed = true;

            tag.RenderOpening(b);
            source.RenderOpening (b);
            tag.RenderClosing (b);
        }
示例#5
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);
                        }
                        if (Uri.TryCreate(url, UriKind.Relative, out var 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>");
            }
        }
示例#6
0
        private static HtmlTag ParseHelper(StringScanner p)
        {
            // Does it look like a tag?
            if (p.Current != '<')
                return null;

            // Skip '<'
            p.SkipForward(1);

            // Is it a comment?
            if (p.SkipString("!--"))
            {
                p.Mark();

                if (p.Find("-->"))
                {
                    var t = new HtmlTag("!");
                    t.m_attributes.Add("content", p.Extract());
                    t.m_closed = true;
                    p.SkipForward(3);
                    return t;
                }
            }

            // Is it a closing tag eg: </div>
            bool bClosing = p.SkipChar('/');

            // Get the tag name
            string tagName=null;
            if (!p.SkipIdentifier(ref tagName))
                return null;

            // Probably a tag, create the HtmlTag object now
            HtmlTag tag = new HtmlTag(tagName);
            tag.m_closing = bClosing;

            // If it's a closing tag, no attributes
            if (bClosing)
            {
                if (p.Current != '>')
                    return null;

                p.SkipForward(1);
                return tag;
            }

            while (!p.Eof)
            {
                // Skip whitespace
                p.SkipWhitespace();

                // Check for closed tag eg: <hr />
                if (p.SkipString("/>"))
                {
                    tag.m_closed=true;
                    return tag;
                }

                // End of tag?
                if (p.SkipChar('>'))
                {
                    return tag;
                }

                // attribute name
                string attributeName = null;
                if (!p.SkipIdentifier(ref attributeName))
                    return null;

                // Skip whitespace
                p.SkipWhitespace();

                // Skip equal sign
                if (p.SkipChar('='))
                {
                    // Skip whitespace
                    p.SkipWhitespace();

                    // Optional quotes
                    if (p.SkipChar('\"'))
                    {
                        // Scan the value
                        p.Mark();
                        if (!p.Find('\"'))
                            return null;

                        // Store the value
                        tag.m_attributes.Add(attributeName, p.Extract());

                        // Skip closing quote
                        p.SkipForward(1);
                    }
                    else
                    {
                        // Scan the value
                        p.Mark();
                        while (!p.Eof && !char.IsWhiteSpace(p.Current) && p.Current != '>' && p.Current != '/')
                            p.SkipForward(1);

                        if (!p.Eof)
                        {
                            // Store the value
                            tag.m_attributes.Add(attributeName, p.Extract());
                        }
                    }
                }
                else
                {
                    tag.m_attributes.Add(attributeName, "");
                }
            }

            return null;
        }
示例#7
0
        // Override to modify the attributes of an image
        public virtual void OnPrepareImage(HtmlTag tag, bool TitledImage)
        {
            if (PrepareImage != null)
            {
                if (PrepareImage(tag, TitledImage))
                    return;
            }

            // Try to determine width and height
            int width, height;
            if (OnGetImageSize(tag.attributes["src"], TitledImage, out width, out height))
            {
                tag.attributes["width"] = width.ToString();
                tag.attributes["height"] = height.ToString();
            }

            // Now qualify the url
            tag.attributes["src"] = OnQualifyUrl(tag.attributes["src"]);
        }
示例#8
0
 private static bool PrepareImage(string imagesPath, HtmlTag tag)
 {
     string src;
     if (tag.attributes.TryGetValue("src", out src))
     {
         src = src.Replace('\\', '/');
         if (src.StartsWith("images/", StringComparison.InvariantCultureIgnoreCase))
             src = src.Substring(7);
         tag.attributes["src"] = imagesPath + src;
     }
     return true;
 }
示例#9
0
        // Scan the input string, creating tokens for anything special
        public void Tokenize(string str, int start, int len)
        {
            // Prepare
            base.Reset(str, start, len);
            m_Tokens.Clear();

            List <Token> emphasis_marks = null;

            List <Abbreviation> Abbreviations = m_Markdown.GetAbbreviations();
            bool ExtraMode = m_Markdown.ExtraMode;

            // Scan string
            int start_text_token = Position;

            while (!Eof)
            {
                int end_text_token = Position;

                // Work out token
                Token token        = null;
                int   positionSave = Position;
                switch (Current)
                {
                case '*':
                case '_':
                    // Create emphasis mark
                    token = CreateEmphasisMark();

                    if (token != null)
                    {
                        // Store marks in a separate list the we'll resolve later
                        switch (token.type)
                        {
                        case TokenType.internal_mark:
                        case TokenType.opening_mark:
                        case TokenType.closing_mark:
                            if (emphasis_marks == null)
                            {
                                emphasis_marks = new List <Token>();
                            }
                            emphasis_marks.Add(token);
                            break;
                        }
                    }
                    break;

                case '~':
                    if (m_Markdown.HnDMode)
                    {
                        // scan for ~~text~~.
                        token = ProcessStrikeThrough();
                    }
                    break;

                case '`':
                    token = ProcessCodeSpan();
                    break;

                case '[':
                case '!':
                    // Process link reference
                    int linkpos = Position;
                    token = ProcessLinkOrImageOrFootnote();

                    // Rewind if invalid syntax
                    // (the '[' or '!' will be treated as a regular character and processed below)
                    if (token == null)
                    {
                        Position = linkpos;
                    }
                    break;

                case '<':
                    // Is it a valid html tag?
                    HtmlTag tag = HtmlTag.Parse(this);
                    if (tag != null)
                    {
                        if (!m_Markdown.SafeMode || tag.IsSafe())
                        {
                            // Yes, create a token for it
                            token = CreateToken(TokenType.HtmlTag, positionSave, Position - positionSave);
                        }
                        else
                        {
                            // No, rewrite and encode it
                            Position = positionSave;
                        }
                    }
                    else
                    {
                        // No, rewind and check if it's a valid autolink eg: <google.com>
                        Position = positionSave;
                        token    = ProcessAutoLink();

                        if (token == null)
                        {
                            Position = positionSave;
                        }
                    }
                    break;

                case '&':
                    // Is it a valid html entity
                    string unused = null;
                    if (SkipHtmlEntity(ref unused))
                    {
                        // Yes, create a token for it
                        token = CreateToken(TokenType.Html, positionSave, Position - positionSave);
                    }

                    break;

                case ' ':
                    // Check for double space at end of a line
                    if (CharAtOffset(1) == ' ' && IsLineEnd(CharAtOffset(2)))
                    {
                        // Yes, skip it
                        SkipForward(2);

                        // Don't put br's at the end of a paragraph
                        if (!Eof)
                        {
                            SkipEol();
                            token = CreateToken(TokenType.br, end_text_token, 0);
                        }
                    }
                    break;

                case '\\':
                    // Special handling for escaping <autolinks>

                    /*
                     * if (CharAtOffset(1) == '<')
                     * {
                     *      // Is it an autolink?
                     *      int savepos = position;
                     *      SkipForward(1);
                     *      bool AutoLink = ProcessAutoLink() != null;
                     *      position = savepos;
                     *
                     *      if (AutoLink)
                     *      {
                     *              token = CreateToken(TokenType.Text, position + 1, 1);
                     *              SkipForward(2);
                     *      }
                     * }
                     * else
                     */
                {
                    // Check followed by an escapable character
                    if (Utils.IsEscapableChar(CharAtOffset(1), ExtraMode))
                    {
                        token = CreateToken(TokenType.Text, Position + 1, 1);
                        SkipForward(2);
                    }
                }
                break;

                case '@':
                    if (m_Markdown.DocNetMode || m_Markdown.HnDMode)
                    {
                        if (this.DoesMatch("@fa-"))
                        {
                            // expect FontAwesome.
                            string iconName    = string.Empty;
                            int    newPosition = 0;
                            if (Utils.SkipFontAwesome(this.Input, this.Position, out newPosition, out iconName))
                            {
                                // token should be just the iconname, so adjust position specification to that.
                                token         = CreateToken(TokenType.font_awesome, newPosition - iconName.Length, iconName.Length);
                                this.Position = newPosition;
                            }
                        }
                    }
                    break;

                case ':':
                    if (m_Markdown.HnDMode && m_Markdown.EmojiFilePerName != null)
                    {
                        // scan till next ':' and stop if EOL or whitespace is seen.
                        string emojiName   = string.Empty;
                        int    newPosition = 0;
                        if (Utils.ParseEmoji(this.Input, this.Position, out newPosition, out emojiName))
                        {
                            token         = CreateToken(TokenType.emoji, emojiName);
                            this.Position = newPosition;
                        }
                        else
                        {
                            // try smiley mapping
                            token = ParseSmileyMapping(positionSave);
                        }
                    }
                    break;

                default:
                    token = ParseSmileyMapping(positionSave);
                    break;
                }

                // Look for abbreviations.
                if (token == null && Abbreviations != null && !Char.IsLetterOrDigit(CharAtOffset(-1)))
                {
                    var savepos = Position;
                    foreach (var abbr in Abbreviations)
                    {
                        if (SkipString(abbr.Abbr) && !Char.IsLetterOrDigit(Current))
                        {
                            token = CreateToken(TokenType.abbreviation, abbr);
                            break;
                        }

                        Position = savepos;
                    }
                }

                // If token found, append any preceeding text and the new token to the token list
                if (token != null)
                {
                    // Create a token for everything up to the special character
                    if (end_text_token > start_text_token)
                    {
                        m_Tokens.Add(CreateToken(TokenType.Text, start_text_token, end_text_token - start_text_token));
                    }

                    // Add the new token
                    m_Tokens.Add(token);

                    // Remember where the next text token starts
                    start_text_token = Position;
                }
                else
                {
                    // Skip a single character and keep looking
                    SkipForward(1);
                }
            }

            // Append a token for any trailing text after the last token.
            if (Position > start_text_token)
            {
                m_Tokens.Add(CreateToken(TokenType.Text, start_text_token, Position - start_text_token));
            }

            // Do we need to resolve and emphasis marks?
            if (emphasis_marks != null)
            {
                ResolveEmphasisMarks(m_Tokens, emphasis_marks);
            }
        }
示例#10
0
        private static HtmlTag ParseHelper(StringScanner p)
        {
            // Does it look like a tag?
            if (p.current != '<')
            {
                return(null);
            }

            // Skip '<'
            p.SkipForward(1);

            // Is it a comment?
            if (p.SkipString("!--"))
            {
                p.Mark();

                if (p.Find("-->"))
                {
                    var t = new HtmlTag("!");
                    t.m_attributes.Add("content", p.Extract());
                    t.m_closed = true;
                    p.SkipForward(3);
                    return(t);
                }
            }

            // Is it a closing tag eg: </div>
            bool bClosing = p.SkipChar('/');

            // Get the tag name
            string tagName = null;

            if (!p.SkipIdentifier(ref tagName))
            {
                return(null);
            }

            // Probably a tag, create the HtmlTag object now
            HtmlTag tag = new HtmlTag(tagName);

            tag.m_closing = bClosing;


            // If it's a closing tag, no attributes
            if (bClosing)
            {
                if (p.current != '>')
                {
                    return(null);
                }

                p.SkipForward(1);
                return(tag);
            }


            while (!p.eof)
            {
                // Skip whitespace
                p.SkipWhitespace();

                // Check for closed tag eg: <hr />
                if (p.SkipString("/>"))
                {
                    tag.m_closed = true;
                    return(tag);
                }

                // End of tag?
                if (p.SkipChar('>'))
                {
                    return(tag);
                }

                // attribute name
                string attributeName = null;
                if (!p.SkipIdentifier(ref attributeName))
                {
                    return(null);
                }

                // Skip whitespace
                p.SkipWhitespace();

                // <tag     attr    =    "foo"   />

                // Skip equal sign
                if (p.SkipChar('='))
                {
                    // @kamranayub: Allow blank attributes per HTML spec

                    // Skip whitespace
                    p.SkipWhitespace();

                    // Optional quotes
                    if (p.SkipChar('\"'))
                    {
                        // Scan the value
                        p.Mark();
                        if (!p.Find('\"'))
                        {
                            return(null);
                        }

                        // Store the value
                        tag.m_attributes.Add(attributeName, p.Extract());

                        // Skip closing quote
                        p.SkipForward(1);
                    }
                    else
                    {
                        // Scan the value
                        p.Mark();
                        while (!p.eof && !char.IsWhiteSpace(p.current) && p.current != '>' && p.current != '/')
                        {
                            p.SkipForward(1);
                        }

                        if (!p.eof)
                        {
                            // Store the value
                            tag.m_attributes.Add(attributeName, p.Extract());
                        }
                    }
                }
                else
                {
                    tag.m_attributes.Add(attributeName, string.Empty);
                }
            }

            return(null);
        }
示例#11
0
		// Scan the input string, creating tokens for anything special 
		public void Tokenize(string str, int start, int len)
		{
			// Prepare
			base.Reset(str, start, len);
			m_Tokens.Clear();

			List<Token> emphasis_marks = null;

			List<Abbreviation> Abbreviations=m_Markdown.GetAbbreviations();
			bool ExtraMode = m_Markdown.ExtraMode;

			// Scan string
			int start_text_token = position;
			while (!eof)
			{
				int end_text_token=position;

				// Work out token
				Token token = null;
				switch (current)
				{
					case '*':
					case '_':

						// Create emphasis mark
						token = CreateEmphasisMark();

						if (token != null)
						{
							// Store marks in a separate list the we'll resolve later
							switch (token.type)
							{
								case TokenType.internal_mark:
								case TokenType.opening_mark:
								case TokenType.closing_mark:
									if (emphasis_marks == null)
									{
										emphasis_marks = new List<Token>();
									}
									emphasis_marks.Add(token);
									break;
							}
						}
						break;

					case '`':
						token = ProcessCodeSpan();
						break;

					case '[':
					case '!':
					{
						// Process link reference
						int linkpos = position;
						token = ProcessLinkOrImageOrFootnote();

						// Rewind if invalid syntax
						// (the '[' or '!' will be treated as a regular character and processed below)
						if (token == null)
							position = linkpos;
						break;
					}

					case '<':
					{
						// Is it a valid html tag?
						int save = position;
						HtmlTag tag = HtmlTag.Parse(this);
						if (tag != null)
						{
							if (!m_Markdown.SafeMode || tag.IsSafe())
							{
								// Yes, create a token for it
								token = CreateToken(TokenType.HtmlTag, save, position - save);
							}
							else
							{
								// No, rewrite and encode it
								position = save;
							}
						}
						else
						{
							// No, rewind and check if it's a valid autolink eg: <google.com>
							position = save;
							token = ProcessAutoLink();

							if (token == null)
								position = save;
						}
						break;
					}

					case '&':
					{
						// Is it a valid html entity
						int save=position;
						string unused=null;
						if (SkipHtmlEntity(ref unused))
						{
							// Yes, create a token for it
							token = CreateToken(TokenType.Html, save, position - save);
						}

						break;
					}

					case ' ':
					{
						// Check for double space at end of a line
						if (CharAtOffset(1)==' ' && IsLineEnd(CharAtOffset(2)))
						{
							// Yes, skip it
							SkipForward(2);

							// Don't put br's at the end of a paragraph
							if (!eof)
							{
								SkipEol();
								token = CreateToken(TokenType.br, end_text_token, 0);
							}
						}
						break;
					}

					case '\\':
					{
						// Special handling for escaping <autolinks>
						/*
						if (CharAtOffset(1) == '<')
						{
							// Is it an autolink?
							int savepos = position;
							SkipForward(1);
							bool AutoLink = ProcessAutoLink() != null;
							position = savepos;

							if (AutoLink)
							{
								token = CreateToken(TokenType.Text, position + 1, 1);
								SkipForward(2);
							}
						}
						else
						 */
						{
							// Check followed by an escapable character
							if (Utils.IsEscapableChar(CharAtOffset(1), ExtraMode))
							{
								token = CreateToken(TokenType.Text, position + 1, 1);
								SkipForward(2);
							}
						}
						break;
					}
				}

				// Look for abbreviations.
				if (token == null && Abbreviations!=null && !Char.IsLetterOrDigit(CharAtOffset(-1)))
				{
					var savepos = position;
					foreach (var abbr in Abbreviations)
					{
						if (SkipString(abbr.Abbr) && !Char.IsLetterOrDigit(current))
						{
							token = CreateToken(TokenType.abbreviation, abbr);
							break;
						}

						position = savepos;
					}

				}

				// If token found, append any preceeding text and the new token to the token list
				if (token!=null)
				{
					// Create a token for everything up to the special character
					if (end_text_token > start_text_token)
					{
						m_Tokens.Add(CreateToken(TokenType.Text, start_text_token, end_text_token-start_text_token));
					}

					// Add the new token
					m_Tokens.Add(token);

					// Remember where the next text token starts
					start_text_token=position;
				}
				else
				{
					// Skip a single character and keep looking
					SkipForward(1);
				}
			}

			// Append a token for any trailing text after the last token.
			if (position > start_text_token)
			{
				m_Tokens.Add(CreateToken(TokenType.Text, start_text_token, position-start_text_token));
			}

			// Do we need to resolve and emphasis marks?
			if (emphasis_marks != null)
			{
				ResolveEmphasisMarks(m_Tokens, emphasis_marks);
			}

			// Done!
			return;
		}
示例#12
0
 private static void HandleSpecialAttributes(List<string> specialAttributes, StringBuilder sb, HtmlTag tag)
 {
     string id = specialAttributes.FirstOrDefault(s => s.StartsWith("#"));
     if(id != null && id.Length > 1)
     {
         sb.Length = 0;
         Utils.SmartHtmlEncodeAmpsAndAngles(sb, id.Substring(1));
         tag.attributes["id"] = sb.ToString();
     }
     var cssClasses = new List<string>();
     foreach(var cssClass in specialAttributes.Where(s => s.StartsWith(".") && s.Length > 1))
     {
         sb.Length = 0;
         Utils.SmartHtmlEncodeAmpsAndAngles(sb, cssClass.Substring(1));
         cssClasses.Add(sb.ToString());
     }
     if(cssClasses.Any())
     {
         tag.attributes["class"] = string.Join(" ", cssClasses.ToArray());
     }
     foreach(var nameValuePair in specialAttributes.Where(s => s.Contains("=") && s.Length > 2 && !s.StartsWith(".") && !s.StartsWith("#")))
     {
         var pair = nameValuePair.Split('=');
         if(pair.Length == 2)
         {
             sb.Length = 0;
             Utils.SmartHtmlEncodeAmpsAndAngles(sb, pair[0]);
             var key = sb.ToString();
             sb.Length = 0;
             Utils.SmartHtmlEncodeAmpsAndAngles(sb, pair[1]);
             var value = sb.ToString();
             tag.attributes[key] = value;
         }
     }
 }
示例#13
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>");
            }
        }
示例#14
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);
        }
示例#15
0
        private static void HandleSpecialAttributes(List <string> specialAttributes, StringBuilder sb, HtmlTag tag)
        {
            string id = specialAttributes.FirstOrDefault(s => s.StartsWith("#"));

            if (id != null && id.Length > 1)
            {
                sb.Length = 0;
                Utils.SmartHtmlEncodeAmpsAndAngles(sb, id.Substring(1));
                tag.attributes["id"] = sb.ToString();
            }
            var cssClasses = new List <string>();

            foreach (var cssClass in specialAttributes.Where(s => s.StartsWith(".") && s.Length > 1))
            {
                sb.Length = 0;
                Utils.SmartHtmlEncodeAmpsAndAngles(sb, cssClass.Substring(1));
                cssClasses.Add(sb.ToString());
            }
            if (cssClasses.Any())
            {
                tag.attributes["class"] = string.Join(" ", cssClasses.ToArray());
            }
            foreach (var nameValuePair in specialAttributes.Where(s => s.Contains("=") && s.Length > 2 && !s.StartsWith(".") && !s.StartsWith("#")))
            {
                var pair = nameValuePair.Split('=');
                if (pair.Length == 2)
                {
                    sb.Length = 0;
                    Utils.SmartHtmlEncodeAmpsAndAngles(sb, pair[0]);
                    var key = sb.ToString();
                    sb.Length = 0;
                    Utils.SmartHtmlEncodeAmpsAndAngles(sb, pair[1]);
                    var value = sb.ToString();
                    tag.attributes[key] = value;
                }
            }
        }
示例#16
0
        internal bool ProcessMarkdownEnabledHtml(Block b, HtmlTag openingTag, MarkdownInHtmlMode mode)
        {
            // Current position is just after the opening tag

            // Scan until we find matching closing tag
            int inner_pos = position;
            int depth = 1;
            bool bHasUnsafeContent = false;
            while (!eof)
            {
                // Find next angle bracket
                if (!Find('<'))
                    break;

                // Is it a html tag?
                int tagpos = position;
                HtmlTag tag = HtmlTag.Parse(this);
                if (tag == null)
                {
                    // Nope, skip it
                    SkipForward(1);
                    continue;
                }

                // In markdown off mode, we need to check for unsafe tags
                if (m_markdown.SafeMode && mode == MarkdownInHtmlMode.Off && !bHasUnsafeContent)
                {
                    if (!tag.IsSafe())
                        bHasUnsafeContent = true;
                }

                // Ignore self closing tags
                if (tag.closed)
                    continue;

                // Same tag?
                if (tag.name == openingTag.name)
                {
                    if (tag.closing)
                    {
                        depth--;
                        if (depth == 0)
                        {
                            // End of tag?
                            SkipLinespace();
                            SkipEol();

                            b.blockType = BlockType.HtmlTag;
                            b.data = openingTag;
                            b.contentEnd = position;

                            switch (mode)
                            {
                                case MarkdownInHtmlMode.Span:
                                {
                                    Block span = this.CreateBlock();
                                    span.buf = input;
                                    span.blockType = BlockType.span;
                                    span.contentStart = inner_pos;
                                    span.contentLen = tagpos - inner_pos;

                                    b.children = new List<Block>();
                                    b.children.Add(span);
                                    break;
                                }

                                case MarkdownInHtmlMode.Block:
                                case MarkdownInHtmlMode.Deep:
                                {
                                    // Scan the internal content
                                    var bp = new BlockProcessor(m_markdown, mode == MarkdownInHtmlMode.Deep);
                                    b.children = bp.ScanLines(input, inner_pos, tagpos - inner_pos);
                                    break;
                                }

                                case MarkdownInHtmlMode.Off:
                                {
                                    if (bHasUnsafeContent)
                                    {
                                        b.blockType = BlockType.unsafe_html;
                                        b.contentEnd = position;
                                    }
                                    else
                                    {
                                        Block span = this.CreateBlock();
                                        span.buf = input;
                                        span.blockType = BlockType.html;
                                        span.contentStart = inner_pos;
                                        span.contentLen = tagpos - inner_pos;

                                        b.children = new List<Block>();
                                        b.children.Add(span);
                                    }
                                    break;
                                }
                            }

                            return true;
                        }
                    }
                    else
                    {
                        depth++;
                    }
                }
            }

            // Missing closing tag(s).
            return false;
        }
示例#17
0
        private static bool PrepareLink(HtmlTag tag, string rootUrl, string trail, string versionUrl)
        {
            string href;
            if (!tag.attributes.TryGetValue("href", out href))
                return true;

            if (Uri.IsWellFormedUriString(href, UriKind.Absolute))
                return true;

            var hashIndex = href.IndexOf("#", StringComparison.InvariantCultureIgnoreCase);
            if (hashIndex != -1)
                href = href.Insert(hashIndex, "?version=" + versionUrl);
            else
                href += "?version=" + versionUrl;

            Uri uri;
            if (!string.IsNullOrWhiteSpace(trail))
                trail += "/"; // make sure we don't lose the current slug

            if (!Uri.TryCreate(new Uri(rootUrl + trail, UriKind.Absolute), new Uri(href, UriKind.Relative), out uri))
            {
                // TODO: Log error
            }

            tag.attributes["href"] = uri.AbsoluteUri;

            return true;
        }
示例#18
0
        private bool OnHtmlLink(HtmlTag arg)
        {
            var src = arg.attributes["href"];
            if (src.StartsWith("http"))
                return false;
            if (src.StartsWith("~"))
            {
                src = VirtualPathHandler(src);
                arg.attributes["href"] = src;
                return true;
            }

            if (!src.StartsWith("/") && !src.StartsWith("#"))
            {
                src = _pageSource.GetAbsoluteUrl(_currentUrlPath, src);
                arg.attributes["href"] = VirtualPathHandler("~/" + _rootUri + "/" + src);
            }

            var exists = _pageSource.PageExists(src) || src.StartsWith("#");
            if (!exists)
                arg.attributes["style"] = MissingLinkStyle;

            return true;
        }
示例#19
0
        private static bool PrepareLink(HtmlTag tag, string rootUrl, string trail, string versionUrl)
        {
            string href;
            if (!tag.attributes.TryGetValue("href", out href))
                return true;

            if (Uri.IsWellFormedUriString(href, UriKind.Absolute))
                return true;

            href += "?version=" + versionUrl;

            Uri uri;
            if (!string.IsNullOrWhiteSpace(trail)) trail += "/"; // make sure we don't lose the current slug
            if (!Uri.TryCreate(new Uri(rootUrl + trail, UriKind.Absolute), new Uri(href, UriKind.Relative), out uri))
            {
                // TODO: Log error
            }

            tag.attributes["href"] = uri.AbsoluteUri;

            return true;
        }
示例#20
0
        private bool OnImageLink(HtmlTag arg1, bool arg2)
        {
            var src = arg1.attributes["src"];
            if (src.StartsWith("http"))
                return false;

            if (src.StartsWith("~"))
            {
                //var url = string.Format(_rootUri + "?image={0}/{1}", _currentUrlPath, arg1.attributes["src"]);
                arg1.attributes["src"] = VirtualPathHandler(src);
                return true;
            }

            src = _pageSource.GetAbsoluteUrl(string.Empty, src);
            var formattedUrl = string.Format(VirtualPathHandler("~/" + _rootUri) + "?image={0}", src);
            arg1.attributes["src"] = formattedUrl;
            return true;
        }
示例#21
0
        // Override to modify the attributes of a link
        public virtual void OnPrepareLink(HtmlTag tag)
        {
            if (PrepareLink != null)
            {
                if (PrepareLink(tag))
                    return;
            }

            string url = tag.attributes["href"];

            // No follow?
            if (NoFollowLinks)
            {
                tag.attributes["rel"] = "nofollow";
            }

            // New window?
            if ( (NewWindowForExternalLinks && Utils.IsUrlFullyQualified(url)) ||
                 (NewWindowForLocalLinks && !Utils.IsUrlFullyQualified(url)) )
            {
                tag.attributes["target"] = "_blank";
            }

            // Qualify url
            tag.attributes["href"] = OnQualifyUrl(url);
        }
示例#22
0
 internal void RenderAudio(Markdown m, StringBuilder b, string alt_text)
 {
     HtmlTag tag = new HtmlTag("audio");
     tag.attributes ["controls"] = "controls";
     // 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();
     }
     tag.RenderOpening (b);
     tag.RenderClosing (b);
 }
示例#23
0
		internal void RenderImg(Markdown m, StringBuilder b, string alt_text)
		{
			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();
			}

			tag.closed = true;

			m.OnPrepareImage(tag, m.RenderingTitledImage);

			tag.RenderOpening(b);
		}
示例#24
0
        private static bool PrepareImage(ICollection<DocumentationImage> images, string directory, string imagesUrl, string documentationVersion, HtmlTag tag)
        {
            string src;
            if (tag.attributes.TryGetValue("src", out src))
            {
                var imagePath = Path.Combine(directory, src);

                src = src.Replace('\\', '/');
                if (src.StartsWith("images/", StringComparison.InvariantCultureIgnoreCase))
                    src = src.Substring(7);

                var newSrc = string.Format("{0}/{1}", documentationVersion, src);

                tag.attributes["src"] = imagesUrl + newSrc;

                images.Add(new DocumentationImage
                {
                    ImagePath = imagePath,
                    ImageKey = newSrc
                });
            }

            tag.attributes["class"] = "img-responsive img-thumbnail";

            return true;
        }