summaryrefslogtreecommitdiff
path: root/CoreWiki/Utils/SafeUrl.cs
diff options
context:
space:
mode:
Diffstat (limited to 'CoreWiki/Utils/SafeUrl.cs')
-rw-r--r--CoreWiki/Utils/SafeUrl.cs104
1 files changed, 104 insertions, 0 deletions
diff --git a/CoreWiki/Utils/SafeUrl.cs b/CoreWiki/Utils/SafeUrl.cs
new file mode 100644
index 0000000..b2de803
--- /dev/null
+++ b/CoreWiki/Utils/SafeUrl.cs
@@ -0,0 +1,104 @@
+using System.Text;
+
+namespace CoreWiki.Utils;
+
+public class SafeUrl
+{
+ public static string Create(bool toLower, params string[] values)
+ {
+ return Create(toLower, String.Join("-", values));
+ }
+
+ public static string Create(bool toLower, string value)
+ {
+ var normalised = value.Normalize(NormalizationForm.FormKD);
+
+ const int maxlen = 80;
+ int len = normalised.Length;
+ bool prevDash = false;
+ var sb = new StringBuilder(len);
+ char c;
+
+ for (int i = 0; i < len; i++)
+ {
+ c = normalised[i];
+ if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
+ {
+ if (prevDash)
+ {
+ sb.Append('-');
+ prevDash = false;
+ }
+ sb.Append(c);
+ }
+ else if (c >= 'A' && c <= 'Z')
+ {
+ if (prevDash)
+ {
+ sb.Append('-');
+ prevDash = false;
+ }
+ // Tricky way to convert to lowercase
+ if (toLower)
+ sb.Append((char)(c | 32));
+ else
+ sb.Append(c);
+ }
+ else if (c == ' ' || c == ',' || c == '.' || c == '/' || c == '\\' || c == '-' || c == '_' || c == '=')
+ {
+ if (!prevDash && sb.Length > 0)
+ {
+ prevDash = true;
+ }
+ }
+ else
+ {
+ string swap = ConvertEdgeCases(c, toLower);
+
+ if (swap != null)
+ {
+ if (prevDash)
+ {
+ sb.Append('-');
+ prevDash = false;
+ }
+ sb.Append(swap);
+ }
+ }
+
+ if (sb.Length == maxlen)
+ break;
+ }
+ return sb.ToString();
+ }
+
+ static string ConvertEdgeCases(char c, bool toLower)
+ {
+ string swap = null;
+ switch (c)
+ {
+ case 'ı':
+ swap = "i";
+ break;
+ case 'ł':
+ swap = "l";
+ break;
+ case 'Ł':
+ swap = toLower ? "l" : "L";
+ break;
+ case 'đ':
+ swap = "d";
+ break;
+ case 'ß':
+ swap = "ss";
+ break;
+ case 'ø':
+ swap = "o";
+ break;
+ case 'Þ':
+ swap = "th";
+ break;
+ }
+ return swap;
+ }
+} \ No newline at end of file