MediaWiki:Gadget-RhymesAdder.js

/* Dependencies: ext.gadget.Editor,ext.gadget.LanguageUtils,mediawiki.util,mediawiki.Uri

To do: * Make less ugly * Ability to remove/edit rhymes * Put rhyme template at the bottom of pronunciation section? * Add qualifier button /*jshint maxerr:1048576, strict:true, undef:true, latedef:true, es5:true */ /*global mw, WikiXml, importScript, importScriptURI, $ */ var numberOfRhymesAdded = 0;

// Derived from User:Erutuon/scripts/templateParser.js. function parseTemplate(templateText) { var parameters = new Object(null), parameterRegex = /\|(?:([^=|}]+)=([^|}]+)|([^|}]+))/g, template = new Object(null); template.parameters = parameters; var match, index = 1, name = templateText.match(/^{{([^|}]+)/); if (name === null) throw new Error("Invalid template: no name."); template.name = name[1]; while ((match = parameterRegex.exec(templateText)) !== null) { if (match[1]) { parameters[match[1]] = match[2]; } else { parameters[index++] = match[3]; }	}	return template; }

var englishCardinalNumerals = [null, 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty' ];

function extractNumberOfSyllables(h3text) { var m = h3text.match(/(\S+) syllables?/); if (!m) return null; var word = m[1]; var index = englishCardinalNumerals.indexOf(word.toLowerCase); return index > 0 ? index : null; }

function hasRhymeTemplate(wikitext, languageCode, rhyme) { // Template:Rhymes and Template:rhyme redirect to Template:rhymes. // Simple regex is sufficient because there are no cases of with // nested templates in the dump. var match, rhymeTemplate = //g; while ((match = rhymeTemplate.exec(wikitext)) !== null) { var template = parseTemplate(match[0]); var templateLanguageCode = template.parameters.lang || template.parameters[1]; if (templateLanguageCode == languageCode) { for (var i = template.parameters.lang ? 1 : 2; template.parameters[i]; ++i) { if (template.parameters[i].trim === rhyme) return true; }		}	}	return false; }

function setUpRhymeAdderFor(h3, div) { var findNumberOfHeaders = parseInt(new mw.Uri(h3.find("a").get(0).href).query.section); var addNewRhymeForm; var syllableCount = extractNumberOfSyllables(h3.text); var syllableArg = syllableCount ? "|s=" + syllableCount : ""; editor = new Editor; new AdderWrapper(editor, {		'createForm': function {			return addNewRhymeForm =				$(' ')				.append( $(' +Add new rhyme: ') .append($(' ').attr("name", 'rhyme')) )				.append($(' ').attr('type', 'submit').val('Add'))[0];		},		'fields': {			'rhyme': function(txt, error) {				return txt || error('Please specify a rhyme.');			}		},		'onsubmit': function(values, render) {			var langname = mw.config.get("wgTitle").split('/')[0];			var lutils = new LanguageUtilsAsync;			lutils.GetWiktionaryCodeByCanonicalName(langname).then(function(langcode) { $(addNewRhymeForm).find('input')[0].value = "";

var newItem = ''; render(newItem, function(newhtml) {					var addedRhymeNode = $("").html(newhtml),						collator = window.Intl && new Intl.Collator( langcode, { "case": false } ),						sortFunction = collator ? 							collator.compare :							function compare( a, b ) {								return a.toUpperCase < b.toUpperCase ? -1 : 1;							};					editor.addEdit({ 'edit': function(wikitext) { var wikixml = WikiXml.parseWikitext(wikitext); var hdr = $(wikixml.find("section").get(findNumberOfHeaders - 1)); var headerData = hdr.find("data").get(0).textContent; var rhymelistbegin_match = headerData.match(//); var rhymelistbegin_index = rhymelistbegin_match.index + rhymelistbegin_match[0].length; var rhymelistend_index = headerData.indexOf(""); var rhymesPrefix = headerData.substring(0, rhymelistbegin_index); var rhymes = headerData.substring(rhymelistbegin_index, rhymelistend_index).trim.split(/\r?\n/); var rhymesSuffix = headerData.substring(rhymelistend_index);

rhymes.push("* " + newItem); var canRearrange = true;

var sortableLines = rhymes.map(function(line) {								var m;								m = line.match(/^\* ?{{l\|[a-zA-Z]{2,3}\|(.+)$/);								if (m && m[1]) return [m[1], line];

m = line.match(/^\* ?\[\[(.+)$/); if (m && m[1]) return [m[1], line];

canRearrange = false; return null; });							console.trace("canRearrange is " + canRearrange);

if (canRearrange) { sortableLines.sort( function(a,b) { return sortFunction(a[0], b[0]);} ); rhymes = sortableLines.map(function(sortableLine) {									var match = sortableLine[1].match(/^\* ?\[\[(.+)]\]$/);									if (match && match[1]) return "* ";									else return sortableLine[1];								}); }							$(hdr.find("data").get(0)).text(rhymesPrefix + "\n" + rhymes.join("\n") + "\n" + rhymesSuffix); return WikiXml.toWikitext(wikixml); },						'redo': function { div.find("ul").append(addedRhymeNode); div.find("li").sort(function(a, b) {								return sortFunction( $(a).text, $(b).text );							}).appendTo(div.find("ul")); },						'undo': function { addedRhymeNode.remove; },						'summary': "+rhyme " + values.rhyme + "", 'after_save': function { numberOfRhymesAdded++; document.body.style.cursor = 'wait'; new mw.Api.edit(values.rhyme, function(text) {								text = text.content;								var rhymehome = mw.config.get("wgTitle").split("/")[1];								if (hasRhymeTemplate(text, langcode, rhymehome)) {									document.body.style.cursor = --numberOfRhymesAdded ? 'wait' : '';									return $.Deferred.reject('rhyme already on page');								}								if (text.match('==' + langname + '==') && !text.match("\\{\\{rhymes(\\|lang=" + langcode + "\\|" + mw.util.escapeRegExp(rhymehome) + "|\\|" + mw.util.escapeRegExp(rhymehome) + "\\|lang=" + langcode + "|\\|" + mw.util.escapeRegExp(rhymehome) + ")\\}\\}")) {									if (!String(text.match("==" + langname + "==[\\s\\S]*?(|$)")).match("=Pronunciation=")) {										text = text.replace(RegExp("(==" + langname + "==[\\s\\S]*?(?=\n=+(?=[^=])(?!(Etymology=|Alternative))))"), "$1\n===Pronunciation===\n");									}									text = text.replace( RegExp('(==' + langname + '==[\\s\\S]*?=+Pronunciation=+[\\s\\S]*?\n(?![\:\*]))'), '$1* \n' );								}								if (text) return {									text: text,									summary: "+rhyme " + "-" + rhymehome + ""								};								else {									document.body.style.cursor = --numberOfRhymesAdded ? 'wait' : ;									return $.Deferred.reject('problem text is false');								}							}).then(function {								document.body.style.cursor = --numberOfRhymesAdded ? 'wait' : ;							}); }					}, addedRhymeNode[ 0 ]);				}); });		}	}, h3.parent[0], div[0]); }

function setUpRhymeAdder { $(".rhymes-list-begin").each(function {		var div = $(this);		if (div.prev.text.indexOf("syllable") != -1) {			try {				setUpRhymeAdderFor(div.prev, $(this));			} catch (e) {				console.log(e);			}		}	}); }

if (mw.config.get('wgNamespaceNumber') === 106 && mw.config.get("wgAction") == "view") $.getScript("//en.wiktionary.org/w/index.php?title=User:Dixtosa/XMLize.js&action=raw", function {		$(setUpRhymeAdder);	});

//