User:Erutuon/scripts/graveToAcuteRedirect.js

/* * Automatically create three types of Ancient Greek redirects: * - from titles with graves to the corresponding title with an acute: *    καὶ → καί * - from titles with apostrophe-like characters to the straight apostrophe: *    γ’ → γ' * - from a title with two accents in the final word to the version with the *  final accent removed: *    ἦέ → ἦε * * Install by adding this to your Special:MyPage/common.js:

importScript('User:Erutuon/scripts/graveToAcuteRedirect.js');

*/

/* jshint boss: true, undef: true, unused: true */ /* globals $, mw, OO */ //

(function { if (mw.config.get('wgCurRevisionId') !== 0)	return;

const decomposedTitle = mw.config.get('wgPageName').normalize('NFD'); // U+02BC MODIFIER LETTER APOSTROPHE, U+1FBD GREEK KORONIS, U+1FBF GREEK PSILI, // U+2019 RIGHT SINGLE QUOTATION MARK const wrongApostrophe = /[ʼ᾽᾿’]/g; // U+0027 APOSTROPHE const rightApostrophe = "'"; // const curlyApostrophe = "’";

// in mainspace and page hasn't been created and title contains a character in // the Greek and Coptic block if (mw.config.get('wgNamespaceNumber') === 0		&& /[Ͱ-Ͽ]/.test(decomposedTitle)) { const grave = '\u0300'; const acute = '\u0301'; const circumflex = '\u0342'; const consonants = 'βγδζθκλμνξπρςστφχψ'; let rightTitle; if (decomposedTitle.includes(grave)) { const finalGraveRegex = new RegExp(grave + '([' + consonants + ']*)$'); if (!finalGraveRegex.test(decomposedTitle)) { mw.notify("No grave accent at end of term!"); return; }		// No need to recompose; the server does that automatically. rightTitle = decomposedTitle.replace(finalGraveRegex, acute + '$1'); } else if (wrongApostrophe.test(decomposedTitle)) { rightTitle = decomposedTitle.replace(wrongApostrophe, rightApostrophe); } else { // If last word has two accents, remove the last and redirect to it. const match = decomposedTitle.match(/[^_]+$/); const lastWord = match && match[0]; if (lastWord) { const allTones = new RegExp("[" + acute + grave + circumflex + "]", "g"); const match = lastWord.match(allTones); if (match && match.length === 2) { let i = 0; rightTitle = decomposedTitle.replace(lastWord,					lastWord.replace(allTones, function (tone) { return ++i === 2 ? "" : tone; }));			}		}	}	if (rightTitle) { const redirect = '#REDIRECT ' + rightTitle.normalize('NFC') + ''; $(function {			switch (mw.config.get('wgAction')) {				case 'edit': case 'submit':					const textbox = $('#wpTextbox1');					if (textbox.textSelection('getContents') === '')						textbox.textSelection('setContents', redirect);					break;				case 'view': {					mw.loader.using([ 'mediawiki.Uri', 'oojs-ui' ]).done(function  { // Use preloadtext parameter implemented in MediaWiki:Common.js // to set text in textbox. const button = new OO.ui.ButtonWidget({							label: 'Create redirect to ' + rightTitle,							href: new mw.Uri(location.href).extend({ action: 'edit', preloadtext: redirect }).toString						});

const buttonContainer = $(' ').append(button.$element);

$('#firstHeading').after(buttonContainer); });				}			}		});	} }

function hasAmbig(greekStr) { // αιυ followed by diacritics (not macron, breve, circumflex, iota subscript) greekStr = greekStr.normalize('NFD'); const diaeresis = '\u0308'; let match; const vowelAndDiacritics = /([αεου]?ι|[αεηο]?υ|α)([\u0300-\u036F]*)/gi; while (match = vowelAndDiacritics.exec(greekStr)) { const [, vowels, diacritics ] = match; // macron, breve, circumflex (perispomeni), iota subscript if (!/[\u0304\u0306\u0342\u0345]/.test(diacritics)				&& (vowels.length === 1 || diacritics.includes(diaeresis))) { return true; }	}	return false; }

/* console.log('start tests'); for (const [ word, expected ] of [	[ 'ἑκατόμβας', true ],	[ 'αἰδοίη', false ],	[ 'ἄγετ', true ],	[ 'Βηθσαϊδά', true ],	[ 'Βηθσαῐ̈δ', false ], ]) { const result = hasAmbig(word); console.log(word, expected, result, result === expected ? 'success' : 'failure'); }

// in mainspace and page hasn't been created and title contains a character in // the Greek and Coptic block and last character of title is straight apostrophe if (mw.config.get('wgNamespaceNumber') === 0		&& /[Ͱ-Ͽ]/.test(decomposedTitle)		&& decomposedTitle[decomposedTitle.length - 1] == rightApostrophe		&& mw.config.get('wgAction') === 'edit') { const charsTemplate = 'grc'; const ambigParameter = hasAmbig(decomposedTitle) ? '|' + charsTemplate.replace(rightApostrophe, '') : '';	const contents = `==Ancient Greek==

POS
$('#wpTextbox1').textSelection('setContents', contents); }

});

//