LINUX.ORG.RU

JS: проблема в юзерскрипте

 , , ,


0

1

Здравствуйте!

Я наткнулся на эту фиговину, которая переводит все ники в KOI7. Решил сделать из нее нормальный русификатор ников, но что-то пошло не так…

// SPDX-License-Identifier: MIT-0

// ==UserScript==
// @name        LOR-Russification
// @namespace   https://www.linux.org.ru/*
// @description LOR-Russification
// @include     https://www.linux.org.ru/*
// @version     1
// @grant       none
// ==/UserScript==

(function () {

window.addEventListener("load", function() {

var c={anonymous:"Анонимус",Deleted:"Удаленный",Zhbert:"Жберт","Vsevolod-linuxoid":"Всеволод",maxcom:"Админ",leave:"leave",cocucka:"Сосиска",zh:"ж",ZH:"Ж",Zh:"Ж",a:"а",b:"б",c:"ц", d:"д",e:"е",f:"ф",g:"г",h:"х",i:"и",j:"й",k:"к",l:"л",m:"м",n:"н",o:"о",p:"п",q:"къ",r:"р",s:"с",t:"т",u:"у",v:"в",w:"у",x:"кс",y:"ы",z:"з",A:"А",B:"Б",C:"Ц",D:"Д",E:"Е",F:"Ф",G:"Г",H:"Х",I:"И",J:"Й",K:"К",L:"Л",M:"М",N:"Н",O:"О",P:"П",Q:"КЪ",R:"Р",S:"С",T:"Т",U:"У",V:"В",W:"У",X:"КС",Y:"Ы",Z:"З",};
    var a = {};
    var b = [];
    document.querySelectorAll('a[itemprop="creator"], .sign_more a, #loginGreating a, table.head a, .nickname, .message-table s, .tag, .secondary, [class="btn btn-default"], [class="btn btn-selected"], #sitetitle, #ft-info, .msg-top-header, .grid-3-2, .navLink, em, .group, option').forEach(function(d) {
        b.push(d)
    });
    document.querySelectorAll(".sign, .sign_more, article .title, .message-table td, .tracker-last p, .tracker-src p").forEach(function(d) {
        for (var e = 0; e < d.childNodes.length; e++) {
            var f = d.childNodes[e];
            if (f.nodeType === 3) {
                b.push(f)
            }
        }
    });
    b.forEach(function(g) {
        var h = g.textContent;
        var e = "";
        if (a[h] != undefined) {
            g.textContent = a[h];
            return
        }
        for (var f = 0; f < h.length; f++) {
            var d = h[f];
            var j = c[d];
            if (j === undefined) {
                e += d
            } else {
                e += j
            }
        }
        g.textContent = e;
        a[h] = e
    })
});
})();

Не работает преобразование zh в ж, Zh и ZH в Ж (то есть Zhbert становится Зхбертом), а также некоторых ников, в т.ч. @anonymous и @Deleted. Гуру JS, помогите, пожалуйста!

ps. JS не знаю, поэтому проблемы. pps. Неужели тут нет гуру JS?

Ответ на: комментарий от hikari

Постойте, у меня сначала стоят целые ники, потом zh, а потом буквы. Или я что-то неправильно понял?

zagatov_lev ()
Ответ на: комментарий от Korchevatel

Нет, не преобразовывается.

ps. А вы – Корцхевател, но потом, после решения проблемы, сделаю вас Корчевателем. А я – загатов_лев. А еще раздел Job стал разделом Йоб…

zagatov_lev ()
Последнее исправление: zagatov_lev (всего исправлений: 2)
Ответ на: комментарий от Korchevatel
~$ echo 'zagatov_lev, Korchevatel, other-nick-name1234567890' | iconv -t utf8 | iconv -f koi8-r
zagatov_lev, Korchevatel, other-nick-name1234567890
~$ 

Абсолютно одно и то же.

zagatov_lev ()

Неужели тут нет гуру JS?

Нет. Гуру на форуме не сидят. Гуру своими знаниями и навыками горы бабла заколачивают. Стебаться над новичками им недосуг.

Не работает преобразование zh в ж, Zh и ZH в Ж

А с чего ты взял, что вообще должно работать? Оригинальный скрипт был рассчитан на побуквенную замену.

Решил сделать из нее нормальный русификатор ников, но что-то пошло не так…

Я нашёл, что пошло не так. Вот:

JS не знаю, поэтому проблемы.

i-rinat ★★★★★ ()
Ответ на: комментарий от zagatov_lev

Пфффф….

У тебя меняются побуквенно символы, поэтому так и происходит. Тебе нужно до начала побуквенной замены пробежаться по слову, и найти вхождения всех «двойных» букв. Если они есть - идти побуквенно, но при дохождении до «двойной» буквы менять ее сразу, а не каждую букву, при этом каретку передвигать на два символа, а не на один.

И для этого нужен список всех «двухбуквенных» символов.

Это без привязки к жабаскрипту. Могу тебе такое на голой джаве написать, но не хочу.

Zhbert ★★★★★ ()
Ответ на: комментарий от gedisdone

Опередил. Но не до конца - я бы не в два прохода делал, а в один, просто с двойным перескоком и предварительным анализом.

Zhbert ★★★★★ ()
Ответ на: комментарий от zagatov_lev

В жабаскрипте я не шарю, уж извиняй. А алгоритм я тебе подсказал.

Вангую, что проблема в том, что до того, как он начинает «искать» двухбуквенные, он успевает изменить их первую букву.

Zhbert ★★★★★ ()
Ответ на: комментарий от Zhbert

Этого не может быть, так как сначала в списке стоят 2хсимвольные, а потом 1символьные. И сначала должны заменяться 2хсимвольные.

zagatov_lev ()
Ответ на: комментарий от Uncle_Bobby

Меня, как чистокровного арийца, это сильно обижает.

Zhbert ★★★★★ ()
Ответ на: комментарий от zagatov_lev

Тут

for (var f = 0; f < h.length; f++) { var d = h[f]; var j = c[d];}
из ника делают массив букв и проверяют по очереди каждую букву, записывая ее в d, потом ища её в коллекции c и записывая русскую букву в j.

kogoth ()

Подержи-ка мой смузи.

const mapping = {
    anonymous: "Анонимус",
    Deleted: "Удаленный",
    Zhbert: "Жберт",
    "Vsevolod-linuxoid": "Всеволод",
    maxcom: "Админ",
    leave: "leave",
    cocucka: "Сосиска",
    zh:"ж", ZH:"Ж", Zh:"Ж", ch: "ч", CH: "Ч", Ch: "Ч", sh: "ш", SH: "Ш", Sh: "Ш",
    a: "а", b: "б", c: "ц", d: "д", e: "е", f: "ф", g: "г", h: "х", i: "и", j: "й",
    k: "к", l: "л", m: "м", n: "н", o: "о", p: "п", q: "къ", r: "р", s: "с", t: "т",
    u: "у", v: "в", w: "у", x: "кс", y: "ы", z: "з",
    A: "А", B: "Б", C: "Ц", D: "Д", E: "Е", F: "Ф", G: "Г", H: "Х", I: "И", J: "Й",
    K: "К", L: "Л", M: "М", N: "Н", O: "О", P: "П", Q: "КЪ", R: "Р", S: "С", T: "Т",
    U: "У", V: "В", W: "У", X: "КС", Y: "Ы", Z: "З"
};

const retranslit = (string, mapping) => {
    let result = string;
    for (let key of Object.keys(mapping)) {
        const keyRegex = new RegExp(key, 'g');
        result = result.replace(keyRegex, mapping[key], 'g');
    }
    return result;
}

// tests

["ppppp", "maxcom", "alpha", "Zhbert", "zhbert", "Nervous", "NeRvOuS"].forEach(name => {
    console.log("%s: %s", name, retranslit(name, mapping));
});
ppppp: ппппп
maxcom: Админ
alpha: алпха
Zhbert: Жберт
zhbert: жберт
Nervous: Нервоус
NeRvOuS: НеРвОуС

Тупо в лоб, работает, но медленно. Но работает.

Nervous ★★★★ ()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от zagatov_lev

Вместо

var c = {...};
пастите едитинг выше
var mapping = {...}; var retranslit = {...};
Соответственно цикл b.forEach будет выглядеть
b.forEach(function(g) { g.textContent = retranslit(g.textContent,mapping);})

kogoth ()
Ответ на: комментарий от zagatov_lev

Блокирован 25.08.20 19:07:08, модератором zagatov_lev по причине: самостоятельная блокировка

Взял и убился с горя. А если бы прочитал книжку Флэнагана, все могло бы быть совсем по-другому.

Nervous ★★★★ ()
Ответ на: комментарий от Nervous

Тупо в лоб, работает, но медленно. Но работает.

Я бы отсортировал еще ключи mapping по длине ключа по убыванию на всякий случай. Хотя в целом код - моё почтение:) Я бы настолько просто не сделал, а нагородил бы как минимум 3 кейса для полного совпадения, больше 1 символа и посимвольный перебор.

crutch_master ★★★★★ ()
Последнее исправление: crutch_master (всего исправлений: 2)
Ответ на: комментарий от crutch_master

Я бы отсортировал еще ключи mapping по длине ключа

Согласен, так проще пользоваться. Еще можно создавать регулярки для всех ключей сразу при загрузке скрипта, чтобы не создавать их при каждом вызове функции — должно меньше тормозить.

Nervous ★★★★ ()
Ответ на: комментарий от zagatov_lev

Тебе четко сказали, что надо пойти, например, на MDN или W3Schools и там минимально подучить язык, прежде чем им пытаться решать реальные задачи. Ну и не только синтаксис и идиомы JS тебе пригодятся, разумеется.

К примеру, выше @Nervous отмечает использование метода списка .push – это императивный стиль. Вне контекста это придирка, конечно, потому что этот метод бывает полезен, когда ты не знаешь заранее итоговую длину списка или когда тебе нужно работать с состоянием вне цикла/тела функции, но здесь состояние анонимной функции не меняется. Ты можешь переписать этот кусочек с использованием функционального стиля и метода .map, поскольку у тебя 1 к 1 отображение одного списка в другой, более того, ты можешь сделать это и с диграфами, и с другими комбинациями букв (делаешь функцию, разбирающую строку с именем на кандидаты букв, делаешь вторую, которая подставляет взамен необходимый символ, и суешь в map, который отображает имена в ASCII в той же длины новый список в КОИ7). Этот метод ест несколько больше памяти по сравнению с вставкой в существующий список, потому что он вызывает предоставленную тобой функцию для каждого из элементов и кладет результаты в том же порядке в новый список, возвращаемый функцией .map. Но при этом ты можешь отчасти гарантировать одинаковые производительность и порядок итерации во всех браузерах. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Надеюсь, что ты перечитаешь это после удаления аккаунта и смены ника. Я сам довольно много докучал умным людям, которые могли бы не мне объяснять, что к чему, а зарабатывать деньги в этот момент, и рекомендую тебе читать мануалы, пока ты точно не будешь уверен, что не можешь самостоятельно решить свою проблему. Приятного написания кода!

mazdai ★★ ()
Последнее исправление: mazdai (всего исправлений: 6)
Ответ на: комментарий от mazdai

Я сам довольно много докучал умным людям, которые могли бы не мне объяснять, что к чему, а зарабатывать деньги в этот момент

Я сейчас сижу с вами вместо того, чтобы «зарабатывать деньги в этот момент». Добровольно, просто так. Потому что заработок денег не является самоцелью ни для кого, кроме отдельных наглухо поехавших людей.

byko3y ★★ ()
Ответ на: комментарий от mazdai

Nervous отмечает использование метода списка .push – это императивный стиль

Nervous вообще хотел отметить однобуквенные имена переменных, но это тоже отличная придирка %)

Nervous ★★★★ ()
Ответ на: комментарий от byko3y

Если судить по стоимости часа работы, то ЛОР – это просто Эльдорадо потерянного времени. Однако я вас прекрасно понимаю и поддерживаю! Мне, правда, не удается формально определить границу между обучением замены себе, что даже для «адекватных» людей не очень выгодно, и помощи такому же пользователю-энтузиасту. Если человек интересуется – я ему помогу, как и мне помогали, потому что и без меня этот человек все найдет и изучит.

mazdai ★★ ()
Ограничение на отправку комментариев: только для зарегистрированных пользователей