public string ProcessArticle(WikiFunctions.Plugin.IAutoWikiBrowser sender, WikiFunctions.Plugin.IProcessArticleEventArgs eventargs)
{
string text = eventargs.ArticleText;
if (!Settings.Enabled)
{
return(text);
}
// Get the set of templates from the article text
MatchCollection matches = WikiFunctions.Parse.Parsers.GetTemplates(text, Settings.TemplateName);
if (matches.Count == 0)
{
eventargs.Skip = Settings.SkipIfNoTemplates;
return(text);
}
// Build our regex from the settings, but only if we need to
if (RegexString == "")
{
BuildRegexes();
}
// Nothing to do? Do nothing.
if (RegexString == "")
{
eventargs.Skip = Settings.SkipIfNoTemplates;
return(text);
}
int deltaLength = 0; // used when re-inserting text, to account for differences in previous replacements
#if DEBUG_OUTPUT_DIALOG
DebugOutput dlg = new DebugOutput();
dlg.Show(AWB.Form);
dlg.AddSection("text", text);
#endif
// Now apply our regex to each instance of the template in the article text
foreach (Match match in matches)
{
string matchSegment = match.Value;
/// Cannot handle wikitables used within templates
if (matchSegment.Contains("{|"))
{
MessageBox.Show("Infobox contains a wikitable:\r\n\r\n" + text, eventargs.ArticleTitle);
eventargs.Skip = Settings.SkipIfNoTemplates;
return(text);
}
if (Settings.RemoveExcessPipes)
{
if (ExcessPipe.IsMatch(matchSegment))
{
matchSegment = ExcessPipe.Replace(matchSegment, RemovePipeReplacement);
}
}
// Matches
if (!findParametersRegex.IsMatch(matchSegment))
{
MessageBox.Show(string.Format("Bad template matched:\r\n\r\n{0}", matchSegment), eventargs.ArticleTitle);
continue;
}
Match m = findParametersRegex.Match(matchSegment);
System.Diagnostics.Debug.Assert(m.Success);
// Determine the pattern for spacing, to minimise the whitespace changes
string paramPipeStr = "|"; // gets replaced with one surrounded by whitespace if that's what the article uses
string paramEqualsStr = "="; // gets replaced with one surrounded by whitespace if that's what the article uses
int paramDesiredLength = 0;
string trailingWhitespace = ""; // any whitespace after the value
foreach (KeyValuePair <string, string> param in Settings.Parameters)
{
string paramSegment = m.Groups["__" + param.Key].ToString();
if (paramSegment != "")
{
paramPipeStr = paramPipeRegex.Match(paramSegment).Value;
string paramPatternMatch = paramEqualsRegex.Match(paramSegment).Value;
paramDesiredLength = paramPatternMatch.Length + param.Key.Length;
paramEqualsStr = paramPatternMatch.PadLeft(paramDesiredLength);
string valueSegment = m.Groups["_" + param.Key].ToString();
if (valueSegment == "")
{
valueSegment = paramSegment;
}
trailingWhitespace = trailingWhiteSpaceRegex.Match(valueSegment).Value;
break;
}
}
// Build the segments of the original input string into one composite, in a specific order
string paramSegments = "";
foreach (KeyValuePair <string, string> param in Settings.Parameters)
{
string paramSegment = m.Groups["__" + param.Key].ToString();
if (paramSegment == "")
{
paramSegments += "|" + param.Key + "=";
}
else
{
paramSegments += paramSegment + m.Groups["_" + param.Key];
}
}
// add a trailing pipe to assist in capturing all the white space
paramSegments += "|";
// Build the segments of the replacement values
// Try to reproduce the whitespace style of the surrounding parameters if they are on separate lines
string paramReplacementStr = "";
foreach (KeyValuePair <string, string> param in Settings.Replacements)
{
string equalsStr;
if (trailingWhitespace.Contains("\n"))
{
int spaceLeft = paramDesiredLength - param.Key.Length;
if (spaceLeft <= 0)
{
// This parameter name is wider than the space to the left of our reference parameter was
equalsStr = "=";
}
else
{
equalsStr = paramEqualsStr;
int indexOfEquals = equalsStr.IndexOf('=');
// Trim space from left as far as we can
equalsStr = equalsStr.Substring(Math.Min(indexOfEquals, paramDesiredLength - spaceLeft));
// Trim space from right if still needed
if (equalsStr.Length > spaceLeft)
{
equalsStr = equalsStr.Remove(spaceLeft);
}
}
}
else
{
equalsStr = paramEqualsStr;
}
paramReplacementStr += paramPipeStr + param.Key + equalsStr + param.Value + trailingWhitespace;
}
// Do the replacement
string paramReplacement = paramReplacementRegex.Replace(paramSegments, paramReplacementStr);
paramReplacement = paramReplacement.Remove(paramReplacement.Length - 1);
// Check for only whitespace difference between old and new
//TODO: re-check this:
if (WikiRegexes.WhiteSpace.Replace(paramSegments, "") == WikiRegexes.WhiteSpace.Replace(paramReplacement, ""))
{
continue;
}
#if DEBUG_OUTPUT_DIALOG
dlg.StartSection(string.Format("Match at {0}", match.Index));
dlg.StartSection("Groups");
for (int i = 0; i < findParametersRegex.GetGroupNumbers().Length; ++i)
{
dlg.AddSection("Group " + findParametersRegex.GetGroupNames()[i], m.Groups[i].ToString());
}
dlg.EndSection();
dlg.AddSection("paramSegments", paramSegments);
dlg.AddSection("paramReplacementStr", paramReplacementStr);
dlg.AddSection("paramReplacementRegex", paramReplacementRegex.ToString());
dlg.AddSection("paramReplacement", paramReplacement);
#endif
// Remove all occurrences of all of the parameters we're operating on.
// Note the index of the first occurrence as the insertion point for the whole replacement group
int firstIndex = match.Length;
foreach (KeyValuePair <string, string> param in Settings.Parameters)
{
Regex segmentRegex = paramRemovalRegexes[param.Key];
Match segmentMatch = segmentRegex.Match(matchSegment);
if (segmentMatch.Success)
{
matchSegment = segmentRegex.Replace(matchSegment, "");
if (segmentMatch.Index < firstIndex)
{
firstIndex = segmentMatch.Index;
}
}
}
if (firstIndex == match.Length)
{
// the parameters don't already exist, so
// a) there's no whitespace pattern on which to base our replacement
// b) there's no position for placing it
continue;
}
// Replace the segments in this match with our new version
matchSegment = matchSegment.Substring(0, firstIndex)
+ paramReplacement
+ matchSegment.Substring(firstIndex);
// Replace this match back into the original text at match.Index+deltaLength
text = text.Substring(0, match.Index + deltaLength)
+ matchSegment
+ text.Substring(match.Index + match.Length + deltaLength);
deltaLength += matchSegment.Length - match.Length;
#if DEBUG_OUTPUT_DIALOG
dlg.AddSection("text after substitution", text);
dlg.EndSection();
#endif
}
return(text);
}