AO3: Language names in English

Display language names in English and sort language dropdowns by this order.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        AO3: Language names in English
// @description Display language names in English and sort language dropdowns by this order.
// @namespace	https://greasyfork.org/en/scripts/373145-ao3-language-names-in-english
// @author	Min
// @version	1.5
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js
// @include     http://*archiveofourown.org/*
// @include     https://*archiveofourown.org/*
// ==/UserScript==


(function ($) {

    const DEBUG = false;

    const languages = [
        { english_name: "Afrikaans", name: ["Afrikaans"], code: ["afr"] },
        { english_name: "Albanian", name: ["Shqip"], code: ["sq"] },
        { english_name: "Arabic", name: ["العربية"], code: ["ar"] },
        { english_name: "Aramaic", name: ["ܐܪܡܝܐ | ארמיא"], code: ["arc"] },
        { english_name: "Armenian", name: ["հայերեն"], code: ["hy"] },
        { english_name: "Asturian", name: ["asturianu"], code: ["ast"] },
        { english_name: "Azerbaijani", name: ["Азәрбајҹан дили | آذربایجان دیلی"], code: ["azj"] },
        { english_name: "Bashkir", name: ["Башҡорт теле"], code: ["ba"] },
        { english_name: "Basque", name: ["Euskara"], code: ["eu"] },
        { english_name: "Belarusian", name: ["беларуская"], code: ["be"] },
        { english_name: "Bengali", name: ["বাংলা"], code: ["bn"] },
        { english_name: "Bosnian", name: ["Bosanski"], code: ["bos"] },
        { english_name: "Breton", name: ["Brezhoneg"], code: ["br"] },
        { english_name: "Bulgarian", name: ["Български"], code: ["bg"] },
        { english_name: "Burmese", name: ["မြန်မာဘာသာ"], code: ["my"] },
        { english_name: "Catalan", name: ["Català"], code: ["ca"] },
        { english_name: "Cebuano", name: ["Cebuano"], code: ["ceb"] },
        { english_name: "Chechen", name: ["Нохчийн мотт"], code: ["ce"] },
        { english_name: "Chinese", name: ["中文"], code: ["zh-CN"] },
        { english_name: "CHINESE - Mandarin", name: ["中文-普通话 國語"], code: ["zh"] },
        { english_name: "Chinese - Cantonese", name: ["中文-广东话 粵語"], code: ["yue"] },
        { english_name: "Chinese - Hakka", name: ["中文-客家话"], code: ["hak"] },
        { english_name: "Chinese - Taiwanese", name: ["中文-闽南话 臺語"], code: ["nan"] },
        { english_name: "Chinese - Wu", name: ["中文-吴语"], code: ["wuu"] },
        { english_name: "Chinook Jargon", name: ["Chinuk Wawa"], code: ["chn"] },
        { english_name: "Coptic", name: ["ϯⲙⲉⲧⲣⲉⲙⲛ̀ⲭⲏⲙⲓ"], code: ["cop"] },
        { english_name: "Croatian", name: ["Hrvatski"], code: ["hr"] },
        { english_name: "Czech", name: ["Čeština"], code: ["cs"] },
        { english_name: "Danish", name: ["Dansk"], code: ["da"] },
        { english_name: "Dutch", name: ["Nederlands"], code: ["nl"] },
        { english_name: "Egyptian", name: ["𓂋𓏺𓈖 𓆎𓅓𓏏𓊖"], code: ["egy"] },
        { english_name: "English", name: ["English"], code: ["en"] },
        { english_name: "Esperanto", name: ["Esperanto"], code: ["eo"] },
        { english_name: "Estonian", name: ["eesti keel"], code: ["et"] },
        { english_name: "Filipino", name: ["Filipino"], code: ["fil"] },
        { english_name: "Finnish", name: ["suomi"], code: ["fi"] },
        { english_name: "French", name: ["Français"], code: ["fr"] },
        { english_name: "Friulian", name: ["Furlan"], code: ["fur"] },
        { english_name: "Gaelic", name: ["Gàidhlig"], code: ["gd"] },
        { english_name: "Galician", name: ["Galego"], code: ["gl"] },
        { english_name: "Georgian", name: ["ქართული"], code: ["kat"] },
        { english_name: "German", name: ["Deutsch"], code: ["de"] },
        { english_name: "Gothic", name: ["Sprēkō Þiudiskō"], code: ["gem"] },
        { english_name: "Gothic", name: ["𐌲𐌿𐍄𐌹𐍃𐌺𐌰"], code: ["got"] },
        { english_name: "Greek", name: ["Ελληνικά"], code: ["el"] },
        { english_name: "Haitian Creole", name: ["kreyòl ayisyen"], code: ["ht"] },
        { english_name: "Hausa | هَرْشَن هَوْسَ", name: ["Hausa | هَرْشَن هَوْسَ"], code: ["hau"] },
        { english_name: "Hawaiian", name: ["ʻŌlelo Hawaiʻi"], code: ["haw"] },
        { english_name: "Hebrew", name: ["עברית"], code: ["he"] },
        { english_name: "Hindi", name: ["हिन्दी", "हिंदी"], code: ["hi"] },
        { english_name: "Hungarian", name: ["Magyar"], code: ["hu"] },
        { english_name: "Icelandic", name: ["Íslenska"], code: ["is"] },
        { english_name: "Indonesian", name: ["Bahasa Indonesia"], code: ["id"] },
        { english_name: "Interlingua", name: ["Interlingua"], code: ["ia"] },
        { english_name: "Irish", name: ["Gaeilge"], code: ["ga"] },
        { english_name: "Italian", name: ["Italiano"], code: ["it"] },
        { english_name: "Japanese", name: ["日本語"], code: ["ja"] },
        { english_name: "Javanese", name: ["Basa Jawa"], code: ["jv"] },
        { english_name: "Kannada", name: ["ಕನ್ನಡ"], code: ["kan"] },
        { english_name: "Kazakh", name: ["qazaqşa | қазақша"], code: ["kaz"] },
        { english_name: "Khmer", name: ["ភាសាខ្មែរ"], code: ["khm"] },
        { english_name: "Khuzdul", name: ["Khuzdul"], code: ["qkz"] },
        { english_name: "Kiswahili", name: ["Kiswahili"], code: ["sw"] },
        { english_name: "Klingon", name: ["tlhIngan-Hol"], code: ["tlh"] },
        { english_name: "Korean", name: ["한국어", "한국말"], code: ["ko"] },
        { english_name: "Kurdish", name: ["Kurdî | کوردی"], code: ["ku"] },
        { english_name: "Kyrgyz", name: ["Кыргызча"], code: ["kir"] },
        { english_name: "Latin", name: ["Lingua latina"], code: ["la"] },
        { english_name: "Latvian", name: ["Latviešu valoda"], code: ["lv"] },
        { english_name: "Lithuanian", name: ["Lietuvių kalba"], code: ["lt"] },
        { english_name: "Low German", name: ["Plattdüütsch"], code: ["nds"] },
        { english_name: "Luxembourgish", name: ["Lëtzebuergesch"], code: ["lb"] },
        { english_name: "Macedonian", name: ["македонски"], code: ["mk"] },
        { english_name: "Malay", name: ["Bahasa Malaysia"], code: ["ms"] },
        { english_name: "Malayalam", name: ["മലയാളം"], code: ["ml"] },
        { english_name: "Maltese", name: ["Malti"], code: ["mt"] },
        { english_name: "Manchu", name: ["ᠮᠠᠨᠵᡠ ᡤᡳᠰᡠᠨ"], code: ["mnc"] },
        { english_name: "Marathi", name: ["मराठी"], code: ["mr"] },
        { english_name: "Mikasuki", name: ["Mikisúkî"], code: ["mik"] },
        { english_name: "Mongolian", name: ["ᠮᠣᠩᠭᠣᠯ ᠪᠢᠴᠢᠭ᠌ | Монгол Кирилл үсэг"], code: ["mon"] },
        { english_name: "Nahuatl", name: ["Nāhuatl"], code: ["nah"] },
        { english_name: "Norwegian", name: ["Norsk"], code: ["no"] },
        { english_name: "Old English", name: ["Eald Englisċ"], code: ["ang"] },
        { english_name: "Ottoman Turkish", name: ["لسان عثمانى"], code: ["ota"] },
        { english_name: "Pashto", name: ["پښتو"], code: ["ps"] },
        { english_name: "Persian", name: ["فارسی"], code: ["fa"] },
        { english_name: "Polish", name: ["Polski"], code: ["pl"] },
        { english_name: "Portuguese-BR", name: ["Português brasileiro"], code: ["ptBR", "pt-BR"] },
        { english_name: "Portuguese-PT", name: ["Português europeu"], code: ["ptPT", "pt-PT"] },
        { english_name: "Punjabi", name: ["ਪੰਜਾਬੀ"], code: ["pa"] },
        { english_name: "Quebec Sign Language", name: ["Langue des signes québécoise"], code: ["fcs"] },
        { english_name: "Quenya", name: ["Quenya"], code: ["qya"] },
        { english_name: "Romanian", name: ["Română"], code: ["ro"] },
        { english_name: "Russian", name: ["Русский"], code: ["ru"] },
        { english_name: "Scots", name: ["Scots"], code: ["sco"] },
        { english_name: "Serbian", name: ["Српски"], code: ["sr"] },
        { english_name: "Sindarin", name: ["Sindarin"], code: ["sjn"] },
        { english_name: "Sinhala", name: ["සිංහල"], code: ["si"] },
        { english_name: "Slovak", name: ["Slovenčina"], code: ["sk"] },
        { english_name: "Slovenian", name: ["Slovenščina"], code: ["slv"] },
        { english_name: "Somali", name: ["af Soomaali"], code: ["so"] },
        { english_name: "Spanish", name: ["Español"], code: ["es"] },
        { english_name: "Sumerian", name: ["𒅴𒂠"], code: ["sux"] },
        { english_name: "Swedish", name: ["Svenska"], code: ["sv"] },
        { english_name: "Tamil", name: ["தமிழ்"], code: ["ta"] },
        { english_name: "Telugu", name: ["తెలుగు"], code: ["tel"] },
        { english_name: "Thermian", name: ["Thermian"], code: ["tqx"] },
        { english_name: "Thai", name: ["ไทย"], code: ["th"] },
        { english_name: "Tibetan", name: ["བོད་སྐད་"], code: ["bod"] },
        { english_name: "toki pona", name: ["toki pona"], code: ["qtp"] },
        { english_name: "Tsakonian", name: ["τσακώνικα"], code: ["tsd"] },
        { english_name: "Turkish", name: ["Türkçe"], code: ["tr"] },
        { english_name: "Ukrainian", name: ["Українська"], code: ["uk"] },
        { english_name: "Urdu", name: ["اُردُو"], code: ["urd"] },
        { english_name: "Uyghur", name: ["ئۇيغۇر تىلى"], code: ["uig"] },
        { english_name: "Vietnamese", name: ["Tiếng Việt"], code: ["vi"] },
        { english_name: "Volapük", name: ["Volapük"], code: ["vol"] },
        { english_name: "Welsh", name: ["Cymraeg"], code: ["cy"] },
        { english_name: "Yiddish", name: ["יידיש"], code: ["yi"] },
        { english_name: "Yucatec Maya", name: ["maayaʼ tʼàan"], code: ["yua"] },
        { english_name: "Zulu", name: ["isiZulu"], code: ["zu"] },
    ];

    // new: { english_name: "", name: [""], code: [""] },

    const languages_by_name = languages.reduce((acc, lang) => {
        lang.name.forEach((name) => {
            acc[name.toLowerCase()] = lang.english_name;
        });
        return acc;
    }, {});

    const getNameWithEnglish = (lang_name) => {
        const result = {
            name_with_english: undefined,
            found_language: false,
        };

        const lang_name_lowercase = lang_name.toLowerCase();
        if (languages_by_name[lang_name_lowercase]) {
            result.found_language = true;
            
            if (lang_name !== languages_by_name[lang_name_lowercase]) {
                result.name_with_english = `${languages_by_name[lang_name_lowercase]} (${lang_name})`;
            }
        }

        return result;
    };

    // dropdowns
    $('select[id$="language_id"]').each(function () {
        const options = $(this).find('option');
        const selected_val = $(this).val();
        const translation_not_found = [];

        options.each(function () {
            const lang_name = $(this).text();
            const { name_with_english, found_language } = getNameWithEnglish(lang_name);
            let option_name = lang_name;

            if (name_with_english) {
                option_name = name_with_english;
                $(this).text(option_name);
            }
            else if (DEBUG && lang_name && !found_language) {
                translation_not_found.push(`{ english_name: "", name: ["${lang_name}"], code: ["${$(this).val()}"] },`);
            }
            $(this).data('sort', $(this).val() ? option_name.toLowerCase() : '');
        });

        if (DEBUG) { console.log(translation_not_found.length + '\n\n' + translation_not_found.join('\n')); }

        options.sort(function (a, b) {
            return ($(a).data('sort') > $(b).data('sort') ? 1 : -1);
        });

        $(this).empty().append(options).val(selected_val);
    });

    // language labels
    $('dd.language, dl.language dt a, .translations a').each(function () {
        const lang_name = $(this).text().trim();
        const { name_with_english } = getNameWithEnglish(lang_name);

        if (name_with_english) {
            $(this).text(name_with_english);
        }
    });

    // translations count in news posts
    const translations_label = $('.news .meta dt.translations');
    if (translations_label.length) {
        translations_label.html(`Translations <b>(${$('.news .meta .translations .languages li').length})</b>:`);
    }

})(jQuery);