Wp2ghost/CSharpGhostImporter/SlugHelper.cs
2026-10-14 19:12:29 +02:00

59 lines
2.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}