4 changed files with 865 additions and 497 deletions
@ -0,0 +1,416 @@
@@ -0,0 +1,416 @@
|
||||
//
|
||||
// Copyright (C) 2016-2019, Maxim Lihachev, <envrm@yandex.ru>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, version 3.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
'use strict'; |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Иерархия элементов на странице
|
||||
var HTML = { |
||||
container: "", |
||||
_select: function(element) { return document.getElementById(this.container + "-" + element); }, |
||||
input: function() { return this._select("word"); }, |
||||
button: function() { return this._select("convert"); }, |
||||
dict: function() { return this._select("dict"); }, |
||||
content: function() { return this._select("content"); }, |
||||
full: function() { return this._select("full"); }, |
||||
help: function() { return this._select("help"); }, |
||||
image: function() { return this._select("image"); }, |
||||
}; |
||||
|
||||
//Вывод справки с примерами использования
|
||||
function show_help() { |
||||
HTML.vis(HTML.help()); |
||||
HTML.vis(HTML.content()); |
||||
} |
||||
|
||||
//Смена названия по клику
|
||||
function swap_title(id) { |
||||
var e = document.getElementById(id); |
||||
if(e.style.display == 'inline') { |
||||
e.style.display = 'none'; |
||||
} else { |
||||
e.style.display = 'inline'; |
||||
} |
||||
} |
||||
|
||||
HTML.vis = function(e, v) { |
||||
if (v !== undefined) { |
||||
e.style.visibility = v; |
||||
} else { |
||||
e.style.visibility = e.style.visibility === "visible" ? "hidden" : "visible"; |
||||
} |
||||
} |
||||
|
||||
//Инициализация документа
|
||||
HTML.init = function(root) { |
||||
//Задание базового id для всех элементов
|
||||
this.container = root; |
||||
|
||||
//Конвертирование по нажатию <Enter>
|
||||
this.input().addEventListener('keyup', event => { |
||||
event.preventDefault(); |
||||
event.keyCode == 13 && tr(); |
||||
}); |
||||
|
||||
//Конвертирование по нажатию кнопки
|
||||
this.button().onclick = () => tr(); |
||||
}; |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
FEM.words.convert = function(string) { |
||||
for (var fem_w in this) { |
||||
string = string.replace(new RegExp('(^|\\s)+' + fem_w, "ig"), '$1' + this[fem_w]) |
||||
.replace(/(.)/, s => s.toUpperCase()); |
||||
} |
||||
return string; |
||||
}; |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Первый элемент списка - окончание (в виде регулярного выражения)
|
||||
let ending = tuple => new RegExp("^.*" + tuple[0] + "$", "i"); |
||||
|
||||
//Второй элемент списка - смещение
|
||||
let offset = tuple => tuple[1]; |
||||
|
||||
//Случайный элемент списка
|
||||
let random_word = wordlist => wordlist[Math.floor(Math.random() * wordlist.length)]; |
||||
|
||||
//Оборачивание в <span> с указанным классом
|
||||
let html_wrap = (str, cl) => `<span class="${cl}">${str}</span>`; |
||||
|
||||
//Цветовое выделение текста
|
||||
let css_end = ending => html_wrap(ending, "ending"); |
||||
|
||||
//Символ gender gap
|
||||
let css_gender_gap = html_wrap(' \u26A7 ', "queer"); |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Конструирование феминитива с gender_gap
|
||||
function construct_feminitive(stem, ending, gap) { |
||||
return gap ? stem + css_gender_gap + css_end(ending) : stem + "_" + ending; |
||||
} |
||||
|
||||
//Длина шаблона, подпадающего под регулярное выражение r
|
||||
function regex_len(r) { |
||||
return r.replace(/\[[^\[\]]*\]/g, "x").length; |
||||
} |
||||
|
||||
//Отправка адреса страницы в vk.com
|
||||
function share_page() { |
||||
let vk_url = "http://vk.com/share.php" |
||||
+ "?url=" + URL.href |
||||
+ "&title=" + URL.title |
||||
+ "&description=" + URL.description.text; |
||||
|
||||
let new_tab = window.open(vk_url,'_blank'); |
||||
new_tab.focus(); |
||||
} |
||||
|
||||
//Сохранение изображения с феминитивом
|
||||
function download_image() { |
||||
html2canvas(HTML.image(), { |
||||
onrendered: canvas => { |
||||
let a = document.createElement('a'); |
||||
a.href = canvas.toDataURL(); |
||||
a.download = HTML.content().innerHTML + '.png'; |
||||
a.click(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
//Создание феминитива
|
||||
function make_feminitives(word, visibleGaps) { |
||||
//Обрабатываем только слова длиннее трёх символов
|
||||
if (word.length < 3) return [word, word]; |
||||
|
||||
if (FEM.words[word] != undefined) { |
||||
let wrd = visibleGaps ? FEM.words[word] : FEM.words[word].replace("_", ""); |
||||
|
||||
return [wrd, wrd]; |
||||
} |
||||
|
||||
var stem = ""; //Основа слова
|
||||
// var current_ending = word.slice(-2); //Текущее окончание
|
||||
var current_endings = [word.slice(-4), word.slice(-3), word.slice(-2)]; |
||||
var feminitives = []; //Массив феминитивов
|
||||
var femicards = []; //Массив феминитивов для карточки
|
||||
|
||||
var found = false; |
||||
|
||||
current_endings.forEach(current_ending => { |
||||
if (!found) { |
||||
for (let fem_ending in FEM.endings) { |
||||
FEM.endings[fem_ending].forEach(end => { |
||||
if (regex_len(end[0]) === current_ending.length |
||||
&& ending(end).test(current_ending)) { |
||||
//Удаление лишних букв из основы
|
||||
stem = offset(end) === 0 ? word : word.slice(0, -offset(end)); |
||||
|
||||
let rule = fem_ending.split("+"); |
||||
|
||||
let prefix, all_fem_endings; |
||||
|
||||
if (rule.length > 1) { |
||||
prefix = rule[0]; |
||||
all_fem_endings = rule[1]; |
||||
} else { |
||||
prefix = ""; |
||||
all_fem_endings = fem_ending; |
||||
} |
||||
|
||||
all_fem_endings.split("|").forEach(e => { |
||||
//Добавление фем-варианта слова в массив
|
||||
feminitives.push(construct_feminitive(stem + prefix, e, 1, visibleGaps)); |
||||
femicards.push(construct_feminitive(stem + prefix, e, 0, visibleGaps)); |
||||
|
||||
}); |
||||
|
||||
found = true; |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
//При отсутствии феминитивов считать корректным исходное слово
|
||||
return [FEM.random_word(femicards) || word, feminitives]; |
||||
} |
||||
|
||||
//Создание феминитива
|
||||
function make_feminitives_old(word) { |
||||
//Обрабатываем только слова длиннее трёх символов
|
||||
if (word.length < 3) return [word, word]; |
||||
|
||||
var stem = ""; //Основа слова
|
||||
var current_ending = word.slice(-2); //Текущее окончание
|
||||
var feminitives = []; //Массив феминитивов
|
||||
var femicards = []; //Массив феминитивов для карточки
|
||||
|
||||
for (let fem_ending in FEM.endings) { |
||||
FEM.endings[fem_ending].forEach(end => { |
||||
if (ending(end).test(current_ending)) { |
||||
//Удаление лишних букв из основы
|
||||
stem = offset(end) === 0 ? word : word.slice(0, -offset(end)); |
||||
|
||||
//Добавление фем-варианта слова в массив
|
||||
feminitives.push(construct_feminitive(stem, fem_ending, 1)); |
||||
femicards.push(construct_feminitive(stem, fem_ending, 0)); |
||||
} |
||||
}); |
||||
} |
||||
//При отсутствии феминитивов считать корректным исходное слово
|
||||
return [random_word(femicards) || word, feminitives]; |
||||
} |
||||
|
||||
//Поиск и феминизация дефиниции в викистранице
|
||||
function parseWikiPage(page) { |
||||
var wiki = page.split('\n'); |
||||
var definition = ""; |
||||
|
||||
wiki.some((line, n) => { |
||||
if (line.match(/^.*==== Значение ====.*$/)) { |
||||
let definition_line = n + 1; |
||||
|
||||
//После заголовка возможна пустая строка или помета (например, {{воен.}})
|
||||
if (wiki[n+1].trim().length === 0 |
||||
|| wiki[n+1].trim().match(/^{{[^}]*}}$/)) { |
||||
definition_line = n + 2; |
||||
} |
||||
|
||||
definition = wiki[definition_line] |
||||
//# дефиниция
|
||||
.replace(/^# ?/, "") |
||||
|
||||
//[[1]]
|
||||
.replace(/\[{2}([^\]|]*)\]{2}/g, "$1") |
||||
|
||||
//[[1|2]]
|
||||
.replace(/\[{2}[^|]*\|([^\]]*)\]{2}/g, "$1") |
||||
|
||||
//{{сокр.|слово<!--ком.-->.*$
|
||||
.replace(/\{{2}[а-яА-Я]+\.[^{}]*\|[^{}]*\}{2}\s*/g, "") |
||||
|
||||
//~ : возможна вложенность
|
||||
.replace(/\{{2}[а-яА-Я]+\.[^{}]*\|[^{}]*\}{2}\s*/g, "") |
||||
|
||||
//{{-}}$
|
||||
.replace(/\{\{-\}\}/g, "") |
||||
|
||||
//{{помета|...}}$
|
||||
.replace(/\{{2}помета\s*\|[^}]+\}{2}/g, "") |
||||
|
||||
//{{действие|(глагол)#...lang=LC}}$
|
||||
.replace(/\{{2}(действие)\s*\|([^#|]+)([#|].*lang=\w{2})?\}{2}/g, "$1 «$2»") |
||||
|
||||
//{{пример/семантика|.*$ или {{пример/семантика}}
|
||||
.replace(/\{{2}(пример|семантика)(\}{2}|\s*\|.*$)/g, "") |
||||
|
||||
//{{1|слово<!--комментарий-->.*$
|
||||
.replace(/\{{2}[^{}]*\|(lang=\w{2})?/g, "") |
||||
|
||||
//{{1}}
|
||||
.replace(/\{{2}([^\]|]*)\}{2}/g, "$1") |
||||
|
||||
//'''ударение'''
|
||||
.replace(/'''([^']*)'''/g, "«$1»") |
||||
|
||||
//<!--комментарий-->
|
||||
.replace(/<!--[^>]*-->/g, "") |
||||
|
||||
//}}
|
||||
.replace(/\}{2}/g, "") |
||||
|
||||
//ссылки [n]
|
||||
.replace(/\[[0-9]{1,}\]/g, "") |
||||
|
||||
//^,; ...
|
||||
.replace(/^\s*[,;]\s*/g, "") |
||||
|
||||
//{{.*$
|
||||
.replace(/\{{2}[^}]*$/g, "") |
||||
|
||||
//HTML
|
||||
.replace(/(<([^>]+)>)/ig, "") |
||||
|
||||
//Неразрывный пробел
|
||||
.replace(/ /g, " ") |
||||
|
||||
//Точка в конце предложения
|
||||
.replace(/ ?$/,"."); |
||||
|
||||
return true; |
||||
} |
||||
}); |
||||
|
||||
//Разделение дефиниции на массив слов и знаков препинания и феминизация слов
|
||||
var tokens = definition.match(/[\wа-яА-Яё]+|\d+| +|[.;,]|[^ \w\d\t.;,]+/ig) || []; |
||||
console.log(tokens); |
||||
|
||||
//Замена местоимений, предлогов и проч.
|
||||
HTML.full().innerHTML = FEM.words.convert(tokens.map(w => make_feminitives(w)[0]).join("")); |
||||
|
||||
//DEBUG
|
||||
console.log(definition); |
||||
console.log(tokens); |
||||
} |
||||
|
||||
//Запрос значения слова в викисловаре
|
||||
function get_wiktionary(term) { |
||||
var cors_url = "https://coors.now.sh/"; |
||||
var wiki_url = cors_url + "https://ru.wiktionary.org/w/index.php?action=raw&title=" + term; |
||||
|
||||
var xmlhttp = window.XMLHttpRequest |
||||
? new XMLHttpRequest() |
||||
: new ActiveXObject("Microsoft.XMLHTTP"); |
||||
|
||||
xmlhttp.onreadystatechange = function() { |
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { |
||||
parseWikiPage(xmlhttp.responseText); |
||||
} |
||||
}; |
||||
|
||||
xmlhttp.open("GET", wiki_url, true); |
||||
xmlhttp.send(); |
||||
} |
||||
|
||||
//Создание и вывод феминитива
|
||||
function tr(word) { |
||||
//Исходное слово
|
||||
var wd = word || HTML.input().value.trim().toLowerCase().replace(/<\/?[^>]+(>|$)/g, "").split(" ")[0]; |
||||
var feminitives = ""; |
||||
|
||||
//Состояние по умолчанию
|
||||
HTML.content().innerHTML = "Введите слово"; |
||||
HTML.dict().innerHTML = ""; |
||||
HTML.full().innerHTML = ""; |
||||
|
||||
HTML.vis(HTML.help(), "hidden"); |
||||
HTML.vis(HTML.content(), "visible"); |
||||
|
||||
//Изменение адреса
|
||||
URL.set(wd); |
||||
|
||||
//Вывод информации
|
||||
if (!wd) { |
||||
show_help(); |
||||
|
||||
return; |
||||
} else if (FEM.exceptions.contains(wd)) { |
||||
HTML.full().innerHTML = FEM.exceptions.definition(wd); |
||||
feminitives = FEM.exceptions.feminitives(wd); |
||||
} else { |
||||
get_wiktionary(wd); |
||||
feminitives = make_feminitives(wd); |
||||
} |
||||
//Вывод информации
|
||||
HTML.input().value = wd; |
||||
HTML.content().innerHTML = feminitives[0].replace(/(.)/, s => s.toUpperCase()); |
||||
HTML.dict().innerHTML = feminitives[1].join(" | ") |
||||
|| "Это слово и так прекрасно. Оставим его как есть."; |
||||
} |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Параметры URL
|
||||
var URL = { |
||||
opt: {}, |
||||
description: { |
||||
clear: function() { this.text = "Как феминистки пишут разные слова."; }, |
||||
set: function(wd) { this.text = 'Как феминистки пишут слово "' +wd+ '".'; }, |
||||
}, |
||||
set: function(wd) { |
||||
if (!wd) { |
||||
window.history.pushState({}, null, window.location.href.split('?')[0]); |
||||
this.description.clear(); |
||||
} else { |
||||
window.history.pushState({}, null, window.location.href.split('?')[0]+'?word='+wd); |
||||
this.description.set(wd); |
||||
} |
||||
this.href = encodeURIComponent(window.location.href); |
||||
} |
||||
}; |
||||
|
||||
//Разбор параметров URL
|
||||
URL.parse = function() { |
||||
var gy = window.location.search.substring(1).split("&"); |
||||
gy.forEach(arg => { |
||||
let ft = arg.split("="); |
||||
this.opt[ft[0]] = this.opt[ft[0]] || decodeURIComponent(ft[1]); |
||||
}); |
||||
|
||||
URL.description.clear(); |
||||
this.title = document.title; |
||||
this.opt.href = encodeURIComponent(window.location.href); |
||||
}; |
||||
|
||||
//Инициализация с разбором адресной строки
|
||||
function init(container) { |
||||
HTML.init(container); |
||||
URL.parse(); |
||||
|
||||
if (URL.opt.word) { |
||||
HTML.input().value = URL.opt.word.replace(/\+/g," "); |
||||
tr(); |
||||
} else { |
||||
show_help(); |
||||
} |
||||
} |
@ -0,0 +1,449 @@
@@ -0,0 +1,449 @@
|
||||
//
|
||||
// Copyright (C) 2016-2019, Maxim Lihachev, <envrm@yandex.ru>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, version 3.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
var FEM = {}; |
||||
|
||||
//Слова для замены и исключения
|
||||
//Имеют высший приоритет и не обрабатываются остальными правилами
|
||||
FEM.words = { |
||||
'без' : 'без', |
||||
'как' : 'как', |
||||
'либо' : 'либо', |
||||
'например' : 'например', |
||||
'них' : 'них', |
||||
'под' : 'под', |
||||
|
||||
'два' : 'две', |
||||
|
||||
'весь' : 'вся', |
||||
'всё' : 'вся', |
||||
|
||||
'чего' : 'чегой', |
||||
|
||||
'ее' : 'е_е', |
||||
'её' : 'е_ё', |
||||
'кто' : 'котор_ая', |
||||
'каким' : 'как_ой', |
||||
'муж.' : 'жен.', |
||||
'муж' : 'жена', |
||||
'то' : 'т_а', |
||||
'того' : 'т_у', |
||||
'тот' : 'т_а', |
||||
'мужчина' : 'женщи_на', |
||||
'мужчины' : 'женщи_ны' |
||||
}; |
||||
|
||||
//Слова со специфичными определениями
|
||||
FEM.exceptions = { |
||||
'феминист' : [ ['профеминист', 'союзник'], |
||||
"Мифическое создание, якобы поддерживающее феминизм. В реальности не встречается." |
||||
], |
||||
'жена' : [ ['мужерабка', 'подстилка патриархата'], |
||||
"Женщина, прогнувшаяся под патриархат и получающая удовольствие от угнетения." |
||||
] |
||||
}; |
||||
|
||||
// Формат:
|
||||
// '<префикс>+окончание1|окончание2|...|окончаниеN' : {
|
||||
// ['<шаблон>', <сколько удалять символов на конце слова>]
|
||||
// }
|
||||
//
|
||||
// Окончания отсортированы от наиболее специфичных к наиболее общим
|
||||
//
|
||||
FEM.endings = { |
||||
//Исключения, которые не нужно феминизировать
|
||||
'бо' : [ |
||||
['либо', 2] // -либо
|
||||
], |
||||
'их' : [ |
||||
['их', 2] // нескольких
|
||||
], |
||||
'ых' : [ |
||||
['ых', 2] // грубых
|
||||
], |
||||
'ной' : [ |
||||
['ной', 3] // платёжной
|
||||
], |
||||
'ных' : [ |
||||
['ных', 3] // засушенных
|
||||
], |
||||
'тей' : [ |
||||
['тей', 3] // обязанностей
|
||||
], |
||||
'ть' : [ |
||||
['[аеи]ть', 2] // глаголы в инфинитиве
|
||||
], |
||||
'ёт' : [ |
||||
['[её]т', 2] // глаголы в форме 3 л. ед.ч.
|
||||
], |
||||
'ют' : [ |
||||
['ают', 2] // глаголы в форме мн.ч.
|
||||
], |
||||
|
||||
// имена прилагательные
|
||||
'ая' : [ |
||||
['[дкнш]ое', 2], // твёрдое, офицерское, полное, большое
|
||||
['[дн]ый', 2], // твёрдый, полный
|
||||
['[бвлмпт][оы][ей]', 2], // новый, круглый, знакомый, глупый, принятый
|
||||
//['[бвклмнтш]ое', 2], // новое, сладкое, круглое, знакомое, полное, принятое, прошлое
|
||||
['[шщ]ее', 2], // пешее, вещее
|
||||
['[кнпщщ]ий', 2] // сладкий, дольний, глупый, пеший, пещий
|
||||
], |
||||
|
||||
'яя' : [ |
||||
['[нчщ]ий', 2], // верхний, ползучий, знающий
|
||||
['[нчщ]ее', 2] // верхнее, ползучее, знающее
|
||||
], |
||||
|
||||
'аяся' : [ |
||||
['ееся', 4], // являющееся
|
||||
['ийся', 4] // занимающийся
|
||||
], |
||||
|
||||
//
|
||||
// ----- ФОРМА РОДИТЕЛЬНОГО ПАДЕЖА (преимущественно) -----
|
||||
//
|
||||
|
||||
// форма мн.ч.
|
||||
'ок|есс|ин|иц' : [ |
||||
['вий', 2], // действий
|
||||
['лей', 2], // родителей
|
||||
['ств', 0], // свойств
|
||||
['тра', 0], // метра
|
||||
['еров', 2] // размеров
|
||||
], |
||||
|
||||
// форма ед.ч.
|
||||
'ч+ки|ессы|ини|ицы' : [ |
||||
['века', 2] // человека
|
||||
], |
||||
|
||||
'ки|ессы|ини|ицы' : [ |
||||
['[ае]за', 1], // газа
|
||||
['[ай]на', 1], // капитана, бассейна
|
||||
['[ас]та', 1], // заката, роста
|
||||
['[её]ма', 1], // водоёма
|
||||
['[коя][тдя]а', 1], // отряда, объекта, города, живота
|
||||
['[мн]ца', 2], // самца, солнца
|
||||
['алла', 1], // металла
|
||||
['дке', 2], // порядке
|
||||
['е[жт]а', 1], // платежа, света
|
||||
['зда', 1], // переезда
|
||||
['ены', 1], // члены (организации)
|
||||
['еста', 1], // теста
|
||||
['и[дтщ]а', 1], // вида, кредита, туловища
|
||||
['иала', 1], // материала
|
||||
['инка', 1], // клинка
|
||||
['кты', 1], // объекты
|
||||
['лива', 1], // полива
|
||||
['нта', 1], // варианта
|
||||
['о[лрс]а', 1], // пола, надзора, космоса
|
||||
['рева', 1], // дерева
|
||||
['ства', 1], // государства
|
||||
['те[лр][аия]', 1], // руководителя
|
||||
['[оу]ви', 1], // крови, обуви
|
||||
['фона', 1], // телефона
|
||||
['я[дс]а', 1] // отряда, мяса
|
||||
], |
||||
|
||||
'ессы|ини|ицы' : [ |
||||
// действия, равновесия, предприятия, метталургии
|
||||
['[вгнст]и[ия]', 2], |
||||
|
||||
['бега', 1], // побега
|
||||
['[бк]оя', 1], // покоя, боя
|
||||
['иги', 1], // подвиги
|
||||
['[врт]ца', 1], // продавца, кварца, отца
|
||||
['ени', 1], // времени
|
||||
['есы', 1], // интересы
|
||||
['[исы]ка', 1], // дворника, песка, языка
|
||||
['изма', 1], // организма
|
||||
['лия', 2], // изделия
|
||||
['сьма', 1], // письма
|
||||
['йма', 1], // займа
|
||||
['нка', 1], // банка
|
||||
['ья', 1], // несчастья
|
||||
['уки', 1], // звуки
|
||||
['юди', 1], // люди
|
||||
['у[сх]а', 1] // вкуса, воздуха
|
||||
], |
||||
|
||||
'ии' : [ |
||||
['[гн]и[ия]', 2] // металлургия
|
||||
], |
||||
|
||||
'есс|иц|инь' : [ |
||||
['вых', 2] // паслёновых
|
||||
], |
||||
|
||||
'й+ки' : [ |
||||
['боя', 1], // боя
|
||||
['ви[йя]', 1] // действия
|
||||
], |
||||
|
||||
// имена прилагательные
|
||||
'ей' : [ |
||||
['[шщ]им', 2], // общим
|
||||
['его', 3] // высшего
|
||||
], |
||||
|
||||
'ой' : [ |
||||
// другого, молодого, женского, целого, художественного, которого, этого, большого
|
||||
['[вгдклнртш]ого', 3], |
||||
|
||||
['[ео]му', 3], // судебному
|
||||
['[гд][иы]м', 2], // твёрдым, другим
|
||||
['[клмнр][оы]м', 2] // музыкальном, прямым
|
||||
], |
||||
|
||||
//
|
||||
// ----- ФОРМЫ ДАТЕЛЬНОГО И ПРЕДЛОЖНОГО ПАДЕЖА -----
|
||||
//
|
||||
|
||||
// форма ед.ч.
|
||||
'ке|ессе|ине|ице' : [ |
||||
['[ия]де', 1], // виде, ряде
|
||||
['[оя]ду', 1], // периоду, взгляду
|
||||
['ане', 1], // плане
|
||||
['е[нс]те', 1], // инструменте -> инструментессе, месте -> местессе
|
||||
['[ар]те', 1], // результате, транспорте
|
||||
['ессе', 1], // процессе
|
||||
['[её]ме', 1], // объёме
|
||||
['ксу', 1], // боксу -> боксессе
|
||||
['лу', 1], // делу
|
||||
['нию', 2], // отношению
|
||||
['нке', 1], // ребёнке
|
||||
['оду', 1], // период
|
||||
['ету', 1], // предмету
|
||||
['сту', 1], // росту
|
||||
['усе', 1] // соусе
|
||||
], |
||||
'ессе|ине|ице' : [ |
||||
['еге', 1], // беге
|
||||
['тве', 1], // государстве
|
||||
['дне', 1], // судне -> суднессе
|
||||
['[иы]ке', 1], // крике, языке
|
||||
['нцу', 1], // концу -> концессе
|
||||
['чае', 1] // случае
|
||||
], |
||||
'ей|це' : [ |
||||
['н[иь]ем', 2] // давлением -> давленией, вареньем -> вареньей
|
||||
], |
||||
|
||||
// форма мн.ч.
|
||||
'ессам' : [ |
||||
['кам', 2] // потомкам -> потомкессам
|
||||
], |
||||
'ессам|иням|ицам' : [ |
||||
['[дт]ям', 2] // людям, детям
|
||||
], |
||||
|
||||
//
|
||||
// ----- ФОРМА ВИНИТЕЛЬНОГО ПАДЕЖА -----
|
||||
//
|
||||
|
||||
'ую' : [ |
||||
['шой', 2], // большой
|
||||
['чий', 2], // горячий
|
||||
['[вг]ое', 2] // готовое, другое
|
||||
], |
||||
|
||||
//
|
||||
// ----- ФОРМА ТВОРИТЕЛЬНОГО ПАДЕЖА -----
|
||||
//
|
||||
|
||||
'ессой|иней|ицей' : [ |
||||
['[вгдл]ом', 2], // клювом, ремеслом, лозунгом, трудом
|
||||
['ью', 2], // осенью
|
||||
['[илнт][её]м', 2] // носителем, лезвием, остриём, временем, путём
|
||||
], |
||||
|
||||
'ками|ессами|ицами' : [ |
||||
['[вдлн][ая]ми', 3], // островами, спортсменами, представителями, плодами
|
||||
['[иы]ми', 3], // мелкими, продолговатыми
|
||||
['тами', 3], // продуктами
|
||||
['ьями', 4] // листьями
|
||||
], |
||||
|
||||
'ессами|ицами' : [ |
||||
['[ая]ми', 3] // лицами, отношениями
|
||||
], |
||||
|
||||
// ---------------------------------
|
||||
// ----- ИМЕНА СУЩЕСТВИТЕЛЬНЫЕ -----
|
||||
// ---------------------------------
|
||||
|
||||
// Слова с заменой согласного основы
|
||||
'ч+ка|есса|ина|иня|ица' : [ |
||||
['ёнок', 1], // ребёнок
|
||||
['ыка', 2], // владыка
|
||||
['[ае]к', 1] // левак, человек
|
||||
], |
||||
|
||||
'ч+есса|ина|иня|ица' : [ |
||||
['цо', 2] // лицо
|
||||
], |
||||
|
||||
'ц+есса|иня|ица' : [ |
||||
['[бнр]ец', 2] // конец, творец, рубец
|
||||
], |
||||
|
||||
'к+иня' : [ |
||||
['ст', 0], // специалист
|
||||
['нт', 0] // агент
|
||||
], |
||||
|
||||
'н+ица' : [ |
||||
['ль', 0] // создатель
|
||||
], |
||||
|
||||
'адья' : [ |
||||
['поп', 0] // поп
|
||||
], |
||||
|
||||
'ка|есса|иня|ица' : [ |
||||
// [а] прораб, нрав, раж, лаз, зал, кран, этап, нагар, ужас, закат, граф, врач, палаш, плащ
|
||||
// [е] хлеб, лев, манеж, вырез, удел, овен, зацеп, характер, лес, авторитет, блеф, меч, флеш, клещ
|
||||
// [ё] небоскрёб, рёв, ёж, -ёз, орёл, клён, поклёп, сапёр, овёс, зачёт, -ёф, -ёч, клёш, -ёщ
|
||||
// [и] гриб, залив, чиж, бриз, спил, блин, хрип, жир, рис, визит, гриф, клич, мякиш, товарищ
|
||||
// [н] -нб, -нв, -нж, ценз, -нл, джинн, -нп, жанр, анонс, бант, аканф, ленч, реванш, -нщ
|
||||
// [о] сноб, ров, нож, воз, пол, район, клоп, узор, снос, азот, штоф, светоч, грош, овощ
|
||||
// [р] ущерб, нерв, морж, -рз, жерл, сатурн, карп, -рр, барс, торт, торф, грач, фарш, борщ
|
||||
// [y] сруб, обдув, уж, арбуз, гул, врун, закуп, амур, трус, жгут, пуф, луч, душ, хрущ
|
||||
// [э] дзэн, кэб, дэв, -эж, -эз, -эл, нэп, мэр, аэс, поэт, -эф, -эч, -эш, -эщ
|
||||
// [ю] книголюб, клюв, -юж, союз, -юл, вьюн, шлюп, бордюр, полюс, уют, -юф, ключ, плюш, плющ
|
||||
|
||||
['[аеёиноруэю][бвжзлнпрстфчшщ]', 0], |
||||
|
||||
['[аеи][дн]ец', 2], // канадец, уроженец
|
||||
['тец', 0], // отец
|
||||
['[лн]ь', 1], // вождь, создатель, создателесса, камень
|
||||
['л[блнпт]', 0], // металл, столб, челн, залп, болт
|
||||
['льм', 0], // фильм
|
||||
['мп', 0], // темп
|
||||
['оша', 1], // юноша
|
||||
['рин', 2], // татарин
|
||||
['с[лст]', 0], // смысл, процесс, специалист
|
||||
['ы[нсш]', 0], // сын, мыс, ландыш
|
||||
['я[жнпрсчшщ]', 0] // пляж, кляп, маляр, пояс, мяч, гуляш, хрящ
|
||||
], |
||||
|
||||
|
||||
'ка' : [ |
||||
['яд',0], // отряд
|
||||
['[аеёуы]м',0], // хам, джем, вотум, дым
|
||||
['рий',0], // гербарий
|
||||
['[аеоу]й',0], // бугай, лакей, зной, буй
|
||||
['[рст]ь', 0] // фонарь, карась, гость
|
||||
], |
||||
|
||||
'есса|иня|ица' : [ |
||||
// [а] маг, клад, знак, хам, страх, плац
|
||||
// [е] берег, бред, человек, джем, цех, боец
|
||||
// [ё] -ёг, лёд, отёк, -ёх, -ём, -ец
|
||||
// [и] подвиг, вид, медик, грим, вывих, шприц
|
||||
// [н] ринг, фонд, банк, сонм, бронх, принц
|
||||
// [о] рог, сброд, срок, дом, вдох, -оц
|
||||
// [р] торг, аккорд, кварк, шторм, стерх, кварц
|
||||
// [с] пеласг, -сд, спуск, микрокосм, -сх, -сц
|
||||
// [у] супруг, пуд, жук, вотум, пух, кибуц
|
||||
// [ы] припрыг, стыд, клык, дым, жмых, -ыц
|
||||
// [я] стяг, отряд, тюфяк, -ям, лях, -паяц
|
||||
|
||||
['[аеёинорсуыя][гдкмхц]', 0], |
||||
|
||||
['[аеи]лец', 2], // жилец
|
||||
|
||||
['[бвдт]р', 0], // бобр, кентавр, театр, кадр
|
||||
['з[дм]', 0], // съезд
|
||||
['ол[гк]', 0], // долг, полк
|
||||
['офе', 1], // кофе
|
||||
['ыв', 0], // взрыв
|
||||
['[аеиоу]й',1], // бугай, лакей, гербарий, зной, буй
|
||||
['[дрст]ь', 1], // вождь, фонарь, карась, путь
|
||||
['ядя', 1], // дядя
|
||||
['дья', 2], // судья
|
||||
|
||||
['[кы]т', 0], // реликт, опыт
|
||||
['к[сх]', 1], // бокс, сикх
|
||||
|
||||
// ----- слова среднего рода -----
|
||||
|
||||
// небо, существо, чудо, яблоко, стекло, письмо, окно, ведро, колесо, пальто, ухо, плечо
|
||||
['[бвдклмнрстхч]о', 1], |
||||
|
||||
// действие, оружие, приспособление, кушанье, участие, отличие, жильё, согласие
|
||||
['[вжлнстч][иь][её]', 2], |
||||
|
||||
['мя', 1], // время
|
||||
['[лрцщ]е', 1] // поле, море, солнце, вместилище
|
||||
], |
||||
|
||||
'есса' : [ |
||||
['[длн]ие', 1] // правосудие, изделие, мнение
|
||||
], |
||||
|
||||
'ыня' : [ |
||||
['рин', 2], // барин
|
||||
['уз', 0] // арбуз
|
||||
], |
||||
|
||||
'ица' : [ |
||||
['[дл]ие', 2], // правосудие, изделие
|
||||
['ще', 3] // вместилище
|
||||
], |
||||
|
||||
'ша' : [ |
||||
['у[нт]', 0], // врун, лилипут
|
||||
['ир', 0] // командир
|
||||
], |
||||
|
||||
'ь+я' : [ |
||||
['ун', 0] // врун
|
||||
], |
||||
|
||||
// формы мн.ч.
|
||||
'ессы|ыни|ицы' : [ |
||||
['нга', 1], // ранга
|
||||
['о[дс]ы', 1], // выводы, матросы
|
||||
['усы', 2] // вкусы
|
||||
], |
||||
|
||||
// ----- РАЗНОЕ -----
|
||||
|
||||
'инь' : [ |
||||
['дей', 2] //людей -> людинь
|
||||
], |
||||
|
||||
'на' : [ |
||||
['обно', 2] //способно -> способна
|
||||
] |
||||
}; |
||||
|
||||
//Случайный элемент списка
|
||||
FEM.random_word = wordlist => wordlist[Math.floor(Math.random() * wordlist.length)]; |
||||
|
||||
//Проверка на исключение
|
||||
FEM.exceptions.contains = word => Object.keys(FEM.exceptions).includes(word); |
||||
|
||||
//Список значений
|
||||
FEM.exceptions.feminitives = word => [FEM.random_word(FEM.exceptions[word][0]), FEM.exceptions[word][0]]; |
||||
|
||||
//Дефиниция слова-исключения
|
||||
FEM.exceptions.definition = word => FEM.exceptions[word][1]; |
||||
|
@ -1,497 +0,0 @@
@@ -1,497 +0,0 @@
|
||||
// Copyright (C) 2016-2017, Maxim Lihachev, <envrm@yandex.ru>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// [ ] TODO: валидация
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
'use strict'; |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Иерархия элементов на странице
|
||||
var HTML = { |
||||
container: "", |
||||
_select: function(element) { return document.getElementById(this.container + "-" + element); }, |
||||
input: function() { return this._select("word"); }, |
||||
button: function() { return this._select("convert"); }, |
||||
dict: function() { return this._select("dict"); }, |
||||
content: function() { return this._select("content"); }, |
||||
full: function() { return this._select("full"); }, |
||||
help: function() { return this._select("help"); }, |
||||
image: function() { return this._select("image"); }, |
||||
}; |
||||
|
||||
//Вывод справки с примерами использования
|
||||
function show_help() { |
||||
HTML.vis(HTML.help()); |
||||
HTML.vis(HTML.content()); |
||||
} |
||||
|
||||
//Смена названия по клику
|
||||
function swap_title(id) { |
||||
var e = document.getElementById(id); |
||||
if(e.style.display == 'inline') { |
||||
e.style.display = 'none'; |
||||
} else { |
||||
e.style.display = 'inline'; |
||||
} |
||||
} |
||||
|
||||
HTML.vis = function(e, v) { |
||||
if (v !== undefined) { |
||||
e.style.visibility = v; |
||||
} else { |
||||
e.style.visibility = e.style.visibility === "visible" ? "hidden" : "visible"; |
||||
} |
||||
} |
||||
|
||||
//Инициализация документа
|
||||
HTML.init = function(root) { |
||||
//Задание базового id для всех элементов
|
||||
this.container = root; |
||||
|
||||
//Конвертирование по нажатию <Enter>
|
||||
this.input().addEventListener('keyup', event => { |
||||
event.preventDefault(); |
||||
event.keyCode == 13 && tr(); |
||||
}); |
||||
|
||||
//Конвертирование по нажатию кнопки
|
||||
this.button().onclick = () => tr(); |
||||
}; |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Правила создания феминитивов
|
||||
var FEM = {}; |
||||
|
||||
FEM.endings = { |
||||
'ка' : [ |
||||
['[аеёо]р', 0], |
||||
['[её]т', 0], //авторитет -> авторитетка
|
||||
['а[ншб]', 0], //кран -> кранка, краб -> крабка
|
||||
['ец', 2], //канадец -> канадка
|
||||
['и[лр]', 0], //библиофил -> библиофилка, командир -> командирка
|
||||
['ин', 2], //татарин -> татарка
|
||||
['ль', 1], //создатель -> создателка
|
||||
['о[тн]', 0], //гот -> готка, адрон -> адронка
|
||||
['рг', 1], |
||||
['[ус]т', 0], //специалист -> специалистка
|
||||
['у[нйп]', 0] //колдун -> колдунка
|
||||
], |
||||
'чка' : [ |
||||
['[ае]к', 1] //левак -> левачка, человек -> человечка
|
||||
], |
||||
'ина' : [ |
||||
['ас', 0], |
||||
['уй', 1], //буй -> буина
|
||||
['уд', 0], //сосуд -> сосудина
|
||||
['ил', 0] //библиофил -> библиофилина
|
||||
], |
||||
'иха' : [ |
||||
['[аеёов]р', 0], //автор -> авториха
|
||||
['а[чб]', 0], //врач -> врачиха, краб -> крабиха
|
||||
['ец', 2], //канадец -> канадиха
|
||||
['и[лр]', 0], //библиофил -> библиофилиха, командир -> командириха
|
||||
['ль', 1], //создатель -> создателиха
|
||||
['рк', 0], //кварк -> кваркиха
|
||||
['о[гдтнп]', 0], //гот -> готиха, адрон -> адрониха, биолог -> биологиха, метод -> методиха, клоп -> клопиха
|
||||
['у[дпт]', 0], //труп -> трупиха, сосуд -> сосудиха
|
||||
['уй', 1] //буй -> буиха
|
||||
], |
||||
'иня' : [ |
||||
['[аеёов]р', 0], |
||||
['[её]т', 2], //авторитет -> авторитиня
|
||||
['[оиы]к', 0], //язык -> языкиня
|
||||
['а[вбкфч]', 0], //левак -> левакиня, граф -> графиня, врач -> врачиня, краб -> крабиня, состав -> составиня
|
||||
['во', 1], //существо -> существиня
|
||||
['ек', 0], //человек -> человекиня
|
||||
['ец', 2], //канадец -> канадиня
|
||||
['ил', 0], //библиофил -> библиофилиня
|
||||
['ль', 1], //создатель -> создателиня
|
||||
['о[дг]', 0], //биолог -> биологиня
|
||||
['од', 0], //метод -> методиня
|
||||
['р[гк]', 0], //кварк -> кваркиня
|
||||
['ро', 1], //ведро -> ведриня
|
||||
['со', 1], //колесо -> колесиня
|
||||
['сс', 0], //процесс -> процессиня
|
||||
['[кс]т', 0], //специалист -> специалистиня, объект -> объектиня
|
||||
['уй', 1], //буй -> буиня
|
||||
['у[тпх]', 0] //труп -> трупиня
|
||||
], |
||||
'ыня' : [ |
||||
['ин', 2], // боярин -> боярыня
|
||||
], |
||||
'киня' : [ |
||||
['[аеёо]р', 0], |
||||
['ок', 0], |
||||
['ст', 0], //специалист -> специалисткиня
|
||||
['ан', 0], |
||||
['ил', 0], //библиофил -> библиофилкиня
|
||||
['уй', 0] //буй -> буйкиня
|
||||
], |
||||
'есса' : [ |
||||
['[аеёов]р', 0], |
||||
['[её]т', 2], //авторитет -> авторитесса
|
||||
['[лн]ь', 1], //создатель -> создателесса, камень -> каменесса
|
||||
['[оиы]к', 0], //язык -> языкесса
|
||||
['[оэ]т', 0], //гот -> готесса, поэт -> поэтесса
|
||||
['а[вчнб]', 0], //врач -> врачесса, баран -> баранесса, краб -> крабесса, состав -> составесса
|
||||
['во', 1], //существо -> существесса
|
||||
['е[кнц]', 0], //член -> членесса, канадец -> канадесса, человек -> человекесса
|
||||
['и[лр]', 0], //библиофил -> библиофилесса, командир -> командиресса
|
||||
['[лр]о', 1], //тело -> телесса, ведро -> ведресса
|
||||
['о[ндгп]', 0], //метод -> методесса, адрон -> адронесса, биолог -> биологесса, клоп -> клопесса
|
||||
['р[гк]', 0], //кварк -> кваркесса
|
||||
['ст', 0], //специалист -> специалистесса
|
||||
['у[дпнхт]', 0], //сосуд -> сосудесса, колдун -> колдунесса, олух -> олухесса
|
||||
['уй', 1], //буй -> буесса
|
||||
['ще', 0], //вместилище -> вместилищесса
|
||||
['ый', 2], //учёный -> учёнесса
|
||||
['яд', 0] //взгляд -> взглядесса
|
||||
], |
||||
'ица' : [ |
||||
['[аеёов]р', 0], |
||||
['[её]т', 2], //авторитет -> авторитица
|
||||
['а[вбнсч]', 0], //врач -> врачица, краб -> крабица, состав -> составица
|
||||
['во', 1], //существо -> существица
|
||||
['ен', 0], //член -> членица
|
||||
['ец', 2], //канадец -> канадица
|
||||
['ик', 2], |
||||
['и[влр]', 0], //библиофил -> библиофилица, командир -> командирица
|
||||
['нь', 1], //камень -> каменица
|
||||
['о[гд]', 0], //биолог -> биологиня, метод -> методица
|
||||
['рг', 0], |
||||
['ст', 3], //специалист -> специалица
|
||||
['сс', 0], //процесс -> процессица
|
||||
['у[днпчт]', 0], //сосуд -> сосудица, колдун -> колдуница, труп -> трупица
|
||||
['уй', 1], //буй -> буица
|
||||
['ще', 3], //вместилище -> вместилищесса
|
||||
['яд', 0] //взгляд -> взглядица
|
||||
], |
||||
'ница' : [ |
||||
['ль', 0], //создатель -> создательница
|
||||
['ас', 0], |
||||
['[её]т', 0], //авторитет -> авторитетица
|
||||
['ец', 2], //канадец -> канадница
|
||||
['уй', 0] //буй -> буйница
|
||||
], |
||||
'ая' : [ |
||||
['[ыио]й', 2], //учёный -> учёная, знающий -> знающая
|
||||
['ое', 2] |
||||
], |
||||
'ша' : [ |
||||
['[её]т', 1], //вертолёт -> вертолёша
|
||||
['ут', 1], //лилипут -> лилипутша
|
||||
['ир', 0] //командир -> командирша
|
||||
], |
||||
'адья' : [ |
||||
['оп', 0] // поп -> попадья
|
||||
], |
||||
//----- ДАЛЬШЕ ИДЁТ ШИЗА -----
|
||||
'ии' : [ |
||||
['и[ия]', 2], //металлургии -> металлург_ии, произведения -> произведении
|
||||
], |
||||
'ца' : [ |
||||
['ие', 1], //металлургии -> металлург_ии, произведения -> произведении
|
||||
], |
||||
'ми' : [ |
||||
['ми', 2] //знаниями -> знания_ми
|
||||
], |
||||
'ой' : [ |
||||
['го', 3] //художественного -> художественн_ой
|
||||
], |
||||
'инь' : [ |
||||
['ей', 2] //людей -> люд_ей
|
||||
], |
||||
'ти' : [ |
||||
['ти', 2] //области -> облас_ти
|
||||
], |
||||
'ю' : [ |
||||
['ью', 1] //матерью -> матерь_ю
|
||||
], |
||||
'ны' : [ |
||||
['на', 2] //бассейна -> бассей_ны
|
||||
], |
||||
'на' : [ |
||||
['но', 2] //способно -> способна
|
||||
], |
||||
'ки' : [ |
||||
['ца', 2] //самца -> самки
|
||||
], |
||||
'аяся' : [ |
||||
['ся', 4], //занимающийся -> занимающ_аяся
|
||||
], |
||||
}; |
||||
|
||||
//Слова со специфичными определениями
|
||||
FEM.exceptions = { |
||||
'феминист' : [ ['профеминист', 'союзник'], |
||||
"Мифическое создание, якобы поддерживающее феминизм. В реальности не встречается." |
||||
], |
||||
'жена' : [ ['мужерабка', 'подстилка патриархата'], |
||||
"Женщина, прогнувшаяся под патриархат и получающая удовольствие от угнетения." |
||||
] |
||||
}; |
||||
|
||||
//Проверка на исключение
|
||||
FEM.exceptions.contains = function(word) { |
||||
return Object.keys(this).includes(word); |
||||
}; |
||||
|
||||
//Список значений
|
||||
FEM.exceptions.feminitives = function(word) { |
||||
return [random_word(this[word][0]), this[word][0]]; |
||||
}; |
||||
|
||||
//Дефиниция слова-исключения
|
||||
FEM.exceptions.definition = function(word) { |
||||
return this[word][1]; |
||||
}; |
||||
|
||||
//Слова для замены
|
||||
FEM.words = { |
||||
'то' : 'т_а', |
||||
'тот' : 'т_а', |
||||
'того' : 'т_у', |
||||
'кто' : 'котор_ая', |
||||
'её' : 'е_ё', |
||||
'ее' : 'е_е', |
||||
'ий' : 'ая', |
||||
'человек' : 'человека', |
||||
'муж' : 'жен' |
||||
}; |
||||
|
||||
FEM.words.convert = function(string) { |
||||
for (var fem_w in this) { |
||||
string = string.replace(new RegExp('(^|\\s)+' + fem_w, "ig"), '$1' + this[fem_w]) |
||||
.replace(/(.)/, s => s.toUpperCase()); |
||||
} |
||||
return string; |
||||
}; |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Первый элемент списка - окончание (в виде регулярного выражения)
|
||||
let ending = tuple => new RegExp("^.*" + tuple[0] + "$", "i"); |
||||
|
||||
//Второй элемент списка - смещение
|
||||
let offset = tuple => tuple[1]; |
||||
|
||||
//Случайный элемент списка
|
||||
let random_word = wordlist => wordlist[Math.floor(Math.random() * wordlist.length)]; |
||||
|
||||
//Оборачивание в <span> с указанным классом
|
||||
let html_wrap = (str, cl) => `<span class="${cl}">${str}</span>`; |
||||
|
||||
//Цветовое выделение текста
|
||||
let css_end = ending => html_wrap(ending, "ending"); |
||||
|
||||
//Символ gender gap
|
||||
let css_gender_gap = html_wrap(' \u26A7 ', "queer"); |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Конструирование феминитива с gender_gap
|
||||
function construct_feminitive(stem, ending, gap) { |
||||
return gap ? stem + css_gender_gap + css_end(ending) : stem + "_" + ending; |
||||
} |
||||
|
||||
//Отправка адреса страницы в vk.com
|
||||
function share_page() { |
||||
let vk_url = "http://vk.com/share.php" |
||||
+ "?url=" + URL.href |
||||
+ "&title=" + URL.title |
||||
+ "&description=" + URL.description.text; |
||||
|
||||
let new_tab = window.open(vk_url,'_blank'); |
||||
new_tab.focus(); |
||||
} |
||||
|
||||
//Сохранение изображения с феминитивом
|
||||
function download_image() { |
||||
html2canvas(HTML.image(), { |
||||
onrendered: canvas => { |
||||
let a = document.createElement('a'); |
||||
a.href = canvas.toDataURL(); |
||||
a.download = HTML.content().innerHTML + '.png'; |
||||
a.click(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
//Создание феминитива
|
||||
function make_feminitives(word) { |
||||
//Обрабатываем только слова длиннее трёх символов
|
||||
if (word.length < 3) return [word, word]; |
||||
|
||||
var stem = ""; //Основа слова
|
||||
var current_ending = word.slice(-2); //Текущее окончание
|
||||
var feminitives = []; //Массив феминитивов
|
||||
var femicards = []; //Массив феминитивов для карточки
|
||||
|
||||
for (let fem_ending in FEM.endings) { |
||||
FEM.endings[fem_ending].forEach(end => { |
||||
if (ending(end).test(current_ending)) { |
||||
//Удаление лишних букв из основы
|
||||
stem = offset(end) === 0 ? word : word.slice(0, -offset(end)); |
||||
|
||||
//Добавление фем-варианта слова в массив
|
||||
feminitives.push(construct_feminitive(stem, fem_ending, 1)); |
||||
femicards.push(construct_feminitive(stem, fem_ending, 0)); |
||||
} |
||||
}); |
||||
} |
||||
//При отсутствии феминитивов считать корректным исходное слово
|
||||
return [random_word(femicards) || word, feminitives]; |
||||
} |
||||
|
||||
//Поиск и феминизация дефиниции в викистранице
|
||||
function parseWikiPage(page) { |
||||
var wiki = page.split('\n'); |
||||
var definition = ""; |
||||
|
||||
wiki.some((line, n) => { |
||||
if (line.match(/^.*==== Значение ====.*$/)) { |
||||
console.log(wiki[n+1]); //DEBUG
|
||||
definition = wiki[n+1] |
||||
.replace(/^# ?/, "") //# дефиниция
|
||||
.replace(/\[{2}([^\]\|]*)\]{2}/g, "$1") //[[1]]
|
||||
.replace(/\[{2}[^\|]*\|([^\]]*)\]{2}/g, "$1") //[[1|2]]
|
||||
.replace(/\[{2}([^\]\|]*)\}{2}/g, "$1") //{{1}}
|
||||
.replace(/\{{2}[^\{\}]*\}{2} ?/g, "") //{{1|2}}
|
||||
.replace(/\{{2}[^\{\}]*\|.*/g, "") //{{1|слово<!--комментарий-->.*$
|
||||
.replace(/\{{2}[^\{\}]*\}{2} ?/g, "") //~ : возможна вложенность
|
||||
.replace(/\[[0-9]{1,}\]/g, "") //ссылки [n]
|
||||
.replace(/^ *, */g, "") //^, ...
|
||||
.replace(/ ?$/,"."); //Точка в конце предложения
|
||||
return true; |
||||
} |
||||
}); |
||||
|
||||
//Разделение дефиниции на массив слов и знаков препинания и феминизация слов
|
||||
var tokens = definition.match(/[\wа-яА-Яё]+|\d+| +|[.;,]|[^ \w\d\t.;,]+/ig) || []; |
||||
console.log(tokens); |
||||
|
||||
//Замена местоимений, предлогов и проч.
|
||||
HTML.full().innerHTML = FEM.words.convert(tokens.map(w => make_feminitives(w)[0]).join("")); |
||||
|
||||
//DEBUG
|
||||
console.log(definition); |
||||
console.log(tokens); |
||||
} |
||||
|
||||
//Запрос значения слова в викисловаре
|
||||
function get_wiktionary(term) { |
||||
var cors_url = "https://coors.now.sh/"; |
||||
var wiki_url = cors_url + "https://ru.wiktionary.org/w/index.php?action=raw&title=" + term; |
||||
|
||||
var xmlhttp = window.XMLHttpRequest |
||||
? new XMLHttpRequest() |
||||
: new ActiveXObject("Microsoft.XMLHTTP"); |
||||
|
||||
xmlhttp.onreadystatechange = function() { |
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { |
||||
parseWikiPage(xmlhttp.responseText); |
||||
} |
||||
}; |
||||
|
||||
xmlhttp.open("GET", wiki_url, true); |
||||
xmlhttp.send(); |
||||
} |
||||
|
||||
//Создание и вывод феминитива
|
||||
function tr(word) { |
||||
//Исходное слово
|
||||
var wd = word || HTML.input().value.trim().toLowerCase().replace(/<\/?[^>]+(>|$)/g, "").split(" ")[0]; |
||||
var feminitives = ""; |
||||
|
||||
//Состояние по умолчанию
|
||||
HTML.content().innerHTML = "Введите слово"; |
||||
HTML.dict().innerHTML = ""; |
||||
HTML.full().innerHTML = ""; |
||||
|
||||
HTML.vis(HTML.help(), "hidden"); |
||||
HTML.vis(HTML.content(), "visible"); |
||||
|
||||
//Изменение адреса
|
||||
URL.set(wd); |
||||
|
||||
//Вывод информации
|
||||
if (!wd) { |
||||
show_help(); |
||||
|
||||
return; |
||||
} else if (FEM.exceptions.contains(wd)) { |
||||
HTML.full().innerHTML = FEM.exceptions.definition(wd); |
||||
feminitives = FEM.exceptions.feminitives(wd); |
||||
} else { |
||||
get_wiktionary(wd); |
||||
feminitives = make_feminitives(wd); |
||||
} |
||||
//Вывод информации
|
||||
HTML.input().value = wd; |
||||
HTML.content().innerHTML = feminitives[0].replace(/(.)/, s => s.toUpperCase()); |
||||
HTML.dict().innerHTML = feminitives[1].join(" | ") |
||||
|| "Это слово и так прекрасно. Оставим его как есть."; |
||||
} |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//Параметры URL
|
||||
var URL = { |
||||
opt: {}, |
||||
description: { |
||||
clear: function() { this.text = "Как феминистки пишут разные слова."; }, |
||||
set: function(wd) { this.text = 'Как феминистки пишут слово "' +wd+ '".'; }, |
||||
}, |
||||
set: function(wd) { |
||||
if (!wd) { |
||||
window.history.pushState({}, null, window.location.href.split('?')[0]); |
||||
this.description.clear(); |
||||
} else { |
||||
window.history.pushState({}, null, window.location.href.split('?')[0]+'?word='+wd); |
||||
this.description.set(wd); |
||||
} |
||||
this.href = encodeURIComponent(window.location.href); |
||||
} |
||||
}; |
||||
|
||||
//Разбор параметров URL
|
||||
URL.parse = function() { |
||||
var gy = window.location.search.substring(1).split("&"); |
||||
gy.forEach(arg => { |
||||
let ft = arg.split("="); |
||||
this.opt[ft[0]] = this.opt[ft[0]] || decodeURIComponent(ft[1]); |
||||
}); |
||||
|
||||
URL.description.clear(); |
||||
this.title = document.title; |
||||
this.opt.href = encodeURIComponent(window.location.href); |
||||
}; |
||||
|
||||
//Инициализация с разбором адресной строки
|
||||
function init(container) { |
||||
HTML.init(container); |
||||
URL.parse(); |
||||
|
||||
if (URL.opt.word) { |
||||
HTML.input().value = URL.opt.word.replace(/\+/g," "); |
||||
tr(); |
||||
} else { |
||||
show_help(); |
||||
} |
||||
} |
Loading…
Reference in new issue