Diacritici Arabi Correttamente: Come Amal Gestisce Tashkeel, Shadda e Hamza
5 min di letturaMohammad Shaker

Diacritici Arabi Correttamente: Come Amal Gestisce Tashkeel, Shadda e Hamza

Amal gestisce tutti i diacritici arabi: tashkeel, varianti di alef, hamza e legature Lam-Alef per un apprendimento preciso.

Engineering

Risposta rapida

Amal gestisce tutti i diacritici arabi: tashkeel, varianti di alef, hamza e legature Lam-Alef per un apprendimento preciso.

Amal gestisce tutta la complessità dei diacritici arabi: 8 segni tashkeel (fatha, damma, kasra, shadda, sukun, fathatan, dammatan, kasratan), 4 varianti di alef (standard, madda, hamza sopra, hamza sotto, wasla), 3 varianti di hamza (isolata, su waw, su ya), e le legature Lam-Alef. Il riconoscimento vocale, la visualizzazione del testo e la valutazione della similarità dell’app trattano l’arabo diacritizzato ("كَتَبَ") in modo diverso rispetto all’arabo senza diacritici ("كتب") — una distinzione fondamentale spesso ignorata da molte app per imparare l’arabo.

Perché i Diacritici Sono Importanti per l’Apprendimento

Il Problema dell’Ambiguità

L’arabo senza diacritici è ambiguo:
- "كتب" può significare:
- "kataba" (lui ha scritto) — passato
- "kutub" (libri) — sostantivo plurale
- "kutiba" (è stato scritto) — forma passiva

Tutte le forme si scrivono identiche senza diacritici. I diacritici eliminano l’ambiguità.

La Progressione dell’Apprendimento
1. Principiante: imparare a leggere CON diacritici (facile — le vocali sono segnate)
2. Intermedio: esercitarsi CON diacritici fino a leggere automaticamente
3. Avanzato: rimuovere gradualmente i diacritici, la lettura diventa più difficile
4. Fluente: leggere senza diacritici fluentemente (livello madrelingua)

La maggior parte delle app per imparare l’arabo salta il primo passo — non insegnano i diacritici o li rimuovono. Questo porta a cattive abitudini. La progressione di Amal è scientificamente corretta.

La Nostra Implementazione a Livello Unicode

I Segni Diacritici (8 totali)

// lib/src/utils/arabic_extension.dart
class ArabicExtension {
  static const Map<String, String> tashkeelMarks = {
    'FATHA': '\u064E',      // َ (vocale 'a')
    'DAMMA': '\u064F',      // ُ (vocale 'u')
    'KASRA': '\u0650',      // ِ (vocale 'i')
    'SUKUN': '\u0652',      // ْ (nessuna vocale)
    'SHADDA': '\u0651',     // ّ (lettera raddoppiata)
    'FATHATAN': '\u064B',   // ً (tanween 'an')
    'DAMMATAN': '\u064C',   // ٌ (tanween 'un')
    'KASRATAN': '\u064D',   // ٍ (tanween 'in')
  };

static const Map<String, String> alefVariants = { 'ALEF_STANDARD': 'ا', // ا 'ALEF_WITH_MADDA': 'آ', // آ (allungata) 'ALEF_WITH_HAMZA_ABOVE': 'أ', // أ 'ALEF_WITH_HAMZA_BELOW': 'إ', // إ 'ALEF_WASLA': 'ٰ', // ٰ (alef congiungente) };

static const Map<String, String> hamzaVariants = { 'HAMZA_ISOLATED': 'ء', // Hamza isolata 'HAMZA_ON_WAW': 'ؤ', // Hamza su waw (و + hamza) 'HAMZA_ON_YEH': 'ئ', // Hamza su yeh (ي + hamza) }; }

Diacritici Coranici e Segni Uthmani

Per Thurayya, supportiamo i segni specifici del Corano:

static const Map<String, String> quranicMarks = {
  'STOP_FULL': 'ۖ',         // Pausa completa (‖)
  'STOP_HALF': 'ۗ',         // Pausa parziale
  'STOP_QUA': 'ۙ',          // Pausa qua
  'STOP_NECESSARY': 'ۚ',     // Pausa necessaria
  'TAJWEED_ELONGATION': '۝', // Indicatore di allungamento
};

Riconoscimento Vocale Consapevole dei Diacritici

Contestualizzazione con Diacritici

Quando un bambino impara "كَتَبَ" (lui ha scritto, passato), il riconoscimento vocale viene orientato verso quella esatta vocalizzazione:

# src/services/stt_client.py
def recognize_with_diacritical_context(audio_bytes, expected_text):
    # expected_text = "كَتَبَ" (con diacritici)
# Creare suggerimento per il contesto vocale
speech_context = {
    'phrases': [expected_text],
    'boost': 20.0  # Forte aumento per il testo atteso
}

# Invio a Google Cloud STT
response = google_stt_client.recognize(
    audio=audio_bytes,
    language_code='ar-SA',
    speech_contexts=[speech_context]
)

# Risultato: Google STT è orientato alla pronuncia "kataba"
return response

Valutazione della Similarità Consapevole dei Diacritici

def compare_pronunciations(expected, actual):
    """
    expected: "كَتَبَ" (con diacritici)
    actual: "كتب" (tentativo del bambino, forse senza diacritici)
    """
# Rimuovere diacritici per confronto grossolano
expected_base = strip_diacritics(expected)  # "كتب"
actual_base = strip_diacritics(actual)      # "كتب"

# Similarità base (ignorando diacritici)
base_similarity = string_similarity(expected_base, actual_base)  # 1.0 (perfetto)

# Bonus diacritico (se il tentativo include diacritici)
diacritic_bonus = 0.0
if has_diacritics(actual):
    diacritic_accuracy = diacritics_match_ratio(expected, actual)
    diacritic_bonus = diacritic_accuracy * 0.15  # Fino a +15% per diacritici corretti

# Punteggio finale
final_score = min(base_similarity + diacritic_bonus, 1.0)

return {
    'base_score': base_similarity,
    'diacritic_bonus': diacritic_bonus,
    'final_score': final_score,
    'feedback': 'Ottimo! La pronuncia è perfetta. Ora esercitati con i segni diacritici.'
}

Ciò significa:
- Il bambino dice "كتب" (senza diacritici) → punteggio 85-90% (corretta base, mancano diacritici)
- Il bambino dice "كَتَبَ" (completamente diacritizzato) → punteggio 98%+ (perfetto)
- La progressione è chiara: prima si padroneggia la pronuncia base, poi i dettagli dei diacritici

Gestione della Scrittura da Destra a Sinistra (RTL)

Gestione della Direzione del Testo

// lib/src/screens/lesson_screen.dart
Column(
  children: [
    Directionality(
      textDirection: TextDirection.rtl,  // Per testo arabo
      child: Text(
        'كَتَبَ',
        textAlign: TextAlign.right,      // Allineamento a destra per RTL
        style: TextStyle(
          fontFamily: 'IBMPlexSansArabic',
          fontSize: 36,
          height: 1.8,  // Altezza linea extra per diacritici
        ),
      ),
    ),
    // Istruzioni in inglese sotto
    Directionality(
      textDirection: TextDirection.ltr,  // Per inglese
      child: Text(
        'Pronounce: "he wrote"',
        textAlign: TextAlign.left,       // Allineamento a sinistra per LTR
      ),
    ),
  ],
)

Formatura delle Lettere Connesse

Le lettere arabe cambiano forma a seconda della posizione:
- Isolata: "ك" (Kaf)
- Iniziale: "كَـــ" (Kaf all’inizio della parola)
- Mediale: "ـــكَـــ" (Kaf in mezzo)
- Finale: "ـــكَ" (Kaf in fine)

Il font IBMPlexSansArabic gestisce automaticamente la formatura, ma servono sequenze Unicode corrette:

// Corretto: usa caratteri di unione Unicode
String word = 'ك' + '\u0640' + 'ت' + '\u0640' + 'ب';  // Kashida (carattere di allungamento)

// Errato: semplice concatenazione\String word = 'ك' + 'ت' + 'ب'; // Potrebbe non formare correttamente

Miscele di Testo Bidirezionale

Quando inglese e arabo appaiono insieme:

RichText(
  textDirection: TextDirection.rtl,  // RTL complessivo
  text: TextSpan(
    children: [
      TextSpan(text: 'means ', style: englishStyle),  // LTR
      TextSpan(text: 'كتاب', style: arabicStyle),    // RTL
      TextSpan(text: ' (book)', style: englishStyle), // LTR
    ],
  ),
)

Risultato: "means كتاب (book)" visualizzato con flusso bidirezionale corretto.

FAQ

Q: Perché forzare i diacritici ai principianti? Non rende più difficile?
A: All’inizio sì. Ma imparare con i diacritici rafforza l’associazione lettera-suono. La ricerca dimostra che si acquisisce fluency più velocemente. Dopo averli padroneggiati, passare a leggere senza diacritici è naturale.

Q: E se la tastiera di mio figlio non supporta i diacritici?
A: L’app non richiede ai bambini di digitare i diacritici. Il riconoscimento e la pronuncia si basano sulla voce. Solo adulti (insegnanti, creatori di contenuti) inseriscono diacritici usando tastiere arabe specializzate.

Q: Amal supporta combinazioni diacritiche non standard?
A: Supportiamo tutte le combinazioni standard Unicode. Combinazioni rare o personalizzate potrebbero non rendere correttamente, ma l’arabo coranico standard e moderno è completamente supportato.

Articoli correlati