using System.Text.RegularExpressions; namespace NozCli.Core.Client; public static class NoteLinkHelper { /// Inserts a wikilink to into . /// Appends to an existing section matching , /// or creates that section at the end of the note if absent. public static string AddLink(string markdown, string targetSlug, string sectionHeader = "Siehe auch") { var link = $"- [[{targetSlug}]]"; // Find the section heading (## Siehe auch, ## See also, etc.) var sectionMatch = Regex.Match( markdown, $@"(?m)^##\s+{Regex.Escape(sectionHeader)}\s*$", RegexOptions.IgnoreCase); if (sectionMatch.Success) { // Already has this link? if (markdown.Contains($"[[{targetSlug}]]", StringComparison.Ordinal)) return markdown; // Insert at the end of this section's content (before next ## heading or EOF) var afterSection = markdown.IndexOf('\n', sectionMatch.Index + sectionMatch.Length); if (afterSection < 0) afterSection = markdown.Length; var nextHeading = Regex.Match( markdown[afterSection..], @"(?m)^##\s", RegexOptions.IgnoreCase); var insertAt = nextHeading.Success ? afterSection + nextHeading.Index : markdown.Length; var before = markdown[..insertAt].TrimEnd(); var after = markdown[insertAt..]; return before + "\n" + link + "\n" + (after.Length > 0 ? "\n" + after.TrimStart() : ""); } // No section found — create one at the end return markdown.TrimEnd() + $"\n\n## {sectionHeader}\n\n{link}\n"; } /// Replaces template placeholders with actual values. public static string ApplyPlaceholders( string template, string title, string topic, string lang, string status) { return template .Replace("{{title}}", title, StringComparison.Ordinal) .Replace("{{topic}}", topic, StringComparison.Ordinal) .Replace("{{lang}}", lang, StringComparison.Ordinal) .Replace("{{status}}", status, StringComparison.Ordinal) .Replace("{{date}}", DateTime.UtcNow.ToString("yyyy-MM-dd"), StringComparison.Ordinal); } }