pyrutext 0.8.0
A Russian text generator based on templating texts and word picking

# Python Rutext: русскоязычный генератор текста

## Введение

Данный проект был вдохновлён одним любительским локальным Discord-ботом. В него добавили новую функцию, генерирующую случайные истории, используя шаблоны текста и случайные вставки.

Получился забавный модуль, но не без недостатков. Так что я захотел сделать свою версию, чтобы если что, помочь таким образом реализовать какие-то фишки, которые предложил я. 🤔

## Что реализовано

1. Ручной ввод форм;
2. Отсеивание избыточных форм;
3. Относительный формат слов (на основе базы и формата строится форма), позволяющий сократить занимаемую память;
4. Ввод/вывод в YAML (используя кэш, достигается минимум затрат в плане заливов на диск); при этом разработчик может использовать собственный I/O;
5. Ссылки на уже определённые слова, что позволяет дополнительно сжимать YAML и сохранить нервы пользователям;
6. Шаблоны текстов, в которые можно вставлять формы слов из словаря; поддерживаются в том числе *указатели* на слова: выбранное слово можно использовать несколько раз;
7. Иерархия классов `I/O` -> `Словарь` -> `DB`, позволяющая встроить на место `I/O` и `DB` собственные классы.

## Чего не хватает

1. Возможность запроса текста по ID;
2. Доработка `I/O` AShell: поддержка алиасов, вывод обязательных/необязательных аргументов в помощи, поддержка выхода из интерфейса;
3. Автосохранение `DB` каждые N минут;
4. Реализация `I/O` Discord API;
5. Реализация `DB` Redis вместо YAML.

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

Точка входа: `pyrutext.py`.

### Ввод слов

Программой предлагается сначала ввести новые слова в список.

Примеры вводов:
- `ЭСТ сущ. абр ж.р.`
- `любить гл. несов.`
- `очки сущ. безл. неодуш. мн.ч.`
- `хорошо нар. сост.`
- `ремонт сущ. м.р. ед.ч.`
- `ступор &ремонт`

**Ссылки** – теги, начинающиеся с `&` и отсылающие к уже определённым словам. Ссылка может быть только одна. Если других тегов нет, они берутся из слова-отсылки, и наоборот: теги по ссылке не извлекаются (а только формы), если пользователь определил другие.

После ввода слова программа запрашивает формы слова. Они могут быть указаны через *относительный формат*.
* Если ввод начинается с `-`, в начало вставляется оригинальное слово с отнятым окончанием (в зависимости от числа минусов *в начале*); остальной ввод добавляется в конец слова.
  * Число минусов `-` в начале указывает на то, сколько букв будет отнято у окончания.
  * Примеры: `'мирный', '--ая' > 'мирная'`; `'любить', '-' > 'любит'`.
* Формат полностью заменяет оригинальное слово, если он не начинается с `-`.
  * Пример: `'быть', 'будет' > 'будет'`.
* Если ввод включает в себя `+`, на его место вставляется оригинальное слово целиком.
  * Примеры: `'буква', '+' > 'буква'`; `'буква', '+ми' > 'буквами'`; `'лить', 'будешь +' > 'будешь лить'`; `'ели', 'по+ бы' > 'поели бы'`.
* При пустом вводе вставляется оригинальное слово (эквивалентно `+`).

В модуле определены следующие части речи:
* **Глагол:** `гл. {несов.|сов.} [1л|2л|3л] [п.в.|н.в.|б.в.] [ед.ч.|мн.ч.] [м.р.|ж.р.|с.р.] [пов.] [инф.]`
* **Прилагательное:** `пр. [ед.ч.|мн.ч.] [м.р.|ж.р.|с.р.] [и.п.|р.п.|д.п.|в.п.|т.п.|п.п.] [одуш.|неодуш.]`
* **Существительное:** `сущ. {м.р.|ж.р.|с.р.|безл.} (ед.ч.|мн.ч.) (нескл.) (абр) (пинг) (перс) [и.п.|р.п.|д.п.|в.п.|т.п.|п.п.] [ед.ч.|мн.ч.]`

В фигурных скобках – обязательные теги, в круглых – необязательные. В квадратных скобках – формы, которые не влияют на подбор слов. Порядок можно менять.

Для остальных (неизменяемых) частей речи (как наречия) форм нет, однако требуется указывать как минимум один тег: например, `хорошо нар.`

Тег может быть *любым*, но крайне желательно использовать уже существующие категории.

### Ввод текстов

Когда Вы закончите вводить слова, просто нажмите Enter. Вы перейдёте к следующему этапу *ввода текстов*. Вводимый текст заканчивается на пустой строке. Чтобы выйти из этого этапа, нажмите Enter в начале.

Пример простого текста-шаблона:
```
Привет, я съел --сущ. в.п.--.
```

Пример текста-шаблона с запоминанием вставок:
```
1=сущ. еда
2 = сущ. юзер
\
Привет, --2--. Я съел --1 в.п.--.
А тебе, -- 2 д.п. --, ничего не досталось.
```
Т.е. указатели на слова через синтаксис `{id} = {tag1 tag2 ...}` вводятся перед знаком `\`, а внутри текста эти указатели вставляются через выражение `--{id} {form1 form2 ...}--`.