User:Pathosbot/TemplateEditor.cs: Difference between revisions
Jump to navigation
Jump to search
Content deleted Content added
Pathoschild (talk | contribs) + correctly parse redundant parameter assignments |
Pathoschild (talk | contribs) + stop editing on error |
||
Line 13: | Line 13: | ||
namespace HeaderConversion { |
namespace HeaderConversion { |
||
public class HeaderConversion : WikiFunctions.Plugin.IAWBPlugin { |
public class HeaderConversion : WikiFunctions.Plugin.IAWBPlugin { |
||
/******************** |
|||
* Pause and display error |
|||
*******************/ |
|||
void StopForError(string message, string text) { |
|||
if (text != "") |
|||
message += "\n\n" + text; |
|||
MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); |
|||
AWB.BotModeCheckbox.Checked = false; |
|||
} |
|||
/******************** |
/******************** |
||
* Explicitly delimit templates in text: |
* Explicitly delimit templates in text: |
||
Line 28: | Line 39: | ||
count++; |
count++; |
||
if (count == 10) |
if (count == 10) |
||
StopForError("exceeded loop limit for template escaping.", text); |
|||
}; |
}; |
||
Line 136: | Line 147: | ||
// exit if no header |
// exit if no header |
||
if (!Regex.IsMatch(header, "<start header2?>", RegexOptions.IgnoreCase)) { |
if (!Regex.IsMatch(header, "<start header2?>", RegexOptions.IgnoreCase)) { |
||
StopForError("header not detected.", text); |
|||
return header; |
return header; |
||
} |
} |
Revision as of 22:51, 4 May 2008
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using WikiFunctions;
using WikiFunctions.AWBSettings;
using WikiFunctions.Parse;
namespace HeaderConversion {
public class HeaderConversion : WikiFunctions.Plugin.IAWBPlugin {
/********************
* Pause and display error
*******************/
void StopForError(string message, string text) {
if (text != "")
message += "\n\n" + text;
MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
AWB.BotModeCheckbox.Checked = false;
}
/********************
* Explicitly delimit templates in text:
* {{foo|bar}} -> <start foo>foo<pipe>bar</end foo>
*******************/
string DelimitTemplates(string text) {
/* delimit parameters */
text = Regex.Replace(text, "\\|", "<pipe>");
text = Regex.Replace(text, "\\[\\[([^\\]]+)<pipe>", "[[$1|"); // fix wikilinks
/* delimit templates */
int count = 0;
while (Regex.IsMatch(text, "{{") && count < 10) {
text = Regex.Replace(text, "{{([\\s\\n\\r]*([^<{}]+?)[\\s\\n\\r]*(?:<pipe>[^{}]*)?)}}", "<start $2>$1<end $2>", RegexOptions.Singleline);
count++;
if (count == 10)
StopForError("exceeded loop limit for template escaping.", text);
};
/* exit */
return text;
}
/********************
* Reverse explicit template delimiting:
* <start foo>foo<pipe>bar</end foo> -> {{foo|bar}}
*******************/
string UndelimitTemplates(string text) {
text = Regex.Replace(text, "<start[^>]+>", "{{");
text = Regex.Replace(text, "<end[^>]+>", "}}");
text = Regex.Replace(text, "<pipe>", "|");
return text;
}
string UndelimitTemplates(string text, string regexSearch) {
MatchCollection matches = Regex.Matches(text, regexSearch);
foreach (Match match in matches) {
text = text.Replace(match.Value, UndelimitTemplates(match.Value));
}
return text;
}
/********************
* Given a delimited template, returns a hash table of its parameters
*******************/
Hashtable GetParameters(string text) {
Hashtable parameters = new Hashtable();
// normalize
text = Regex.Replace(text, "^[\\r\\n\\s]]*<(?:start|end)[^>]+>[\\r\\n\\s]]*", ""); // remove template delimiters
text = Regex.Replace(text, "[\\r\\n\\s]*<pipe>[\\r\\n\\s]*", "<pipe>"); // remove pipe whitespace
text = Regex.Replace(text, "<pipe>([a-z_]+?)[\\r\\n\\s]*=[\\r\\n\\s]*", "<pipe>$1=", RegexOptions.IgnoreCase); // remove parameter whitespace
// unescape nested templates
text = UndelimitTemplates(text, "<start[^>]+>.+?<end[^>]+>");
// no parameters
if (!Regex.IsMatch(text, "(?<=<pipe>)[a-z_]+=.*?(?=<pipe>|$)")) {
MessageBox.Show("No parameters detected:\n" + text);
return parameters;
}
// process each parameters
int unnamed = 0;
MatchCollection matches = Regex.Matches(text, "(?<=<pipe>)[a-z_]+=.*?(?=<pipe>|$)", RegexOptions.Singleline);
foreach(Match match in matches) {
// parse key/value
string name, value;
if (Regex.IsMatch(match.Value, "^[a-z_]+=")) {
name = Regex.Replace(match.Value, "=.*$", "", RegexOptions.Singleline);
value = Regex.Replace(match.Value, "^[a-z_]+=", "", RegexOptions.Singleline);
}
else {
unnamed++;
name = "" + unnamed;
value = match.Value;
}
// add to hash
if(parameters.Contains(name))
parameters[name] = value;
else
parameters.Add(name, value);
}
// exit
return parameters;
}
#region IAWBPlugin Members
internal WikiFunctions.Plugin.IAutoWikiBrowser AWB;
/********************
* initialize plugin
*******************/
public void Initialise(WikiFunctions.Plugin.IAutoWikiBrowser sender) {
if (sender == null)
throw new ArgumentNullException("sender");
else
AWB = sender;
}
/********************
* return plugin name
*******************/
string WikiFunctions.Plugin.IAWBPlugin.Name {
get { return "HeaderConversion"; }
}
string WikiFunctions.Plugin.IAWBPlugin.WikiName {
get { return "HeaderConversion"; }
}
/********************
* Process article text
*******************/
public string ProcessArticle(WikiFunctions.Plugin.IAutoWikiBrowser sender, WikiFunctions.Plugin.ProcessArticleEventArgs eventargs) {
// get text
string text = DelimitTemplates(eventargs.ArticleText);
string header = text;
// exit if no header
if (!Regex.IsMatch(header, "<start header2?>", RegexOptions.IgnoreCase)) {
StopForError("header not detected.", text);
return header;
}
// get header parameters
header = Regex.Replace(header, "<start header2?>|<end header2?>.+", "", RegexOptions.IgnoreCase | RegexOptions.Singleline);
Hashtable parameters = GetParameters(header);
// cleanup header parameters
if(parameters.Contains("notes"))
parameters["notes"] = Regex.Replace(parameters["notes"].ToString(), "[\\r\\n\\s]*$", "");
if (parameters.Contains("previous"))
parameters["previous"] = Regex.Replace(parameters["previous"].ToString(), "^(?:←|←)+\\s*|^<(?!=.+>)", "");
if (parameters.Contains("next"))
parameters["next"] = Regex.Replace(parameters["next"].ToString(), "\\s*(?:→|→)+\\s*|(?!<<.+)>[\\r\\n\\s]*$", "");
// generate header2 format
string newHeader = "{{header2"
+ "\r\n | title = " + ((parameters.Contains("title")) ? parameters["title"] : "")
+ "\r\n | author = " + ((parameters.Contains("override_author") && parameters["override_author"].ToString() != "") ? "|override_author=" + parameters["override_author"] : (parameters.Contains("author")) ? parameters["author"] : "");
if (parameters.Contains("translator")) {
newHeader += "\r\n | translator = " + parameters["translator"];
}
newHeader += "\r\n | section = " + ((parameters.Contains("section")) ? parameters["section"] : "")
+ "\r\n | previous = " + ((parameters.Contains("previous")) ? parameters["previous"] : "")
+ "\r\n | next = " + ((parameters.Contains("next")) ? parameters["next"] : "")
+ "\r\n | notes = " + ((parameters.Contains("notes")) ? parameters["notes"] : "")
+ "\r\n}}";
// insert into text
text = Regex.Replace(text, "<start header2?>.+?<end header2?>", newHeader, RegexOptions.IgnoreCase | RegexOptions.Singleline);
text = UndelimitTemplates(text);
return text;
}
/********************
* Not implemented
*******************/
public void LoadSettings(object[] prefs) {
return;
}
public object[] SaveSettings() {
return null;
}
public void Nudge(out bool Cancel) {
Cancel = false;
}
public void Nudged(int Nudges) {}
public void Reset() {}
#endregion
}
}