");
sb.Append("
");
sb.Append(EscapeHtml(node.Label));
if (!string.IsNullOrWhiteSpace(node.Subtitle)) {
sb.Append(" - ");
sb.Append(EscapeHtml(node.Subtitle!));
sb.Append("");
}
sb.Append("
");
if (node.Rows is { Count: > 0 }) {
sb.Append("
");
sb.Append("
");
for (var i = 0; i < node.Rows.Count; i += _compactTableColumns) {
sb.Append("");
for (var c = 0; c < _compactTableColumns; c++) {
var idx = i + c;
if (idx >= node.Rows.Count) { sb.Append(" | "); continue; }
GraphNodeRow row = node.Rows[idx];
sb.Append("");
sb.Append("").Append(EscapeHtml(row.Name)).Append("");
if (!string.IsNullOrEmpty(row.Detail))
sb.Append("").Append(EscapeHtml(row.Detail!)).Append("");
sb.Append(" | ");
}
sb.Append("
");
}
sb.Append("
");
}
sb.Append("
");
// Mermaid label is wrapped in "...", so any " in our HTML must be
// entity-encoded. We avoid literal " in inline styles by using
// single quotes; this last pass catches anything still embedded.
return sb.ToString().Replace("\"", """);
}
private static string EscapeHtml(string s) =>
s.Replace("&", "&").Replace("<", "<").Replace(">", ">");
}