Amal支持阿拉伯语所有复杂的附加符号:8种tashkeel符号(fatha、damma、kasra、shadda、sukun、fathatan、dammatan、kasratan),4种alef变体(标准、madda、上方hamza、下方hamza、wasla),3种hamza变体(独立、位于waw上、位于yeh上)以及Lam-Alef连写。该应用的语音识别、文本渲染和相似度评分均区别对待有附加符号的阿拉伯字("كَتَبَ")与无附加符号字("كتب")——这一关键细节多数阿拉伯语学习应用忽视。
为什么附加符号对学习至关重要
模糊性问题
无附加符号的阿拉伯语存在歧义:
- "كتب"可能表示:
- "kataba"(他写了)——过去时
- "kutub"(书籍)——复数名词
- "kutiba"(它被写)——被动语态
这些词形拼写相同,附加符号消除歧义。
学习进阶
- 初学者:学习带附加符号的阅读(简单,元音标注明确)
- 中级:练习含附加符号直到自动识别
- 高级:逐步移除附加符号,阅读难度渐增
- 流利:流利阅读无附加符号文本(母语者级别)
大多数阿拉伯语学习应用跳过步骤1——完全忽略附加符号教学甚至去掉附加符号,培养不良习惯。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', // ً (tanween 'an')
'DAMMATAN': '\u064C', // ٌ (tanween 'un')
'KASRATAN': '\u064D', // ٍ (tanween 'in')
};
static const Map<String, String> alefVariants = {
'ALEF_STANDARD': 'ا', // ا
'ALEF_WITH_MADDA': 'آ', // آ (长音)
'ALEF_WITH_HAMZA_ABOVE': 'أ', // أ
'ALEF_WITH_HAMZA_BELOW': 'إ', // إ
'ALEF_WASLA': 'ٰ', // ٰ (连接alef)
};
static const Map<String, String> hamzaVariants = {
'HAMZA_ISOLATED': 'ء', // 独立hamza
'HAMZA_ON_WAW': 'ؤ', // waw上hamza (و + hamza)
'HAMZA_ON_YEH': 'ئ', // yeh上hamza (ي + hamza)
};
}
古兰经特定附加符号与乌斯曼停顿
针对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云语音识别
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, // 右对齐
style: TextStyle(
fontFamily: 'IBMPlexSansArabic',
fontSize: 36,
height: 1.8, // 提升行高以显示附加符号
),
),
),
// 下面是英语说明
Directionality(
textDirection: TextDirection.ltr, // 英文左对齐
child: Text(
'Pronounce: "he wrote"',
textAlign: TextAlign.left, // 左对齐
),
),
],
)
字母连写形变
阿拉伯字母根据位置改变形态:
- 独立:"ك" (Kaf)
- 词首:"كَـــ" (Kaf开头)
- 词中:"ـــكَـــ" (Kaf中间)
- 词尾:"ـــكَ" (Kaf结尾)
IBMPlexSansArabic字体自动完成形态变化,但需正确Unicode序列:
// 正确:使用链接字符
String word = 'ك' + '\u0640' + 'ت' + '\u0640' + 'ب'; // Kashida(连接符)
// 错误:直接拼接
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不要求孩子手动输入附加符号,识别和发音依赖语音。只有教师和内容创作者需要输入附加符号,他们使用专业阿拉伯键盘。
问:Amal支持非标准附加符号组合吗?
答:支持所有Unicode标准组合,少见或自定义组合可能显示异常,但标准古兰经和现代阿拉伯语完全支持。



