您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Replaces hyphens, quotation marks, uncanonic smiles and "yo" in some russian words.
当前为
- // ==UserScript==
- // @name Textarea Typograf
- // @namespace https://github.com/glebkema/tampermonkey-textarea-typograf
- // @description Replaces hyphens, quotation marks, uncanonic smiles and "yo" in some russian words.
- // @author glebkema
- // @copyright 2020, glebkema (https://github.com/glebkema)
- // @license MIT
- // @version 0.4.24
- // @match http://*/*
- // @match https://*/*
- // @grant none
- // @run-at context-menu
- // ==/UserScript==
- // ==OpenUserJS==
- // @author glebkema
- // ==/OpenUserJS==
- 'use strict';
- const MODE_ENDINGS = 'endings';
- const MODE_EXCEPTIONS = 'exceptions';
- const MODE_EXTRA_PREFIXES = 'extraPrefixes';
- const MODE_NO_CAPITAL_LETTER = 'noCapitalLetter';
- const MODE_NO_PREFIXES = 'noPrefixes';
- const MODE_NO_SUFFIXES = 'noSuffixes';
- const MODE_STANDARD = 'standard';
- class Typograf {
- run(element) {
- if (element && 'textarea' === element.tagName.toLowerCase() && element.value) {
- const start = element.selectionStart;
- const end = element.selectionEnd;
- if (start === end) {
- element.value = this.improve(element.value);
- } else {
- const selected = element.value.substring(start, end);
- const theLength = element.value.length;
- element.value = element.value.substring(0, start)
- + this.improve(selected) + element.value.substring(end, theLength);
- }
- } else {
- // console.info('Start editing a non-empty textarea before calling the script');
- }
- }
- improve(text) {
- if (text) {
- text = this.improveDash(text);
- text = this.improveQuotes(text);
- text = this.improveSmile(text);
- text = this.improveYo(text);
- }
- return text;
- }
- improveDash(text) {
- text = text.replace(/ - /g, ' — ');
- return text;
- }
- improveQuotes(text) {
- text = text.replace(/(?<=^|[(\s])"/g, '«');
- text = text.replace(/"(?=$|[.,;:!?)\s])/g, '»');
- return text;
- }
- improveSmile(text) {
- text = text.replace(/([:;])[—oо]?([D)(|])/g, '$1-$2');
- return text;
- }
- improveYo(text) {
- // verbs - list of the cores (with a capital letter and yo)
- text = this.improveYoVerb(text, MODE_EXCEPTIONS,
- 'Льё,Мнё,Рвё,Трё');
- text = this.improveYoVerb(text, MODE_EXTRA_PREFIXES,
- 'Берё,Вернё,Даё,Орё,Плывё,Поё,Стаё');
- text = this.improveYoVerb(text, MODE_NO_CAPITAL_LETTER,
- 'Йдё,Ймё');
- text = this.improveYoVerb(text, MODE_NO_PREFIXES,
- 'Идё,Льнё,Начнё,Обернё,Придё,Прильнё,Улыбнё');
- text = this.improveYoVerb(text, MODE_NO_SUFFIXES,
- 'Шёл');
- text = this.improveYoVerb(text, MODE_STANDARD,
- 'Бьё,Ведё,Везё,Врё,Вьё,Ждё,Жмё,Жрё,Несё,Прё,Пьё,Ткнё,Чтё,Шлё,Шьё');
- // verbs - fix the exceptions
- text = this.replaceException(text, 'Расстаёт', '(?![а-дж-я])');
- text = this.replaceException(text, 'Шлём');
- // list of the words (with a capital letter and yo)
- text = this.improveYoWord(text, null,
- 'Её,Ещё,Моё,Неё,Своё,Твоё');
- text = this.improveYoWord(text, null,
- 'Вдвоём,Втроём,Объём,Остриём,Приём,Причём,Огнём,Своём,Твоём');
- text = this.improveYoWord(text, null,
- 'Василёк,Мотылёк,Огонёк,Пенёк,Ручеёк');
- text = this.improveYoWord(text, null,
- 'Затёк,Натёк,Потёк');
- text = this.improveYoWord(text, null,
- 'Грёза,Грёзы,Слёзы');
- text = this.improveYoWord(text, MODE_ENDINGS,
- 'Партнёр,Проём');
- text = this.improveYoWord(text, MODE_ENDINGS,
- 'Зачёт,Отчёт,Расчёт,Учёт');
- return text;
- }
- improveYoVerb(text, mode, list) {
- return this.iterator(text, mode, list, this.replaceYoVerb.bind(this));
- }
- improveYoWord(text, mode, list) {
- return this.iterator(text, mode, list, this.replaceYoWord.bind(this));
- }
- iterator(text, mode, list, callback) {
- if ('string' === typeof list) {
- list = list.split(',');
- }
- for (let i = 0; i < list.length; i++) {
- const replace = list[i].trim();
- if (replace) {
- const find = this.removeAllYo(replace);
- text = callback(text, mode, find, replace);
- }
- }
- return text;
- }
- removeAllYo(text) {
- return text.replace(/ё/g, 'е').replace(/Ё/g, 'Е');
- }
- replaceException(text, exception, lookAhead = '') {
- const replace = this.removeAllYo(exception);
- let regex = new RegExp(exception + lookAhead, 'g');
- text = text.replace(regex, replace);
- regex = new RegExp('(?<![А-Яa-я])' + exception.toLowerCase() + lookAhead, 'g');
- text = text.replace(regex, replace.toLowerCase());
- return text;
- }
- replaceYo(text, find, replace,
- lookBehind = '(?<![б-джзй-нп-тф-я])', // +аеиоу
- // lookAhead = '(?=[мтш])'
- lookAhead = '(?=(?:м|мся|т|те|тесь|тся|шь|шься)(?:[^а-яё]|$))'
- ) {
- let regex;
- let findLowerCase = find.toLowerCase();
- // NB: \b doesn't work for russian words
- // 1) starts with a capital letter = just a begining of the word
- if (find !== findLowerCase) {
- regex = new RegExp(find + lookAhead, 'g');
- text = text.replace(regex, replace);
- }
- // 2) in lowercase = with a prefix ahead or without it
- regex = new RegExp(lookBehind + findLowerCase + lookAhead, 'gi');
- text = text.replace(regex, replace.toLowerCase());
- return text;
- }
- replaceYoVerb(text, mode, find, replace) {
- if (MODE_EXCEPTIONS === mode) {
- return this.replaceYo(text, find, replace,
- '(?<![б-джзй-нп-тф-я]|зе|ко|фе)' ); // +аеиоу -"зельем" -"корвет" -"фельетон"
- // '(?=[мтш])(?!мо)(?!ть)'); // -"мнемо" -"треть"
- }
- if (MODE_EXTRA_PREFIXES === mode) {
- let lookBehind = '(?<![гжк-нпрф-я])'; // +аеиоу +бвдзст
- if ('Даё' === replace) {
- lookBehind = '(?<![гжк-нпрф-ъь-я])'; // +ы
- } else if ('Стаё' === replace) {
- lookBehind = '(?<![гжк-нпрф-я]|ра)'; // -"вы/за/от/подрастает"
- }
- return this.replaceYo(text, find, replace, lookBehind);
- }
- if (MODE_NO_CAPITAL_LETTER === mode) {
- return this.replaceYo(text, find.toLowerCase(), replace);
- }
- if (MODE_NO_PREFIXES === mode) {
- return this.replaceYo(text, find, replace,
- '(?<![А-Яа-яЁё])');
- }
- if (MODE_NO_SUFFIXES === mode) {
- return this.replaceYo(text, find, replace,
- '(?<![б-джзй-нп-тф-я])', // +аеиоу
- '(?![а-яё])');
- }
- // MODE_STANDARD
- return this.replaceYo(text, find, replace);
- }
- replaceYoWord(text, mode, find, replace) {
- if (MODE_ENDINGS === mode) {
- return this.replaceYo(text, find, replace,
- '(?<![А-Яа-яЁё])',
- '');
- }
- return this.replaceYo(text, find, replace,
- '(?<![А-Яа-яЁё])',
- '(?![а-яё])');
- }
- }
- // if it's a browser, not a test
- if ('undefined' !== typeof document) {
- let typograf = new Typograf();
- typograf.run(document.activeElement);
- }
- // if it's a test by Node.js
- if (module) {
- module.exports = {
- Typograf: Typograf,
- };
- } else {
- var module; // hack for Tampermonkey's eslint
- }