Skip to content

Commit

Permalink
fix: backport triple colon extension updates (#9000)
Browse files Browse the repository at this point in the history
  • Loading branch information
yufeih committed Jul 22, 2023
1 parent d0b4992 commit 78b4679
Show file tree
Hide file tree
Showing 16 changed files with 387 additions and 200 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@ namespace Docfx.MarkdigEngine.Extensions;
public class ChromelessFormExtension : ITripleColonExtensionInfo
{
public string Name => "form";

public bool SelfClosing => true;

public bool TryProcessAttributes(IDictionary<string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary<string, string> renderProperties, Action<string> logError, Action<string> logWarning, MarkdownObject markdownObject)
public bool IsInline => false;

public bool IsBlock => true;

public bool TryProcessAttributes(IDictionary<string, string> attributes, out HtmlAttributes htmlAttributes, Action<string> logError, Action<string> logWarning, MarkdownObject markdownObject)
{
htmlAttributes = null;
renderProperties = new Dictionary<string, string>();
var model = string.Empty;
var action = string.Empty;
var submitText = string.Empty;
var model = "";
var action = "";
var submitText = "";
foreach (var attribute in attributes)
{
var name = attribute.Key;
Expand All @@ -33,46 +37,44 @@ public bool TryProcessAttributes(IDictionary<string, string> attributes, out Htm
action = value;
break;
case "submittext":
submitText = WebUtility.HtmlEncode(value);
submitText = value;
break;
default:
logError($"Unexpected attribute \"{name}\".");
return false;
}
}

if (action == string.Empty)
if (string.IsNullOrEmpty(action))
{
logError("Form action must be specified.");
return false;
}
if (submitText == string.Empty)
if (string.IsNullOrEmpty(submitText))
{
logError("Submit text must be specified.");
return false;
}

htmlAttributes = new HtmlAttributes();
if (model != string.Empty)
if (!string.IsNullOrEmpty(model))
{
htmlAttributes.AddProperty("data-model", model);
}
htmlAttributes.AddProperty("data-action", action);
htmlAttributes.AddClass("chromeless-form");

renderProperties.Add(new KeyValuePair<string, string>("submitText", submitText));

return true;
}

public bool Render(HtmlRenderer renderer, MarkdownObject markdownObject, Action<string> logWarning)
{
var block = (TripleColonBlock)markdownObject;
block.RenderProperties.TryGetValue("submitText", out var buttonText);
block.Attributes.TryGetValue("submitText", out var submitText);

renderer.Write("<form").WriteAttributes(block).WriteLine(">");
renderer.WriteLine("<div></div>");
renderer.WriteLine($"<button class=\"button is-primary\" disabled=\"disabled\" type=\"submit\">{buttonText}</button>");
renderer.WriteLine($"<button class=\"button is-primary\" disabled=\"disabled\" type=\"submit\">{WebUtility.HtmlEncode(submitText)}</button>");
renderer.WriteLine("</form>");

return true;
Expand All @@ -82,4 +84,4 @@ public bool TryValidateAncestry(ContainerBlock container, Action<string> logErro
{
return true;
}
}
}
68 changes: 39 additions & 29 deletions src/Docfx.MarkdigEngine.Extensions/TripleColon/CodeExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,50 @@ namespace Docfx.MarkdigEngine.Extensions;
public class CodeExtension : ITripleColonExtensionInfo
{
public string Name => "code";

public bool SelfClosing => true;
public bool EndingTripleColons => false;

public static bool EndingTripleColons => false;

public bool IsInline => false;

public bool IsBlock => true;

private readonly MarkdownContext _context;
private readonly HtmlCodeSnippetRenderer _codeSnippetRenderer;

public CodeExtension(MarkdownContext context)
{
_context = context;
_codeSnippetRenderer = new(_context);
}

public bool Render(HtmlRenderer renderer, MarkdownObject markdownObject, Action<string> logWarning)
{
var block = (TripleColonBlock)markdownObject;
block.Attributes.TryGetValue("id", out var currentId); //it's okay if this is null
block.Attributes.TryGetValue("range", out var currentRange); //it's okay if this is null
block.Attributes.TryGetValue("source", out var currentSource); //source has already been checked above
block.Attributes.TryGetValue("id", out var currentId); // it's okay if this is null
block.Attributes.TryGetValue("range", out var currentRange); // it's okay if this is null
block.Attributes.TryGetValue("source", out var currentSource); // source has already been checked above
var (code, codePath) = _context.ReadFile(currentSource, block);
if (string.IsNullOrEmpty(code))
{
logWarning($"The code snippet \"{currentSource}\" could not be found.");
return false;
}

//var updatedCode = GetCodeSnippet(currentRange, currentId, code, logError).TrimEnd();
var htmlCodeSnippetRenderer = new HtmlCodeSnippetRenderer(_context);
var snippet = new CodeSnippet(null);
snippet.CodePath = currentSource;
snippet.TagName = currentId;

HtmlCodeSnippetRenderer.TryGetLineRanges(currentRange, out var ranges);
snippet.CodeRanges = ranges;
var updatedCode = htmlCodeSnippetRenderer.GetContent(code, snippet);

var snippet = new CodeSnippet(null)
{
CodePath = currentSource,
TagName = currentId,
CodeRanges = ranges,
};

var updatedCode = _codeSnippetRenderer.GetContent(code, snippet);
updatedCode = ExtensionsHelper.Escape(updatedCode).TrimEnd();

if (updatedCode == string.Empty)
if (string.IsNullOrEmpty(updatedCode))
{
logWarning($"It looks like your code snippet was not rendered. Try range instead.");
return false;
Expand All @@ -57,17 +66,15 @@ public bool Render(HtmlRenderer renderer, MarkdownObject markdownObject, Action<
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)
public bool TryProcessAttributes(IDictionary<string, string> attributes, out HtmlAttributes htmlAttributes, Action<string> logError, Action<string> logWarning, MarkdownObject markdownObject)
{

htmlAttributes = null;
renderProperties = new Dictionary<string, string>();
var source = string.Empty;
var range = string.Empty;
var id = string.Empty;
var highlight = string.Empty;
var language = string.Empty;
var interactive = string.Empty;
var source = "";
var range = "";
var id = "";
var highlight = "";
var language = "";
var interactive = "";

foreach (var attribute in attributes)
{
Expand Down Expand Up @@ -117,12 +124,20 @@ public bool TryProcessAttributes(IDictionary<string, string> attributes, out Htm
htmlAttributes.AddProperty("data-interactive", language);
htmlAttributes.AddProperty("data-interactive-mode", interactive);
}
if (!string.IsNullOrEmpty(highlight)) htmlAttributes.AddProperty("highlight-lines", highlight);
if (!string.IsNullOrEmpty(highlight))
{
htmlAttributes.AddProperty("highlight-lines", highlight);
}

return true;
}

private string InferLanguageFromFile(string source, Action<string> logError)
public bool TryValidateAncestry(ContainerBlock container, Action<string> logError)
{
return true;
}

private static string InferLanguageFromFile(string source, Action<string> logError)
{
var fileExtension = Path.GetExtension(source);
if (fileExtension == null)
Expand All @@ -136,9 +151,4 @@ private string InferLanguageFromFile(string source, Action<string> logError)
}
return language;
}

public bool TryValidateAncestry(ContainerBlock container, Action<string> logError)
{
return true;
}
}
90 changes: 46 additions & 44 deletions src/Docfx.MarkdigEngine.Extensions/TripleColon/ImageExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,24 @@ public class ImageExtension : ITripleColonExtensionInfo
private readonly MarkdownContext _context;

public string Name => "image";

public bool SelfClosing => true;

public bool IsInline => true;

public bool IsBlock => true;

public ImageExtension(MarkdownContext context)
{
_context = context;
}

public bool TryProcessAttributes(IDictionary<string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary<string, string> renderProperties, Action<string> logError, Action<string> logWarning, MarkdownObject markdownObject)
public bool TryProcessAttributes(IDictionary<string, string> attributes, out HtmlAttributes htmlAttributes, 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;
var src = "";
var alt = "";
var type = "";
foreach (var attribute in attributes)
{
var name = attribute.Key;
Expand All @@ -41,7 +44,7 @@ public bool TryProcessAttributes(IDictionary<string, string> attributes, out Htm
type = value;
break;
case "loc-scope":
loc_scope = value;
var loc_scope = value;
break;
case "source":
src = value;
Expand Down Expand Up @@ -73,29 +76,10 @@ public bool TryProcessAttributes(IDictionary<string, string> attributes, out Htm
}

// 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;
}
Expand All @@ -108,19 +92,33 @@ public bool Render(HtmlRenderer renderer, MarkdownObject obj, Action<string> log
{
currentType = "content";
}
tripleColonObj.Attributes.TryGetValue("lightbox", out var currentLightbox); //it's okay if this is null
tripleColonObj.Attributes.TryGetValue("border", out var currentBorderStr); //it's okay if this is null
tripleColonObj.Attributes.TryGetValue("link", out var currentLink); //it's okay if this is null
if (!bool.TryParse(currentBorderStr, out var currentBorder))
tripleColonObj.Attributes.TryGetValue("lightbox", out var currentLightbox); // it's okay if this is null
tripleColonObj.Attributes.TryGetValue("border", out var currentBorderStr); // it's okay if this is null
tripleColonObj.Attributes.TryGetValue("link", out var currentLink); // it's okay if this is null
tripleColonObj.Attributes.TryGetValue("alt-text", out var alt); // it's okay if this is null
tripleColonObj.Attributes.TryGetValue("source", out var src); // it's okay if this is null

var htmlAttributes = new HtmlAttributes();

htmlAttributes.AddProperty("src", _context.GetImageLink(src, obj, alt));

if (currentType == "icon")
{
if (currentType == "icon")
{
currentBorder = false;
htmlAttributes.AddProperty("role", "presentation");
}
else
{
currentBorder = true;
htmlAttributes.AddProperty("alt", alt);
}
var htmlId = GetHtmlId(obj);
if (currentType == "complex")
{
htmlAttributes.AddProperty("aria-describedby", htmlId);
}

if (!bool.TryParse(currentBorderStr, out var currentBorder))
{
currentBorder = currentType != "icon";
}

if (currentBorder)
Expand All @@ -133,11 +131,13 @@ public bool Render(HtmlRenderer renderer, MarkdownObject obj, Action<string> log
{
renderer.WriteLine("<span class=\"mx-imgBorder\">");
}

}
else
{
if (tripleColonObj is Block) renderer.WriteLine("<p>");
if (tripleColonObj is Block)
{
renderer.WriteLine("<p>");
}
}
if (!string.IsNullOrEmpty(currentLink))
{
Expand All @@ -156,15 +156,14 @@ public bool Render(HtmlRenderer renderer, MarkdownObject obj, Action<string> log
}
if (currentType != "complex")
{
renderer.Write("<img").WriteAttributes(obj).WriteLine(">");
renderer.Write("<img").WriteAttributes(htmlAttributes).WriteLine(">");

if (tripleColonObj is ContainerBlock
&& (tripleColonObj as ContainerBlock).LastChild != null)
{
var inline = ((tripleColonObj as ContainerBlock).LastChild as ParagraphBlock).Inline;
renderer.WriteChildren(inline);
}

}
else
{
Expand All @@ -173,11 +172,10 @@ public bool Render(HtmlRenderer renderer, MarkdownObject obj, Action<string> log
logWarning("If type is \"complex\", then descriptive content is required. Please make sure you have descriptive content.");
return false;
}
var htmlId = GetHtmlId(obj);
renderer.Write("<img").WriteAttributes(obj).WriteLine(">");
renderer.WriteLine($"<div id=\"{htmlId}\" class=\"visually-hidden\">");
renderer.WriteChildren(tripleColonObj as ContainerBlock);
renderer.WriteLine("</div>");
renderer.Write("<img").WriteAttributes(htmlAttributes).WriteLine(">");
renderer.WriteLine($"<div id=\"{htmlId}\" class=\"visually-hidden\"><p>");
renderer.Write(tripleColonObj.Body);
renderer.WriteLine("</p></div>");
}
if (!string.IsNullOrEmpty(currentLightbox) || !string.IsNullOrEmpty(currentLink))
{
Expand All @@ -189,7 +187,11 @@ public bool Render(HtmlRenderer renderer, MarkdownObject obj, Action<string> log
}
else
{
if (currentBorder) renderer.WriteLine("</span>");
if (currentBorder)
{
renderer.WriteLine("</span>");
}

renderer.WriteChildren(tripleColonObj as ContainerInline);
}
return true;
Expand Down
Loading

0 comments on commit 78b4679

Please sign in to comment.