Karber:Mirzali/sort-çarnayış.js
Note: Qeydi ra dıme, gani viriya cıgeyrayoği pak bo ke vurnayışi bıvêniyê.
- Gışta şıma ke niya ro gocega Firefox / Safari: Shift ser, bıtıknê ra newe ra bar kerên ya zi Ctrl-F5 ya zi Ctrl-R bıtıknê (seba Mac ra ⌘-R).
- Google Chrome: Ctrl-Shift-R ro nê. (seba Mac ra ⌘-Shift-R)
- Internet Explorer / Edge: Ctrl ke niyo ro cı, Newe ke bıtıknê ya zi Ctrl-F5 bıkerê.
- Opera: Ctrl-F5 bıtıknê.
// <nowiki>
let langUtilsInstance;
$(document).ready(function() {
mw.loader.using(['jquery.ui'], function() {
mw.util.addCSS('#t-sortwerger { font-weight: normal; }');
$(mw.util.addPortletLink('p-tb', '#', 'Sort-çarnayış', 't-sortcarnayis', 'Sort language codes in Çarnayış')).click(init);
});
langUtilsInstance = new LanguageUtilsAsync();
function init() {
sortWerger();
}
function LanguageUtilsAsync() {
const langNameToLangCodePromise = new mw.Api().get({
"action": "expandtemplates",
"format": "json",
"text": "{{#invoke:languages/javascript-interface|AllCanonicalToCode}}",
"prop": "wikitext"
}).then(function(response) {
return JSON.parse(response.expandtemplates.wikitext);
});
const langCodeToLangNamePromise = langNameToLangCodePromise.then(function(name2code) {
const code2name = {};
for (const name in name2code) {
code2name[name2code[name]] = name;
}
return code2name;
});
this.GetWiktionaryCodeByCanonicalName = function(canonicalName) {
return langNameToLangCodePromise.then(function(r) {
return r[canonicalName];
});
};
this.GetCanonicalNameByWiktionaryCode = function(langcode) {
return langCodeToLangNamePromise.then(function(r) {
return r[langcode];
});
};
}
// Zazaki alphabet
const zazakiAlphabet = "ABCÇDEÊFGĞHIİJKLMNOPQRSŞTUÛVWXYZǃǀǁǂ";
function customSort(langNameA, langNameB) {
const minLength = Math.min(langNameA.length, langNameB.length);
for (let i = 0; i < minLength; i++) {
const indexA = zazakiAlphabet.indexOf(langNameA[i]);
const indexB = zazakiAlphabet.indexOf(langNameB[i]);
if (indexA < indexB) {
return -1;
} else if (indexA > indexB) {
return 1;
}
}
return langNameA.length - langNameB.length;
}
var stripArabicDiacritics = {
strip: "\u064B\u064C\u064D\u064E\u064F\u0650\u0651\u0652"
};
var stripGraveAndAcute = {
strip: "\u0300\u0301"
};
var fullToHalfWidthNumbers = {
from: "0123456789",
to: "0123456789"
};
const diacriticStrippers = {
ang: {
from: "ĀāǢǣĊċĒēĠġĪīŌōŪūȲȳ",
to: "AaÆæCcEeGgIiOoUuYy",
strip: "\u0304\u0307",
}, //macron and above dot
ar: stripArabicDiacritics,
aao: stripArabicDiacritics,
acm: stripArabicDiacritics,
acx: stripArabicDiacritics,
adf: stripArabicDiacritics,
aeb: stripArabicDiacritics,
afb: stripArabicDiacritics,
ajp: stripArabicDiacritics,
apc: stripArabicDiacritics,
apd: stripArabicDiacritics,
arq: stripArabicDiacritics,
ary: stripArabicDiacritics,
arz: stripArabicDiacritics,
fa: stripArabicDiacritics,
ps: stripArabicDiacritics,
sd: stripArabicDiacritics,
ur: stripArabicDiacritics,
chl: {
from: "ÁáÉéÍíÓóÚú",
to: "AaEeIiOoUu",
strip: "\u0304",
}, //acute accent
he: {
strip: "\u05B0\u05B1\u05B2\u05B3\u05B4\u05B5\u05B6\u05B7\u05B8\u05B9\u05BA\u05BB\u05BC\u05BD\u05BF\u05C1\u05C2",
from: "-'\"",
to: "־׳״",
},
la: {
from: "ĀāĒēĪīŌōŪūȲȳ",
to: "AaEeIiOoUuYy",
strip: "\u0304",
}, //macron
lt: {
from: "áãàéẽèìýỹñóõòúù",
to: "aaaeeeiyynooouu",
strip: "\u0340\u0301\u0303",
},
nci: {
from: "ĀāĒēĪīŌōŪūȲȳ",
to: "AaEeIiOoUu",
strip: "\u0304",
}, //macron
//strip ́ and ̀ on Cyrillic Slavic languages, Serbo-Croatian has a longer list
ru: stripGraveAndAcute,
uk: stripGraveAndAcute,
be: stripGraveAndAcute,
bg: stripGraveAndAcute,
orv: stripGraveAndAcute,
cu: stripGraveAndAcute,
rue: stripGraveAndAcute,
mk: stripGraveAndAcute,
sh: {
from: "ȀȁÀàȂȃÁáĀāȄȅÈèȆȇÉéĒēȈȉÌìȊȋÍíĪīȌȍÒòȎȏÓóŌōȐȑȒȓŔŕȔȕÙùȖȗÚúŪūѝӣ",
to: "AaAaAaAaAaEeEeEeEeEeIiIiIiIiIiOoOoOoOoOoRrRrRrUuUuUuUuUuии",
strip: "\u030F\u0300\u0311\u0301\u0304",
},
sl: {
from: "áÁàÀâÂȃȂȁȀéÉèÈêÊȇȆȅȄíÍìÌîÎȋȊȉȈóÓòÒôÔȏȎȍȌŕŔȓȒȑȐúÚùÙûÛȗȖȕȔệỆộỘẹẸọỌəł",
to: "aAaAaAaAaAeEeEeEeEeEiIiIiIiIiIoOoOoOoOoOrRrRrRuUuUuUuUuUeEoOeEoOel",
strip: "\u0301\u0300\u0302\u0311\u030f\u0323",
},
kk: stripGraveAndAcute,
ky: stripGraveAndAcute,
tg: stripGraveAndAcute,
sa: {
strip: "ः",
},
/** visarga **/
bo: {
strip: "།",
},
/** shad **/
tr: {
from: "ÂâÛû",
to: "AaUu",
strip: "\u0302",
},
ja: fullToHalfWidthNumbers,
cmn: fullToHalfWidthNumbers,
yue: fullToHalfWidthNumbers,
nan: fullToHalfWidthNumbers,
ko: fullToHalfWidthNumbers,
zu: {
strip_init_hyphen: true,
}
};
function removeDiacritics(langCode, str) {
var stripper = diacriticStrippers[langCode];
if (stripper) {
var map = makeMap(stripper);
var output = applyMap(map, str);
return output;
}
return str;
}
function stringOrNull(val) {
return typeof val == "string" ? val : null;
}
function makeMap(obj) {
var from = stringOrNull(obj.from);
var to = stringOrNull(obj.to);
var strip = stringOrNull(obj.strip);
var map = {};
if (from && to) {
for (var i = 0; i < from.length; i++) {
map[from.charAt(i)] = to.charAt(i);
}
}
if (strip) {
for (var ii = 0; ii < strip.length; ii++) {
map[strip.charAt(ii)] = "";
}
}
return map;
}
function applyMap(map, str) {
var input = str.split("");
var output = "";
for (var i = 0; i < input.length; i++) {
var char = input[i];
var repl = map[char];
output += repl ? repl : char;
}
return output;
}
function page_exists(lang_code, page) {
var domain;
var wm_liens = {
'cmn': 'zh',
'fra-nor': 'nrm',
'gsw': 'als',
'ko-Hani': 'ko',
'lzh': 'zh-classical',
'nan': 'zh-min-nan',
'kmr': 'ku',
'nb': 'no',
'nn': 'no',
'rup': 'roa-rup',
'yue': 'zh-yue',
};
var wiktios = [
'en', 'mg', 'fr', 'zh', 'lt', 'ru', 'es', 'el', 'pl', 'sv', 'ko',
'nl', 'de', 'tr', 'ku', 'ta', 'io', 'kn', 'fi', 'vi', 'hu', 'pt',
'chr', 'no', 'ml', 'my', 'id', 'it', 'li', 'ro', 'et', 'ja', 'te',
'jv', 'fa', 'cs', 'ca', 'ar', 'eu', 'gl', 'lo', 'uk', 'br', 'fj',
'eo', 'bg', 'hr', 'th', 'oc', 'is', 'vo', 'ps', 'zh-min-nan',
'simple', 'cy', 'uz', 'scn', 'sr', 'af', 'ast', 'az', 'da', 'sw',
'fy', 'tl', 'he', 'nn', 'wa', 'ur', 'la', 'sq', 'hy', 'sm', 'sl',
'ka', 'pnb', 'nah', 'hi', 'tt', 'bs', 'lb', 'lv', 'tk', 'sk', 'hsb',
'nds', 'kk', 'ky', 'be', 'km', 'mk', 'ga', 'wo', 'ms', 'ang', 'co',
'sa', 'gn', 'mr', 'csb', 'ckb', 'ug', 'st', 'ia', 'sd', 'sh', 'si', 'mn',
'tg', 'or', 'kl', 'vec', 'jbo', 'an', 'ln', 'fo', 'zu', 'gu', 'kw',
'gv', 'rw', 'qu', 'ss', 'ie', 'mt', 'om', 'bn', 'pa', 'roa-rup',
'iu', 'so', 'am', 'su', 'za', 'gd', 'mi', 'tpi', 'ne', 'yi', 'ti',
'sg', 'na', 'dv', 'tn', 'ts', 'ha', 'ks', 'ay',
];
var keepApos = [
'fr', 'de',
];
if (wm_liens.hasOwnProperty(lang_code)) {
domain = wm_liens[lang_code] + '.wiktionary';
} else if (lang_code === 'navz') {
domain = 'species.wikimedia';
} else if ($.inArray(lang_code, wiktios) !== -1) {
domain = lang_code + '.wiktionary';
}
// Si le Wiktionnaire n'existe pas, inutile de faire une requête HTTP
if (!domain) {
return $.Deferred().resolve('ç').promise();
}
// traiter l'apostrophe typographique comme une apostrophe dactylographique
// dans les liens interwikis, les autres wiktionnaires privilégiant la seconde
if ($.inArray(lang_code, keepApos) === -1) {
page = page.replace('’', "'");
page = page.replace('ʼ', "'");
}
const normalizedPageTitle = removeDiacritics(lang_code, page);
var def = $.Deferred();
$.ajax({
url: '//' + domain + '.org/w/api.php?origin=' + location.protocol + '//' + location.host,
data: {
action: 'query',
titles: normalizedPageTitle,
format: 'json'
},
dataType: 'json'
}).fail(function() {
def.resolve('ç');
}).then(function(data) {
// The page title is already normalized, so no need to normalize again.
// We can directly use the data to check for existence.
// If the AJAX request succeeds, check if the page exists in the API response.
// If it exists, resolve the promise with 'W+' (indicating existence).
// Otherwise, resolve the promise with 'W-' (indicating non-existence).
def.resolve(data.query.pages[-1] ? 'ç' : 'ç+');
});
return def.promise();
}
function fetchLanguageNames(langCodes) {
return Promise.all(langCodes.map(langCode => {
return langUtilsInstance.GetCanonicalNameByWiktionaryCode(langCode).then(languageName => {
return {
langCode,
languageName,
};
});
}));
}
function sortAlphabetically(content) {
const wergerSections = extractWergerSections(content);
if (wergerSections.length > 0) {
const fetchPromises = wergerSections.map(wergerSection => {
const lines = wergerSection.trim().split("\n");
const langCodeRegex = /\{\{z\|([a-zA-Z-]+)(\|[^\}]+)?/;
const langSet = [];
let currentMainLang = null;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const langCodeMatches = line.match(langCodeRegex);
if (langCodeMatches !== null) {
const langCode = langCodeMatches[1]?.toLowerCase() || "";
if (!line.startsWith("*:")) {
if (currentMainLang) {
langSet.push(currentMainLang);
}
currentMainLang = {
type: 'mainLang',
line,
langCode,
subsets: [],
};
} else if (currentMainLang) {
currentMainLang.subsets.push(line);
}
} else {
if (currentMainLang) {
currentMainLang.subsets.push(line);
} else {
langSet.push({
type: 'unknown',
line,
});
}
}
}
if (currentMainLang) {
langSet.push(currentMainLang);
}
return fetchLanguageNames(langSet.filter(item => item.type === 'mainLang').map(item => item.langCode)).then(function(languageNames) {
langSet.sort((a, b) => {
if (a.type === 'mainLang' && b.type === 'mainLang') {
const langNameA = languageNames.find(lang => lang.langCode === a.langCode)?.languageName || "";
const langNameB = languageNames.find(lang => lang.langCode === b.langCode)?.languageName || "";
return customSort(langNameA, langNameB);
} else {
return a.type === 'mainLang' ? -1 : 1;
}
});
const sortedLines = langSet.reduce((result, item) => {
if (item.type === 'mainLang') {
result.push(item.line, ...item.subsets);
} else {
result.push(item.line);
}
return result;
}, []);
const sortedContent = "" + sortedLines.join("\n") + "";
content = content.replace(new RegExp(escapeRegExp(wergerSection), "g"), sortedContent);
return content;
});
});
return Promise.all(fetchPromises).then(() => {
return content;
});
}
return Promise.resolve(content);
}
function extractWergerSections(content) {
const wergerSections = [];
const wergerSerRegex = /\{\{ç-ser(?:\|[^}]+)?}}/gi; // Regular expression to match {{werger-ser}} with optional arguments
let match;
while ((match = wergerSerRegex.exec(content)) !== null) {
const startIndex = match.index;
const endIndex = content.indexOf("{{ç-bın}}", startIndex);
if (endIndex !== -1) {
const sectionContent = content.substring(startIndex + match[0].length, endIndex).trim();
wergerSections.push(sectionContent);
} else {
break;
}
}
return wergerSections;
}
function updateWTemplateOutcome($textBox) {
const langCodeRegex = /\{\{ç(\+|-)?\|([^\|]+)\|([^\|\}]+)/g;
let match;
let promises = [];
while ((match = langCodeRegex.exec($textBox.val())) !== null) {
const fullMatch = match[0];
const sign = match[1] || '+';
const langCode = match[2].toLowerCase();
const page = match[3];
const promise = page_exists(langCode, page).then(function(outcome) {
const newTemplate = `{{ç${outcome === 'ç+' ? '+' : '-'}|${langCode}|${page}`;
$textBox.val($textBox.val().replace(fullMatch, newTemplate));
});
promises.push(promise);
}
return Promise.all(promises);
}
window.sortWerger = function() {
const $textBox = $("#wpTextbox1");
if ($textBox.length > 0 && $textBox.val().includes("{{ç-ser") && $textBox.val().includes("{{ç-bın}}")) {
sortAlphabetically($textBox.val()).then(function(sortedContent) {
$textBox.val(sortedContent);
mw.notify("Hatine rêzkirin");
return updateWTemplateOutcome($textBox); // Pass the $textBox as an argument
}).then(function() {
mw.notify("Sererastkirinên W-/+ çêbû.");
mw.notify("Xilas.");
}).catch(function(error) {
mw.notify("Failed to fetch language names or update W templates: " + error);
});
} else {
mw.notify("Required templates not found on page: " + mw.config.get("wgTitle"));
}
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function flatten(arr) {
return arr.reduce((flat, toFlatten) => flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten), []);
}
});
// </nowiki>