using System.Text; using System.IO; using UnityEngine; namespace Unity.PerformanceTesting.Benchmark { internal class MarkdownBuilder { StringBuilder sb = new StringBuilder(32768); int blockDepth = 0; void Prefix() { if (blockDepth == 0) return; int len = sb.Length; if (len == 0 || sb[len - 1] == '\n') sb.Append($"{new string('>', blockDepth)} "); } MarkdownBuilder EnsureBlankLine() { int len = sb.Length; if ((len > 0 && sb[len - 1] != '\n')) Br().Br(); else if (len > 1 && sb[len - 2] != '\n') Br(); return this; } public MarkdownBuilder Append(string text) { Prefix(); sb.Append(text); return this; } public MarkdownBuilder AppendLine(string text) => Append(text.TrimEnd('\n')).BrParagraph().Br(); public MarkdownBuilder AppendLines(string[] lines) { foreach (string line in lines) AppendLine(line); return this; } public MarkdownBuilder AppendLines(string line, params string[] optLines) { AppendLine(line); return AppendLines(optLines); } public MarkdownBuilder Header(int level, string text) => EnsureBlankLine().Append($"{new string('#', Mathf.Clamp(level, 1, 6))} {text}").Br().Br(); public MarkdownBuilder HorizontalLine() => EnsureBlankLine().Append("---").Br(); public MarkdownBuilder Br() => Append("\n"); public MarkdownBuilder BrParagraph() => Append("
"); public MarkdownBuilder Italic(string text) => Append($"*{text}*"); public MarkdownBuilder Bold(string text) => Append($"**{text}**"); public MarkdownBuilder BoldItalic(string text) => Append($"***{text}***"); public MarkdownBuilder Code(string text) => Append($"`{text}`"); public MarkdownBuilder Link(string url) => Append($"<{url}>"); public MarkdownBuilder Link(string url, string name) => Append($"[{name}]({url.Replace(" ", "%20")})"); public MarkdownBuilder Link(string url, string name, string tooltip) => Append($"[{name}]({url} \"{tooltip}\")"); public MarkdownBuilder LinkHeader(string headerName) => Append($"[{headerName}](#{headerName.Replace(" ", "-").ToLower()})"); public MarkdownBuilder ListItem(int zeroBasedDepth) => Append($"{new string(' ', Mathf.Clamp(zeroBasedDepth * 2, 0, 6))}- "); public MarkdownBuilder ListItem(int zeroBasedDepth, string text) => Append($"{new string(' ', Mathf.Clamp(zeroBasedDepth * 2, 0, 6))}- {text}").Br(); public MarkdownBuilder BeginBlock() { EnsureBlankLine(); // *before* increasing block depth blockDepth++; return this; } public MarkdownBuilder EndBlock() { if (blockDepth > 0) blockDepth--; return EnsureBlankLine(); // *after* decreasing block depth } public MarkdownBuilder TableHeader(bool alignRightFirst, string columnName, bool alignRightOthers, params string[] optColumnNames) { EnsureBlankLine(); TableRow(columnName, optColumnNames); if (alignRightFirst) Append("|--:|"); else Append("|---|"); for (int i = 0; i < optColumnNames.Length; i++) { if (alignRightOthers) Append($"--:|"); else Append($"---|"); } return Br(); } public MarkdownBuilder TableRow(string columnData, params string[] optColumnData) { Append($"| {columnData} |"); for (int i = 0; i < optColumnData.Length; i++) Append($" {optColumnData[i]} |"); return Br(); } public MarkdownBuilder Note(string title, string descLine, params string[] optDescLines) => BeginBlock().Bold(title).Br().Br().AppendLines(descLine, optDescLines).EndBlock(); public MarkdownBuilder Note(string title, string[] descLines) => BeginBlock().Bold(title).Br().Br().AppendLines(descLines).EndBlock(); public MarkdownBuilder Note(string[] descLines) => BeginBlock().AppendLines(descLines).EndBlock(); public override string ToString() => sb.ToString(); public void Save(string path) => File.WriteAllText(path, ToString()); } }