using System.Text; using System.Text.RegularExpressions; namespace ZelWiki.Library { public class NamespaceNavigation { private string _namespace = string.Empty; private string _page = string.Empty; private readonly bool _lowerCase = false; public string Namespace { get => _namespace; set => _namespace = CleanAndValidate(value.Replace("::", "_")).Trim(); } public string Page { get => _page; set => _page = CleanAndValidate(value.Replace("::", "_")).Trim(); } public string Canonical { get { if (string.IsNullOrWhiteSpace(Namespace)) { return Page; } return $"{Namespace}::{Page}"; } set { var cleanedAndValidatedValue = CleanAndValidate(value, _lowerCase); var parts = cleanedAndValidatedValue.Split("::"); if (parts.Length < 2) { Page = parts[0].Trim(); } else { Namespace = parts[0].Trim(); Page = string.Join("_", parts.Skip(1).Select(o => o.Trim())).Trim(); } } } /// /// /// /// public NamespaceNavigation(string givenCanonical) { _lowerCase = true; Canonical = givenCanonical; } /// /// /// /// /// public NamespaceNavigation(string givenCanonical, bool lowerCase) { _lowerCase = lowerCase; Canonical = givenCanonical; } public override string ToString() { return Canonical; } /// /// /// /// /// /// /// public static string CleanAndValidate(string? str, bool lowerCase = true) { if (str == null) { return string.Empty; } str = str.Trim().Trim([':']).Trim(); if (str.Contains("::")) { var parts = str.Split("::"); if (parts.Length != 2) { throw new Exception("导航不能包含多个命名空间"); } return $"{CleanAndValidate(parts[0].Trim())}::{CleanAndValidate(parts[1].Trim(), lowerCase)}"; } str = str.Replace(""", "\"") .Replace("&", "&") .Replace("<", "<") .Replace(">", ">") .Replace(" ", " "); str = str.Replace('\\', '/'); var sb = new StringBuilder(); foreach (var c in str) { if (char.IsWhiteSpace(c) || c == '.') { sb.Append('_'); } else if (char.IsLetterOrDigit(c) || c == '_' || c == '/' || c == '-') { sb.Append(c); } } var result = sb.ToString(); result = Regex.Replace(result, @"[_]{2,}", "_"); result = Regex.Replace(result, @"[/]{2,}", "/"); return lowerCase ? result.TrimEnd(['/', '\\']).ToLowerInvariant() : result.TrimEnd(['/', '\\']); } } }