Правильное использование арабских диакритиков в Amal
5 мин. чтенияMohammad Shaker

Правильное использование арабских диакритиков в Amal

Amal учитывает все арабские диакритики, обеспечивая точное распознание речи и красивый текст для эффективного обучения арабскому.

Engineering

Короткий ответ

Amal учитывает все арабские диакритики, обеспечивая точное распознание речи и красивый текст для эффективного обучения арабскому.

Правильное использование арабских диакритиков в Amal: как работают Ташкил, Шадда и Хамза

Amal обрабатывает полную сложность арабских диакритиков: 8 знаков ташкил (фатха, дамма, касра, шадда, сукун, фатхан, дамматан, касратан), 4 варианта алефа (стандартный, мадда, хамза сверху, хамза снизу, васла), 3 варианта хамзы (изолированная, на вау, на йа) и лигатуры лям-алеф. Речевое распознавание, отображение текста и оценка сходства в приложении учитывают диакритизированный арабский («كَتَبَ») по-другому, чем без диакритиков («كتب») — важное различие, которое многие обучающие приложения игнорируют.

Почему диакритики важны для обучения

Проблема неоднозначности

Арабский без диакритиков неоднозначен:

  • "كتب" может означать:
    • "kataba" (он написал) — прошедшее время
    • "kutub" (книги) — множественное число
    • "kutiba" (это было написано) — страдательный залог

Все пишутся одинаково без диакритиков. Диакритики снимают неоднозначность.

Этапы обучения

  1. Начинающий: учится читать с диакритиками (легко — гласные отмечены)
  2. Средний: практикует чтение с диакритиками до автоматизма
  3. Продвинутый: постепенно убирает диакритики, чтение усложняется
  4. Свободное владение: читает без диакритиков свободно (на уровне носителя)

Большинство приложений для изучения арабского пропускают первый этап — они не учат диакритикам или удаляют их. Это формирует плохие привычки. Прогрессия Amal построена научно правильно.

Реализация на уровне Unicode

Диакритические знаки (всего 8):

// lib/src/utils/arabic_extension.dart
class ArabicExtension {
  static const Map<String, String> tashkeelMarks = {
    'FATHA': '\u064E',      // َ (гласная 'a')
    'DAMMA': '\u064F',      // ُ (гласная 'u')
    'KASRA': '\u0650',      // ِ (гласная 'i')
    'SUKUN': '\u0652',      // ْ (без гласной)
    'SHADDA': '\u0651',     // ّ (удвоенная буква)
    'FATHATAN': '\u064B',   // ً (танвин 'ан')
    'DAMMATAN': '\u064C',   // ٌ (танвин 'ун')
    'KASRATAN': '\u064D',   // ٍ (танвин 'ин')
  };

static const Map<String, String> alefVariants = { 'ALEF_STANDARD': 'ا', // ا 'ALEF_WITH_MADDA': 'آ', // آ (удлинённый) 'ALEF_WITH_HAMZA_ABOVE': 'أ', // أ 'ALEF_WITH_HAMZA_BELOW': 'إ', // إ 'ALEF_WASLA': 'ٰ', // ٰ (соединительный алеф) };

static const Map<String, String> hamzaVariants = { 'HAMZA_ISOLATED': 'ء', // Изолированная хамза 'HAMZA_ON_WAW': 'ؤ', // Хамза на вау (و + хамза) 'HAMZA_ON_YEH': 'ئ', // Хамза на йа (ي + хамза) }; }

Коранные диакритики и у-смятения (uthmani stops)

Для приложения Thurayya поддерживаются специальные знаки, используемые в Коране:

static const Map<String, String> quranicMarks = {
  'STOP_FULL': 'ۖ',         // Полная остановка (‖)
  'STOP_HALF': 'ۗ',         // Полупауза
  'STOP_QUA': 'ۙ',          // Qua-пауза
  'STOP_NECESSARY': 'ۚ',     // Обязательная пауза
  'TAJWEED_ELONGATION': '۝', // Индикатор удлинения
};

Распознавание речи с учётом диакритиков

Контекстное смещение с диакритиками

Когда ребёнок учит «كَتَبَ» (он написал), система смещает распознавание речи в сторону именно этого произношения:

# src/services/stt_client.py
def recognize_with_diacritical_context(audio_bytes, expected_text):
    # expected_text = "كَتَبَ" (с диакритиками)
# Создаём подсказку для распознавания
speech_context = {
    'phrases': [expected_text],
    'boost': 20.0  # Сильное смещение на ожидаемый текст
}

# Отправляем в Google Cloud STT
response = google_stt_client.recognize(
    audio=audio_bytes,
    language_code='ar-SA',
    speech_contexts=[speech_context]
)

# Результат: Google STT ориентирован на произношение "kataba"
return response

Оценка сходства с учётом диакритиков

def compare_pronunciations(expected, actual):
    """
    expected: "كَتَبَ" (с диакритиками)
    actual: "كتب" (попытка ребёнка, возможно без диакритиков)
    """
# Убираем диакритики для грубого сравнения
expected_base = strip_diacritics(expected)  # "كتب"
actual_base = strip_diacritics(actual)      # "كتب"

# Базовое сходство (без учёта диакритиков)
base_similarity = string_similarity(expected_base, actual_base)  # 1.0 (идеально)

# Бонус за правильные диакритики (если есть)
diacritic_bonus = 0.0
if has_diacritics(actual):
    diacritic_accuracy = diacritics_match_ratio(expected, actual)
    diacritic_bonus = diacritic_accuracy * 0.15  # До +15% за корректные диакритики

# Итоговый балл
final_score = min(base_similarity + diacritic_bonus, 1.0)

return {
    'base_score': base_similarity,
    'diacritic_bonus': diacritic_bonus,
    'final_score': final_score,
    'feedback': 'Отлично! Произношение идеальное. Далее практикуйте диакритики.'
}

Это значит:

  • Ребёнок сказал "كتب" (без диакритиков) → 85-90% баллов (правильная база, отсутствуют диакритики)
  • Ребёнок сказал "كَتَبَ" (полностью с диакритиками) → 98%+ баллов (идеально)
Прогресс ясен: сначала уточнить корневое произношение, потом учить диакритические тонкости.

Проблемы отображения текста справа налево

Управление направлением текста

// lib/src/screens/lesson_screen.dart
Column(
  children: [
    Directionality(
      textDirection: TextDirection.rtl,  // Для арабского
      child: Text(
        'كَتَبَ',
        textAlign: TextAlign.right,      // Выравнивание вправо для RTL
        style: TextStyle(
          fontFamily: 'IBMPlexSansArabic',
          fontSize: 36,
          height: 1.8,  // Увеличенная высота строк для диакритиков
        ),
      ),
    ),
    // Инструкции ниже на английском
    Directionality(
      textDirection: TextDirection.ltr,  // Для английского
      child: Text(
        'Pronounce: "he wrote"',
        textAlign: TextAlign.left,       // Выравнивание влево для LTR
      ),
    ),
  ],
)

Формы букв в зависимости от позиции

Арабские буквы меняют форму в зависимости от положения в слове:

  • Изолированная: "ك" (Каф)
  • Начальная: "كَـــ" (Каф в начале)
  • Средняя: "ـــكَـــ" (Каф в середине)
  • Конечная: "ـــكَ" (Каф в конце)
Шрифт IBMPlexSansArabic автоматически меняет форму, если верно указаны юникодные последовательности:

// Правильно: используется символ расширения (кашида)
String word = 'ك' + '\u0640' + 'ت' + '\u0640' + 'ب';  // Кашида

// Неправильно: простая конкатенация String word = 'ك' + 'ت' + 'ب'; // Могут быть ошибки отображения

Смешение направлений текста

Когда английский и арабский идут вместе:

RichText(
  textDirection: TextDirection.rtl,  // Основное направление — справа налево
  text: TextSpan(
    children: [
      TextSpan(text: 'means ', style: englishStyle),  // Слева направо
      TextSpan(text: 'كتاب', style: arabicStyle),    // Справа налево
      TextSpan(text: ' (book)', style: englishStyle), // Слева направо
    ],
  ),
)

Будет корректно отображено «means كتاب (book)» с правильным порядком и направлением.

Часто задаваемые вопросы

В: Зачем заставлять новичков использовать диакритики? Разве это не сложнее?
О: Да, сначала это сложнее. Но обучение с диакритиками укрепляет связь между буквами и звуками. Исследования показывают, что это ускоряет овладение языком. После освоения с диакритиками переход к чтению без них — естественный этап.

В: Что делать, если клавиатура ребёнка не поддерживает ввод диакритиков?
О: Приложение не требует от детей вводить диакритики вручную — распознавание и произношение основаны на речи. Только преподаватели и создатели контента вводят диакритики с помощью специализированных арабских клавиатур.

В: Поддерживает ли Amal нестандартные комбинации диакритиков?
О: Мы поддерживаем все стандартизированные Unicode варианты. Редкие или кастомные сочетания могут отображаться некорректно, но стандартный коранный и современный арабский полностью поддерживаются.

ПоделитьсяTwitterLinkedInWhatsApp

Похожие статьи