private void UpdateLinks(MarkdownObject markdownObject) { switch (markdownObject) { case TabTitleBlock _: break; case LinkInline linkInline: linkInline.Url = linkInline.IsImage ? _context.GetImageLink(linkInline.Url, linkInline, null) : _context.GetLink(linkInline.Url, linkInline); foreach (var subBlock in linkInline) { UpdateLinks(subBlock); } break; case ContainerBlock containerBlock: foreach (var subBlock in containerBlock) { UpdateLinks(subBlock); } break; case LeafBlock leafBlock when leafBlock.Inline != null: foreach (var subInline in leafBlock.Inline) { UpdateLinks(subInline); } break; case ContainerInline containerInline: foreach (var subInline in containerInline) { UpdateLinks(subInline); } break; default: break; } }
private static void UpdateLinks(MarkdownObject markdownObject, MarkdownContext context) { if (markdownObject == null || context == null) { return; } if (markdownObject is ContainerBlock containerBlock) { foreach (var subBlock in containerBlock) { UpdateLinks(subBlock, context); } } else if (markdownObject is LeafBlock leafBlock) { if (leafBlock.Inline != null) { foreach (var subInline in leafBlock.Inline) { UpdateLinks(subInline, context); } } } else if (markdownObject is ContainerInline containerInline) { foreach (var subInline in containerInline) { UpdateLinks(subInline, context); } if (markdownObject is LinkInline linkInline) { linkInline.GetDynamicUrl = () => context.GetLink(linkInline.Url, InclusionContext.File); } } }
private void UpdateLinks(MarkdownObject markdownObject) { if (markdownObject == null) { return; } if (markdownObject is LinkInline linkInline && !linkInline.IsAutoLink) { linkInline.Url = _context.GetLink(linkInline.Url, InclusionContext.File, InclusionContext.RootFile, linkInline); } if (markdownObject is ContainerBlock containerBlock) { foreach (var subBlock in containerBlock) { UpdateLinks(subBlock); } } else if (markdownObject is LeafBlock leafBlock) { if (leafBlock.Inline != null) { foreach (var subInline in leafBlock.Inline) { UpdateLinks(subInline); } } } else if (markdownObject is ContainerInline containerInline) { foreach (var subInline in containerInline) { UpdateLinks(subInline); } } }
public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, Action <string> logWarning, TripleColonBlock block) { htmlAttributes = null; renderProperties = new Dictionary <string, string>(); var src = string.Empty; var alt = string.Empty; var type = string.Empty; var loc_scope = string.Empty; foreach (var attribute in attributes) { var name = attribute.Key; var value = attribute.Value; switch (name) { case "alt-text": alt = value; break; case "type": type = value; break; case "loc-scope": loc_scope = value; break; case "source": src = value; break; case "border": break; case "lightbox": break; case "link": break; default: logError($"Image reference '{src}' is invalid per the schema. Unexpected attribute: '{name}'."); return(false); } } if (string.IsNullOrEmpty(type)) { type = "content"; } if (string.IsNullOrEmpty(src)) { logError("source is a required attribute. Please ensure you have specified a source attribute."); } if (string.IsNullOrEmpty(alt) && type != "icon") { logError("alt-text is a required attribute. Please ensure you have specified an alt-text attribute."); } if ((string.IsNullOrEmpty(alt) && type != "icon") || string.IsNullOrEmpty(src)) { return(false); } htmlAttributes = new HtmlAttributes(); htmlAttributes.AddProperty("src", _context.GetLink(src, InclusionContext.File, InclusionContext.RootFile, block)); if (type == "icon") { htmlAttributes.AddProperty("role", "presentation"); } else { htmlAttributes.AddProperty("alt", alt); } var id = GetHtmlId(block.Line, block.Column); if (type == "complex") { htmlAttributes.AddProperty("aria-describedby", id); } RenderDelegate = (renderer, obj) => { var currentType = string.Empty; var currentLightbox = string.Empty; var currentBorderStr = string.Empty; var currentBorder = true; var currentLink = string.Empty; if (!obj.Attributes.TryGetValue("type", out currentType)) { currentType = "content"; } obj.Attributes.TryGetValue("lightbox", out currentLightbox); //it's okay if this is null obj.Attributes.TryGetValue("border", out currentBorderStr); //it's okay if this is null obj.Attributes.TryGetValue("link", out currentLink); //it's okay if this is null if (!bool.TryParse(currentBorderStr, out currentBorder)) { if (currentType == "icon") { currentBorder = false; } else { currentBorder = true; } } if (!string.IsNullOrEmpty(currentLink)) { var linkHtmlAttributes = new HtmlAttributes(); currentLink = _context.GetLink(currentLink, InclusionContext.File, InclusionContext.RootFile, obj); linkHtmlAttributes.AddProperty("href", $"{currentLink}"); renderer.Write("<a").WriteAttributes(linkHtmlAttributes).WriteLine(">"); } else if (!string.IsNullOrEmpty(currentLightbox)) { var lighboxHtmlAttributes = new HtmlAttributes(); var path = _context.GetLink(currentLightbox, InclusionContext.File, InclusionContext.RootFile, obj); lighboxHtmlAttributes.AddProperty("href", $"{path}#lightbox"); lighboxHtmlAttributes.AddProperty("data-linktype", $"relative-path"); renderer.Write("<a").WriteAttributes(lighboxHtmlAttributes).WriteLine(">"); } if (currentBorder) { renderer.WriteLine("<div class=\"mx-imgBorder\"><p>"); } if (currentType != "complex") { renderer.Write("<img").WriteAttributes(obj).WriteLine(">"); } else { if (currentType == "complex" && obj.Count == 0) { logWarning("If type is \"complex\", then descriptive content is required. Please make sure you have descriptive content."); return(false); } var htmlId = GetHtmlId(obj.Line, obj.Column); renderer.Write("<img").WriteAttributes(obj).WriteLine(">"); renderer.WriteLine($"<div id=\"{htmlId}\" class=\"visually-hidden\">"); renderer.WriteChildren(obj); renderer.WriteLine("</div>"); } if (currentBorder) { renderer.WriteLine("</p></div>"); } if (!string.IsNullOrEmpty(currentLightbox) || !string.IsNullOrEmpty(currentLink)) { renderer.WriteLine($"</a>"); } return(true); }; return(true); }
public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, Action <string> logWarning, MarkdownObject markdownObject) { htmlAttributes = null; renderProperties = new Dictionary <string, string>(); var src = string.Empty; var alt = string.Empty; var type = string.Empty; var loc_scope = string.Empty; foreach (var attribute in attributes) { var name = attribute.Key; var value = attribute.Value; switch (name) { case "alt-text": alt = value; break; case "type": type = value; break; case "loc-scope": loc_scope = value; break; case "source": src = value; break; case "border": break; case "lightbox": break; case "link": break; default: logError($"Image reference '{src}' is invalid per the schema. Unexpected attribute: '{name}'."); return(false); } } if (string.IsNullOrEmpty(type)) { type = "content"; } if (string.IsNullOrEmpty(src)) { logError("source is a required attribute. Please ensure you have specified a source attribute."); } if (string.IsNullOrEmpty(alt) && type != "icon") { logError("alt-text is a required attribute. Please ensure you have specified an alt-text attribute."); } // add loc scope missing/invalid validation here if ((string.IsNullOrEmpty(alt) && type != "icon") || string.IsNullOrEmpty(src)) { return(false); } htmlAttributes = new HtmlAttributes(); // alt is allowed to be empty for icon type image if (string.IsNullOrEmpty(alt) && type == "icon") { htmlAttributes.AddProperty("src", _context.GetLink(src, markdownObject)); } else { htmlAttributes.AddProperty("src", _context.GetImageLink(src, markdownObject, alt)); } if (type == "icon") { htmlAttributes.AddProperty("role", "presentation"); } else { htmlAttributes.AddProperty("alt", alt); } var id = GetHtmlId(markdownObject); if (type == "complex") { htmlAttributes.AddProperty("aria-describedby", id); } return(true); }