/// <summary> /// Handles internal links, and the 'attachment:' prefix for attachment links. /// </summary> private void LinkParsed(object sender, LinkEventArgs e) { if (!_externalLinkPrefixes.Any(x => e.OriginalHref.StartsWith(x))) { e.IsInternalLink = true; // Parse internal links, including attachments, tag: and special: links string href = e.OriginalHref; string lowerHref = href.ToLower(); if (lowerHref.StartsWith("attachment:") || lowerHref.StartsWith("~/")) { ConvertAttachmentHrefToFullPath(e); } else if (lowerHref.StartsWith("special:")) { ConvertSpecialPageHrefToFullPath(e); } else { ConvertInternalLinkHrefToFullPath(e); } } else { // Add the external-link class to all outward bound links, // except for anchors pointing to <a name=""> tags on the current page. if (!e.OriginalHref.StartsWith("#")) { e.CssClass = "external-link"; } } }
/// <summary> /// Handles internal links, and the 'attachment:' prefix for attachment links. /// </summary> private void LinkParsed(object sender, LinkEventArgs e) { if (!_externalLinkPrefixes.Any(x => e.OriginalHref.StartsWith(x))) { string href = e.OriginalHref; string lowerHref = href.ToLower(); if (lowerHref.StartsWith("attachment:") || lowerHref.StartsWith("~/")) { ConvertAttachmentHrefToFullPath(e); } else if (lowerHref.StartsWith("special:")) { ConvertSpecialPageHrefToFullPath(e); } else { ConvertInternalLinkHrefToFullPath(e); } } else { e.CssClass = "external-link"; } }
/// <summary> /// Updates the LinkEventArgs.Href to be a full path to the attachment /// </summary> private void ConvertAttachmentHrefToFullPath(LinkEventArgs e) { string href = e.OriginalHref; string lowerHref = href.ToLower(); if (lowerHref.StartsWith("attachment:")) { // Remove the attachment: part href = href.Remove(0, 11); if (!href.StartsWith("/")) { href = "/" + href; } } else if (lowerHref.StartsWith("~/")) { // Remove the ~ href = href.Remove(0, 1); } // Get the full path to the attachment string attachmentsPath = _applicationSettings.AttachmentsUrlPath; e.Href = UrlResolver.ConvertToAbsolutePath(attachmentsPath) + href; }
/// <summary> /// Raises the <see cref="LinkParsed"/> event. /// </summary> /// <param name="e">The event data. </param> protected void OnLinkParsed(LinkEventArgs e) { if (LinkParsed != null) { LinkParsed(this, e); } }
/// <summary> /// Updates the LinkEventArgs.Href to be a full path to the page, and the CssClass /// </summary> private void ConvertInternalLinkHrefToFullPath(LinkEventArgs e) { string href = e.OriginalHref; // Parse internal links string title = href; string anchorHash = ""; // Parse anchors for other pages if (_anchorRegex.IsMatch(href)) { // Grab the hash contents Match match = _anchorRegex.Match(href); anchorHash = match.Groups["hash"].Value; // Grab the url title = href.Replace(anchorHash, ""); } if (Parser is MarkdownParser) { // For markdown, only urls with "-" in them are valid, spaces are ignored. // Remove these, so a match is made. No url has a "-" in, so replacing them is ok. title = title.Replace("-", " "); } // Find the page, or if it doesn't exist point to the new page url Page page = _pageRepository.GetPageByTitle(title); if (page != null) { href = UrlResolver.GetInternalUrlForTitle(page.Id, page.Title); href += anchorHash; } else { href = UrlResolver.GetNewPageUrlForTitle(href); e.CssClass = "missing-page-link"; } e.Href = href; e.Target = ""; }
private void FixLinks(MarkdownDocument document) { foreach (var item in document.Descendants().OfType <LinkInline>()) { LinkInline link = (LinkInline)item; if (item.IsImage) { ImageEventArgs args = new ImageEventArgs(link.Url, link.Url, link.Label, link.Label); ImageParsed?.Invoke(this, args); link.Url = args.Src; } else { LinkEventArgs args = new LinkEventArgs(link.Url, link.Url, link.Label, ""); LinkParsed?.Invoke(this, args); link.Url = args.Href; } } }
private string AnchorRefShortcutEvaluator(Match match) { string wholeMatch = match.Groups[1].Value; string linkText = match.Groups[2].Value; string linkID = Regex.Replace(linkText.ToLowerInvariant(), @"[ ]*\n[ ]*", " "); // lower case and remove newlines / extra spaces string result; // links like this: [link text](url "optional title") or [link text](url "optional title") if (_urls.ContainsKey(linkID)) { string url = _urls[linkID]; url = EncodeProblemUrlChars(url); url = EscapeBoldItalic(url); LinkEventArgs args = new LinkEventArgs(url, url, linkText, ""); OnLinkParsed(args); result = "<a href=\"" + args.Href + "\""; result += AddNoRelToLink(args); if (_titles.ContainsKey(linkID)) { string title = _titles[linkID]; title = EscapeBoldItalic(title); result += " title=\"" + title + "\""; } if (!string.IsNullOrEmpty(args.Target)) { result += " target=\"" + args.Target + "\""; } if (!string.IsNullOrEmpty(args.CssClass)) { result += " class=\"" + args.CssClass + "\""; } result += ">" + args.Text + "</a>"; } else result = wholeMatch; return result; }
private string AnchorRefEvaluator(Match match) { string wholeMatch = match.Groups[1].Value; string linkText = match.Groups[2].Value; string linkID = match.Groups[3].Value.ToLowerInvariant(); string result; // for shortcut links like [this][]. if (linkID == "") linkID = linkText.ToLowerInvariant(); if (_urls.ContainsKey(linkID)) { string url = _urls[linkID]; url = EncodeProblemUrlChars(url); url = EscapeBoldItalic(url); LinkEventArgs args = new LinkEventArgs(url, url, linkText, ""); OnLinkParsed(args); result = "<a href=\"" + args.Href + "\""; result += AddNoRelToLink(args); if (_titles.ContainsKey(linkID)) { string title = _titles[linkID]; title = EscapeBoldItalic(title); result += " title=\"" + title + "\""; } if (!string.IsNullOrEmpty(args.Target)) { result += " target=\"" + args.Target + "\""; } if (!string.IsNullOrEmpty(args.CssClass)) { result += " class=\"" + args.CssClass + "\""; } result += ">" + args.Text + "</a>"; } else result = wholeMatch; return result; }
private string AnchorInlineEvaluator(Match match) { string linkText = match.Groups[2].Value; string url = match.Groups[3].Value; string title = match.Groups[6].Value; string result; url = EncodeProblemUrlChars(url); url = EscapeBoldItalic(url); if (url.StartsWith("<") && url.EndsWith(">")) url = url.Substring(1, url.Length - 2); // remove <>'s surrounding URL, if present LinkEventArgs args = new LinkEventArgs(url, url, linkText, ""); OnLinkParsed(args); result = "<a href=\"" + args.Href + "\""; result += AddNoRelToLink(args); if (!String.IsNullOrEmpty(title)) { title = title.Replace("\"", """); title = EscapeBoldItalic(title); result += string.Format(" title=\"{0}\"", title); } if (!string.IsNullOrEmpty(args.Target)) { result += " target=\"" + args.Target + "\""; } if (!string.IsNullOrEmpty(args.CssClass)) { result += " class=\"" + args.CssClass + "\""; } result += string.Format(">{0}</a>", args.Text); return result; }
private string AddNoRelToLink(LinkEventArgs args) { if (args.IsInternalLink == false) return "rel=\"nofollow\" "; else return ""; }
/// <summary> /// Updates the LinkEventArgs.Href to be a full path to the Special: page /// </summary> private void ConvertSpecialPageHrefToFullPath(LinkEventArgs e) { string href = e.OriginalHref; e.Href = UrlResolver.ConvertToAbsolutePath("~/wiki/" + href); }
private string AddNoRelToLink(LinkEventArgs args) { if (args.Href.StartsWith("http://") || args.Href.StartsWith("https://")) return "rel=\"nofollow\" "; else return ""; }
/// <summary> /// Updates the LinkEventArgs.Href to be a full path to the page, and the CssClass /// </summary> private void ConvertInternalLinkHrefToFullPath(LinkEventArgs e) { string href = e.OriginalHref; // Parse internal links string title = href; string anchorHash = ""; // Parse anchors for other pages if (_anchorRegex.IsMatch(href)) { // Grab the hash contents Match match = _anchorRegex.Match(href); anchorHash = match.Groups["hash"].Value; // Grab the url title = href.Replace(anchorHash, ""); } if (Parser is MarkdownParser) { // For markdown, only urls with "-" in them are valid, spaces are ignored. // Remove these, so a match is made. No url has a "-" in, so replacing them is ok. title = title.Replace("-", " "); } // Find the page, or if it doesn't exist point to the new page url Page page = _repository.GetPageByTitle(title); if (page != null) { href = UrlResolver.GetInternalUrlForTitle(page.Id, page.Title); href += anchorHash; } else { href = UrlResolver.GetNewPageUrlForTitle(href); e.CssClass = "missing-page-link"; } e.Href = href; e.Target = ""; }
/// <summary> /// Updates the LinkEventArgs.Href to be a full path to the Special: page /// </summary> private void ConvertSpecialPageHrefToFullPath(LinkEventArgs e) { string href = e.OriginalHref; e.Href = UrlResolver.ConvertToAbsolutePath("~/wiki/"+href); }
/// <summary> /// Updates the LinkEventArgs.Href to be a full path to the attachment /// </summary> private void ConvertAttachmentHrefToFullPath(LinkEventArgs e) { string href = e.OriginalHref; string lowerHref = href.ToLower(); if (lowerHref.StartsWith("attachment:")) { // Remove the attachment: part href = href.Remove(0, 11); if (!href.StartsWith("/")) href = "/" + href; } else if (lowerHref.StartsWith("~/")) { // Remove the ~ href = href.Remove(0, 1); } // Get the full path to the attachment string attachmentsPath = _applicationSettings.AttachmentsUrlPath; e.Href = UrlResolver.ConvertToAbsolutePath(attachmentsPath) + href; }
/// <summary> /// Handles internal links, and the 'attachment:' prefix for attachment links. /// </summary> private void LinkParsed(object sender, LinkEventArgs e) { if (!_externalLinkPrefixes.Any(x => e.OriginalHref.StartsWith(x))) { e.IsInternalLink = true; // Parse internal links, including attachments, tag: and special: links string href = e.OriginalHref; string lowerHref = href.ToLower(); if (lowerHref.StartsWith("attachment:") || lowerHref.StartsWith("~/")) { ConvertAttachmentHrefToFullPath(e); } else if (lowerHref.StartsWith("special:")) { ConvertSpecialPageHrefToFullPath(e); } else { ConvertInternalLinkHrefToFullPath(e); } } else { // Add the external-link class to all outward bound links, // except for anchors pointing to <a name=""> tags on the current page. if (!e.OriginalHref.StartsWith("#")) e.CssClass = "external-link"; } }
/// <summary> /// Raises the <see cref="LinkParsed"/> event. /// </summary> /// <param name="e">The event data. </param> protected void OnLinkParsed(LinkEventArgs e) { if (LinkParsed != null) LinkParsed(this, e); }
/// <summary> /// Processes link markup into HTML /// </summary> /// <param name="markup">markup</param> /// <returns>markup with [[foo]] translated into <a href></a></returns> protected virtual string _processLinkCreole(string markup) { int iPos = _indexOfWithSkip(markup, "[[", 0); while (iPos >= 0) { int iEnd = _indexOfWithSkip(markup, "]]", iPos); if (iEnd > iPos) { iPos += 2; // get the contents of the cell string cell = markup.Substring(iPos, iEnd - iPos); string link = cell; string href = cell; //default to assuming it's the href string text = href; // as well as the text int iSplit = cell.IndexOf('|'); // unless of course there is a splitter if (iSplit > 0) { // href is the front href = cell.Substring(0, iSplit); link = href; // text is the creole processed fragment left over text = _processCreoleFragment(cell.Substring(iSplit + 1)); } // handle interwiki links iSplit = href.IndexOf(':'); if (iSplit > 0) { string scheme = href.Substring(0, iSplit); if (InterWiki.ContainsKey(scheme)) { href = InterWiki[scheme] + href.Substring(iSplit + 1); } } // Remove any attribute enders: ", <, >, &, ' href = href.Replace("&", "&"); href = href.Replace("\"", "2"); href = href.Replace("<", "<"); href = href.Replace(">", ">"); href = href.Replace("'", "'"); // Use the MarkupConverter to parse the link LinkEventArgs linkEventArgs = new LinkEventArgs(link, href, text, ""); OnLinkParsed(linkEventArgs); string nofollow = ""; if (linkEventArgs.IsInternalLink == false) nofollow = "rel=\"nofollow\" "; string target = ""; if (!string.IsNullOrWhiteSpace(linkEventArgs.Target)) target= " target=\"" + linkEventArgs.Target + "\""; string cssClass = ""; if (!string.IsNullOrWhiteSpace(linkEventArgs.CssClass)) cssClass = " class=\"" + linkEventArgs.CssClass + "\""; string anchorHtml = string.Format("<a {0}href=\"{1}\"{2}{3}>{4}</a>", nofollow, linkEventArgs.Href, target, cssClass, linkEventArgs.Text); markup = markup.Substring(0, iPos - 2) + anchorHtml + markup.Substring(iEnd + 2); } else break; iPos = _indexOfWithSkip(markup, "[[", iPos); } return markup; }
/// <summary> /// Processes link markup into HTML /// </summary> /// <param name="markup">markup</param> /// <returns>markup with [[foo]] translated into <a href></a></returns> protected virtual string _processLinkCreole(string markup) { int iPos = _indexOfWithSkip(markup, "[[", 0); while (iPos >= 0) { int iEnd = _indexOfWithSkip(markup, "]]", iPos); if (iEnd > iPos) { iPos += 2; // get the contents of the cell string cell = markup.Substring(iPos, iEnd - iPos); string link = cell; string href = cell; //default to assuming it's the href string text = href; // as well as the text int iSplit = cell.IndexOf('|'); // unless of course there is a splitter if (iSplit > 0) { // href is the front href = cell.Substring(0, iSplit); link = href; // text is the creole processed fragment left over text = _processCreoleFragment(cell.Substring(iSplit + 1)); } // handle interwiki links iSplit = href.IndexOf(':'); if (iSplit > 0) { string scheme = href.Substring(0, iSplit); if (InterWiki.ContainsKey(scheme)) { href = InterWiki[scheme] + href.Substring(iSplit + 1); } } // Remove any attribute enders: ", <, >, &, ' href = href.Replace("&", "&"); href = href.Replace("\"", "2"); href = href.Replace("<", "<"); href = href.Replace(">", ">"); href = href.Replace("'", "'"); // Use the MarkupConverter to parse the link LinkEventArgs linkEventArgs = new LinkEventArgs(link, href, text, ""); OnLinkParsed(linkEventArgs); string nofollow = ""; if (linkEventArgs.IsInternalLink == false) { nofollow = "rel=\"nofollow\" "; } string target = ""; if (!string.IsNullOrWhiteSpace(linkEventArgs.Target)) { target = " target=\"" + linkEventArgs.Target + "\""; } string cssClass = ""; if (!string.IsNullOrWhiteSpace(linkEventArgs.CssClass)) { cssClass = " class=\"" + linkEventArgs.CssClass + "\""; } string anchorHtml = string.Format("<a {0}href=\"{1}\"{2}{3}>{4}</a>", nofollow, linkEventArgs.Href, target, cssClass, linkEventArgs.Text); markup = markup.Substring(0, iPos - 2) + anchorHtml + markup.Substring(iEnd + 2); } else { break; } iPos = _indexOfWithSkip(markup, "[[", iPos); } return(markup); }