<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-RhymesAdder.js</id>
	<title>MediaWiki:Gadget-RhymesAdder.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-RhymesAdder.js"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-RhymesAdder.js&amp;action=history"/>
	<updated>2026-04-09T18:55:30Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=MediaWiki:Gadget-RhymesAdder.js&amp;diff=475065&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-RhymesAdder.js&amp;diff=475065&amp;oldid=prev"/>
		<updated>2025-11-04T17:52:52Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:52, 4 November 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=MediaWiki:Gadget-RhymesAdder.js&amp;diff=475064&amp;oldid=prev</id>
		<title>wikt&gt;Ioaxxere: mw:Migrating mw.Uri to URL</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-RhymesAdder.js&amp;diff=475064&amp;oldid=prev"/>
		<updated>2025-09-17T22:26:11Z</updated>

		<summary type="html">&lt;p&gt;&lt;a href=&quot;http://www.mediawiki.org/wiki/Migrating_mw.Uri_to_URL&quot; class=&quot;extiw&quot; title=&quot;mw:Migrating mw.Uri to URL&quot;&gt;mw:Migrating mw.Uri to URL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/* {{documentation}}&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Dependencies: ext.gadget.Editor,ext.gadget.LanguageUtils,mediawiki.util,mediawiki.Uri&lt;br /&gt;
&lt;br /&gt;
To do:&lt;br /&gt;
 * Make less ugly&lt;br /&gt;
 * Ability to remove/edit rhymes&lt;br /&gt;
 * Put rhyme template at the bottom of pronunciation section?&lt;br /&gt;
 * Add qualifier button&lt;br /&gt;
*/&lt;br /&gt;
/*jshint maxerr:1048576, strict:true, undef:true, latedef:true, es5:true */&lt;br /&gt;
/*global mw, WikiXml, importScript, importScriptURI, $ */&lt;br /&gt;
var numberOfRhymesAdded = 0;&lt;br /&gt;
&lt;br /&gt;
// Derived from [[User:Erutuon/scripts/templateParser.js]].&lt;br /&gt;
function parseTemplate(templateText) {&lt;br /&gt;
	var parameters = new Object(null),&lt;br /&gt;
    	parameterRegex = /\|(?:([^=|}]+)=([^|}]+)|([^|}]+))/g,&lt;br /&gt;
		template = new Object(null);&lt;br /&gt;
	&lt;br /&gt;
	template.parameters = parameters;&lt;br /&gt;
	&lt;br /&gt;
	var match,&lt;br /&gt;
		index = 1,&lt;br /&gt;
		name = templateText.match(/^{{([^|}]+)/);&lt;br /&gt;
	&lt;br /&gt;
	if (name === null)&lt;br /&gt;
		throw new Error(&amp;quot;Invalid template: no name.&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	template.name = name[1];&lt;br /&gt;
	&lt;br /&gt;
	while ((match = parameterRegex.exec(templateText)) !== null) {&lt;br /&gt;
		if (match[1]) {&lt;br /&gt;
			parameters[match[1]] = match[2];&lt;br /&gt;
		} else {&lt;br /&gt;
			parameters[index++] = match[3];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return template;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var englishCardinalNumerals = [null,&lt;br /&gt;
	&amp;#039;one&amp;#039;, &amp;#039;two&amp;#039;, &amp;#039;three&amp;#039;, &amp;#039;four&amp;#039;, &amp;#039;five&amp;#039;,&lt;br /&gt;
	&amp;#039;six&amp;#039;, &amp;#039;seven&amp;#039;, &amp;#039;eight&amp;#039;, &amp;#039;nine&amp;#039;, &amp;#039;ten&amp;#039;,&lt;br /&gt;
	&amp;#039;eleven&amp;#039;, &amp;#039;twelve&amp;#039;, &amp;#039;thirteen&amp;#039;, &amp;#039;fourteen&amp;#039;, &amp;#039;fifteen&amp;#039;,&lt;br /&gt;
	&amp;#039;sixteen&amp;#039;, &amp;#039;seventeen&amp;#039;, &amp;#039;eighteen&amp;#039;, &amp;#039;nineteen&amp;#039;, &amp;#039;twenty&amp;#039;&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
function extractNumberOfSyllables(h3text) {&lt;br /&gt;
	var m = h3text.match(/(\S+) syllables?/);&lt;br /&gt;
	if (!m) return null;&lt;br /&gt;
	var word = m[1];&lt;br /&gt;
	var index = englishCardinalNumerals.indexOf(word.toLowerCase());&lt;br /&gt;
	return index &amp;gt; 0 ? index : null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function hasRhymeTemplate(wikitext, languageCode, rhyme) {&lt;br /&gt;
	// [[Template:rhyme]] redirects to [[Template:rhymes]].&lt;br /&gt;
	// Simple regex is sufficient because there are no cases of {{rhymes}} with&lt;br /&gt;
	// nested templates in the dump. (FIXME: Could change in the future.)&lt;br /&gt;
	var match, rhymeTemplate = /{{rhymes?\|.+?}}/g;&lt;br /&gt;
	while ((match = rhymeTemplate.exec(wikitext)) !== null) {&lt;br /&gt;
		var template = parseTemplate(match[0]);&lt;br /&gt;
		var templateLanguageCode = template.parameters.lang || template.parameters[1];&lt;br /&gt;
		if (templateLanguageCode == languageCode) {&lt;br /&gt;
			for (var i = template.parameters.lang ? 1 : 2; template.parameters[i]; ++i) {&lt;br /&gt;
				if (template.parameters[i].trim() === rhyme)&lt;br /&gt;
					return true;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setUpRhymeAdderFor(h3, div) {&lt;br /&gt;
	var findNumberOfHeaders = parseInt(new URL(h3.find(&amp;quot;a&amp;quot;).get(0).href).searchParams.get(&amp;quot;section&amp;quot;));&lt;br /&gt;
	var addNewRhymeForm;&lt;br /&gt;
	var syllableCount = extractNumberOfSyllables(h3.text());&lt;br /&gt;
	var syllableArg = syllableCount ? &amp;quot;|s=&amp;quot; + syllableCount : &amp;quot;&amp;quot;;&lt;br /&gt;
	editor = new Editor();&lt;br /&gt;
	new AdderWrapper(editor, {&lt;br /&gt;
		&amp;#039;createForm&amp;#039;: function() {&lt;br /&gt;
			return addNewRhymeForm =&lt;br /&gt;
				$(&amp;#039;&amp;lt;form&amp;gt;&amp;#039;)&lt;br /&gt;
				.append(&lt;br /&gt;
					$(&amp;#039;&amp;lt;label&amp;gt;+Add new rhyme: &amp;lt;/label&amp;gt;&amp;#039;)&lt;br /&gt;
					.append($(&amp;#039;&amp;lt;input&amp;gt;&amp;#039;).attr(&amp;quot;name&amp;quot;, &amp;#039;rhyme&amp;#039;))&lt;br /&gt;
				)&lt;br /&gt;
				.append($(&amp;#039;&amp;lt;input&amp;gt;&amp;#039;).attr(&amp;#039;type&amp;#039;, &amp;#039;submit&amp;#039;).val(&amp;#039;Add&amp;#039;))[0];&lt;br /&gt;
		},&lt;br /&gt;
		&amp;#039;fields&amp;#039;: {&lt;br /&gt;
			&amp;#039;rhyme&amp;#039;: function(txt, error) {&lt;br /&gt;
				return txt || error(&amp;#039;Please specify a rhyme.&amp;#039;);&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		&amp;#039;onsubmit&amp;#039;: function(values, render) {&lt;br /&gt;
			var langname = mw.config.get(&amp;quot;wgTitle&amp;quot;).split(&amp;#039;/&amp;#039;)[0];&lt;br /&gt;
			var lutils = new LanguageUtilsAsync();&lt;br /&gt;
			lutils.GetWiktionaryCodeByCanonicalName(langname).then(function(langcode) {&lt;br /&gt;
				$(addNewRhymeForm).find(&amp;#039;input&amp;#039;)[0].value = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
				var newItem = &amp;#039;{{l|&amp;#039; + langcode + &amp;#039;|&amp;#039; + values.rhyme + &amp;#039;}}&amp;#039;;&lt;br /&gt;
				render(newItem, function(newhtml) {&lt;br /&gt;
					var addedRhymeNode = $(&amp;quot;&amp;lt;li&amp;gt;&amp;quot;).html(newhtml),&lt;br /&gt;
						collator = window.Intl &amp;amp;&amp;amp; new Intl.Collator( langcode, { &amp;quot;case&amp;quot;: false } ),&lt;br /&gt;
						sortFunction = collator ? &lt;br /&gt;
							collator.compare :&lt;br /&gt;
							function compare( a, b ) {&lt;br /&gt;
								return a.toUpperCase() &amp;lt; b.toUpperCase() ? -1 : 1;&lt;br /&gt;
							};&lt;br /&gt;
					editor.addEdit({&lt;br /&gt;
						&amp;#039;edit&amp;#039;: function(wikitext) {&lt;br /&gt;
							var wikixml = WikiXml.parseWikitext(wikitext);&lt;br /&gt;
							var hdr = $(wikixml.find(&amp;quot;section&amp;quot;).get(findNumberOfHeaders - 1));&lt;br /&gt;
							var headerData = hdr.find(&amp;quot;data&amp;quot;).get(0).textContent;&lt;br /&gt;
							&lt;br /&gt;
							var rhymelistbegin_match = headerData.match(/{{(?:rhyme-top|rhyme list begin)\|?[0-9]?}}/);&lt;br /&gt;
							var rhymelistbegin_index = rhymelistbegin_match.index + rhymelistbegin_match[0].length;&lt;br /&gt;
							var rhymelistend_match = headerData.match(/{{(?:rhyme-bottom|rhyme list end)}}/);&lt;br /&gt;
							var rhymelistend_index = rhymelistend_match.index;&lt;br /&gt;
							var rhymesPrefix = headerData.substring(0, rhymelistbegin_index);&lt;br /&gt;
							var rhymes = headerData.substring(rhymelistbegin_index, rhymelistend_index).trim().split(/\r?\n/);&lt;br /&gt;
							var rhymesSuffix = headerData.substring(rhymelistend_index);&lt;br /&gt;
&lt;br /&gt;
							rhymes.push(&amp;quot;* &amp;quot; + newItem);&lt;br /&gt;
							var canRearrange = true;&lt;br /&gt;
&lt;br /&gt;
							var sortableLines = rhymes.map(function(line) {&lt;br /&gt;
								var m;&lt;br /&gt;
								m = line.match(/^\* ?{{l\|[a-zA-Z]{2,3}\|(.+)$/);&lt;br /&gt;
								if (m &amp;amp;&amp;amp; m[1]) return [m[1], line];&lt;br /&gt;
&lt;br /&gt;
								m = line.match(/^\* ?\[\[(.+)$/);&lt;br /&gt;
								if (m &amp;amp;&amp;amp; m[1]) return [m[1], line];&lt;br /&gt;
&lt;br /&gt;
								canRearrange = false;&lt;br /&gt;
								return null;&lt;br /&gt;
							});&lt;br /&gt;
							console.trace(&amp;quot;canRearrange is &amp;quot; + canRearrange);&lt;br /&gt;
&lt;br /&gt;
							if (canRearrange) {&lt;br /&gt;
								sortableLines.sort( function(a,b) { return sortFunction(a[0], b[0]);} );&lt;br /&gt;
								rhymes = sortableLines.map(function(sortableLine) {&lt;br /&gt;
									var match = sortableLine[1].match(/^\* ?\[\[(.+)]\]$/);&lt;br /&gt;
									if (match &amp;amp;&amp;amp; match[1]) return &amp;quot;* {{l|&amp;quot; + langcode + &amp;quot;|&amp;quot; + match[1] + &amp;quot;}}&amp;quot;;&lt;br /&gt;
									else return sortableLine[1];&lt;br /&gt;
								});&lt;br /&gt;
							}&lt;br /&gt;
							&lt;br /&gt;
							$(hdr.find(&amp;quot;data&amp;quot;).get(0)).text(rhymesPrefix + &amp;quot;\n&amp;quot; + rhymes.join(&amp;quot;\n&amp;quot;) + &amp;quot;\n&amp;quot; + rhymesSuffix);&lt;br /&gt;
							&lt;br /&gt;
							return WikiXml.toWikitext(wikixml);&lt;br /&gt;
						},&lt;br /&gt;
						&amp;#039;redo&amp;#039;: function() {&lt;br /&gt;
							div.find(&amp;quot;ul&amp;quot;).append(addedRhymeNode);&lt;br /&gt;
							div.find(&amp;quot;li&amp;quot;).sort(function(a, b) {&lt;br /&gt;
								return sortFunction( $(a).text(), $(b).text() );&lt;br /&gt;
							}).appendTo(div.find(&amp;quot;ul&amp;quot;));&lt;br /&gt;
						},&lt;br /&gt;
						&amp;#039;undo&amp;#039;: function() {&lt;br /&gt;
							addedRhymeNode.remove();&lt;br /&gt;
						},&lt;br /&gt;
						&amp;#039;summary&amp;#039;: &amp;quot;+rhyme [[&amp;quot; + values.rhyme + &amp;quot;]]&amp;quot;,&lt;br /&gt;
						&amp;#039;after_save&amp;#039;: function() {&lt;br /&gt;
							numberOfRhymesAdded++;&lt;br /&gt;
							document.body.style.cursor = &amp;#039;wait&amp;#039;;&lt;br /&gt;
							new mw.Api().edit(values.rhyme, function(text) {&lt;br /&gt;
								text = text.content;&lt;br /&gt;
								var rhymehome = mw.config.get(&amp;quot;wgTitle&amp;quot;).split(&amp;quot;/&amp;quot;)[1];&lt;br /&gt;
								if (hasRhymeTemplate(text, langcode, rhymehome)) {&lt;br /&gt;
									document.body.style.cursor = --numberOfRhymesAdded ? &amp;#039;wait&amp;#039; : &amp;#039;&amp;#039;;&lt;br /&gt;
									return $.Deferred().reject(&amp;#039;rhyme already on page&amp;#039;);&lt;br /&gt;
								}&lt;br /&gt;
								if (text.match(&amp;#039;==&amp;#039; + langname + &amp;#039;==&amp;#039;) &amp;amp;&amp;amp; !text.match(&amp;quot;\\{\\{rhymes?(\\|&amp;quot; + langcode + &amp;quot;\\|&amp;quot; + mw.util.escapeRegExp(rhymehome) + &amp;quot;|\\|&amp;quot; + mw.util.escapeRegExp(rhymehome) + &amp;quot;\\|&amp;quot; + langcode + &amp;quot;|\\|&amp;quot; + mw.util.escapeRegExp(rhymehome) + &amp;quot;)\\}\\}&amp;quot;)) {&lt;br /&gt;
									// If the current L2 section does not contain a pronunciation section, create the header.&lt;br /&gt;
									if (!String(text.match(&amp;quot;==&amp;quot; + langname + &amp;quot;==[\\s\\S]*?(\n==[^=]|$)&amp;quot;)).match(&amp;quot;=Pronunciation=&amp;quot;)) {&lt;br /&gt;
										text = text.replace(RegExp(&amp;quot;(==&amp;quot; + langname + &amp;quot;==[\\s\\S]*?(?=\n=+(?=[^=])(?!(Etymology=|Alternative))))&amp;quot;), &amp;quot;$1\n===Pronunciation===\n&amp;quot;);&lt;br /&gt;
									}&lt;br /&gt;
									// Add the rhymes template under the pronunciation header.&lt;br /&gt;
									text = text.replace(&lt;br /&gt;
										RegExp(&amp;#039;(==&amp;#039; + langname + &amp;#039;==[\\s\\S]*?=+Pronunciation=+[\\s\\S]*?\n(?![\:\*]))&amp;#039;),&lt;br /&gt;
										&amp;#039;$1* {{rhymes|&amp;#039; + langcode + &amp;quot;|&amp;quot; + rhymehome + syllableArg + &amp;#039;}}\n&amp;#039;&lt;br /&gt;
									);&lt;br /&gt;
								}&lt;br /&gt;
								if (text) return {&lt;br /&gt;
									text: text,&lt;br /&gt;
									summary: &amp;quot;+rhyme [[&amp;quot; + mw.config.get(&amp;quot;wgPageName&amp;quot;) + &amp;quot;|&amp;quot; + &amp;quot;-&amp;quot; + rhymehome + &amp;quot;]]&amp;quot;&lt;br /&gt;
								};&lt;br /&gt;
								else {&lt;br /&gt;
									document.body.style.cursor = --numberOfRhymesAdded ? &amp;#039;wait&amp;#039; : &amp;#039;&amp;#039;;&lt;br /&gt;
									return $.Deferred().reject(&amp;#039;problem text is false&amp;#039;);&lt;br /&gt;
								}&lt;br /&gt;
							}).then(function() {&lt;br /&gt;
								document.body.style.cursor = --numberOfRhymesAdded ? &amp;#039;wait&amp;#039; : &amp;#039;&amp;#039;;&lt;br /&gt;
							});&lt;br /&gt;
						}&lt;br /&gt;
					}, addedRhymeNode[ 0 ]);&lt;br /&gt;
				});&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	}, h3.parent()[0], div[0]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function setUpRhymeAdder() {&lt;br /&gt;
	$(&amp;quot;.rhymes-list-begin&amp;quot;).each(function() {&lt;br /&gt;
		var div = $(this);&lt;br /&gt;
		if (div.prev().text().indexOf(&amp;quot;syllable&amp;quot;) != -1) {&lt;br /&gt;
			try {&lt;br /&gt;
				setUpRhymeAdderFor(div.prev(), $(this));&lt;br /&gt;
			} catch (e) {&lt;br /&gt;
				console.log(e);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;) === 106 &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgAction&amp;quot;) == &amp;quot;view&amp;quot;)&lt;br /&gt;
	$.getScript(&amp;quot;//en.wiktionary.org/w/index.php?title=User:Dixtosa/XMLize.js&amp;amp;action=raw&amp;quot;, function() {&lt;br /&gt;
		$(setUpRhymeAdder);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>wikt&gt;Ioaxxere</name></author>
	</entry>
</feed>