Task 32 edit

In templates transcluding Template:CBB standings entry, Template:CBSB standings entry, and Template:CFB standings entry:

Replace
((?:CFB|CBB|CBSB) [Ss]tandings [Ee]ntry\s*\|\s*)(No\.|#)\s?
With
$1{{abbr|No.|Number}}

Task 30 edit

WikiProject banner mergers (taskforces etc) edit

Replace
<
\{\{(<insert template name and all redirects here>)([\S\s]*?)}}([\s\S]*?)\{\{(?:<insert outgoing template/redirects here>)[^}]*importance\s*=\s*([A-Za-z]*)[^}]*}}
With
<
{{$1$2|<taskforce code>=yes|<taskforce>-importance=$4}}$3

OR

Replace
<
\{\{(?:<insert outgoing template/redirects here>)[^}]*importance\s*=\s*([A-Za-z]*)[^}]*}}([\s\S]*?)\{\{(<insert template name and all redirects here>)([\S\s]*?)}}
With
<
{{$3$4|<taskforce code>=yes|<taskforce>-importance=$1}}$2

Infobox parameter changes edit

Hopefully fairly obvious what's going on - submodules for alternate infobox names, parameter replacement, parameter removal, and Headbomb's proposed infobox genfixes logic. Everything at the end is a modified version of the standard AWB library to allow me to hack a few of the functions that don't quite work with my logic as they were written.

	public static bool skipRemove = false;
	public static bool skipRename = false;
	public string ProcessArticle(string ArticleText, string ArticleTitle, int wikiNamespace, out string Summary, out bool Skip)
	{
		ArticleText = ArticleText.Replace('$' ,'╤');
		Skip = false;
		skipRemove = false;
		skipRename = false;
		Summary = "";
		string templateName = "";
		templateName = "__infobox_name__";
        
		// Avoid template redirects
		ArticleText = commonName(ArticleText, templateName);
        
		// Remove parameters if necessary. If not, uncomment next line
		// skipRemove = true;
		ArticleText = Tools.NestedTemplateRegex(templateName).Replace(ArticleText, m => paramKiller(m.Value));
        
		// Replace parameters if necessary. If not, uncomment next line
		skipRename = true;
		// ArticleText = Tools.NestedTemplateRegex(templateName).Replace(ArticleText, m => paramReplace(m.Value));
        
		// Infobox genfixes - [[User:Headbomb/sandbox#Proposed_logic]]
		ArticleText = Tools.NestedTemplateRegex(templateName).Replace(ArticleText, m => infoboxCleanup(m.Value));
		ArticleText = ArticleText.Replace('╤','$');
		if(skipRemove && skipRename)
		{
			Skip = true;
		}
		return ArticleText;
	}
	// Avoid template redirects
	public static string commonName(string ArticleText, string templateName)
	{
		// Switch the template name to the default
		List<string> otherNames = new List<string>();
		string[] array1 = new string[]{"__infobox_redirects__"};
		otherNames.AddRange(array1);
		foreach(string callName in otherNames)
		{
			ArticleText = WikiFunctions.Tools.RenameTemplate(ArticleText, callName, templateName);
		}
		
		return ArticleText;
	}
	// Remove any relevant parameters
	public static string paramKiller(string templateCall)
	{
		string tempTC = templateCall;
		
		// Set up parameters to remove
		List<string> paramsToKill = new List<string>();
		string[] array2 = new string[]{"__params_to_remove__"};
		paramsToKill.AddRange(array2);
		foreach(string param in paramsToKill)
		{
			templateCall = WikiFunctions.Tools.RemoveTemplateParameter(templateCall, param, false);
		}
		// If no parameters were removed, set this skip parameter to "true" (avoid genfixes etc)
		if(tempTC == templateCall)
		{
			skipRemove = true;
		}
		return templateCall;
	}
	// Rename any relevant parameters
	public static string paramReplace(string templateCall)
	{
		string tempTC = templateCall;
		
		List<string> paramsToReplace = new List<string>();
		List<string> paramReplacements = new List<string>();
		string[] array3 = new string[]{"__params to replace___"};
		paramsToReplace.AddRange(array3);
		string[] array4 = new string[]{"__replacement params__"};
		paramReplacements.AddRange(array4);
		for(int x=0; x<paramsToReplace.Count ; x++)
		{
			templateCall = WikiFunctions.Tools.RenameTemplateParameter(templateCall, paramsToReplace[x], paramReplacements[x]);
		}
		if(tempTC == templateCall)
		{
			skipRename = true;
		}
		return templateCall;
	}
	
        // "Infobox genfixes" - [[User:Headbomb/sandbox#Proposed_logic]]
	// 1a. move pipes to left of parameters
	// 1b. one parameter per line
	// 1c. excess pipe removal
	// 2a/b/c. normalize pipe/equal space (one space after |, = lined up)
	// 2d. empty line removal
	// 2e. bypass template redirect (technically done via commonName above)
	// 2f. final }} is on its own line
	public static string infoboxCleanup(string templatecall)
        {
//System.IO.StreamWriter sw = System.IO.File.AppendText("E:/insertfilenamehere.txt");
//sw.WriteLine(templatecall);
		string tempTC = "";
		tempTC = templatecall;
		
		// Initialize container, pull out named params from template
		string newTemplate = "{{" + Tools.GetTemplateName(templatecall) + "\r\n}}";
            	Dictionary<string, string> allParams = TemplateParameterValues(templatecall);
		// Find longest parameter (for setting spaces before equals)
	    	int longestParam = 0;
		int paramLen;
	    	foreach(KeyValuePair<string, string> kvp in allParams)
	    	{
	    		paramLen = kvp.Key.Length;
	    		if (paramLen > longestParam)
			longestParam = paramLen;
	   	}
		// Put each param/value pair into the template
		foreach(KeyValuePair<string, string> kvp in allParams)
		{
			string separatorBefore = "\r\n", separatorAfter = " ", equalsFormat = " = ", numSpaces = new String(' ', longestParam - kvp.Key.Length);
		    	newTemplate = WikiRegexes.TemplateEnd.Replace(newTemplate, separatorBefore + @"|" + separatorAfter + kvp.Key + numSpaces + equalsFormat + kvp.Value + @"$1}}");
		}
		return newTemplate;
	}


// -- Everything past this point is just a slightly (if at all) modified version of the built-in AWB code, mainly because it makes things easier

	private static readonly Regex param = new Regex(@"\|\s*([\w0-9_ -]+?)\s*=([^|}]*)");
	public static Dictionary<string, string> TemplateParameterValues(string templateCall)
	{
		Dictionary<string, string> paramsFound = new Dictionary<string, string>();
		string pipecleanedtemplate = PipeCleanTemplate(templateCall, false);
		foreach(Match m in param.Matches(pipecleanedtemplate))
 		{
			if (!paramsFound.ContainsKey(m.Groups[1].Value))
				paramsFound.Add(m.Groups[1].Value, templateCall.Substring(m.Groups[2].Index, m.Groups[2].Length).Trim());
		}
		return paramsFound;
	}
	private const char RepWith = '#';
	public static string PipeCleanTemplate(string templateCall, bool commentsastilde)
	{
		if (templateCall.Length < 5)
			return templateCall;
		string restoftemplate = templateCall.Substring(3);
		// clear out what may contain pipes that are not the pipe indicating the end of the parameter's value
		// Contains checks for performance gain
		if (restoftemplate.Contains(@"{{"))
			restoftemplate = ReplaceWith(restoftemplate, WikiRegexes.NestedTemplates, RepWith);
		if (restoftemplate.Contains(@"[["))
			restoftemplate = ReplaceWith(restoftemplate, WikiRegexes.SimpleWikiLink, RepWith);
		if (restoftemplate.Contains(@"<"))
		{
			restoftemplate = commentsastilde
				? ReplaceWith(restoftemplate, WikiRegexes.Comments, '~')
				: ReplaceWithSpaces(restoftemplate, WikiRegexes.Comments);
 			restoftemplate = ReplaceWith(restoftemplate, AllTagsV2, RepWith);
		}
		return (templateCall.Substring(0, 3) + restoftemplate);
        }
	/// <summary>
	/// Matches all tags: &lt;nowiki>, &lt;pre>, &lt;math>, &lt;timeline>, &lt;code>, &lt;source>, &lt;cite>, &lt;syntaxhighlight>, &lt;blockquote>, &lt;poem>, &lt;imagemap>, &lt;includeonly>, &lt;onlyinclude>, &lt;noinclude>, &lt;hiero>, &lt;score>
	/// </summary>
	public static readonly Regex AllTagsV2 = new Regex(@"<\s*(ref|nowiki|pre|math|timeline|code|source|cite|syntaxhighlight|blockquote|poem|imagemap|includeonly|onlyinclude|noinclude|hiero|score)[^<>]*>(?>(?!<\s*\1[^<>]*>|<\s*/\s*\1\b[^<>]*>).|<\s*\1[^<>]*>(?<Depth>)|<\s*/\s*\1\b[^<>]*>(?<-Depth>))*(?(Depth)(?!))<\s*/\s*\1\b[^<>]*>", RegexOptions.Singleline | RegexOptions.IgnoreCase);
        /// <summary>
        /// Replaces the values of all matches with spaces
        /// </summary>
        /// <param name="input">The article text to update</param>
        /// <param name="matches">Collection of matches to replace with spaces</param>
        /// <returns>The updated article text</returns>
        public static string ReplaceWithSpaces(string input, MatchCollection matches)
        {
            return ReplaceWith(input, matches, ' ');
        }
        /// <summary>
        /// Replaces the values of all matches with spaces
        /// </summary>
        /// <param name="input">The article text to update</param>
        /// <param name="matches">Collection of matches to replace with spaces</param>
        /// <param name="keepGroup">Regex match group to keep text of in replacement</param>
        /// <returns>The updated article text</returns>
        public static string ReplaceWithSpaces(string input, MatchCollection matches, int keepGroup)
        {
            return ReplaceWith(input, matches, ' ', keepGroup);
        }
        /// <summary>
        /// Replaces the values of all matches with a given character
        /// </summary>
        /// <param name="input">The article text to update</param>
        /// <param name="matches">Collection of matches to replace with spaces</param>
        /// <param name="rwith">The character to use</param>
        /// <returns>The updated article text</returns>
        public static string ReplaceWith(string input, MatchCollection matches, char rwith)
        {
            return ReplaceWith(input, matches, rwith, 0);
        }
        /// <summary>
        /// Replaces the values of all matches with a given character
        /// </summary>
        /// <param name="input">The article text to update</param>
        /// <param name="matches">Collection of matches to replace with spaces</param>
        /// <param name="rwith">The character to use</param>
        /// <param name="keepGroup">Regex match group to keep text of in replacement</param>
        /// <returns>The updated article text</returns>
        public static string ReplaceWith(string input, MatchCollection matches, char rwith, int keepGroup)
        {
            StringBuilder sb = new StringBuilder(input.Length);
            foreach (Match m in matches)
            {
                sb.Append(input, sb.Length, m.Index - sb.Length);
                if (keepGroup < 1 || m.Groups[keepGroup].Value.Length == 0)
                    sb.Append(rwith, m.Length);
                else
                {
                    sb.Append(rwith, m.Groups[keepGroup].Index - m.Index);
                    sb.Append(m.Groups[keepGroup].Value);
                    sb.Append(rwith, m.Index + m.Length - m.Groups[keepGroup].Index - m.Groups[keepGroup].Length);
                }
            }
            if (input.Length > sb.Length)
                sb.Append(input, sb.Length, input.Length - sb.Length);
            return sb.ToString();
        }
        /// <summary>
        /// Replaces all matches of a given regex in a string with space characters
        /// such that the length of the string remains the same
        /// </summary>
        /// <param name="input">The article text to update</param>
        /// <param name="regex">The regex to replace all matches of</param>
        /// <returns>The updated article text</returns>
        public static string ReplaceWithSpaces(string input, Regex regex)
        {
            return ReplaceWithSpaces(input, regex.Matches(input));
        }
        /// <summary>
        /// Replaces all matches of a given regex in a string with space characters
        /// such that the length of the string remains the same
        /// </summary>
        /// <param name="input">The article text to update</param>
        /// <param name="regex">The regex to replace all matches of</param>
        /// <param name="keepGroup">Regex match group to keep text of in replacement</param>
        /// <returns>The updated article text</returns>
        public static string ReplaceWithSpaces(string input, Regex regex, int keepGroup)
        {
            return ReplaceWithSpaces(input, regex.Matches(input), keepGroup);
        }
        /// <summary>
        /// Replaces all matches of a given regex in a string with a character
        /// such that the length of the string remains the same
        /// </summary>
        /// <param name="input">The article text to update</param>
        /// <param name="regex">The regex to replace all matches of</param>
        /// <param name="rwith">The character to use</param>
        /// <returns>The updated article text</returns>
        public static string ReplaceWith(string input, Regex regex, char rwith)
        {
            return ReplaceWith(input, regex.Matches(input), rwith);
        }
        /// <summary>
        /// Replaces all matches of a given regex in a string with a character
        /// such that the length of the string remains the same
        /// </summary>
        /// <param name="input">The article text to update</param>
        /// <param name="regex">The regex to replace all matches of</param>
        /// <param name="rwith">The character to use</param>
        /// <param name="keepGroup">Regex match group to keep text of in replacement</param>
        /// <returns>The updated article text</returns>
        public static string ReplaceWith(string input, Regex regex, char rwith, int keepGroup)
        {
            return ReplaceWith(input, regex.Matches(input), rwith, keepGroup);
        }