/// <summary> /// Parse a matched wiki link syntax. /// </summary> /// <param name="link">Regular expression match.</param> /// <param name="goal">Discord server ID.</param> /// <returns>A parsed URL from the match.</returns> static public string AddLink(Match link, string goal) { string linkFormat = Config.GetWiki(goal); GroupCollection groups = link.Groups; string type = (groups[1].Value.Length == 0 ? groups[3].Value : groups[1].Value).Trim(); string str = (groups[2].Value.Length == 0 ? groups[4].Value : groups[2].Value).Trim(); // Default site info WikiSite defaultSiteInfo = WikiSiteInfo[Config.GetWiki(goal)]; // Temporary site info storage for other wikis WikiSite tempSiteInfo = null; // Remove escaping symbols before Markdown syntax in Discord // (it converts \ to / anyway) str = str.Replace(@"\", ""); // Check for invalid page titles if (IsInvalid(str)) { return(""); } // Storages for prefix and namespace data string iw = "%%%%%"; string ns = ""; if (str.Length > 0) { // Add template namespace for template links and remove substitution if (type == "{{") { if (!str.StartsWith(':')) { ns = defaultSiteInfo.Namespaces["template"].CustomName; str = Regex.Replace(str, "^:?(?:subst|подст):", ""); // MediaWiki page transclusion if (str.StartsWith("int:")) { ns = defaultSiteInfo.Namespaces["mediawiki"].CustomName; str = Regex.Replace(str, "^int:", ""); } } } WikiSite latestSiteInfo = defaultSiteInfo; // Check if link contains interwikis Match iwMatch = Regex.Match(str, "^:?([A-Za-z-]+):"); while (type == "[[" && iwMatch.Length > 0) { string prefix = iwMatch.Groups[1].Value.ToLower(); latestSiteInfo = tempSiteInfo ?? defaultSiteInfo; InterwikiMap latestIWList = latestSiteInfo.InterwikiMap; NamespaceCollection latestNSList = latestSiteInfo.Namespaces; if (latestIWList.Contains(prefix) && !latestNSList.Contains(prefix)) { string oldLinkFormat = linkFormat; linkFormat = latestIWList[prefix].Url; // Fetch temporary site information if necessary and store new prefix if (iw != "" || oldLinkFormat.Replace(iw, prefix) != linkFormat) { WikiSite data = FetchSiteInfo(linkFormat).Result; tempSiteInfo = data; latestSiteInfo = tempSiteInfo; } iw = prefix; Regex only = new Regex($":?{prefix}:", RegexOptions.IgnoreCase); str = only.Replace(str, "", 1).Trim(); iwMatch = Regex.Match(str, "^:?([A-Za-z-]+):"); } else { // Return the regex that can’t be matched iwMatch = Regex.Match(str, "^\b$"); } } // Check if link contains namespace Match nsMatch = Regex.Match(str, "^:?([^:]+):"); if (nsMatch.Length > 0) { string prefix = nsMatch.Groups[1].Value.ToUpper(); NamespaceCollection latestNSList = latestSiteInfo.Namespaces; if (latestNSList.Contains(prefix)) { var namespaceInfo = latestNSList[prefix]; if ((namespaceInfo.Id == 2 || namespaceInfo.Id == 3) && namespaceInfo.Aliases.Count > 0) { // Get title according to gender for User namespaces str = GetNormalisedTitle(str, linkFormat).Result; } else { ns = namespaceInfo.CustomName; Regex only = new Regex($":?{prefix}:", RegexOptions.IgnoreCase); str = only.Replace(str, "", 1).Trim(); } } } // If there is only namespace, return nothing if (ns != "" && str.Length == 0) { return(""); } // Check if it’s a parser function if (type == "{{" && str.StartsWith("#")) { return(""); } // Check for invalid page title length if (IsInvalid(str, true)) { return(""); } // Rewrite other text if (str.Length > 0) { // Trim : from the start (nuisance) str = str.TrimStart(':'); // Capitalise first letter if wiki does not allow lowercase titles if (latestSiteInfo?.SiteInfo?.IsTitleCaseSensitive == false) { str = str[0].ToString().ToUpper() + str.Substring(1); } // Add namespace before any transformations if (ns != "") { str = string.Join(":", new[] { ns, str }); } } return(string.Format("<{0}>", GetLink(str, linkFormat))); } return(""); }
static public string AddLink(Match link, string goal) { string linkFormat = Config.GetWiki(goal); GroupCollection groups = link.Groups; string type = (groups[1].Value.Length == 0 ? groups[3].Value : groups[1].Value).Trim(); string str = (groups[2].Value.Length == 0 ? groups[4].Value : groups[2].Value).Trim(); // Default site info InterwikiMap defaultIWList = GetList(goal, "iw"); NamespaceCollection defaultNSList = GetList(goal, "ns"); // Temporary site info for other wikis InterwikiMap tempIWList = null; NamespaceCollection tempNSList = null; bool tempIsCaseSensitive = true; // Remove escaping symbols before Markdown syntax in Discord // (it converts \ to / anyway) str = str.Replace("\\", ""); // Check for invalid page titles if (IsInvalid(str)) { return(""); } // Storages for prefix and namespace data string iw = "%%%%%"; string ns = ""; if (str.Length > 0) { // Add template namespace for template links and remove substitution if (type == "{{") { ns = defaultNSList["template"].CustomName; str = Regex.Replace(str, "^(?:subst|подст):", ""); } // Check if link contains interwikis Match iwMatch = Regex.Match(str, "^:?([A-Za-z-]+):"); while (type == "[[" && iwMatch.Length > 0) { string prefix = iwMatch.Groups[1].Value.ToLower(); InterwikiMap latestIWList = (tempIWList != null ? tempIWList : defaultIWList); NamespaceCollection latestNSList = (tempNSList != null ? tempNSList : defaultNSList); if (latestIWList.Contains(prefix) && !latestNSList.Contains(prefix)) { string oldLinkFormat = linkFormat; linkFormat = latestIWList[prefix].Url; // Fetch temporary site information if necessary and store new prefix if (iw != "" || oldLinkFormat.Replace(iw, prefix) != linkFormat) { SiteInfo data = FetchSiteInfo(linkFormat).Result; tempIWList = data.iw; tempNSList = data.ns; tempIsCaseSensitive = data.isCaseSensitive; } iw = prefix; Regex only = new Regex($":?{prefix}:", RegexOptions.IgnoreCase); str = only.Replace(str, "", 1).Trim(); iwMatch = Regex.Match(str, "^:?([A-Za-z-]+):"); } else { // Return the regex that can’t be matched iwMatch = Regex.Match(str, "^\b$"); } } // Check if link contains namespace Match nsMatch = Regex.Match(str, "^:?([^:]+):"); if (nsMatch.Length > 0) { string prefix = nsMatch.Groups[1].Value.ToUpper(); NamespaceCollection latestNSList = defaultNSList; if (linkFormat != Config.GetWiki(goal) && tempNSList != null) { latestNSList = tempNSList; } if (latestNSList.Contains(prefix)) { ns = latestNSList[prefix].CustomName; Regex only = new Regex($":?{prefix}:", RegexOptions.IgnoreCase); str = only.Replace(str, "", 1).Trim(); } } // If there is only namespace, return nothing if (ns != "" && str.Length == 0) { return(""); } // Check if it’s a parser function if (type == "{{" && str.StartsWith("#")) { return(""); } // Rewrite other text if (str.Length > 0) { // Capitalise first letter if wiki does not allow lowercase titles if ((linkFormat == Config.GetWiki(goal) && !GetList(goal)) || (linkFormat != Config.GetWiki(goal) && !tempIsCaseSensitive)) { str = str[0].ToString().ToUpper() + str.Substring(1); } // Clear temporary site info tempIWList = null; tempNSList = null; tempIsCaseSensitive = false; // Add namespace before any transformations if (ns != "") { str = string.Join(":", new[] { ns, str }); } } return(string.Format("<{0}>", GetLink(str, linkFormat))); } return(""); }