59 lines
2.7 KiB
C#
59 lines
2.7 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|