From 0eae872e7a5ce5f7175cdeec22081684dfdefccc Mon Sep 17 00:00:00 2001
From: erjemin <erjemin@gmail.com>
Date: Sun, 11 May 2025 21:54:27 +0300
Subject: [PATCH] =?UTF-8?q?add:=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE?=
 =?UTF-8?q?=D0=B9=D0=BA=D0=B8=20=D1=8F=D0=B7=D1=8B=D0=BA=D0=BE=D0=B2=20?=
 =?UTF-8?q?=D0=B8=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B0=20=D0=BF=D0=B5?=
 =?UTF-8?q?=D1=80=D0=B5=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D1=8B=20=D0=B2=20con?=
 =?UTF-8?q?fig?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md             |  2 +-
 etpgrf/comutil.py     | 31 +++++++++++++++++++++++++++++--
 etpgrf/hyphenation.py | 21 +++++++++++----------
 etpgrf/typograph.py   | 18 +++++++-----------
 main.py               |  2 +-
 5 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/README.md b/README.md
index 27bc2c3..12b33bd 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 | in progress // в процессе разработки |
 |--------------------------------------|
-| --1                                  |
+| ---2                                 |
 
 # Типограф для Web
 
diff --git a/etpgrf/comutil.py b/etpgrf/comutil.py
index 6ef4967..0b1baae 100644
--- a/etpgrf/comutil.py
+++ b/etpgrf/comutil.py
@@ -1,7 +1,34 @@
-from etpgrf.config import DEFAULT_LANGS, SUPPORTED_LANGS
+# Общие функции для типографа etpgrf
+from etpgrf.config import MODE_UNICODE, MODE_MNEMONIC, MODE_MIXED, DEFAULT_MODE, DEFAULT_LANGS, SUPPORTED_LANGS
 import os
 import regex
-# Общие функции для типографа etpgrf
+
+
+def parce_and_validate_mode(
+    mode_input: str | None = None,
+) -> str:
+    """
+    Обрабатывает и валидирует входной параметр mode.
+    Если mode_input не предоставлен (None), используется режим по умолчанию.
+
+    :param mode_input: Режим обработки текста. Может быть 'unicode', 'mnemonic' или 'mixed'.
+    :return: Валидированный режим в нижнем регистре.
+    :raises TypeError: Если mode_input имеет неожиданный тип.
+    :raises ValueError: Если mode_input пуст после обработки или содержит неподдерживаемый режим.
+    """
+    if mode_input is None:
+        # Если mode_input не предоставлен явно, используем режим по умолчанию
+        _mode_input = DEFAULT_MODE
+    else:
+        _mode_input = str(mode_input).lower()
+
+    if _mode_input not in {MODE_UNICODE, MODE_MNEMONIC, MODE_MIXED}:
+        raise ValueError(
+            f"etpgrf: режим '{_mode_input}' не поддерживается. Поддерживаемые режимы: {MODE_UNICODE}, {MODE_MNEMONIC}, {MODE_MIXED}"
+        )
+
+    return _mode_input
+
 
 def parse_and_validate_langs(
     langs_input: str | list[str] | tuple[str, ...] | frozenset[str] | None = None,
diff --git a/etpgrf/hyphenation.py b/etpgrf/hyphenation.py
index df85452..3118b2f 100755
--- a/etpgrf/hyphenation.py
+++ b/etpgrf/hyphenation.py
@@ -1,7 +1,6 @@
-from os.path import exists
-
 import regex
-from etpgrf.comutil import parse_and_validate_langs
+from etpgrf.config import DEFAULT_MODE, DEFAULT_LANGS, SHY_ENTITIES, MODE_UNICODE
+from etpgrf.comutil import parce_and_validate_mode, parse_and_validate_langs
 
 _RU_VOWELS_UPPER = frozenset(['А', 'О', 'И', 'Е', 'Ё', 'Э', 'Ы', 'У', 'Ю', 'Я'])
 _RU_CONSONANTS_UPPER = frozenset(['Б', 'В', 'Г', 'Д', 'Ж', 'З', 'К', 'Л', 'М', 'Н', 'П', 'Р', 'С', 'Т', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ'])
@@ -16,10 +15,12 @@ class Hyphenator:
     """Правила расстановки переносов для разных языков.
     """
     def __init__(self,
-                 langs: frozenset[str],  # Языки, которые обрабатываем в переносе слов
+                 langs: frozenset[str] = DEFAULT_LANGS,  # Языки, которые обрабатываем в переносе слов
+                 mode: str = DEFAULT_MODE,  # Режим обработки текста
                  max_unhyphenated_len: int = 14,  # Максимальная длина непереносимой группы
                  min_chars_per_part: int = 3):  # Минимальная длина после переноса (хвост, который разрешено переносить)
         self.langs: frozenset[str] = parse_and_validate_langs(langs)
+        self.mode: str = parce_and_validate_mode(mode)
         self.max_unhyphenated_len = max_unhyphenated_len
         self.min_chars_per_part = min_chars_per_part
 
@@ -28,10 +29,10 @@ class Hyphenator:
         self._consonants: frozenset = frozenset()
         self._j_sound_upper: frozenset = frozenset()
         self._signs_upper: frozenset = frozenset()
-
-        self._load_language_resources_for_hyphenation() # Загружает наборы символов на основе self.langs
-
-        self._split_memo: dict[str, str] = {} # Кеш для этого экземпляра
+        # Загружает наборы символов на основе self.langs
+        self._load_language_resources_for_hyphenation()
+        # Определяем символ переноса в зависимости от режима
+        self._split_code: str = SHY_ENTITIES['SHY'][0] if self.mode == MODE_UNICODE else SHY_ENTITIES['SHY'][1]
 
 
     def _load_language_resources_for_hyphenation(self):
@@ -118,8 +119,8 @@ class Hyphenator:
             left_part = word_to_split[:hyphen_idx]
             right_part = word_to_split[hyphen_idx:]
 
-            # Рекурсивно делим левую и правую части
-            return split_word(left_part) + "-­" + split_word(right_part)
+            # Рекурсивно делим левую и правую части и соединяем их через символ переноса
+            return split_word(left_part) + self._split_code + split_word(right_part)
 
         # Основная логика
         if len(word) <= self.max_unhyphenated_len or not any(self._is_vow(c) for c in word):
diff --git a/etpgrf/typograph.py b/etpgrf/typograph.py
index ffc0730..bf5233b 100644
--- a/etpgrf/typograph.py
+++ b/etpgrf/typograph.py
@@ -1,13 +1,13 @@
-from etpgrf.config import UTF, MNEMO_CODE
-from etpgrf.comutil import parse_and_validate_langs
+from etpgrf.config import DEFAULT_MODE, DEFAULT_LANGS
+from etpgrf.comutil import parce_and_validate_mode, parse_and_validate_langs
 from etpgrf.hyphenation import Hyphenator
 
 
 # --- Основной класс Typographer ---
 class Typographer:
     def __init__(self,
-                 langs: str | list[str] | tuple[str, ...] | frozenset[str] = 'ru',
-                 code_out: str = 'mnemo',
+                 langs: str | list[str] | tuple[str, ...] | frozenset[str] = DEFAULT_LANGS,
+                 mode: str = DEFAULT_MODE,
                  hyphenation_rule: Hyphenator | None = None,  # Перенос слов и параметры расстановки переносов
                  # glue_prepositions_rule: GluePrepositionsRule | None = None, # Для других правил
                  # ... другие модули правил ...
@@ -16,16 +16,12 @@ class Typographer:
         # --- Обработка и валидация параметра langs ---
         self.langs: frozenset[str] = parse_and_validate_langs(langs)
 
-        # --- Обработка и валидация параметра code_out ---
-        if code_out not in MNEMO_CODE | UTF:
-            raise ValueError(f"etpgrf: code_out '{code_out}' is not supported. Supported codes: {MNEMO_CODE | UTF}")
+        # --- Обработка и валидация параметра mode ---
+        self.mode: str = parce_and_validate_mode(mode)
 
         # Сохраняем переданные модули правил
         self.hyphenation_rule = hyphenation_rule
 
-        # TODO: вынести все соответствия UTF ⇄ MNEMO_CODE в отдельный класс
-        # self.hyphen_char = "­" if code_out in UTF else "&shy;" # Мягкий перенос по умолчанию
-
     # Конвейер для обработки текста
     def process(self, text: str) -> str:
         processed_text = text
@@ -43,5 +39,5 @@ class Typographer:
         return processed_text
 
     # def _get_nbsp(self): # Пример получения неразрывного пробела
-    #     return "\u00A0" if self.code_out in UTF else "&nbsp;"
+    #     return "\u00A0" if self.mode in UTF else "&nbsp;"
 
diff --git a/main.py b/main.py
index c8e57db..159aae2 100644
--- a/main.py
+++ b/main.py
@@ -8,7 +8,7 @@ if __name__ == '__main__':
     # Определяем пользовательские правила переносов
     hyphen_settings = etpgrf.Hyphenator(langs=frozenset(['ru']), max_unhyphenated_len=8)
     # Определяем пользовательские правила типографа
-    typo = etpgrf.Typographer(langs='ru', code_out='utf-8', hyphenation_rule=hyphen_settings)
+    typo = etpgrf.Typographer(langs='ru', mode='mnemonic', hyphenation_rule=hyphen_settings)
 
     result = hyphen_settings.hyp_in_text("Бармалейщина")
     print(result, "\n\n")