Files
mybb-april-fools/src/jokes/latinization.ts
T

107 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {Joke, JokeSettings} from '../joke';
import {getTextNodes} from '../common';
/**
* **Латинизация**
*
* Все символы на странице или только в постах или еще где-то местами -
* латиницей вместо кириллицы и наоборот
*
* @author Идея: Alex_63
* @author Kozhilya
*/
export class LatinizationJoke extends Joke<LatinizationJokeSettings> {
id = 'latinization';
title = 'Латинизация';
description = 'Все символы на странице или только в постах ' +
'или еще где-то местами - латиницей вместо кириллицы и наоборот';
_settings = new LatinizationJokeSettings();
/**
* Запуск шутки
*/
start(): void {
const textNodes = getTextNodes(this.settings.selector);
textNodes.each((_, node) => this.processNode(node as Text));
}
/**
* Латинизация или кириллизация слова
* @param {string} word
* @return {string}
* @private
*/
private latinize(word: string): string {
if (/[а-яА-ЯёЁ0-9_-]+/.test(word)) {
// Кириллица в латиницу
for (const [ru, en] of Object.entries(this.settings.ruToEn)) {
word = word.replace(new RegExp(ru, 'g'), en).
replace(new RegExp(ru.toUpperCase(), 'gi'), en.toUpperCase());
}
} else if (/[a-zA-Z0-9_-]+/.test(word)) {
// Латиница в кириллицу
for (const [en, ru] of Object.entries(this.settings.enToRu)) {
word = word.replace(new RegExp(en, 'g'), ru).
replace(new RegExp(en.toUpperCase(), 'gi'), ru.toUpperCase());
}
}
return word;
}
/**
* Обработка текстовой ноды
* @param {Text} node
* @private
*/
private processNode(node: Text) {
node.textContent = node.textContent?.replace(
/([А-Яа-яA-Za-z]+)/gm,
(_: string, word: string) => this.latinize(word),
);
}
}
/**
* Класс настроек для шутки "Латинизация"
*/
export class LatinizationJokeSettings implements JokeSettings {
enabled: boolean = true;
chance: number = 10;
/**
* Селектор, в котором может изменяться текст
*/
selector: string = '.post-content';
/**
* Правила преобразования из кириллицы в латиницу
*/
ruToEn: { [key in string]: string } = {
'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd',
'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i',
'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n',
'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't',
'у': 'u', 'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch',
'ш': 'sh', 'щ': 'shch', 'ъ': 'ie', 'ы': 'y', 'ь': '',
'э': 'e', 'ю': 'u', 'я': 'ya',
};
/**
* Правила преобразования из латиницы в кириллицу
*/
enToRu: { [key in string]: string } = {
'a': 'а', 'b': 'б', 'c': 'с', 'd': 'д', 'e': 'е',
'f': 'ф', 'gh': 'ж', 'g': 'г', 'h': 'х', 'i': 'и',
'j': 'й', 'k': 'к', 'l': 'л', 'm': 'м', 'n': 'н',
'o': 'о', 'p': 'п', 'q': 'кью', 'r': 'р', 's': 'с',
't': 'т', 'u': 'ю', 'v': 'в', 'w': 'в', 'x': 'кс',
'y': 'ы', 'z': 'з',
};
}