User:Lightmouse/javascript conversion/all dates to dmy

From Wikipedia, the free encyclopedia

//

        WikiFunctions.Parse.HideText ht = new WikiFunctions.Parse.HideText(true, false, true);

        public string ProcessArticle(string ArticleText, string ArticleTitle, int wikiNamespace, out string Summary, out bool Skip)
        {
            Skip = false;
            Summary = "";

ArticleText = ht.Hide(ArticleText);

//year: temporary change to protect band '4AD'. Undone below
ArticleText = Regex.Replace(ArticleText, @"\[\[4AD\]\]", "[[xx4ADxx]]");

// century
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[((?:first|second|third|fourth|fifth|sixth|seventh|eighth|ninth|tenth|eleventh|twelfth|thirteenth|fourteenth|fifteenth|sixteenth|seventeenth|eighteenth|nineteenth|twentieth|twenty(?: |-)first)(?: |-))century\]\]", "$1century");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[((?:first|second|third|fourth|fifth|sixth|seventh|eighth|ninth|tenth|eleventh|twelfth|thirteenth|fourteenth|fifteenth|sixteenth|seventeenth|eighteenth|nineteenth|twentieth|twenty(?: |-)first)(?: |-))century (AD|BC|CE|BCE)\]\]", "$1century");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(\d{1,2}(?:st|nd|rd|th)(?: |-))century\]\]", "$1century");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(\d{1,2}(?:st|nd|rd|th)(?: |-))centuries\]\]", "$1centuries");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,2}(?:st|nd|rd|th)(?: |-)century\|(\d{1,2}(?:st|nd|rd|th))\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,2}(?:st|nd|rd|th)(?: |-)century\|(\d{1,2}(?:st|nd|rd|th)(?: |-))century\]\]", "$1century");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,2}(?:st|nd|rd|th)(?: |-)century\|(\d{1,2}(?:st|nd|rd|th)(?: |-))centuries\]\]", "$1centuries");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(\d{1,2}(?:st|nd|rd|th)(?: |-))century (AD|BC|CE|BCE)\]\]", "$1century $2");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,2}(?:st|nd|rd|th)(?: |-)century\|(\d{1,2}(?:st|nd|rd|th)(?: |-))century (AD|BC|CE|BCE)\]\]", "$1century $2");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,2}(?:st|nd|rd|th)(?: |-)century\|(\d{1,2}(?:st|nd|rd|th)(?: |-))centuries (AD|BC|CE|BCE)\]\]", "$1centuries $2");

// decades and years
ArticleText = Regex.Replace(ArticleText, @"\[\[(\d{1,4})\'?s\]\]", "$1s");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(\d{1,4})\'?(s)? ?(AD|BC|CE|BCE)\]\]", "$1$2 $3");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,4}\'?s? ?(?:AD|BC|CE|BCE)\|(\d{1,4})\'?(s)?\]\]", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,4}\'?s? ?(?:AD|BC|CE|BCE)\|(\d{1,4})\'?(s)? ?(AD|BC|CE|BCE)\]\]", "$1$2 $3");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,4}\'?s?\|(\d{1,4})\'?(s)? ?(AD|BC|CE|BCE)\]\]", "$1$2 $3");
ArticleText = Regex.Replace(ArticleText, @"\[\[\d{1,4}\'?s?\|(\d{1,4})\'?(s)?\]\]", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d\d?(?:st|nd|rd|th) centur(?:y|ies)\|(\d{1,4})\'?(s)?\]\]", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\w{5,12} centur(?:y|ies)\|(\d{1,4})\'?(s)?\]\]", "$1$2");

// solitary day_numbers
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2}(?:st|nd|rd|th))\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,2} (?:January|February|March|April|May|June|July|August|September|October|November|December)\|(\d{1,2}(?:st|nd|rd|th))\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(\d{1,2}(?:st|nd|rd|th))\]\]", "$1");


//Month+day_number "March 7th" -> "March 7"
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(January|February|March|April|May|June|July|August|September|October|November|December) (\d?\d)(?:st|nd|rd|th)\]\]", "[[$1 $2]]");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[((?:January|February|March|April|May|June|July|August|September|October|November|December) \d?\d)\]\](?:st|nd|rd|th)", "[[$1]]");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(\d?\d)(?:st|nd|rd|th) (January|February|March|April|May|June|July|August|September|October|November|December)\]\]", "[[$1 $2]]");

//Month + year
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[((?:January|February|March|April|May|June|July|August|September|October|November|December) \d{3,4})\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(\d{3,4} (?:January|February|March|April|May|June|July|August|September|October|November|December))\]\]", "$1");

//delink autoformattable dates
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)) ([0-3][\d]|[\d])(?:st|nd|rd|th|)\]\](?:st|nd|rd|th|),? \[\[(\d{1,4})\]\]", "$2 $1 $3");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)) ([0-3][\d]|[\d])(?:st|nd|rd|th|)\]\](?:st|nd|rd|th|),? \[\[(\d{1,4}) in [^\]]{1,32}\]\]", "$2 $1 $3");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)) ([0-3][\d]|[\d])(?:st|nd|rd|th|)\]\](?:st|nd|rd|th|),? {{(?:avyear|by|ly|scy|sdy)\|(\d{1,4})}}", "$2 $1 $3");

ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[([0-3][\d]|[\d])(?:st|nd|rd|th|) (Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember))\]\],? \[\[(\d{1,4})\]\]", "$1 $2 $3");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[([0-3][\d]|[\d])(?:st|nd|rd|th|) (Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember))\]\],? \[\[(\d{1,4}) in [^\]]{1,32}\]\]", "$1 $2 $3");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[([0-3][\d]|[\d])(?:st|nd|rd|th|) (Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember))\]\],? {{(?:avyear|by|ly|scy|sdy)\|(\d{1,4})}}", "$1 $2 $3");

ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)) ([0-3][\d]|[\d])(?:st|nd|rd|th|)\]\](?:st|nd|rd|th|)", "$2 $1");

ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[([0-3][\d]|[\d])(?:st|nd|rd|th|) (Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember))\]\]", "$1 $2");

//remove piped years
//protect some
ArticleText = Regex.Replace(ArticleText, @"(?i)(\[\[\d{1,4} in) ((?:baseball|film|literature|comics|ireland)\|\d{1,4}\]\])",  "$1xx$2");
//now removed the piped years
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,4} in [^\|]+\|(\d{1,4})\]\]",  "[[$1]]");
//unprotect baseball and film
ArticleText = Regex.Replace(ArticleText, @"(?i)(\[\[\d{1,4} in)xx((?:baseball|film|literature|comics|ireland)\|\d{1,4}\]\])",  "$1 $2");


//'present'
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Present \(time\)\|(Present)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Present)\]\]", "$1");

//Season
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(spring \(season\)|summer|winter|autumn)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[spring \(season\)\|(spring)\]\]", "$1");

//Identify surprise or 'Easter egg' diversions linking months to year articles.
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,4}#[^\|]+\|(January|February|March|April|May|June|July|August|September|October|November|December)\]\]", "$1");

//'As of year'
ArticleText = Regex.Replace(ArticleText, @"(?i)(As of )\[\[(\d{1,4})\]\]", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(As of \d{1,4})\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(as of \d{1,4})\]\]", "$1");

// months
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(January|February|March|April|May|June|July|August|September|October|November|December)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December)\|(January|February|March|April|May|June|July|August|September|October|November|December)\]\]", "$1");
//Treat 'Sept' (i.e. month abbreviation) differently from 'sept' (i.e. family)
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Sept)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[January\|(Jan)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[February\|(Feb)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[March\|(Mar)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[April\|(Apr)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[May\|(May)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[June\|(Jun)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[July\|(Jul)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[August\|(Aug)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[September\|(Sep)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[October\|(Oct)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[November\|(Nov)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[December\|(Dec)\]\]", "$1");

//month piped to number
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December)\|(\d{1,4})\]\]", "$1");

//month piped to number
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December)\|(\d{1,4})\]\]", "$1");

//Month+day_number piped into number. Preferences do not work. They don't work in sequence because digits in the two dates must be adjacent
ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[((?:January|February|March|April|May|June|July|August|September|October|November|December) \d?\d)\]\]( ?\-? ?)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2})\]\]", "$1$2$3$4");
//same again but with ndash or mdash instead of hyphen
ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[((?:January|February|March|April|May|June|July|August|September|October|November|December) \d?\d)\]\]( ?&[nm]dash; ?)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2})\]\]", "$1$2$3$4");
//same again but with slash instead of hyphen
ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[((?:January|February|March|April|May|June|July|August|September|October|November|December) \d?\d)\]\](\/)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2})\]\]", "$1$2$3$4");

ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[((?:January|February|March|April|May|June|July|August|September|October|November|December) \d?\d)\]\]( ?\-? ?)\[\[(\d{1,2})\]\]", "$1$2$3$4");
//same again but with ndash instead of hyphen
ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[((?:January|February|March|April|May|June|July|August|September|October|November|December) \d?\d)\]\]( ?&[nm]dash; ?)\[\[(\d{1,2})\]\]", "$1$2$3$4");
//same again but with slash instead of hyphen
ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[((?:January|February|March|April|May|June|July|August|September|October|November|December) \d?\d)\]\](\/)\[\[(\d{1,2})\]\]", "$1$2$3$4");

ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[(\d?\d) (?:January|February|March|April|May|June|July|August|September|October|November|December)\]\]( ?\-? ?)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2})\]\]", "$1$2$3$4");
//same again but with ndash instead of hyphen
ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[(\d?\d) (?:January|February|March|April|May|June|July|August|September|October|November|December)\]\]( ?&[nm]dash; ?)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2})\]\]", "$1$2$3$4");
//same again but with slash instead of hyphen
ArticleText = Regex.Replace(ArticleText, @"(?i)([^\[]{4})\[\[(\d?\d) (?:January|February|March|April|May|June|July|August|September|October|November|December)\]\](\/)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2})\]\]", "$1$2$3$4");

ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2})\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,2} (?:January|February|March|April|May|June|July|August|September|October|November|December)\|(\d{1,2})\]\]", "$1");

ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2})\]\]", "$1");
//month+day piped into month+day or vice versa
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,2} (?:January|February|March|April|May|June|July|August|September|October|November|December)\|((?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2})\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}\|(\d{1,2} (?:January|February|March|April|May|June|July|August|September|October|November|December))\]\]", "$1");


// days of the week in full. Optional plurals
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Mondays?|Tuesdays?|Wednesdays?|Thursdays?|Fridays?|Saturdays?|Sundays?)\]\]", "$1");
// days of the week abbreviated. Leave out 'Sun' as potentially valid link to the Sun. Leave out 'SAT' in upper case as potential link to 'Scholastic achievement/aptitude test'.
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(Mon|Tue|Tues|Wed|Thu|Thur|Thurs|Fri)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"\[\[(Sat)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Mondays?\|(Mondays?|Mon)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Tuesdays?\|(Tuesdays?|Tues?)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Wednesdays?\|(Wednesdays?|Wed)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Thursdays?\|(Thursdays?|Thur?)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Fridays?\|(Fridays?|Fri)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Saturdays?\|(Saturdays?|Sat)\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Sundays?\|(Sundays?|Sun)\]\]", "$1");

//4 digit years piped into 2
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[\d{1,4}\|(\d{1,2})\]\]", "$1");

//year: temporary change to protect accessyear. Undone below at #1
ArticleText = Regex.Replace(ArticleText, @"(?i)(accessyear ?= ?)\[\[(\d{1,4})\]\]", "$1xx$2xx");

//mdy -> dmy in unlinked dates
ArticleText = Regex.Replace(ArticleText, @"(?i)(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)) (\d\d?), (\d{1,4})",  "$2 $1 $3");
ArticleText = Regex.Replace(ArticleText, @"(?i)(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)) (\d\d?)([^\d\w])",  "$2 $1$3");


//year: now remove unprotected linked years
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[(\d{1,4})\]\]", "$1");
//year: #1. Undo temporary change to protect accessyear and date preference dates
ArticleText = Regex.Replace(ArticleText, @"(?i)xx(\d{1,4})xx", "[[$1]]");

//year: unprotect band '4AD'.
ArticleText = Regex.Replace(ArticleText, @"\[\[xx4ADxx\]\]", "[[4AD]]");


//change deprecated birth and death templates
ArticleText = Regex.Replace(ArticleText, @"(?i)({{(?:Birth|Death|release|Start date|End date)[^}]*)\|mf=ye?s?", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)({{(?:Birth|Death|release|Start date|End date)[^|]*\|)", "$1df=yes|");
ArticleText = Regex.Replace(ArticleText, @"(?i)({{(?:Birth|Death|release|Start date|End date)[^|]*\|)df=ye?s?\|([^}]*df=ye?s?)", "$1$2");

//change deprecated dts2 template
ArticleText = Regex.Replace(ArticleText, @"(?i){{dts2\|(.*?)\|(.*?)\|(.*?)}}", "{{dts|link=off|format=dmy|$3|$2|$1}}");

//fix dts template
ArticleText = Regex.Replace(ArticleText, @"(?i)({{dts\|)", "$1link=off|format=dmy|");
ArticleText = Regex.Replace(ArticleText, @"(?i)({{dts\|)link=off\|([^}]*link=off)", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)({{dts\|)format=dmy\|([^}]*format=dmy)", "$1$2");

//remove flagicons from birth and death
ArticleText = Regex.Replace(ArticleText, @"(?i)((?:birth|birth_?place|death|death_?place|burial) ?= ?)\{\{flagicon\|[^\}]+\}\}", "$1");

//delink common units
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|[\d\.]*\|(?:mm|mm2|mm3|cm|cm2|cm3|m|m2|m3|km|km2|km3|g|kg|mL|L|in|in2|in3|ft|sqft|ft2|cuft|ft3|yd|sqyd|yd2|cuyd|yd3|mi|sqmi|mi2|cumi|mi3|acre|nmi|lb|USgal)\|[^\}]*)\|lk=(?:on|in|out)", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|[^\}]*)\|lk=off", "$1");

//aviation specifications: protect "main=" and "alt=" - undone below
ArticleText = Regex.Replace(ArticleText, @"(?i)((?:main|alt) ?= ?)(\d)", "$1xx$2");

//convert excessive zeros for oil
ArticleText = Regex.Replace(ArticleText, @"(?i)({{convert\|\d+)000000000000\|oilbbl\|", "$1|Toilbbl|");
ArticleText = Regex.Replace(ArticleText, @"(?i)({{convert\|\d+)000000000\|oilbbl\|", "$1|Goilbbl|");
ArticleText = Regex.Replace(ArticleText, @"(?i)({{convert\|\d+)000000\|oilbbl\|", "$1|Moilbbl|");

//embed 'per day' into pre-existing conversions
ArticleText = Regex.Replace(ArticleText, @"(?i)(oilbbl)\|(k?m3)(}})(?: |-| |)(?:per|a)(?: |-| |)day", "$1/d|$2/d$3");
ArticleText = Regex.Replace(ArticleText, @"(?i)(oilbbl)\|(k?m3)(\|abbr=on}})(?: |-| |)(?:per|a)(?: |-| |)day", "$1/d|$2/d$3");
ArticleText = Regex.Replace(ArticleText, @"(?i)(oilbbl)\|(k?m3)(\|sing=on}})(?: |-| |)(?:per|a)(?: |-| |)day", "$1/d|$2/d$3");
ArticleText = Regex.Replace(ArticleText, @"(?i)(oilbbl)\|(k?m3)(}})/d", "$1/d|$2/d");

//foot - remove period when followed by parentheses
ArticleText = Regex.Replace(ArticleText, @"(\d ft)\.( \(\d)", "$1$2");

// knot
ArticleText = Regex.Replace(ArticleText, @"(?i)\[knot \(unit\)\|", "[knot (speed)|");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[kts\]\]", "[[knot (speed)|knots]]");
ArticleText = Regex.Replace(ArticleText, @"(?i)\|kts\]\]", "|knots]]");

//convert knot template to kn to match km
ArticleText = Regex.Replace(ArticleText, @"(?i)({{convert\|[\d\.]+)\|knot\|", "$1|kn|");

//nautical mile - rename "miles" as "nautical miles" when followed by knots or conversion code
ArticleText = Regex.Replace(ArticleText, @"(?i)(\d)(?: |-| |)miles (?:at|@) ([\d\.]{1,9}(?: |-| |)knots|{{convert)", "$1 nautical miles at $2");
ArticleText = Regex.Replace(ArticleText, @"(?i)(\d)( |-| )(?:mi|nm|nmi) (?:at|@) ([\d\.]{1,9}(?: |-| |)knots|{{convert)", "$1$2nmi at $3");


//remove commas from numerical values in convert template
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|\d+),(\d)", "$1$2");


//aviation specifications: unprotect "main=" and "alt="
ArticleText = Regex.Replace(ArticleText, @"(?i)((?:main|alt) ?= ?)xx(\d)", "$1$2");

//replace other templates with convert template
ArticleText = Regex.Replace(ArticleText, @"(?i){{mi to km\|(\d{1,9})}}", "{{convert|$1|mi|km}}");
ArticleText = Regex.Replace(ArticleText, @"(?i){{mi to km\|(\d{1,9})\|round[^\}]{1,5}}}", "{{convert|$1|mi|km}}");
ArticleText = Regex.Replace(ArticleText, @"(?i){{mi2 to km2\|(\d{1,9})}}", "{{convert|$1|mi|km}}");
ArticleText = Regex.Replace(ArticleText, @"(?i){{mi2 to km2\|(\d{1,9})\|round[^\}]{1,5}}}", "{{convert|$1|mi|km}}");

//remove commas from numerical values in convert template
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|\d+),(\d)", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|\d+),(\d)", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|\d+),(\d)", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|\d+),(\d)", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|\d+),(\d)", "$1$2");

//remove leading zeros from convert template
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|)0(\d)", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|)0(\d)", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"(?i)({convert\|)0(\d)", "$1$2");

//Remove surprise or "Easter egg" diversions linking unit name to orders of magnitude articles
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[1 ?_?E ?[\-\+]?\d{1,2} ?..?\|([^\]]{1,50})\]\]", "$1");
ArticleText = Regex.Replace(ArticleText, @"(?i)\[\[Orders of magnitude \([^\)]+\)\|([^\]]{1,50})\]\]", "$1");

//convert squares and cubes
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqmm\|", "$1|mm2|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqcm\|", "$1|cm2|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqm\|", "$1|m2|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqkm\|", "$1|km2|");

ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqmm}", "$1|mm2}");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqcm}", "$1|cm2}");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqm}", "$1|m2}");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqkm}", "$1|km2}");

ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|cumm\|", "$1|mm3|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|cucm\|", "$1|cm3|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|cum\|", "$1|m3|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|cukm\|", "$1|km3|");

ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|cumm}", "$1|mm3}");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|cucm}", "$1|cm3}");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|cum}", "$1|m3}");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|cukm}", "$1|km3}");

ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqmi sqkm}", "$1|sqmi km2}");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|sqmi sqkm\|", "$1|sqmi km2|");

ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|(in|ft|yd|mi)2\|", "$1|sq$2|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|(in|ft|yd|mi)2}", "$1|sq$2}");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|(in|ft|yd|mi)3\|", "$1|cu$2|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|(in|ft|yd|mi)3}", "$1|cu$2}");

ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|mi2 (?:sqkm|km2)\|", "$1|sqmi km2|");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|[^}]+)\|mi2 (?:sqkm|km2)}", "$1|sqmi km2}");


//delink common units of measurement in convert template
ArticleText = Regex.Replace(ArticleText, @"({{convert\|\d+\|)(mm|mm2|mm3|cm|cm2|cm3|m|m2|m3|km|km2|km3|in|ft|sqft|mi|sqmi)\|lk=on", "$1$2");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|\d+\|)(mm|mm2|mm3|cm|cm2|cm3|m|m2|m3|km|km2|km3|in|ft|sqft|mi|sqmi)(\|\d)\|lk=on", "$1$2$3");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|\d+\|)(mm|mm2|mm3|cm|cm2|cm3|m|m2|m3|km|km2|km3|in|ft|sqft|mi|sqmi)\|(mm|mm2|mm3|cm|cm2|cm3|m|m2|m3|km|km2|km3|in|ft|sqft|mi|sqmi)\|lk=on", "$1$2|$3");
ArticleText = Regex.Replace(ArticleText, @"({{convert\|\d+\|)(mm|mm2|mm3|cm|cm2|cm3|m|m2|m3|km|km2|km3|in|ft|sqft|mi|sqmi)\|(mm|mm2|mm3|cm|cm2|cm3|m|m2|m3|km|km2|km3|in|ft|sqft|mi|sqmi)(\|\d)\|lk=on", "$1$2|$3$4");

            return ht.AddBack(ArticleText);

            return ArticleText;
        }
//