namespace wp2ghost { // ============================================================================= // HTML zu Markdown Konverter // ============================================================================= public static class HtmlToMarkdownConverter { public static string Convert(string html) { if (string.IsNullOrEmpty(html)) return ""; string result = html; result = System.Text.RegularExpressions.Regex.Replace(result, "", "", System.Text.RegularExpressions.RegexOptions.Singleline); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", m => new string('#', int.Parse(m.Groups[1].Value)) + " " + StripTags(m.Groups[2].Value) + Environment.NewLine + Environment.NewLine, System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", m => "> " + StripTags(m.Groups[1].Value).Replace(Environment.NewLine, Environment.NewLine + "> ") + Environment.NewLine, System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>]*>(.*?)", m => "```\n" + StripTags(m.Groups[1].Value) + "\n```\n\n", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", m => "`" + StripTags(m.Groups[1].Value) + "`", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", m => ConvertList(m.Groups[1].Value, "-"), System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", m => ConvertOrderedList(m.Groups[1].Value), System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = ConvertTables(result); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)

", m => CleanInnerHtml(m.Groups[1].Value) + Environment.NewLine + Environment.NewLine, System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"", Environment.NewLine, System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", "**$1**", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", "**$1**", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", "*$1*", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", "*$1*", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*href=[""']([^""']+)[""'][^>]*>(.*?)", "[$2]($1)", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*src=[""']([^""']+)[""'][^>]*alt=[""']([^""']*)[""'][^>]*>", m => "![" + m.Groups[2].Value + "](" + m.Groups[1].Value + ")", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*src=[""']([^""']+)[""'][^>]*>", m => "![](" + m.Groups[1].Value + ")", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*class=[""'][^""']*wp-block-heading[^""']*[""'][^>]*>(.*?)", m => "# " + StripTags(m.Groups[1].Value) + Environment.NewLine + Environment.NewLine, System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = System.Text.RegularExpressions.Regex.Replace(result, @"]*>(.*?)", m => ConvertFigure(m.Groups[1].Value), System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); result = StripTagsKeepFigure(result); result = System.Text.RegularExpressions.Regex.Replace(result, @"\n{3,}", "\n\n"); result = result.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace(""", "\"").Replace("’", "'").Replace(" ", " ").Replace("—", "—").Replace("–", "–"); return result.Trim(); } private static string StripTags(string html) => System.Text.RegularExpressions.Regex.Replace(html, "<[^>]*>", ""); private static string CleanInnerHtml(string html) { string cleaned = StripTags(html); cleaned = System.Text.RegularExpressions.Regex.Replace(cleaned, @"\*\*(.+?)\*\*", "**$1**"); return cleaned.Trim(); } private static string ConvertFigure(string figureContent) { string imgSrc = "", altText = "", caption = ""; var imgMatch = System.Text.RegularExpressions.Regex.Match(figureContent, @"]*src=[""']([^""']+)[""']"); if (imgMatch.Success) imgSrc = imgMatch.Groups[1].Value; var altMatch = System.Text.RegularExpressions.Regex.Match(figureContent, @"alt=[""']([^""']*)[""']"); if (altMatch.Success) altText = altMatch.Groups[1].Value; var figMatch = System.Text.RegularExpressions.Regex.Match(figureContent, @"]*>(.*?)", System.Text.RegularExpressions.RegexOptions.Singleline); if (figMatch.Success) caption = System.Text.RegularExpressions.Regex.Replace(figMatch.Groups[1].Value, "<[^>]*>", "").Trim(); if (string.IsNullOrEmpty(imgSrc)) return ""; string result = $"
\"{altText}\"";{caption}"; result += "
"; return result + Environment.NewLine; } private static string StripTagsKeepFigure(string html) { var figureBlocks = new List(); html = System.Text.RegularExpressions.Regex.Replace(html, @"]*>.*?", m => { figureBlocks.Add(m.Value); return $"__FIGURE_{figureBlocks.Count - 1}__"; }, System.Text.RegularExpressions.RegexOptions.Singleline); html = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]*>", ""); for (int i = 0; i < figureBlocks.Count; i++) html = html.Replace($"__FIGURE_{i}__", figureBlocks[i]); return html; } private static string ConvertList(string listHtml, string bullet) { listHtml = System.Text.RegularExpressions.Regex.Replace(listHtml, @"]*>(.*?)", m => bullet + " " + CleanInnerHtml(m.Groups[1].Value) + Environment.NewLine, System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); return StripTags(listHtml).Trim() + Environment.NewLine; } private static string ConvertOrderedList(string listHtml) { int counter = 0; listHtml = System.Text.RegularExpressions.Regex.Replace(listHtml, @"]*>(.*?)", m => { counter++; return counter + ". " + CleanInnerHtml(m.Groups[1].Value) + Environment.NewLine; }, System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); return StripTags(listHtml).Trim() + Environment.NewLine; } private static string ConvertTables(string html) { return System.Text.RegularExpressions.Regex.Replace(html, @"]*>(.*?)", m => { string tableContent = m.Groups[1].Value; var headerMatch = System.Text.RegularExpressions.Regex.Match(tableContent, @"]*>(.*?)", System.Text.RegularExpressions.RegexOptions.Singleline); if (!headerMatch.Success) return StripTags(tableContent) + Environment.NewLine; string headers = CleanInnerHtml(headerMatch.Groups[1].Value); headers = headers.Replace("", ""); string headerLine = "| " + string.Join(" | ", StripTags(headers).Split(new[] { "", " c.Trim())) + " |"; string separator = "|" + string.Join("|", StripTags(headers).Split(new[] { "", " "---")) + "|"; var rows = System.Text.RegularExpressions.Regex.Matches(tableContent, @"]*>(.*?)", System.Text.RegularExpressions.RegexOptions.Singleline); var dataRows = new List(); for (int i = 1; i < rows.Count; i++) { string rowText = CleanInnerHtml(rows[i].Groups[1].Value); string[] cells = rowText.Split(new[] { "", " c.Trim().Replace("", "").Replace("", "").Replace("", "").Replace("", ""))) + " |"); } return headerLine + Environment.NewLine + separator + Environment.NewLine + string.Join(Environment.NewLine, dataRows) + Environment.NewLine + Environment.NewLine; }, System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase); } } }