protected override void Write(HtmlRenderer renderer, TabGroupBlock block) { renderer.Write(@"<div class=""tabGroup"" id=""tabgroup_"); var groupId = ExtensionsHelper.Escape(block.Id); renderer.Write(groupId); renderer.Write("\""); renderer.WriteAttributes(block); renderer.Write(">\n"); WriteTabHeaders(renderer, block, groupId); WriteTabSections(renderer, block, groupId); renderer.Write("</div>\n"); }
private static string GetCodeSnippet(string range, string id, string code, Action <string> logError) { if (!string.IsNullOrEmpty(range) && !string.IsNullOrEmpty(id)) { logError("You must set only either Range or Id, but not both."); } var codeSections = new List <string>(); if (!string.IsNullOrEmpty(range)) { var codeLines = code.Split('\n'); codeSections = GetCodeSectionsFromRange(range, codeLines, codeSections, logError); } else if (!string.IsNullOrEmpty(id)) { var codeLines = code.Split('\n'); var beg = codeLines.FindIndexOfTag(id); var end = codeLines.FindIndexOfTag(id, true); if (end == 0) { logError($"Could not find snippet id '{id}'. Make sure your snippet is in your source file."); } codeSections = GetCodeSectionsFromRange($"{beg}-{end}", codeLines, codeSections, logError, false); } else { codeSections.Add(code); } if (codeSections == null) { return(string.Empty); } codeSections = Dedent(codeSections); var source = string.Join("\n", codeSections.ToArray()); source = ExtensionsHelper.Escape(source); return(source); }
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 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); updatedCode = ExtensionsHelper.Escape(updatedCode).TrimEnd(); if (updatedCode == string.Empty) { logWarning($"It looks like your code snippet was not rendered. Try range instead."); return(false); } renderer.WriteLine("<pre>"); renderer.Write("<code").WriteAttributes(block).Write(">"); renderer.WriteLine(updatedCode); renderer.WriteLine("</code></pre>"); return(true); }
private static string GetCodeSnippet(string range, string id, string code, Action <string> logError) { if (!string.IsNullOrEmpty(range) && !string.IsNullOrEmpty(id)) { logError($"You must set only either Range or Id, but not both."); } var codeSections = new List <string>(); if (!string.IsNullOrEmpty(range)) { var codeLines = code.Split('\n'); codeSections = GetCodeSectionsFromRange(range, codeLines, codeSections, logError); } else if (!string.IsNullOrEmpty(id)) { var codeLines = code.Split('\n'); var beg = Array.FindIndex(codeLines, line => line.Replace(" ", "").IndexOf($"<{id}>", StringComparison.OrdinalIgnoreCase) > -1) + 2; var end = Array.FindIndex(codeLines, line => line.Replace(" ", "").IndexOf($"</{id}>", StringComparison.OrdinalIgnoreCase) > -1); codeSections = GetCodeSectionsFromRange($"{beg}-{end}", codeLines, codeSections, logError); } else { codeSections.Add(code); } if (codeSections == null) { return(string.Empty); } codeSections = Dedent(codeSections); var source = string.Join(" ...\n", codeSections.ToArray()); source = ExtensionsHelper.Escape(source); return(source); }
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 source = string.Empty; var range = string.Empty; var id = string.Empty; var highlight = string.Empty; var language = string.Empty; var interactive = string.Empty; foreach (var attribute in attributes) { var name = attribute.Key; var value = attribute.Value; switch (name) { case "source": source = value; break; case "range": range = value; break; case "id": id = value; break; case "highlight": highlight = value; break; case "language": language = value; break; case "interactive": interactive = value; break; default: logError($"Unexpected attribute \"{name}\"."); return(false); } } if (string.IsNullOrEmpty(source)) { logError("source is a required attribute. Please ensure you have specified a source attribute"); return(false); } if (string.IsNullOrEmpty(language)) { language = InferLanguageFromFile(source, logError); } htmlAttributes = new HtmlAttributes(); htmlAttributes.AddProperty("class", $"lang-{language}"); if (!string.IsNullOrEmpty(interactive)) { htmlAttributes.AddProperty("data-interactive", language); htmlAttributes.AddProperty("data-interactive-mode", interactive); } if (!string.IsNullOrEmpty(highlight)) { htmlAttributes.AddProperty("highlight-lines", highlight); } RenderDelegate = (renderer, obj) => { var currentId = string.Empty; var currentRange = string.Empty; var currentSource = string.Empty; obj.Attributes.TryGetValue("id", out currentId); //it's okay if this is null obj.Attributes.TryGetValue("range", out currentRange); //it's okay if this is null obj.Attributes.TryGetValue("source", out currentSource); //source has already been checked above var(code, codePath) = _context.ReadFile(currentSource, obj); 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 = source; snippet.TagName = currentId; List <CodeRange> ranges; HtmlCodeSnippetRenderer.TryGetLineRanges(currentRange, out ranges); snippet.CodeRanges = ranges; var updatedCode = htmlCodeSnippetRenderer.GetContent(code, snippet); updatedCode = ExtensionsHelper.Escape(updatedCode).TrimEnd(); if (updatedCode == string.Empty) { return(false); } renderer.WriteLine("<pre>"); renderer.Write("<code").WriteAttributes(obj).Write(">"); renderer.WriteLine(updatedCode); renderer.WriteLine("</code></pre>"); return(true); }; return(true); }