Wp2ghost/CSharpGhostImporter/SlugHelper.cs

60 lines
2.7 KiB
C#
Raw Normal View History

2026-10-14 19:12:29 +02:00
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
namespace wp2ghost
{
// =============================================================================
// SlugHelper — WordPress-Slugs in saubere Ghost-Slugs (nur a-z, 0-9, "-") umwandeln
// =============================================================================
static class SlugHelper
{
// Griechisch → Latein (Akzente werden vorher abgetrennt)
private static readonly Dictionary<char, string> GreekToLatin = new()
{
['α'] = "a", ['β'] = "v", ['γ'] = "g", ['δ'] = "d", ['ε'] = "e", ['ζ'] = "z", ['η'] = "i", ['θ'] = "th",
['ι'] = "i", ['κ'] = "k", ['λ'] = "l", ['μ'] = "m", ['ν'] = "n", ['ξ'] = "x", ['ο'] = "o", ['π'] = "p",
['ρ'] = "r", ['σ'] = "s", ['ς'] = "s", ['τ'] = "t", ['υ'] = "y", ['φ'] = "f", ['χ'] = "ch", ['ψ'] = "ps", ['ω'] = "o"
};
private static readonly Dictionary<char, string> GermanToLatin = new()
{
['ä'] = "ae", ['ö'] = "oe", ['ü'] = "ue", ['ß'] = "ss"
};
/// <summary>
/// WordPress speichert nicht-lateinische Zeichen im Slug prozentkodiert
/// ("%ce%b3%ce%b9%ce%b1" = "για"). Die Kodierung wird aufgelöst, Griechisch nach Latein
/// umgeschrieben ("gia") und alles übrige auf a-z, 0-9 und "-" reduziert.
/// </summary>
public static string Clean(string? wpSlug, string fallback)
{
string slug = wpSlug ?? "";
try { slug = Uri.UnescapeDataString(slug); } catch { }
// Reste einer abgeschnittenen Kodierung entfernen (WordPress kürzt lange Slugs mitten im Zeichen)
slug = Regex.Replace(slug, "%[0-9a-fA-F]{0,2}", "");
slug = slug.Replace('<27>', '-').ToLowerInvariant();
foreach (var (german, latin) in GermanToLatin)
slug = slug.Replace(german.ToString(), latin);
// Akzente abtrennen: "ί" → "ι", "é" → "e"
slug = string.Concat(slug.Normalize(NormalizationForm.FormD)
.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark));
slug = slug.Replace("ου", "ou");
var result = new StringBuilder();
foreach (char c in slug)
{
if (GreekToLatin.TryGetValue(c, out string? latin)) result.Append(latin);
else if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) result.Append(c);
else result.Append('-');
}
string cleaned = Regex.Replace(result.ToString(), "-{2,}", "-").Trim('-');
return cleaned.Length > 0 ? cleaned : fallback;
}
}
}