Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 55 additions & 6 deletions Source/FileManager/ReplacementCharacters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ public void Update(char charToReplace, string replacementString, string descript
public static Replacement OpenAngleBracket(string replacement) => new('<', replacement, "Open Angle Bracket");
public static Replacement CloseAngleBracket(string replacement) => new('>', replacement, "Close Angle Bracket");
public static Replacement Pipe(string replacement) => new('|', replacement, "Vertical Line");
public static Replacement a_umlaut(string replacement = "ae") => new('ä', replacement, "a umlaut (ä)");
public static Replacement o_umlaut(string replacement = "oe") => new('ö', replacement, "o umlaut (ö)");
public static Replacement u_umlaut(string replacement = "ue") => new('ü', replacement, "u umlaut (ü)");
public static Replacement A_umlaut(string replacement = "Ae") => new('Ä', replacement, "A umlaut (Ä)");
public static Replacement O_umlaut(string replacement = "Oe") => new('Ö', replacement, "O umlaut (Ö)");
public static Replacement U_umlaut(string replacement = "Ue") => new('Ü', replacement, "U umlaut (Ü)");
public static Replacement Eszett(string replacement = "ss") => new('ß', replacement, "Eszett (ß)");

}

Expand Down Expand Up @@ -92,7 +99,14 @@ public override bool Equals(object? obj)
Replacement.Colon("_"),
Replacement.Asterisk("✱"),
Replacement.QuestionMark("?"),
Replacement.Pipe("⏐")]
Replacement.Pipe("⏐"),
Replacement.a_umlaut(),
Replacement.o_umlaut(),
Replacement.u_umlaut(),
Replacement.A_umlaut(),
Replacement.O_umlaut(),
Replacement.U_umlaut(),
Replacement.Eszett()]
};

private static readonly ReplacementCharacters HiFi_Other = new()
Expand All @@ -103,7 +117,14 @@ public override bool Equals(object? obj)
Replacement.FilenameBackSlash("\\"),
Replacement.OpenQuote("“"),
Replacement.CloseQuote("”"),
Replacement.OtherQuote("\"")]
Replacement.OtherQuote("\""),
Replacement.a_umlaut(),
Replacement.o_umlaut(),
Replacement.u_umlaut(),
Replacement.A_umlaut(),
Replacement.O_umlaut(),
Replacement.U_umlaut(),
Replacement.Eszett()]
};

private static readonly ReplacementCharacters LoFi_NTFS = new()
Expand All @@ -117,7 +138,14 @@ public override bool Equals(object? obj)
Replacement.OtherQuote("'"),
Replacement.OpenAngleBracket("{"),
Replacement.CloseAngleBracket("}"),
Replacement.Colon("-")]
Replacement.Colon("-"),
Replacement.a_umlaut(),
Replacement.o_umlaut(),
Replacement.u_umlaut(),
Replacement.A_umlaut(),
Replacement.O_umlaut(),
Replacement.U_umlaut(),
Replacement.Eszett()]
};

private static readonly ReplacementCharacters LoFi_Other = new()
Expand All @@ -128,7 +156,14 @@ public override bool Equals(object? obj)
Replacement.FilenameBackSlash("\\"),
Replacement.OpenQuote("\""),
Replacement.CloseQuote("\""),
Replacement.OtherQuote("\"")]
Replacement.OtherQuote("\""),
Replacement.a_umlaut(),
Replacement.o_umlaut(),
Replacement.u_umlaut(),
Replacement.A_umlaut(),
Replacement.O_umlaut(),
Replacement.U_umlaut(),
Replacement.Eszett()]
};

private static readonly ReplacementCharacters BareBones_NTFS = new()
Expand All @@ -139,7 +174,14 @@ public override bool Equals(object? obj)
Replacement.FilenameBackSlash("_"),
Replacement.OpenQuote("_"),
Replacement.CloseQuote("_"),
Replacement.OtherQuote("_")]
Replacement.OtherQuote("_"),
Replacement.a_umlaut(),
Replacement.o_umlaut(),
Replacement.u_umlaut(),
Replacement.A_umlaut(),
Replacement.O_umlaut(),
Replacement.U_umlaut(),
Replacement.Eszett()]
};

private static readonly ReplacementCharacters BareBones_Other = new()
Expand All @@ -150,7 +192,14 @@ public override bool Equals(object? obj)
Replacement.FilenameBackSlash("\\"),
Replacement.OpenQuote("\""),
Replacement.CloseQuote("\""),
Replacement.OtherQuote("\"")]
Replacement.OtherQuote("\""),
Replacement.a_umlaut(),
Replacement.o_umlaut(),
Replacement.u_umlaut(),
Replacement.A_umlaut(),
Replacement.O_umlaut(),
Replacement.U_umlaut(),
Replacement.Eszett()]
};
#endregion
/// <summary>
Expand Down
42 changes: 42 additions & 0 deletions Source/_Tests/FileManager.Tests/FileUtilityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,48 @@ public void Tests(string input, string extension, string expected, PlatformID pl
}
}

[TestClass]
public class UmlautReplacements
{
static readonly ReplacementCharacters Default = ReplacementCharacters.Default(true);
static readonly ReplacementCharacters LoFi = ReplacementCharacters.LoFiDefault(true);
static readonly ReplacementCharacters Barebones = ReplacementCharacters.Barebones(true);

[TestMethod]
[DataRow("Märchen", "Maerchen")]
[DataRow("Über den Wolken", "Ueber den Wolken")]
[DataRow("schön", "schoen")]
[DataRow("grün", "gruen")]
[DataRow("Straße", "Strasse")]
[DataRow("Ärger", "Aerger")]
[DataRow("Ökonom", "Oekonom")]
[DataRow("Übel", "Uebel")]
public void DefaultPreset_ReplacesUmlauts(string input, string expected)
=> Default.ReplaceFilenameChars(input).Should().Be(expected);

[TestMethod]
[DataRow("Märchen", "Maerchen")]
[DataRow("Straße", "Strasse")]
public void LoFiPreset_ReplacesUmlauts(string input, string expected)
=> LoFi.ReplaceFilenameChars(input).Should().Be(expected);

[TestMethod]
[DataRow("Märchen", "Maerchen")]
[DataRow("Straße", "Strasse")]
public void BarebonesPreset_ReplacesUmlauts(string input, string expected)
=> Barebones.ReplaceFilenameChars(input).Should().Be(expected);

// Regression guard: the Defaults block once had its ASCII string delimiters
// auto-formatted into curly quotes (U+201C/U+201D), which broke compilation.
// Pin the actual Unicode replacement codepoints so a future re-corruption
// is caught here even if the file still compiles.
[TestMethod]
[DataRow("\"foo\"", "“foo”")] // ASCII " between non-letters → OpenQuote U+201C / CloseQuote U+201D
[DataRow("\"a\"b\"", "“a"b”")] // ASCII " surrounded by letters on both sides → OtherQuote U+FF02
public void DefaultPreset_UsesUnicodeCurlyQuotesForOpenAndClose(string input, string expected)
=> Default.ReplaceFilenameChars(input).Should().Be(expected);
}

[TestClass]
public class RemoveLastCharacter
{
Expand Down
Loading