public void WPBiography() { string a = @"{{WPBiography|foo=yes|living=yes|listas=Foé}}"; Assert.AreEqual(a.Replace(@"é", "e"), TalkPageFixes.WPBiography(a), "diacritics removed from WPBiography listas"); Assert.AreEqual(a.Replace(@"é", "e"), TalkPageFixes.WPBiography(a.Replace(@"é", "e")), "no change when no diacritics in WPBiography listas"); }
public void TalkHeaderDefaultsortChange() { string start = @" ==Foo== bar", df = @"{{DEFAULTSORT:Bert}}"; string articleText = start + "\r\n" + df; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.MoveToBottom); Assert.AreEqual(start + "\r\n" + "\r\n" + df, articleText); articleText = start + df; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.MoveToTop); Assert.AreEqual(df + "\r\n" + start, articleText); articleText = start + df; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.NoChange); Assert.AreEqual(start + df, articleText); string df2 = @"{{DEFAULTSORT:}}"; articleText = start + df2; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.MoveToBottom); Assert.AreEqual(start, articleText, "defaultsort with no key removed"); articleText = start + df2; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.MoveToTop); Assert.AreEqual(start, articleText, "defaultsort with no key removed"); }
public void AddWikiProjectBannerShell() { const string a = @"{{WikiProject a|text}}", b = @"{{WikiProject b|text}}", c = @"{{WikiProject c|text}}", d = @"{{WikiProject d|text}}"; Assert.AreEqual(a, TalkPageFixes.WikiProjectBannerShell(a)); Assert.AreEqual(a + b, TalkPageFixes.WikiProjectBannerShell(a + b)); Assert.AreEqual(a + b + c, TalkPageFixes.WikiProjectBannerShell(a + b + c)); Assert.AreEqual(@"{{WikiProjectBannerShell|1=" + "\r\n" + a + "\r\n" + b + "\r\n" + c + "\r\n" + d + "\r\n" + @"}}", TalkPageFixes.WikiProjectBannerShell(a + b + c + d)); const string e = @"{{talk header}} {{WikiProject Biography|listas=Bar, F|living=yes|class=Start|priority=mid|sports-work-group=yes}} {{WikiProject F|class=Start|importance=mid|italy=y}} {{WikiProject X|class=Start|importance=Mid}} {{WikiProject D|class=Start|importance=Low}}", f = @"{{WikiProjectBannerShell|1= {{WikiProject Biography|listas=Bar, F|living=yes|class=Start|priority=mid|sports-work-group=yes}} {{WikiProject F|class=Start|importance=mid|italy=y}} {{WikiProject X|class=Start|importance=Mid}} {{WikiProject D|class=Start|importance=Low}} | blp=yes }}{{talk header}} "; Assert.AreEqual(f, TalkPageFixes.WikiProjectBannerShell(e), "adds WPBS, ignores non-wikiproject templates"); }
public void WikiProjectBannerShellBLP() { const string a = @"{{WikiProjectBannerShell|blp=yes|1={{WPBiography|foo=bar|living=yes}}}}"; Assert.AreEqual(a, TalkPageFixes.WikiProjectBannerShell(a + "{{Blp}}")); Assert.AreEqual(a, TalkPageFixes.WikiProjectBannerShell(a.Replace("blp=yes", "blp=") + "{{Blp}}")); Assert.AreEqual("{{Blp}}", TalkPageFixes.WikiProjectBannerShell("{{Blp}}")); }
public void RenameTalkHeader() { string talkheader = @"{{talkheader|noarchive=no}}", talkrest = @"==hello== hello talk"; string articleText = talkrest + "\r\n" + talkheader; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.NoChange); Assert.AreEqual(@"{{Talk header|noarchive=no}}" + "\r\n" + talkrest + "\r\n", articleText, "renamed to upper case with space"); }
public void WikiProjectBannerShellUnnamedParam() { Assert.AreEqual(@"{{WikiProjectBannerShell|1={{WPBiography|foo=bar}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|{{WPBiography|foo=bar}}}}"), "1= added when missing"); Assert.AreEqual(@"{{WikiProjectBannerShell|1= {{WPBiography|foo=bar}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell| {{WPBiography|foo=bar}}}}")); const string otherUnnamed = @"{{WikiProjectBannerShell|random}}"; Assert.AreEqual(otherUnnamed, TalkPageFixes.WikiProjectBannerShell(otherUnnamed), "other unknown parameter not named 1="); }
public void WikiProjectBannerShellWPBiography() { Assert.AreEqual(@"{{WikiProjectBannerShell|1={{WPBiography|foo=bar}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|1={{WPBiography|foo=bar}}}}")); Assert.AreEqual(@"{{WikiProjectBannerShell|blp=yes|1={{WPBiography|foo=bar|living=yes}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|blp=|1={{WPBiography|foo=bar|living=yes}}}}")); Assert.AreEqual(@"{{WikiProjectBannerShell|blp=yes|1={{WikiProject Biography|foo=bar|living=yes}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|blp=|1={{WikiProject Biography|foo=bar|living=yes}}}}")); Assert.AreEqual(@"{{WikiProjectBannerShell|activepol=yes|1={{WPBiography|foo=bar|activepol=yes}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|activepol=abc|1={{WPBiography|foo=bar|activepol=yes}}}}")); Assert.AreEqual(@"{{WikiProjectBannerShell|blpo=yes|1={{WPBiography|foo=bar|blpo=yes}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|blpo=|1={{WPBiography|foo=bar|blpo=yes}}}}")); Assert.AreEqual(@"{{WikiProjectBannerShell|blpo=|1={{WPBiography|foo=bar|blpo=no}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|blpo=|1={{WPBiography|foo=bar|blpo=no}}}}")); Assert.AreEqual(@"{{WikiProjectBannerShell|1={{WPBiography|foo=bar|living=no}}}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|blp=yes|1={{WPBiography|foo=bar|living=no}}}}")); }
public void SkipToTalk() { string articleText = @"{{Skiptotoc}}", STT = @"{{Skip to talk}}"; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.NoChange); Assert.AreEqual(STT + "\r\n", articleText); articleText = @"{{skiptotoctalk}}"; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.NoChange); Assert.AreEqual(STT + "\r\n", articleText); }
public void AddMissingFirstCommentHeader() { const string comment = @" Hello world comment."; string articleTextIn = articleTextHeader + comment; // plain comment TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(articleTextIn, articleTextHeader + "\r\n" + @" ==Untitled== Hello world comment."); // idented comment2 articleTextIn = articleTextHeader + @" *Hello world comment2."; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(articleTextIn, articleTextHeader + "\r\n" + @" ==Untitled== *Hello world comment2."); // idented comment3 articleTextIn = articleTextHeader + @" :Hello world comment3."; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(articleTextIn, articleTextHeader + "\r\n" + @" ==Untitled== :Hello world comment3."); // quoted comment articleTextIn = articleTextHeader + @" ""Hello world comment4""."; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(articleTextIn, articleTextHeader + "\r\n" + @" ==Untitled== ""Hello world comment4""."); // heading level 3 changed to level 2 articleTextIn = articleTextHeader + "\r\n" + @"===Foo bar=== *Hello world comment2."; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.IsTrue(articleTextIn.Contains(@"==Foo bar==")); Assert.IsFalse(articleTextIn.Contains(@"==Untitled==")); }
public void WikiProjectBannerShellAddingWikiProjects() { Assert.AreEqual(@"{{WikiProjectBannerShell|1={{WPBiography|foo=bar}} {{WikiProject foo}}}} ", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|1={{WPBiography|foo=bar}}}} {{WikiProject foo}}"), "WikiProjects pulled into WPBS"); Assert.AreEqual(@"{{WikiProjectBannerShell|1={{WPBiography|foo=bar}} {{WikiProject foo}} {{WikiProject bar}}}} ", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|1={{WPBiography|foo=bar}}}} {{WikiProject foo}} {{WikiProject bar}}"), "WikiProjects pulled into WPBS"); }
public void RemoveTemplateNamespace() { string T1 = @"{{Template:Foo}}", T2 = @"{{Template:Foo}} ==Section== {{Template:Bar}}"; Assert.IsFalse(TalkPageFixes.ProcessTalkPage(ref T1, DEFAULTSORT.NoChange)); Assert.AreEqual("{{Foo}}", T1, "template namespace removed"); Assert.IsFalse(TalkPageFixes.ProcessTalkPage(ref T2, DEFAULTSORT.NoChange)); Assert.AreEqual(@"{{Foo}} ==Section== {{Template:Bar}}", T2, "changes only made in zeroth section"); }
public void WikiProjectBannerShellMisc() { const string a = @"{{wpbs|1=|banner collapsed=no| {{WPBiography|living=yes|class=Start|priority=|listas=Hill, A}} {{WikiProject Gender Studies}} {{WikiProject Oklahoma}} }}", b = @"{{WikiProjectBannerShell|banner collapsed=no|1= {{WPBiography|living=yes|class=Start|priority=|listas=Hill, A}} {{WikiProject Gender Studies}} {{WikiProject Oklahoma}} | blp=yes }}"; Assert.AreEqual(b, TalkPageFixes.WikiProjectBannerShell(a)); }
public void WPBiographyTopBilling() { string a = @"{{WPBiography|foo=yes|living=yes}} {{WikiProject London}} ", b = @"{{WikiProjectBannerShell|banner collapsed=no|1= {{WPBiography|living=yes|class=Start|priority=|listas=Hill, A}} {{WikiProject Gender Studies}} {{WikiProject Oklahoma}} | blp=yes }}", c = @"{{WPBiography|foo=yes|living=no}} {{WikiProject London}}"; Assert.AreEqual(a, TalkPageFixes.WPBiography(@"{{WikiProject London}} {{WPBiography|foo=yes|living=yes}}"), "WPBiography moved above WikiProjects"); Assert.AreEqual(a, TalkPageFixes.WPBiography(a), "no change when WPBiography ahead of WikiProjects"); Assert.AreEqual(b, TalkPageFixes.WPBiography(b), "no change when WPBS present"); Assert.AreEqual(c, TalkPageFixes.WPBiography(c), "no change when not living"); Assert.AreEqual(c + @"{{blp}}", TalkPageFixes.WPBiography(c + @"{{blp}}"), "no change when not living"); Assert.AreEqual(a, TalkPageFixes.WPBiography(a + @"{{blp}}"), "blp template removed when living=y"); }
public void MoveTalkHeader() { string talkheader = @"{{talk header|noarchive=no|search=no|arpol=no|wp=no|disclaimer=no|shortcut1|shortcut2}}", talkrest = @"==hello== hello talk"; string articleText = talkrest + "\r\n" + talkheader; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.NoChange); Assert.AreEqual(talkheader.Replace("{{talk", @"{{Talk") + "\r\n" + talkrest + "\r\n", articleText); // handles {{talk header}} on same line as other template string WPBS = @"{{WikiProjectBannerShell|blp=yes|1= {{OH-Project|class=B|importance=Low|nested=yes}} {{WPBiography|living=yes|class=B|priority=Low|filmbio-work-group=yes|nested=yes|listas=Parker, Sarah Jessica}} {{WikiProject Cincinnati|class=B|importance=mid|nested=yes}} }}", rest = "\r\n" + @"==Song Jessie by Joshua Kadison== In the article it says that above mentioned"; articleText = WPBS + @"{{Talkheader}}" + rest; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.NoChange); Assert.AreEqual(@"{{Talk header}}" + "\r\n" + WPBS + rest, articleText); // no change if already at top articleText = talkheader + "\r\n" + talkrest; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.NoChange); Assert.AreEqual(talkheader + "\r\n" + talkrest, articleText); // no change if no talk header articleText = talkrest; TalkPageFixes.ProcessTalkPage(ref articleText, DEFAULTSORT.NoChange); Assert.AreEqual(talkrest, articleText); }
public void WikiProjectBannerShellUnneededParams() { Assert.AreEqual(@"{{WikiProjectBannerShell}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|blp=no|activepol=no|collapsed=no}}")); }
public void WikiProjectBannerShellDupeParameters() { Assert.AreEqual(@"{{WikiProjectBannerShell|blp=yes}}", TalkPageFixes.WikiProjectBannerShell(@"{{WikiProjectBannerShell|blp=yes|blp=yes}}")); }
/// <summary> /// Extracts DEFAULTSORT + categories from the article text; removes duplicate categories, cleans whitespace and underscores /// </summary> /// <param name="articleText">The wiki text of the article.</param> /// <param name="articleTitle">Title of the article</param> /// <returns>The cleaned page categories in a single string</returns> public string RemoveCats(ref string articleText, string articleTitle) { List <string> categoryList = new List <string>(); string originalArticleText = articleText; // allow comments between categories, and keep them in the same place, but don't grab any comment just after the last category Regex r = new Regex(@"<!-- [^<>]*?\[\[\s*" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @".*?(\]\]|\|.*?\]\]).*?-->|\[\[" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @".*?(\]\]|\|.*?\]\])(\s*⌊⌊⌊⌊\d{1,4}⌋⌋⌋⌋|\s*<!--.*?-->(?=\r\n\[\[\s*" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @"))?", RegexOptions.Singleline); MatchCollection matches = r.Matches(articleText); foreach (Match m in matches) { if (!Regex.IsMatch(m.Value, @"\[\[Category:(Pages|Categories|Articles) for deletion\]\]")) { categoryList.Add(m.Value); } } articleText = Tools.RemoveMatches(articleText, matches); // if category tidying has changed comments/nowikis return with no changes – we've pulled a cat from a comment if (!UnformattedTextNotChanged(originalArticleText, articleText)) { articleText = originalArticleText; return(""); } if (AddCatKey) { categoryList = CatKeyer(categoryList, articleTitle); } if (CatCommentRegex.IsMatch(articleText)) { string catComment = CatCommentRegex.Match(articleText).Value; articleText = articleText.Replace(catComment, ""); categoryList.Insert(0, catComment); } MatchCollection mc = WikiRegexes.Defaultsort.Matches(articleText); if (mc.Count > 1) { throw new ArgumentException("Page contains multiple {{DEFAULTSORTS}} tags. Metadata sorting cancelled"); } string defaultSort = ""; if (Variables.LangCode.Equals("sl") && LifeTime.IsMatch(articleText)) { defaultSort = LifeTime.Match(articleText).Value; } else { // ignore commented out DEFAULTSORT – http://en.wikipedia.org/wiki/Wikipedia_talk:AutoWikiBrowser/Bugs#Moving_DEFAULTSORT_in_HTML_comments if (mc.Count > 0 && WikiRegexes.Defaultsort.Matches(WikiRegexes.Comments.Replace(articleText, "")).Count == mc.Count) { defaultSort = mc[0].Value; } } if (!string.IsNullOrEmpty(defaultSort)) { articleText = articleText.Replace(defaultSort, ""); } if (!string.IsNullOrEmpty(defaultSort) && defaultSort.ToUpper().Contains("DEFAULTSORT")) { defaultSort = TalkPageFixes.FormatDefaultSort(defaultSort); } if (!string.IsNullOrEmpty(defaultSort)) { defaultSort += "\r\n"; } return(defaultSort + ListToString(categoryList)); }
public void AddMissingFirstCommentHeaderNoChanges() { // no change – header already string articleTextIn = articleTextHeader + @" ==Question== :Hello world comment3."; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(articleTextIn, articleTextHeader + @" ==Question== :Hello world comment3."); // no change – already header at top articleTextIn = @" {{Some template}} ==Question== :Hello world comment3."; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(@" {{Some template}} ==Question== :Hello world comment3.", articleTextIn); // no change – already header at top 2 articleTextIn = @" ==Question== {{Some template}} :Hello world comment3."; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(@" ==Question== {{Some template}} :Hello world comment3.", articleTextIn); // no change – no comments articleTextIn = @" ==Question== {{Some template}}"; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(@" ==Question== {{Some template}}", articleTextIn); // no change – only text in template articleTextIn = @" {{foo| bar| end}}"; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(@" {{foo| bar| end}}", articleTextIn); // no change – only comments articleTextIn = @" <!-- foo -->"; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(@" <!-- foo -->", articleTextIn); // no change – only TOC articleTextIn = @" __TOC__"; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(@" __TOC__", articleTextIn); // no change -- only in template const string allInTemplate = @"{{archive box| *[[/Archive: GA review|Good Article review]]}} == Explanation of Wright's work in ''Certaine Errors'' =="; articleTextIn = allInTemplate; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(allInTemplate, articleTextIn); // no change -- only after template on same line // http://en.wikipedia.org/wiki/Wikipedia_talk:AutoWikiBrowser/Bugs#Section_header_added_in_wrong_position const string allAfterTemplate = @"{{archive box|words}} extra foo {{another one}}"; articleTextIn = allAfterTemplate; TalkPageFixes.ProcessTalkPage(ref articleTextIn, DEFAULTSORT.NoChange); Assert.AreEqual(allAfterTemplate, articleTextIn); }
public void WikiProjectBannerShellRedirects() { string red1 = @"{{WPBS}}", WikiProjectBannerShell = @"{{WikiProjectBannerShell}}"; Assert.AreEqual(WikiProjectBannerShell, TalkPageFixes.WikiProjectBannerShell(red1)); }
/// <summary> /// Extracts DEFAULTSORT + categories from the article text; removes duplicate categories, cleans whitespace and underscores /// </summary> /// <param name="articleText">The wiki text of the article.</param> /// <param name="articleTitle">Title of the article</param> /// <returns>The cleaned page categories in a single string</returns> public string RemoveCats(ref string articleText, string articleTitle) { // don't pull category from redirects to a category e.g. page Hello is #REDIRECT[[Category:Hello]] string rt = Tools.RedirectTarget(articleText); if (rt.Length > 0 && WikiRegexes.Category.IsMatch(@"[[" + rt + @"]]")) { return(""); } // don't operate on pages with (incorrectly) multiple defaultsorts MatchCollection mc = WikiRegexes.Defaultsort.Matches(articleText); if (mc.Count > 1) { return(""); } List <string> categoryList = new List <string>(); string originalArticleText = articleText; string articleTextNoComments = WikiRegexes.Comments.Replace(articleText, ""); // allow comments between categories, and keep them in the same place, only grab any comment after the last category if on same line // whitespace: remove all whitespace after, but leave a blank newline before a heading (rare case where category not in last section) Regex r = new Regex(@"<!-- [^<>]*?\[\[\s*" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @".*?(\]\]|\|.*?\]\]).*?-->|\[\[" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @".*?(\]\]|\|.*?\]\])(\s*⌊⌊⌊⌊\d{1,4}⌋⌋⌋⌋| *<!--.*?-->|\s*<!--.*?-->(?=\r\n\[\[\s*" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @")|\s*(?=\r\n==)|\s*)?", RegexOptions.Singleline); // performance: apply regex on portion of article containing category links rather than whole text Match cq = WikiRegexes.CategoryQuick.Match(articleText); if (cq.Success) { int cutoff = Math.Max(0, cq.Index - 500); articleText = articleText.Substring(0, cutoff) + r.Replace(articleText.Substring(cutoff), m => { if (!CatsForDeletion.IsMatch(m.Value)) { categoryList.Add(m.Value.Trim()); } return(""); }); } // if category tidying has changed comments/nowikis return with no changes – we've pulled a cat from a comment if (!Tools.UnformattedTextNotChanged(originalArticleText, articleText)) { articleText = originalArticleText; return(""); } if (AddCatKey) { categoryList = CatKeyer(categoryList, articleTitle); } articleText = CatCommentRegex.Replace(articleText, m => { categoryList.Insert(0, m.Value); return(""); }, 1); string defaultSort = ""; if (Variables.LangCode.Equals("sl") && LifeTime.IsMatch(articleText)) { defaultSort = LifeTime.Match(articleText).Value; } else { // ignore commented out DEFAULTSORT – https://en.wikipedia.org/wiki/Wikipedia_talk:AutoWikiBrowser/Bugs#Moving_DEFAULTSORT_in_HTML_comments if (mc.Count > 0 && WikiRegexes.Defaultsort.Matches(articleTextNoComments).Count == mc.Count) { defaultSort = mc[0].Value; } } if (!string.IsNullOrEmpty(defaultSort)) { articleText = articleText.Replace(defaultSort, ""); if (defaultSort.ToUpper().Contains("DEFAULTSORT")) { defaultSort = TalkPageFixes.FormatDefaultSort(defaultSort); } defaultSort += "\r\n"; } // Extract any {{uncategorized}} template, but not uncat stub templates string uncat = ""; if (WikiRegexes.Uncat.IsMatch(articleTextNoComments)) { Match uncatm = WikiRegexes.Uncat.Match(articleText); if (uncatm.Success && !WikiRegexes.PossiblyCommentedStub.IsMatch(uncatm.Value)) { articleText = articleText.Replace(uncatm.Value, ""); uncat = uncatm.Value + "\r\n"; } } return(uncat + defaultSort + ListToString(categoryList)); }
/// <summary> /// Extracts DEFAULTSORT + categories from the article text; removes duplicate categories, cleans whitespace and underscores /// </summary> /// <param name="articleText">The wiki text of the article.</param> /// <param name="articleTitle">Title of the article</param> /// <returns>The cleaned page categories in a single string</returns> public string RemoveCats(ref string articleText, string articleTitle) { // mainspace only. In category space it may ruin category tree if (!Namespace.IsMainSpace(articleTitle)) { return(""); } // don't pull category from redirects to a cagegory e.g. page Hello is #REDIRECT[[Category:Hello]] if (WikiRegexes.Category.IsMatch(@"[[" + Tools.RedirectTarget(articleText) + @"]]")) { return(""); } // don't operate on pages with (incorrectly) multiple defaultsorts MatchCollection mc = WikiRegexes.Defaultsort.Matches(articleText); if (mc.Count > 1) { return(""); } List <string> categoryList = new List <string>(); string originalArticleText = articleText; // allow comments between categories, and keep them in the same place, only grab any comment after the last category if on same line Regex r = new Regex(@"<!-- [^<>]*?\[\[\s*" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @".*?(\]\]|\|.*?\]\]).*?-->|\[\[" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @".*?(\]\]|\|.*?\]\])(\s*⌊⌊⌊⌊\d{1,4}⌋⌋⌋⌋| *<!--.*?-->|\s*<!--.*?-->(?=\r\n\[\[\s*" + Variables.NamespacesCaseInsensitive[Namespace.Category] + @")|\s*)?", RegexOptions.Singleline); MatchCollection matches = r.Matches(articleText); foreach (Match m in matches) { if (!CatsForDeletion.IsMatch(m.Value)) { categoryList.Add(m.Value.Trim()); } } articleText = Tools.RemoveMatches(articleText, matches); // if category tidying has changed comments/nowikis return with no changes – we've pulled a cat from a comment if (!UnformattedTextNotChanged(originalArticleText, articleText)) { articleText = originalArticleText; return(""); } if (AddCatKey) { categoryList = CatKeyer(categoryList, articleTitle); } if (CatCommentRegex.IsMatch(articleText)) { string catComment = CatCommentRegex.Match(articleText).Value; articleText = articleText.Replace(catComment, ""); categoryList.Insert(0, catComment); } string defaultSort = ""; if (Variables.LangCode.Equals("sl") && LifeTime.IsMatch(articleText)) { defaultSort = LifeTime.Match(articleText).Value; } else { // ignore commented out DEFAULTSORT – https://en.wikipedia.org/wiki/Wikipedia_talk:AutoWikiBrowser/Bugs#Moving_DEFAULTSORT_in_HTML_comments if (mc.Count > 0 && WikiRegexes.Defaultsort.Matches(WikiRegexes.Comments.Replace(articleText, "")).Count == mc.Count) { defaultSort = mc[0].Value; } } if (!string.IsNullOrEmpty(defaultSort)) { articleText = articleText.Replace(defaultSort, ""); if (defaultSort.ToUpper().Contains("DEFAULTSORT")) { defaultSort = TalkPageFixes.FormatDefaultSort(defaultSort); } defaultSort += "\r\n"; } return(defaultSort + ListToString(categoryList)); }