User:Proteins/mosheadcheck.js

//

// Checks whether the Manual of Style is satisfied for article titles and section headings

//

// To use this script, add "importScript('User:Proteins/mosheadcheck.js');" to your monobook.js subpage

// under your user page, as you can see at User:Proteins/monobook.js

// Black list of words that probably shouldn't appear at the start of a section heading

var forbidden_first_words_in_section_headings = [

"a", "an", "the", "in", "on", "concerning", "about", "through", "against", "for", "with", "without", "around", "from", "out", "because", "since", "while", "during", "throughout", "my", "your", "his", "her", "its", "our", "their", "I", "me", "you", "he", "him", "she", "it", "we", "us", "they", "them"

];

//****************************************************

// Check that the section headings conform to MOS:HEAD

//****************************************************

function checkSectionHeadings() {

var alert_string = "";

var num_errors = 0;

var error_index = 0;

var error_string = "";

var max_num_errors_per_alert = 10;

var error_string_list = new Array();

var body_content;

var article_title_node;

var article_title = "";

var anchors;

var temp_anchor;

var num_anchors = 0;

var anchor_index = 0;

var num_H2_anchors = 0;

var anchor_string_index = 0;

var proper_anchor_level = 0;

var proper_anchor_string = "";

var parent_node;

var sibling_node;

var next_sibling_node;

var child_nodes;

var num_child_nodes;

var span_nodes;

var temp_span_node;

var num_span_nodes = 0;

var span_node_index = 0;

var anchor_level = 0;

var prev_anchor_level = 0;

var section_name = "";

var temp_anchor_name = "";

var num_section_names = 0;

var section_name_index = 0;

var apparent_section_name = "";

var section_name_list = new Array();

var words;

var temp_word;

var first_word;

var num_words = 0;

var word_index = 0;

var forbidden_word;

var num_forbidden_words = forbidden_first_words_in_section_headings.length;

var num_See_also_sections = 0;

var num_Notes_sections = 0;

var num_References_sections = 0;

var num_Bibliography_sections = 0;

var num_Further_reading_sections = 0;

var num_External_links_sections = 0;

// Get the bodyContent node

body_content = document.getElementById('bodyContent');

if (!body_content) {

error_string = "ERROR: There is no bodyContent node in this article.";

window.alert(error_string);

return;

}

// Determine the article title and check for MoS violations

num_errors = 0;

error_string = "";

article_title_node = body_content.previousSibling;

while ((article_title_node) && (article_title_node.nodeType != 1)) {

article_title_node = article_title_node.previousSibling;

}

if (article_title_node) {

if ((article_title_node.nodeName == "H1") && (article_title_node.className.match(/firstHeading/))) {

article_title = article_title_node.innerHTML;

article_title = article_title.replace(/]*>.*<\/span>/, "");

if (!article_title.match(/^[A-Z0-9]/)) {

num_errors++;

error_string = "ERROR " + num_errors + ": Article title \"" + article_title + "\" does not begin with a capital letter or a digit.\n";

error_string += "\tPlease capitalize the first word of the title, but no other words.\n";

error_string_list.push(error_string);

article_title_node.style.cssText = "background-color:red";

}

// Check for punctuation generally

if (article_title.match(/[^A-Za-z0-9–,:'\(\)\s\-]/g)) {

num_errors++;

error_string = "ERROR " + num_errors + ": Article title \"" + article_title + "\" has punctuation or non-English characters.\n";

error_string_list.push(error_string);

article_title_node.style.cssText = "background-color:red";

}

if ((article_title.match(/\s\-/g)) || (article_title.match(/\-\s/g))) {

num_errors++;

error_string = "ERROR " + num_errors + ": Article title \"" + article_title + "\" has a spaced hyphen.\n";

error_string += "\tPlease use hyphens only for compound nouns and adjectives in article titles.\n";

error_string_list.push(error_string);

article_title_node.style.cssText = "background-color:red";

}

if ((article_title.match(/\s–/g)) || (article_title.match(/–\s/g))) {

num_errors++;

error_string = "ERROR " + num_errors + ": Article title \"" + article_title + "\" has a spaced en-dash.\n";

error_string += "\tPlease use en-dashes only for compound nouns and adjectives in article titles.\n";

error_string_list.push(error_string);

article_title_node.style.cssText = "background-color:red";

}

words = article_title.split(' ');

if (words) {

num_words = words.length;

if (num_words > 0) {

if (num_words > 9) {

num_errors++;

error_string = "ERROR " + num_errors + ": Article title \"" + article_title + "\" has more than nine words (" + num_words + " words).\n";

error_string_list.push(error_string);

article_title_node.style.cssText = "background-color:red";

}

for (word_index=0; word_index

if ((word_index > 0) && (words[word_index].match(/^[A-Z]/)) && (!words[word_index-1].match(/:$/))) {

num_errors++;

error_string = "ERROR " + num_errors + ": Word \"" + words[word_index] + "\" in article title \"" + article_title + "\" is capitalized.\n";

error_string += "\tPlease capitalize only the first word of an article title, unless a proper name.\n";

error_string_list.push(error_string);

article_title_node.style.cssText = "background-color:red";

}

temp_word = words[word_index].substr(1);

if (!temp_word) { continue; }

if (temp_word.match(/[A-Z]/)) {

num_errors++;

error_string = "ERROR " + num_errors + ": Word \"" + words[word_index] + "\" in article title \"" + article_title + "\" has internal capital letters.\n";

error_string_list.push(error_string);

article_title_node.style.cssText = "background-color:red";

}

} // closes loop checking the individual words

first_word = words[0].toLowerCase();

for (word_index=0; word_index

forbidden_word = forbidden_first_words_in_section_headings[word_index];

if (first_word == forbidden_word) {

num_errors++;

error_string = "ERROR " + num_errors + ": Article title \"" + article_title + "\" begins with a forbidden word \"" + forbidden_word + "\".\n";

switch (forbidden_word) {

case "a":

case "an":

error_string += "\tPlease do not start an article title with an indefinite article such as \"" + forbidden_word + "\".\n";

break;

case "the":

error_string += "\tPlease do not start an article title with an definite article such as \"" + forbidden_word + "\".\n";

break;

case "in":

case "on":

case "for":

case "out":

case "with":

case "from":

case "about":

case "around":

case "through":

case "without":

case "against":

error_string += "\tPlease do not start an article title with a preposition such as \"" + forbidden_word + "\".\n";

break;

case "concerning":

error_string += "\tPlease do not start an article title with a verb participle such as \"" + forbidden_word + "\".\n";

break;

case "since":

case "while":

case "during":

case "because":

case "throughout":

error_string += "\tPlease do not start an article title with a conjunction such as \"" + forbidden_word + "\".\n";

break;

case "my":

case "your":

case "yours":

case "his":

case "her":

case "hers":

case "its":

case "our":

case "their":

case "I":

case "me":

case "you":

case "he":

case "him":

case "she":

case "it":

case "we":

case "us":

case "they":

case "them":

error_string += "\tPlease do not start an article title with a pronoun such as \"" + forbidden_word + "\".\n";

break;

} // closes switch on the forbidden word

error_string_list.push(error_string);

article_title_node.style.cssText = "background-color:red";

break; // break out of loop over forbidden words

}

}

} // closes check for positive number of words in article title

} // closes check that words exist in the article title

} // closes check for proper article title

} // closes check for article title node

section_name_list.push(article_title);

// Get the document anchors

anchors = document.anchors;

if (!anchors) {

window.alert("This document has no anchors.\n\n");

return;

}

num_anchors = anchors.length;

if (num_anchors<1) {

window.alert("This document has zero anchors.\n\n");

return;

}

// Loop over the anchors

num_See_also_sections = 0;

num_Notes_sections = 0;

num_References_sections = 0;

num_Bibliography_sections = 0;

num_Further_reading_sections = 0;

num_External_links_sections = 0;

num_H2_anchors = 0;

num_section_headings = 0;

section_name = "lead section";

prev_anchor_level = 1; //begin at the H1 heading

for (anchor_index=1; anchor_index

temp_anchor = anchors[anchor_index];

if (!temp_anchor) { continue; }

parent_node = temp_anchor.parentNode;

if (!parent_node) { continue; }

sibling_node = parent_node.nextSibling;

if (!sibling_node) { continue; }

temp_anchor_name = temp_anchor.name;

// Check headings for jumps upwards in heading level

anchor_level = 0;

if (sibling_node.nodeName == "H1") {

num_errors++;

if (num_H2_anchors == 0) {

error_string = "ERROR " + num_errors + ": Illegal H1 heading \"" + temp_anchor_name.replace(/(_+)/ig, " ") + "\" in the lead section\n";

} else {

error_string = "ERROR " + num_errors + ": Illegal H1 heading \"" + temp_anchor_name.replace(/(_+)/ig, " ") + "\" in section \"" + section_name.replace(/(_+)/ig, " ") + "\"\n";

}

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

} else if (sibling_node.nodeName == "H2") {

anchor_level = 2;

} else if (sibling_node.nodeName == "H3") {

anchor_level = 3;

} else if (sibling_node.nodeName == "H4") {

anchor_level = 4;

} else if (sibling_node.nodeName == "H5") {

anchor_level = 5;

} else {

next_sibling_node = sibling_node.nextSibling;

if (!next_sibling_node) { continue; }

// Check headings for jumps upwards in heading level

if (next_sibling_node.nodeName == "H1") {

num_errors++;

if (num_H2_anchors == 0) {

error_string = "ERROR " + num_errors + ": Illegal H1 heading \"" + temp_anchor_name.replace(/(_+)/ig, " ") + "\" in the lead section\n";

} else {

error_string = "ERROR " + num_errors + ": Illegal H1 heading \"" + temp_anchor_name.replace(/(_+)/ig, " ") + "\" in section \"" + section_name.replace(/(_+)/ig, " ") + "\"\n";

}

error_string_list.push(error_string);

next_sibling_node.style.cssText = "background-color:red";

} else if (next_sibling_node.nodeName == "H2") {

anchor_level = 2;

} else if (next_sibling_node.nodeName == "H3") {

anchor_level = 3;

} else if (next_sibling_node.nodeName == "H4") {

anchor_level = 4;

} else if (next_sibling_node.nodeName == "H5") {

anchor_level = 5;

}

sibling_node = next_sibling_node;

} // closes assignment of the anchor level, if any

if (((anchor_level - prev_anchor_level) > 1) && (prev_anchor_level != 0)) {

proper_anchor_level = prev_anchor_level - 0 + 1;

proper_anchor_string = "";

for (anchor_string_index=0; anchor_string_index

proper_anchor_string += "=";

}

if (num_H2_anchors == 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + prev_anchor_level + " to H" + anchor_level + " jump in the lead section\n";

error_string += "\tThe correct subheading would be H" + proper_anchor_level + ", which is \"" + proper_anchor_string + temp_anchor_name.replace(/(_+)/ig, " ") + proper_anchor_string + "\" in wiki-markup.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

} else {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + prev_anchor_level + " to H" + anchor_level + " jump in section \"" + section_name.replace(/(_+)/ig, " ") + "\"\n";

error_string += "\tThe correct subheading would be H" + proper_anchor_level + ", which is \"" + proper_anchor_string + temp_anchor_name.replace(/(_+)/ig, " ") + proper_anchor_string + "\" in wiki-markup.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

}

// Check section names

if (anchor_level > 0) {

section_name = temp_anchor.name;

prev_anchor_level = anchor_level;

// Compare the heading section name with the anchor section name

apparent_section_name = section_name;

span_nodes = sibling_node.getElementsByTagName("SPAN");

if (span_nodes) {

num_span_nodes = span_nodes.length;

if (num_span_nodes > 0) {

for (span_node_index=0; span_node_index

temp_span_node = span_nodes[span_node_index];

if (!temp_span_node) { continue; }

if (temp_span_node.className == "mw-headline") {

apparent_section_name = temp_span_node.innerHTML;

apparent_section_name = apparent_section_name.replace(/<[^>]+>/ig, "");

// Check for links in section name

child_nodes = temp_span_node.getElementsByTagName("A");

if (child_nodes) {

num_child_nodes = child_nodes.length;

if (num_child_nodes > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" has a forbidden hyperlink.\n";

error_string += "\tSection headings should never have hyperlinks.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} // closes check for child nodes in span node

// Check for boldface type in section name

child_nodes = temp_span_node.getElementsByTagName("B");

if (child_nodes) {

num_child_nodes = child_nodes.length;

if (num_child_nodes > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" has boldface formatting.\n";

error_string += "\tIt is never appropriate to use boldface type in a section heading; see MOS:BOLD.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} // closes check for child nodes in span node

// Check for italics in section name

child_nodes = temp_span_node.getElementsByTagName("I");

if (child_nodes) {

num_child_nodes = child_nodes.length;

if (num_child_nodes > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" has italics formatting.\n";

error_string += "\tPlease use italics only for titles of longer works and similar uses; see MOS:ITALICS.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} // closes check for child nodes in span node

}

} // closes loop over span nodes

}

}

if (apparent_section_name != section_name.replace(/(_+)/ig, " ")) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" does not agree with its apparent section heading \"" + apparent_section_name + "\".\n";

error_string += "\tThis may indicate a bad character or a repeated section heading.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

// Check for repeats with earlier section headings including article title (section 0)

for (section_name_index=0; section_name_index<=num_section_names; section_name_index++) {

if (section_name.indexOf(section_name_list[section_name_index]) == 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" repeats an earlier section heading \"" + section_name_list[section_name_index] + "\" (index " + section_name_index + ").\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} // closes loop over prior section names

num_section_names++;

section_name_list.push(apparent_section_name);

// Check for final colons and other punctuation

if (section_name.match(/:$/)) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" should not end in a colon.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

// Check for punctuation generally

if (apparent_section_name.match(/[^A-Za-z0-9,':–\(\)\s\-]/g)) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + apparent_section_name + "\" has punctuation or non-English characters.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if ((apparent_section_name.match(/\s\-/g)) || (apparent_section_name.match(/\-\s/g))) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + apparent_section_name + "\" has a spaced hyphen.\n";

error_string += "\tPlease use hyphens only for compound nouns and adjectives in section headings.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if ((apparent_section_name.match(/\s–/g)) || (apparent_section_name.match(/–\s/g))) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + apparent_section_name + "\" has a spaced en-dash.\n";

error_string += "\tPlease use en-dashes only for compound nouns and adjectives in section headings.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

// Check for initial capital letter

if (!section_name.match(/^[A-Z0-9]/)) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" does not begin with a capital letter or a digit.\n";

error_string += "\tPlease capitalize the first word of the heading, but no other words.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

words = apparent_section_name.split(' ');

if (words) {

num_words = words.length;

if (num_words > 0) {

if (num_words > 9) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" has more than nine words (" + num_words + " words).\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

for (word_index=0; word_index

if ((word_index > 0) && (words[word_index].match(/^[A-Z]/)) && (!words[word_index-1].match(/:$/))) {

num_errors++;

error_string = "ERROR " + num_errors + ": Word \"" + words[word_index] + "\" in H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" is capitalized.\n";

error_string += "\tPlease capitalize only the first word of a section heading, unless a proper name.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

temp_word = words[word_index].substr(1);

if (!temp_word) { continue; }

if (temp_word.match(/[A-Z]/)) {

num_errors++;

error_string = "ERROR " + num_errors + ": Word \"" + words[word_index] + "\" in H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" has internal capital letters.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} // closes loop checking the individual words

first_word = words[0].toLowerCase();

for (word_index=0; word_index

forbidden_word = forbidden_first_words_in_section_headings[word_index];

if (first_word == forbidden_word) {

num_errors++;

error_string = "ERROR " + num_errors + ": H" + anchor_level + " section \"" + section_name.replace(/(_+)/ig, " ") + "\" begins with a forbidden word \"" + forbidden_word + "\".\n";

switch (forbidden_word) {

case "a":

case "an":

error_string += "\tPlease do not start a section heading with an indefinite article such as \"" + forbidden_word + "\".\n";

break;

case "the":

error_string += "\tPlease do not start a section heading with an definite article such as \"" + forbidden_word + "\".\n";

break;

case "in":

case "on":

case "for":

case "out":

case "with":

case "from":

case "about":

case "around":

case "through":

case "without":

case "against":

error_string += "\tPlease do not start a section heading with a preposition such as \"" + forbidden_word + "\".\n";

break;

case "concerning":

error_string += "\tPlease do not start a section heading with a verb participle such as \"" + forbidden_word + "\".\n";

break;

case "since":

case "while":

case "during":

case "because":

case "throughout":

error_string += "\tPlease do not start a section heading with a conjunction such as \"" + forbidden_word + "\".\n";

break;

case "my":

case "your":

case "yours":

case "his":

case "her":

case "hers":

case "its":

case "our":

case "their":

case "I":

case "me":

case "you":

case "he":

case "him":

case "she":

case "it":

case "we":

case "us":

case "they":

case "them":

error_string += "\tPlease do not start a section heading with a pronoun such as \"" + forbidden_word + "\".\n";

break;

} // closes switch on the forbidden word

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

break; // break out of loop over forbidden words

}

}

} // closes check on num_words in section heading

} // closes check on num_words in section heading

} // closes check for section anchor

//Check major section headings for closing sections

if (anchor_level == 2) {

num_H2_anchors++;

if (section_name.match(/See_also/ig)) {

num_See_also_sections++;

if (num_See_also_sections > 1) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section \"" + section_name.replace(/(_+)/ig, " ") + "\" makes " + num_See_also_sections + " \"See also\" sections.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (!section_name.match(/^See_also$/ig)) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" does not match correct form \"See also\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Notes_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"Notes\" (or \"Footnotes\") section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_References_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"References\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Bibliography_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"Bibliography\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Further_reading_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"Further reading\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_External_links_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"External links\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} else if ((section_name.match(/Note/ig)) || (section_name.match(/Footnote/ig))) {

num_Notes_sections++;

if (num_Notes_sections > 1) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section \"" + section_name.replace(/(_+)/ig, " ") + "\" makes " + num_Notes_sections + " \"Notes\" (\"Footnotes\") sections.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if ((!section_name.match(/^Note$/i)) && (!section_name.match(/^Notes$/i)) && (!section_name.match(/^Footnote$/i)) && (!section_name.match(/^Footnotes$/i)) && (!section_name.match(/^Notes_and_references$/i)) && (!section_name.match(/^Footnotes_and_references$/i)) && (!section_name.match(/^References_and_notes$/i)) && (!section_name.match(/^References_and_footnotes$/i))) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" does not match correct forms \"Note\", \"Notes\", \"Footnote\", \"Footnotes\", \"Notes and references\" , \"Footnotes and references\", \"References and notes\" or \"References and footnotes\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_References_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"References\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Bibliography_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"Bibliography\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Further_reading_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"Further reading\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_External_links_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"External links\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} else if (section_name.match(/Reference/ig)) {

num_References_sections++;

if (num_References_sections > 1) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section \"" + section_name.replace(/(_+)/ig, " ") + "\" makes " + num_References_sections + " \"References\" sections.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if ((!section_name.match(/^Reference$/ig)) && (!section_name.match(/^References$/ig))) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" does not match correct forms \"Reference\" or \"References\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Bibliography_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"Bibliography\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Further_reading_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"Further reading\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_External_links_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"External links\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} else if (section_name.match(/Bibliography/ig)) {

num_Bibliography_sections++;

if (num_Bibliography_sections > 1) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section \"" + section_name.replace(/(_+)/ig, " ") + "\" makes " + num_Bibliography_sections + " \"Bibliography\" sections.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (!section_name.match(/^Bibliography$/ig)) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" does not match correct form \"Bibliography\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Further_reading_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"Further reading\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_External_links_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"External links\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} else if (section_name.match(/Further_reading/ig)) {

num_Further_reading_sections++;

if (num_Further_reading_sections > 1) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section \"" + section_name.replace(/(_+)/ig, " ") + "\" makes " + num_Further_reading_sections + " \"Further reading\" sections.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (!section_name.match(/^Further_reading$/ig)) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" does not match correct form \"Further reading\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_External_links_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": The section \"" + section_name.replace(/(_+)/ig, " ") + "\" should come before the \"External links\" section.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} else if (section_name.match(/External_link/ig)) {

num_External_links_sections++;

if (num_External_links_sections > 1) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section \"" + section_name.replace(/(_+)/ig, " ") + "\" makes " + num_External_link_sections + " \"External_links\" sections.\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if ((!section_name.match(/^External_link$/ig)) && (!section_name.match(/^External_links$/ig))) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" does not match correct forms \"External_link\" or \"External_links\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} else {

if (num_See_also_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" comes after a \"See also\" section.\n";

error_string += "\tPlease put this before closing sections such as \"See also\", \"References\" and \"External links\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_References_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" comes after a \"References\" section.\n";

error_string += "\tPlease put this before closing sections such as \"See also\", \"References\" and \"External links\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Bibliography_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" comes after a \"Bibliography\" section.\n";

error_string += "\tPlease put this before closing sections such as \"See also\", \"References\" and \"External links\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_Further_reading_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" comes after a \"Further reading\" section.\n";

error_string += "\tPlease put this before closing sections such as \"See also\", \"References\" and \"External links\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

if (num_External_links_sections > 0) {

num_errors++;

error_string = "ERROR " + num_errors + ": Section heading \"" + section_name.replace(/(_+)/ig, " ") + "\" comes after an \"External links\" section.\n";

error_string += "\tPlease put this before closing sections such as \"See also\", \"References\" and \"External links\".\n";

error_string_list.push(error_string);

sibling_node.style.cssText = "background-color:red";

}

} // closes check for the closing sections

} // closes check for H2 anchor

} // closes loop over the anchors

// List the section headings for debugging

alert_string = "This article has " + num_section_names + " section headings.\n\n";

alert_string += "\tArticle title: " + article_title + "\n\nSections:\n";

for (section_name_index=1; section_name_index<=num_section_names; section_name_index++) {

alert_string += "\t" + section_name_index + ". " + section_name_list[section_name_index] + "\n";

}

window.alert(alert_string);

// Print summary of section-heading errors

if (num_errors < 1) {

error_string = "No errors in heading levels and order of sections.\n";

window.alert(error_string);

return;

} else if (num_errors == 1) {

initial_error_string = "There is one potential MoS error in the section headings";

} else {

initial_error_string = "There are " + num_errors + " potential MoS errors in the section headings";

}

error_string = initial_error_string + ":\n\n";

for (error_index=0; error_index

if ((error_index%max_num_errors_per_alert == 0) && (error_index > 1)) {

error_string += "\n\t\t\t\tContinued on next screen...\n";

window.alert(error_string);

error_string = initial_error_string + " (continued from previous screen):\n\n";

}

error_string += error_string_list[error_index];

} // closes loop over errors

error_string += "\nYou should also check that:\n";

error_string += "\t1. The section headings are nouns or noun phrases.\n";

error_string += "\t2. The section headings do not refer to the article title or other section headings.\n";

window.alert(error_string);

} // closes function checkSectionHeadings()

//******************

// The Main Function

//******************

function checkManualOfStyle() {

checkSectionHeadings(); // MOS:HEAD

} // closes function checkManualOfStyle()

addOnloadHook(function () {

mw.util.addPortletLink('p-navigation', 'javascript:checkManualOfStyle()', 'Check MOS:HEAD', 'ca-moscheck', 'Checks for violations of the Manual of Style on section headings', , );

});

//