User:Pathosbot/TemplateEditor.cs: Difference between revisions
Jump to navigation
Jump to search
Content deleted Content added
Pathoschild (talk | contribs) m tweaks |
Pathoschild (talk | contribs) various tweaks, fix escaping of nested parameters with named parameters |
||
Line 31: | Line 31: | ||
/* delimit parameters */ |
/* delimit parameters */ |
||
text = Regex.Replace(text, "\\|", "<pipe>"); |
text = Regex.Replace(text, "\\|", "<pipe>"); |
||
text = Regex.Replace(text, "\\[\\[([^\\]]+)<pipe>", "[[$1|"); // |
text = Regex.Replace(text, "\\[\\[([^\\]]+)<pipe>", "[[$1|"); // unescape wikilinks |
||
/* delimit templates */ |
/* delimit templates */ |
||
Line 58: | Line 58: | ||
} |
} |
||
string UndelimitTemplates(string text, string regexSearch) { |
string UndelimitTemplates(string text, string regexSearch) { |
||
return UndelimitTemplates(text, regexSearch, RegexOptions.None); |
|||
} |
|||
string UndelimitTemplates(string text, string regexSearch, RegexOptions options) { |
|||
MatchCollection matches = Regex.Matches(text, regexSearch, options); |
|||
foreach (Match match in matches) { |
foreach (Match match in matches) { |
||
Line 73: | Line 76: | ||
Hashtable parameters = new Hashtable(); |
Hashtable parameters = new Hashtable(); |
||
⚫ | |||
⚫ | |||
// unescape main parameters |
|||
text = UndelimitTemplates(text, "<start([^>]+)>.*<end\\1>", RegexOptions.Singleline); |
|||
// normalize |
// normalize |
||
⚫ | |||
text = Regex.Replace(text, "[\\r\\n\\s]*<pipe>[\\r\\n\\s]*", "<pipe>"); // remove pipe whitespace |
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 |
text = Regex.Replace(text, "<pipe>([a-z_]+?)[\\r\\n\\s]*=[\\r\\n\\s]*", "<pipe>$1=", RegexOptions.IgnoreCase); // remove parameter whitespace |
||
text = Regex.Replace(text, "[\\r\\n\\s]*$", ""); // remove ending whitespace |
text = Regex.Replace(text, "[\\r\\n\\s]*$", ""); // remove ending whitespace |
||
// |
// exit if no parameters |
||
if (!Regex.IsMatch(text, "<pipe>")) { |
|||
⚫ | |||
⚫ | |||
if (!Regex.IsMatch(text, "(?<=<pipe>)[a-z_]+=.*?(?=<pipe>|$)")) { |
|||
⚫ | |||
return parameters; |
return parameters; |
||
} |
} |
||
// process each |
// process each parameter |
||
int unnamed = 0; |
int unnamed = 0; |
||
MatchCollection matches = Regex.Matches(text, "(?<=<pipe>) |
MatchCollection matches = Regex.Matches(text, "(?<=<pipe>)(.+?)(?=<pipe>|$)", RegexOptions.Singleline); |
||
foreach(Match match in matches) { |
foreach(Match match in matches) { |
||
// parse key/value |
// parse key/value |
||
Line 146: | Line 151: | ||
// exit if no header |
// exit if no header |
||
if (!Regex.IsMatch( |
if (!Regex.IsMatch(text, "<start header2?>", RegexOptions.IgnoreCase)) { |
||
StopForError("header not detected.", text); |
StopForError("header not detected.", text); |
||
return |
return text; |
||
} |
} |
||
// get header parameters |
// get header parameters |
||
header = Regex. |
header = Regex.Match(text, "<start header2?>.+?<end header2?>", RegexOptions.IgnoreCase | RegexOptions.Singleline).Value; |
||
Hashtable parameters = GetParameters(header); |
Hashtable parameters = GetParameters(header); |
||
Revision as of 22:39, 5 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|"); // unescape 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) {
return UndelimitTemplates(text, regexSearch, RegexOptions.None);
}
string UndelimitTemplates(string text, string regexSearch, RegexOptions options) {
MatchCollection matches = Regex.Matches(text, regexSearch, options);
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();
// remove main delimiters
text = Regex.Replace(text, "^[\\r\\n\\s]*<start([^>]+)>[\\r\\n\\s]*(.+?)[\\r\\n\\s]*<end\\1>[\\r\\n\\s]*$", "$2", RegexOptions.Singleline);
// unescape main parameters
text = UndelimitTemplates(text, "<start([^>]+)>.*<end\\1>", RegexOptions.Singleline);
// normalize
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
text = Regex.Replace(text, "[\\r\\n\\s]*$", ""); // remove ending whitespace
// exit if no parameters
if (!Regex.IsMatch(text, "<pipe>")) {
StopForError("no parameters detected.", text);
return parameters;
}
// process each parameter
int unnamed = 0;
MatchCollection matches = Regex.Matches(text, "(?<=<pipe>)(.+?)(?=<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) {
string text = DelimitTemplates(eventargs.ArticleText);
string header = text;
// exit if no header
if (!Regex.IsMatch(text, "<start header2?>", RegexOptions.IgnoreCase)) {
StopForError("header not detected.", text);
return text;
}
// get header parameters
header = Regex.Match(text, "<start header2?>.+?<end header2?>", RegexOptions.IgnoreCase | RegexOptions.Singleline).Value;
Hashtable parameters = GetParameters(header);
// cleanup header parameters
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*|(?!<<.+)>$", "");
// generate new header
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"] : "")
+ ((parameters.Contains("translator"))?"\r\n | translator = " + parameters["translator"]:"")
+ "\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
}
}