npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

reduplicator

v2.0.1

Published

Лексический редупликатор русских слов

Downloads

10

Readme

Лексический редупликатор

npm npm Build Status

Внимание! Исходный код содержит ненормативную лексику! Здесь, в readme, все нецензурные слова прикрыты звёздочками. Х*ёздочками.

Что это такое?

Лексическая-х*ическая редупликация-х*епликация.

Более подробную информацию про лексическую редупликацию можно найти в Википедии.

Данная библиотека для слова вычисляет его редуплицированную форму. Примеры:

  • привет -> х*евет
  • собака -> х*яка
  • собака -> хренака
  • холодильник -> х*едильник
  • водоворот -> х*еворот
  • водоворот -> хреноворот

Особенности

  • Два режима редупликации (х*ефикация и хренофикация + легко добавить новый режим)
  • Нет внешних зависимостей
  • Синхронный API

Демо

Попробовать библиотеку можно на демо-странице.

Также можно поиграться в консоли: клонируем репозиторий, выполняем npm i и запускаем REPL: npm run repl.

Использование

Самый простой вариант использования

Х*ефикация
import { DefaultStressManager, Hueficator } from 'reduplicator';

const dict = new DefaultStressManager();

const hueficator = new Hueficator(dict);
hueficator.reduplicate('собака'); // => х*яка
Хренофикация
import { DefaultStressManager, Hrenoficator } from 'reduplicator';

const dict = new DefaultStressManager();

const hrenoficator = new Hrenoficator(dict);
hrenoficator.reduplicate('собака'); // => хренака

Как это работает

На то, какая будет гласная после префикса "ху"/"хрен" и сколько будет слогов в итоговом слове, влияет ударение в исходном слове. Пример:

  • собáка -> х*яка
  • со́бака -> х*ёбака

Поэтому редупликатору для работы нужна реализация интерфейса StressManager. То есть нечто, что умеет определять ударение в слове. Сейчас таких реализации написано три:

  • DefaultStressManager - работает со встроенным словарем ударений
  • DynamicStressManager - умеет работать со встроенным словарем, но пользователи также могут указать ему какое-то своё ударение в слове
  • NullStressManager - всегда отвечает, что ударение неизвестно и не использует словарь ударений. Может пригодиться для случаев, когда мало памяти и загружать в нее словарь нет возможности. Разумеется, результат работы редупликатора будет хуже.

В теории можно легко написать свою реализацию с произвольной логикой.

Продвинутый вариант использования

Если мы хотим использовать встроенный словарь ударений, но также иметь возможность указывать редупликатору кастомные ударения в словах:

import { DynamicStressManager, Hueficator } from 'reduplicator';

const dict = new DynamicStressManager();
const r = new Hueficator(dict);

r.reduplicate('сОбака'); // => х*ёбака
r.reduplicate('собАка'); // => х*яка
r.reduplicate('собака'); // => х*яка - ударение возьмется из встроенного словаря

DynamicDictionaryManager анализирует регистр букв в слове и, если одна и только одна гласная буква в нем написана капсом (например, "москвА"), посчитает ее ударной. Эти ударения можно сохранять в кастомный словарь, который переопределяет встроенный. Об этом - ниже.

Пользовательский словарь ударений

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

Для этого подходит все тот же DynamicDictionaryManager.

Его конструктор принимает два необязательных параметра:

  • путь к JSON-файлу с пользовательским словарем ударений (на момент создания объекта файл не обязательно должен существовать)
  • второй параметр - boolean, если его установить в true, пользовательский словарь будет read-only. Это может быть полезно, если вы хотите подложить какие-то свои слова, но не доверяете пользователям изменять словарь.

JSON-файл со словарем должен иметь формат "слово -> zero-based индекс ударной буквы".

Например, чтобы переопределить дефолтное ударение в слове "собака", как будто оно падает на первый слог, т.е. букву "о" (индекс буквы "о" - 1), создайте файл custom.json со следующим содержимым:

{
  "собака": 1
}

В коде создайте экземпляр DynamicStressManager и передайте ему путь к словарю:

import * as path from 'path';
import { DynamicStressManager, Hueficator } from 'reduplicator';

// допустим, путь к вашему словарю такой
const customDictionaryPath = path.join(__dirname, './custom.json');

const dict = new DynamicStressManager(customDictionaryPath, true);
const r = new Hueficator(dict);
r.reduplicate('сОбака'); // => х*ёбака

Если путь к кастомному словарю не был передан, DynamicStressManager будет все так же считать капс ударением, но ударение сохранено не будет, даже в памяти. Возможно, в будущем реализация изменится. Пока что это видится странным, т.к. при перезапуске приложения все равно все потеряется.

Также примеры использования в коде можно посмотреть в тестах и в repl.ts.

Настройки редупликации

Метод reduplicate принимает необязательный параметр - объект с опциями:

  • oneSyllableWordHandling:
    • OneSyllableWordReduplicationMode.Default - (по умолчанию) односложные слова редуплицируются как остальные
    • OneSyllableWordReduplicationMode.AddPrefix - к односложным словам просто добавляется префикс 'х*е'

Пример вызова:

import {OneSyllableWordReduplicationMode} from './oneSyllableWordReduplicationMode';

r.reduplicate('кот', {
  oneSyllableWordHandling: OneSyllableWordReduplicationMode.AddPrefix
});

Кастомный редупликатор

Библиотека предоставляет возможность добавить свой редупликатор с любым префиксом. Можно легко сделать фигофикатор или, например, шмедупликатор.

Для этого нужно воспользоваться классом Reduplicator. Его конструктор принимает конфигурацию - объект со следующими полями:

  • prefix - (обязательное поле) общий префикс для редуплицированных слов; т.е. "ху", "хрен" (без последующей гласной);
  • stressedVowelPairs - соответствие пар гласных в исходном слове и в редуплицированном слове для случаев, когда гласная после префикса ударная; пример: собака -> х*яка (т.е. а -> я); не нужно указывать, если prefix не содержит гласных
  • defaultPairVowel - гласная, соответствующая гласным в исходном слове для случаев, когда гласная после префикса безударная; пример: занавеска -> хреновеска (defaultPairVowel - 'о'); не нужно указывать, если prefix не содержит гласных.

Классы Hueficator и Hrenoficator являются, по сути, просто обёрткой над Reduplicator, каждый - со своей конфигурацией.

Вот так легко, например, можно сделать редупликатор-шмедупликатор:

import { DefaultStressManager, Hueficator } from 'reduplicator';

const r = new Reduplicator(new DefaultStressManager(), {
  prefix: 'шм'
});

// Всё!

// defaultPairVowel для префикса без гласных букв (шм) указывать смысла нет,
// т.к. гласная в редуплицированном слове всегда будет исходной (собака - шмобака, буква О вне зависимости от ударения)

// stressedVowelPairs тоже указывать бессмыссленно: насморк - шмасморк, ударная буква "а" сохраняется

console.log(r.reduplicate('редупликатор')); // шмедупликатор

Тесты

npm run test

Что нового

2.0

  • Переделан API библиотеки: появились классы Hueficator, Hrenoficator, добавлена возможность создавать собственные редупликаторы

v1.2

  • Добавлены режимы редупликации слов, состоящих из одного слога

v1.1.1

  • В readme добавлена ссылка на демо-страницу
  • Небольшие улучшения в коде

v1.1.0

  • Инициализация редупликатора ускорена приблизительно в 25 раз
  • Потребление оперативной памяти снижено в 5 раз
  • Объем пакета в распакованном виде уменьшен в 11 раз
  • Улучшена обработка слов, содержащих дефисы
  • Добавлен NullStressManager

Кредиты

Словарь ударений составлен из словаря "Полная парадигма. Морфология. Частотный словарь. Совмещенный словарь. Автор М. Хаген", доступного тут.

Фидбэк

Предложения, баг-репорты, звезды на гитхабе, пулл-реквесты - любой фидбэк приветствуется.