معيار المصطلحات
اسم معتمد واحد لكل مفهوم، وتهجئة برمجية تُشتق بقاعدة بدل أن تُختار.
معيار لتوحيد تسمية المفاهيم المستخدمة في البرمجيات والتطبيقات القرآنية وتعريفها، بحيث تكون واضحة دقيقة مستقرة، يتوقعها المطور قبل أن يبحث عنها، ويستخدمها استخدامًا متسقًا في:
- الكود
- الـ
API - قواعد البيانات
- الـ
dataset - الحزم
- التوثيق
الفكرة الأساسية مستوحاة من مبدأ convention over configuration، أي أن الاصطلاح يغني عن الإعداد:
عندما يعرف المطور قواعد المعيار، يستطيع توقع أسماء المفاهيم والعلاقات والحقول وطريقة استخدامها دون الرجوع إلى التوثيق في كل مرة.
في سطور
- نحدد المفهوم قبل اسمه (§1).
- لكل مفهوم اسم معتمد واحد، ولا يشترك مفهومان في اسم (§2).
- المفهوم القرآني أو العلمي يحتفظ باسمه العربي، والمفهوم العام يأخذ اسمه الإنجليزي، حتى داخل الاسم المركب (§3).
- تهجئة المصطلح العربي في الكود تُشتق من اسمه المشكول بدالة واحدة هي
tools/translit.py، ولا يختارها أحد باجتهاده (§4–§8). codeللمعرفات، وdisplayللقارئ، وarabic.vocalizedللقارئ العربي، وقد تختلف الثلاثة (§9).- لكل مدخل
kindواحد وcategoryواحد. وللأنواع والقيم مداخل مستقلة، أما أفراد المجموعة المغلقة فسطور في سجل (§12–§13). - يشرح
definitionما المفهوم، ويشرحpurposeلماذا تحتاج إليه البرمجيات، وتذكرboundariesما لا يشمله (§15–§17). - الأسماء والتهجئات والمقابلات الإنجليزية والأسماء المهجورة حقول منفصلة (§19–§20).
- المفردات نفسها تجري في الكود والـ
APIوقواعد البيانات والتوثيق (§26). - القاموس مقروء آليًا، والقواعد التي ينص عليها تفحصها الأدوات (§29).
النطاق. يدخل المفهوم في هذا المعيار إذا لم يمكن تعريفه دون الرجوع إلى القرآن أو المصحف. وما سوى ذلك مما يخزنه التطبيق جائز، لكن المعيار لا يسميه (§30).
1. نحدد المفهوم قبل أن نسميه
نحدد المفهوم أولًا ثم نختار اسمه.
قبل اعتماد أي مصطلح يجب تحديد:
- ما الذي يمثله؟
- ما حدوده؟
- ما الذي لا يشمله؟
- هل يختلف عن مفهوم قريب منه؟
- ما الغرض من تمثيله برمجيًا؟
والسؤال الأول هو:
ما المفهوم الذي نريد تمثيله؟
وليس:
كيف نترجم هذه الكلمة؟
ثم نختار الاسم الأنسب له.
2. اسم معتمد واحد لكل مفهوم
لكل مفهوم اسم معتمد واحد، وهو الاسم الذي يُستخدم افتراضيًا في الكود في كل المشاريع التي تتبع المعيار. ونسمي تهجئته البرمجية Canonical Code Spelling، وقواعد اشتقاقها في §4.
مثلًا:
surah
ayah
word
mushaf
tajwid
يمكن تسجيل أسماء وتهجئات وترجمات أخرى، لكنها لا تنافس الاسم المعتمد.
ولا يشترك مفهومان في اسم واحد. ويوقف tools/build_aliases.py البناء إذا ادعى مدخلان اسمًا واحدًا بأي تهجئة من تهجئاتهما. والموضع الوحيد الذي يشترك فيه اسم هو بين قيمتي تصنيفين، لأن العمود يحمل قيم تصنيف واحد ولا يحمل قيم اثنين: فـmakki قيمة من قيم revelation_classification ومن قيم ayah_numbering_system، وللمدخلين معرّفان مختلفان (§14).
القاعدة:
لكل مفهوم اسم معتمد واحد.
One concept, one canonical name.
3. متى نحتفظ بالمصطلح العربي
نحتفظ بالمصطلح العربي عندما يمثل مفهومًا قرآنيًا أو علميًا متخصصًا، ويؤدي استبداله بكلمة إنجليزية عامة إلى فقدان الدقة أو هوية المفهوم.
مثل:
surah
ayah
mushaf
juz
hizb
qiraah
riwayah
tajwid
tafsir
أما المفاهيم العامة التي لها أسماء تقنية إنجليزية واضحة، فنستخدم الإنجليزية الطبيعية:
word
letter
page
line
root
translation
glyph
لذلك نفضل مثلًا:
surah → ayah → word
على:
chapter → verse → word
وعلى:
surah → ayah → kalimah
ووجود اسم عربي للمفهوم لا يعني أن الأولى نقله بحروفه.
القاعدة نفسها داخل الاسم المركب
إذا جمع الاسم المركب كلمة اصطلاحية وكلمة عامة، نقلنا الكلمة الاصطلاحية بحروفها وترجمنا الكلمة العامة:
المِيم الصَّغِيرَة → small_meem لا meem_saghirah
الصِّفْر المُسْتَدِير → rounded_zero لا sifr_mustadir
الثَّلَاث نُقَط → three_dots لا thalath_nuqat
الأَلِف المَحْذُوفَة → omitted_alif لا alif_mahdhufah
فكلمة saghirah لا تضيف شيئًا إلى small، ولا يستفيد منها قارئ عربي ولا قارئ إنجليزي.
وتأتي الصفة المترجمة قبل موصوفها كما في ترتيب الإنجليزية. ويأتي المضاف المترجم في آخر الاسم، وإذا تتابعت عدة مضافات انعكس ترتيبها:
عَلَامَة الوَقْف → waqf_mark
نَوْع عَلَامَة الوَقْف → waqf_mark_type
أما الكلمة الاصطلاحية فتُنقل بحروفها حتى لو بدت كلمة مألوفة:
النُّون السَّاكِنَة → noon_sakinah فـ«ساكنة» مصطلح تجويدي
الوَقْف اللَّازِم → waqf_lazim فـ«لازم» مصطلح في الوقف
الكلمات العامة مسجلة في standards/terminology/data/general_words.tsv، ومع كل كلمة دورها. فالكلمة الموسومة word تبقى في موضعها، والموسومة head تنتقل إلى آخر الاسم، والموسومة with_head تترجم إذا جاءت بجوار كلمة رأس وتنقل بحروفها في غير ذلك (العَلَامَة الإِمْلَائِيَّة → orthographic_mark، أما الرَّسْم الإِمْلَائِيّ → rasm_imlai).
القاعدة:
المفهوم القرآني يحتفظ باسمه القرآني، والمفهوم العام يأخذ الإنجليزية التقنية الطبيعية.
Quran-specific concepts retain Quranic names; general concepts use natural technical English.
4. التهجئة البرمجية المعتمدة
عندما نقرر استخدام مصطلح عربي الأصل، يعتمد له المعيار تهجئة برمجية واحدة، اسمها Canonical Code Spelling.
الهدف تهجئة بسيطة وثابتة يتوقعها المطورون، وليس نظام نقل حرفي دقيق مثل ALA-LC أو DIN 31635.
القواعد العامة
- تكتب بمحارف
ASCIIوحدها. - لا تستخدم علامات النقل الدقيق:
āوīوūوʿوʾ. - لا تستخدم
'لتمثيل الهمزة أو العين. - لكل مصطلح تهجئة واحدة معتمدة.
- التهجئات الشائعة الأخرى تسجل في
alternative_spellings.
كيف تُشتق التهجئة
نشتق Canonical Code Spelling من الاسم العربي بالحركات بدالة واحدة، ولا نترك التهجئة لاجتهاد كل مشروع. وهذا ممكن لأن قواعد الأقسام من 4 إلى 8 قواعد آلية يمكن تنفيذها في برنامج.
python3 tools/translit.py "سُورَة" "رُبْع الحِزْب"
سُورَة surah Surah
رُبْع الحِزْب rubu_al_hizb Rubu al-Hizb
- نكتب المدخل بالحركات، لأن الحركات القصيرة لا تُستنتج من النص المجرد، واستنتاجها هو الاجتهاد الذي نريد الاستغناء عنه. وترفض الدالة همزة الوصل غير المشكولة ولا تخمن لها حكمًا:
اِسْتِعَاذَةتعطيistiadhah، أمااستعاذةفترفضها الدالة. ونكتب همزة الوصل ألفًا عليها حركتها (اِ) وليسٱ. - ولا تُرَدّ التهجئة إلى أصلها العربي، وهذا مقصود. فالحرف المفخم ونظيره المرقق يعطيان حرفًا لاتينيًا واحدًا، مثل
صوسوكلاهماs. الهدف أن يبقى المعرف ثابتًا حتى لو لم يكن النطق دقيقًا. - يعيد
tools/check_conformance.pyفي كل بناء اشتقاقcodeلكل مدخلorigin: quranicمنarabic.vocalized، ويحتفظtools/test_translit.pyبالحالات المرجعية. وإذا تغيرت قاعدة من قواعد التهجئة، بيّنت الأداتان أي الأسماء تتغير معها.
مثلًا:
qiraah
ruku
irab
istiadhah
بدل:
qira'ah
rukūʿ
i'rab
istiʿādhah
جدول الحروف
تكتب الحروف الصامتة كما يلي، ويشترك الحرف المفخم ونظيره المرقق في تهجئة واحدة:
ب b ت t ث th ج j ح h خ kh د d ذ dh ر r ز z
س s ش sh ص s ض d ط t ظ z غ gh ف f ق q ك k
ل l م m ن n ه h و w ي y ة h (و t في الإضافة، §5)
- الهمزة والعين لا يقابلهما حرف (§7).
- الحركات القصيرة: الفتحة
a، والكسرةi، والضمةu. - حروف المد:
ا/ى→a، وي→i، وو→u، ولا تضاعف (§6). وتعامل الألف الخنجرية والمدة معاملة الألف الطويلة. - الحروف اللينة:
وْبعد فتحة تعطيaw، ويْبعد فتحة تعطيay:mawdiوawlaوtarafayn. - الشدة تضاعف الحرف:
makkiوmuqattaوshaddah. - التنوين يعطي الحركة القصيرة وحدها، وتسقط حركة الإعراب على آخر الكلمة:
هُدًى→huda. - أداة التعريف
alدائمًا، ولا تدغم في الحرف الشمسي (§8).
5. التاء المربوطة
عند نقل مصطلح عربي مفرد ينتهي بتاء مربوطة، تعتمد h في النهاية:
سُورَة → surah
آيَة → ayah
رِوَايَة → riwayah
قِرَاءَة → qiraah
بَسْمَلَة → basmalah
لذلك:
surah وليس sura
ayah وليس aya
riwayah وليس riwaya
وتسجل الصور الأخرى تهجئات بديلة.
التاء المربوطة في الإضافة
إذا كانت الكلمة مضافة إلى ما بعدها كتبنا تاءها المربوطة t بدل h، لأنها تنطق تاءً في الإضافة:
هَمْزَة الوَصْل → hamzat_al_wasl لا hamzah_al_wasl
سَجْدَة التِّلَاوَة → sajdat_al_tilawah لا sajdah_al_tilawah
أما الاسم الذي تتبعه صفة فليس مضافًا، فتبقى تاؤه المربوطة h:
القَلْقَلَة الصُّغْرَى → qalqalah_sughra لا qalqalat_sughra
وهذه القاعدة آلية: التاء المربوطة تعطي t في المضاف، وتعطي h في غير ذلك، أي في آخر الاسم وقبل الصفة. ويتحقق منها tools/test_translit.py.
6. حروف المد
لا نستخدم مضاعفة الحروف الإنجليزية لتمثيل طول حروف المد في Canonical Code Spelling.
نعتمد بصورة عامة:
ا / ى → a
ي → i
و → u
وليس:
aa
ee
oo
لذلك:
tajwid
tafsir
tariq
nuzul
tahqiq
tadwir
وليس:
tajweed
tafseer
tareeq
nuzool
tahqeeq
tadweer
هذه الصور ليست خاطئة بالضرورة في الاستخدام العام، لكنها ليست التهجئة المعتمدة في هذا المعيار.
ياء النسب
الياء المشددة في آخر الاسم المنسوب تعطي i واحدة:
مَكِّيّ → makki لا makkiyy
مَدَنِيّ → madani لا madaniyy
عُثْمَانِيّ → uthmani لا uthmaniyy
أسماء الحروف تكتب كما تُنطق
أسماء الحروف تكتب كما تنطق، لأن اسم الحرف هو صوته:
نُون → noon وليس nun
مِيم → meem وليس mim
سِين → seen وليس sin
جِيم → jeem وليس jim
يَاء → yaa وليس ya
هذه القاعدة خاصة باسم الحرف وحده. أما بقية المصطلحات فتشتق كما في الأقسام 4–8:
small_noon اسم حرف، فيكتب كما ينطق
seen_al_qiraah اسم حرف
tajwid ليس اسم حرف، فيشتق (لا tajweed)
haqiqi ليس اسم حرف، فيشتق (لا haqeeqi)
makki ليس اسم حرف، فيشتق (لا makkee)
أسماء الحروف الـ28 مسجلة في standards/terminology/data/letter_names.tsv، وتقرؤها الدالة من ذلك الملف. وسبب القاعدة وقياسها في سجل القرارات.
كيف يكتب tajwid مع شيوع tajweed
يحمل code الصورة المشتقة tajwid، مع أن tajweed أكثر استعمالًا. والسبب في سجل القرارات.
ولا يضيع الاستعمال الغالب، لأن لكل مفهوم حقلين:
code tajwid مشتق بالقاعدة، وهو ما يكتب في الكود
display Tajweed مقيس بالاستعمال، وهو ما يقرؤه القارئ
ونسجل tajweed كذلك في alternative_spellings، حتى يجدها البحث وربط المرادفات.
مفتوح: اشتراك حرفين في اسم واحد بعد جمع المفخم والمرقق، ولا يستعمله مدخل اليوم. المسألة في سجل القرارات.
7. الهمزة والعين
لا نمثل الهمزة أو العين بعلامات خاصة داخل أسماء الكود.
نعتمد:
qiraah
irab
istiadhah
ruku
ولا نعتمد:
qira'ah
i'rab
isti'adhah
ruku'
أما النقل الحرفي الدقيق فنكتبه في names.transliteration، ويمكن استخدامه في واجهة العرض أو في المحتوى العلمي عند الحاجة.
الهمزة والعين في آخر الكلمة
إذا وقعت الهمزة أو العين في آخر الكلمة، وكان ما قبلها ساكنًا، كررنا الحركة التي قبلها:
رُبْع → rubu
جَمْع → jama
قَطْع → qata
الرَّفْع → rafa
والسبب أن حذفها في آخر الكلمة يقطع الكلمة قبل موضعها، فيصير ربع هو rub وجمع هو jam، وهذه كلمات إنجليزية أخرى لا صلة لها بالمعنى.
وإذا كان ما قبلها حرف مد فلا نزيد شيئًا، لأن الكلمة تنتهي بحركة أصلًا:
الرُّكُوع → ruku
المَمْنُوع → mamnu
المُقَطَّع → muqatta
مَوْضِع → mawdi
والهمزة والعين في وسط الكلمة تحذفان كما سبق، وتبقى حركتهما: muallim وqiraah. ولكل حالة من هذه الحالات اختبار في tools/test_translit.py.
الأسماء التي استقرت على صورة واحدة
بعض الأسماء استقرت في البرمجيات القرآنية على صورة واحدة، والصورة المشتقة لها صحيحة لكن لا يكتبها أحد. مثال ذلك juz: قواعد الحروف تعطي juzu، بينما لا يكاد يُستعمل غير juz.
هذه الأسماء مسجلة في standards/terminology/data/established_spellings.tsv، ومع كل سطر قياسه. ولا نقبل سطرًا جديدًا إلا ومعه قياس يثبت أن الصورة المشتقة لا تكاد تستعمل. ولا يكفي أن يكون الاستعمال راجحًا فقط، وإلا لدخل tajweed في هذا الملف. والقياسات في سجل القرارات.
حالتان خاصتان في الملف نفسه: آل عِمْرَان والسور المسماة بحروفها
يحتوي الملف نفسه على حالتين أخريين لا تحتاجان إلى قياس، لأن قاعدة صريحة تثبتهما. ونبقيهما فيه حتى تقرأهما الدالة من موضع واحد:
- لا يبدأ اسم بـ
al. اشتقاقآل عِمْرَانيعطيal_imran، لكن §8 يحفظalلأداة التعريف، لذلك يكون الاسمaal_imran. - السورة المسماة بالحروف التي تفتتح بها تكتب باسم الحرف. قواعد الحروف تقرأ
طهحروفًا صامتة متتابعة وتعطيth، بينما الاسم المعتمدtaha. وكذلكyasinوsaadوqaaf.
8. الأسماء المركبة وal-
عند الاحتفاظ بمصطلح عربي مركب نستخدم صيغة ثابتة قدر الإمكان:
Rubu al-Hizb
Asbab al-Nuzul
Sujud al-Tilawah
ولا نغير al- بحسب الحروف الشمسية في التهجئة المعتمدة.
وفي المعرفات:
rubu_al_hizb
asbab_al_nuzul
sujud_al_tilawah
متى تحذف al
al جزء من الاسم في الإضافة فقط، وتحذف في حالتين:
أداة التعريف في أول الاسم لا تدخل في الاسم البرمجي:
الفَتْحَة → fathah لا al_fathah
السُّكُون → sukun لا al_sukun
أداة التعريف في الصفة لا تدخل كذلك. فإذا كان الموصوف معرفًا وصفته معرفة، فهما اسم واحد وليسا إضافة:
الوَقْف اللَّازِم → waqf_lazim لا waqf_al_lazim
النُّون السَّاكِنَة → noon_sakinah لا noon_al_sakinah
الرَّسْم العُثْمَانِيّ → rasm_uthmani لا rasm_al_uthmani
وتميز الدالة بين الحالتين آليًا، وتنظر في كل كلمتين متجاورتين: يتحدد حكم كل كلمة بالكلمة التي قبلها مباشرة، أينما بدأ الاسم. فإذا كانت الكلمة التي قبلها معرفة بـال فهي صفة وتحذف أداة تعريفها، وإذا كانت الكلمة التي قبلها نكرة فهي مضاف إليه وتبقى فيها al:
رُبْع الحِزْب → rubu_al_hizb
(الأولى نكرة، فهي إضافة)
الوَقْف اللَّازِم → waqf_lazim
(الأولى معرفة، فهي صفة)
الوَقْف الجَائِز مُسْتَوِي الطَّرَفَيْن → waqf_jaiz_mustawi_al_tarafayn
(الجائز صفة للوقف،
والطرفين مضاف إليه لمستوي)
ولا يدخل المضاف المترجم (§3) في هذا الحكم. فنحكم على بقية الاسم كأنها أوله، لأن الإنجليزية لا تضع أداة تعريف على الوصف:
عَلَامَة الوَقْف اللَّازِم → waqf_lazim_mark لا al_waqf_lazim_mark
حرف الجر المتصل يبقى جزءًا مستقلًا
حرف الجر المكتوب بحرف واحد متصل بما بعده، مثل بِ ولِ، يصير جزءًا مستقلًا من الاسم، ويحتفظ الاسم المجرور بعده بأداة تعريفه. والسبب أن حرف الجر يفتح عبارة خاصة به، فلا يكون ما بعده صفة:
تَفْسِير بِالرَّأْي → tafsir_bi_al_ray
المَدّ العَارِض لِلسُّكُون → madd_arid_li_al_sukun
نحذف حروف الربط من الاسم البرمجي
نحذف الكلمة التي لا تفعل شيئًا غير ربط جزء من الاسم بجزء آخر، مثل مَعَ وكَوْن وبِحَيْثُ وجَوَازًا، لأن ترتيب الأجزاء يدل على معناها:
الوَقْف الجَائِز مَعَ كَوْنِ الوَصْل أَوْلَى → waqf_jaiz_wasl_awla
وحروف الربط مسجلة في standards/terminology/data/connectives.tsv. ويحتفظ الاسم العربي بحروف ربطه، ويسقطها الاسم البرمجي وحده (§14).
9. الاسم البرمجي واسم العرض
لا يلزم أن يطابق الاسم البرمجي صورة النقل الدقيق.
يمكن أن يكون:
code: qiraah
display: Qiraah
transliteration: qirāʾah
arabic: قراءة
تبقى Canonical Code Spelling ثابتة، بينما تختلف طريقة العرض بحسب اللغة والجمهور والسياق.
حقول التسمية
نستخدم عدة حقول لتخزين الأسماء المختلفة للمفهوم:
names:
code: hamzah
display: Hamzah
arabic:
vocalized: الهَمْزَة
dabt: الهَمْزَة — رَأْس العَيْن
by_shape: رَأْس عَيْن
mushaf_introduction: null
unicode: ARABIC LETTER HAMZA
alternative_spellings:
- hamza
الحقول
code هو المعرف الثابت المستخدم في الكود والـAPI وقواعد البيانات. نولده حسب قواعد الأقسام 4 إلى 8، ولا نغيره لاحقًا لمجرد وجود اسم أكثر شيوعًا.
display هو الاسم الذي يظهر للمستخدم في التوثيق والواجهات. نأخذ التهجئة الإنجليزية الأكثر شيوعًا، ونسجل مصدر هذا الاختيار في display_evidence. والدليل لازم قبل أن يوسم المدخل بـadopted. أما مدخل draft فيجوز أن يحمل display دون دليل.
transliteration هو النقل الدقيق للاسم بحروف لاتينية، على نظام ALA-LC أو DIN 31635. نكتبه عند الحاجة فقط، وهو حقل اختياري.
arabic.vocalized هو الاسم العربي مكتوبًا بالحركات. نشتق منه code، ولا نستطيع اشتقاق code دونه. وهو كذلك الاسم الذي يراه القارئ العربي، فالقاموس العربي يعرضه في الموضع الذي يعرض فيه القاموس الإنجليزي display. أما arabic.singular و**arabic.plural** فيحملان الصورتين المجردتين من الحركات، ونحتفظ بهما معلومةً لغوية.
وarabic.vocalized هو اسم المفهوم في هذا المعيار، وقد يختلف عن الاسم الذي يستعمله المصدر. ونحفظ اسم المصدر في dabt أو في mushaf_introduction حتى لا يضيع.
ولا نعدل arabic.vocalized إلا لسبب لغوي، وهو أن الاسم الجديد يدل على حدود المفهوم دلالة أوضح. ولا نعدله أبدًا للوصول إلى اسم برمجي مرغوب. ومثال ذلك division_mark، وسببه في سجل القرارات.
ويحمل الاسم المفرد أداة التعريف (السُّورَة والتَّجْوِيد). أما القيمة التي هي صفة فتبقى دون أداة تعريف (مَكِّيّ ومُرَتَّل). ويحتفظ الاسم المركب بأدوات التعريف التي يقتضيها نحوه.
dabt هو اسم العلامة في علم الضبط. ننقله كما ورد في مصدره.
by_shape هو وصف صورة العلامة كما ترسم في المصحف. ننقله كما ورد في مصدره.
mushaf_introduction هو اسم العلامة كما ورد في مقدمة المصحف. نكتب null إذا لم تذكر المقدمة اسمًا لها، وهذه معلومة عن المصدر نفسه.
unicode هو اسم المحرف في يونيكود. نقرؤه من قاعدة يونيكود، ولا نستخدمه معرفًا في الكود.
alternative_spellings يحتوي على التهجئات البديلة المعروفة. نستخدمها في البحث وربط المدخلات المختلفة بالمفهوم نفسه.
قواعد ثابتة
codeوdisplayقد يختلفان، وهذا مقصود.- لا نستخدم اسم يونيكود معرفًا في الكود، لأنه يصف صورة المحرف ولا يصف وظيفته، وقد يقع المحرف الواحد لعلامتين مختلفتين.
- إذا كان
mushaf_introductionفارغًا فهذه معلومة عن المصدر، وليست نقصًا في المدخل.
10. شكل الأسماء في الكود
نستخدم أسماء واضحة وكاملة:
surah
ayah
word
translation
ونتجنب الاختصارات غير المعروفة:
srh
ay
wrd
trans
كما نتجنب الكلمات المبهمة عندما يوجد اسم أدق:
data
info
item
object
value
ونسمي التصنيف باسم ما يصنفه، ولا نستخدم اللاحقة _type إلا في تصنيف نوع العلامة، لأن العلامة نفسها هي المصنَّفة هناك:
waqf_mark_type ما تدل عليه علامة الوقف المرسومة
waqf_ruling لا waqf_type: حكم الموضع نفسه
recitation_style لا recitation_type
ويبلغ audit_terminology.py --strict عن الاختصارات والأسماء المبهمة في كود
المشروع، أما اختيار اسم التصنيف نفسه فقاعدة للكاتب.
11. المفرد والجمع
نستخدم:
- المفرد للكيان الواحد.
- الجمع للمجموعات.
مثلًا:
ayah → ayahs
surah → surahs
mushaf → mushafs
riwayah → riwayahs
ويتبع الجمع البرمجي قاعدة إنجليزية بسيطة، وهي الاسم البرمجي كاملًا وs بعده، سواء كان كلمة واحدة أو اسمًا مركبًا:
ayahs
juzs
hizbs
sajdahs
ولا نستخدم الجمع العربي اسمًا للمجموعة:
ayat
suwar
ajza
ahzab
ونسجل الجمع العربي في names.arabic.plural معلومةً لغوية.
ونكتب plural في المدخل الذي يخزن أو يعرض مجموعةً، مثل الكيان والوحدة والمحتوى، ونتركه في المدخل الذي لا تكون منه قائمة أبدًا. ويفحص tools/check_conformance.py أن الجمع المسجل هو الاسم البرمجي وs.
12. لكل مدخل نوع (kind)
نحدد في kind أيَّ شيء هو المدخل: أكيان هو أم مفهوم أم تصنيف، ونختاره من قائمة مغلقة لا يزاد عليها، لأن المصطلحات ليست كلها من نوع واحد.
والقائمة مسجلة في standards/terminology/schema.json، ويفحصها tools/validate.py:
entity كيان له هوية مستقلة
concept مفهوم يمثل ولا يخزن ككيان
classification تصنيف له قيم
classification_value قيمة من قيم تصنيف
property خاصية لكيان
role دور يقوم به شخص
process عملية تجرى على النص
content محتوى مرتبط بالنص
analysis تحليل مشتق من النص
mark علامة مرسومة في المصحف
unit وحدة نصية أو كتابية أو طباعية
وprocess محجوز ولا يحمله أي مدخل اليوم، لأن عمليات §23 اصطلاحات وليست مداخل في القاموس.
ويصف kind شكل المدخل، أما مجاله فيحمله category وحده. ولذلك لا ننشئ أنواعًا مثل textual_concept أو recitation_concept أو typographic_unit، فهذه كلها concept أو unit يختلف بينها category ويتفق kind.
ولكل مدخل kind واحد فقط.
مثلًا:
ayah → entity
tajwid → concept
translation → content
reciter → role
revelation_order → property
revelation_classification → classification
makki → classification_value
waqf_mark → mark
glyph → unit
irab → analysis
ولا نعامل هذه الأشياء كلها قائمة واحدة لا مراتب فيها اسمها «المصطلحات».
عائلة العلامة في parent
لكل علامة من علامات الضبط عائلة تنتمي إليها، ونسجل هذه العائلة في حقل parent، فلا تكون العلامات قائمة واحدة لا مراتب فيها. والشجرة كما في المداخل:
mushaf_mark
├── harakah fathah, dammah, kasrah, sukun, shaddah
├── tanwin tanwin_al_fath, tanwin_al_kasr, tanwin_al_damm
├── ijam dot, two_dots, three_dots
├── orthographic_mark hamzah, hamzat_al_wasl, maddah, omitted_alif,
│ small_noon, small_waw, small_yaa
├── qiraah_mark saktah_mark, seen_al_qiraah, ishmam, tashil, imalah
└── (بلا عائلة) waqf_mark, ayah_mark, sajdah_mark, sajdah_line,
division_mark, small_meem, rounded_zero,
rectangular_zero
ولا نجعل mushaf_mark أبًا لكل علامة، لأن أبًا واحدًا فوق كل العلامات لا يضيف معلومة. ويبقى أبًا للعلامات التي لا عائلة لها.
أما علامات الوقف فليست في هذه الشجرة. waqf_mark هي العلامة نفسها، وما تدل عليه كل علامة معينة هو قيمة من قيم التصنيف waqf_mark_type:
waqf_mark_type
├── waqf_lazim
├── waqf_mamnu
├── waqf_jaiz_mustawi_al_tarafayn
├── waqf_jaiz_wasl_awla
├── waqf_jaiz_waqf_awla
└── waqf_al_muanaqah
وهذه القيم الـ6 من نوع classification_value، لكنها مرسومة في المصحف، لذلك تحمل symbol وunicode وmark_family كما تحملها العلامة. ولا تحمل هذه الحقول قيمة أخرى، ويرفضها tools/check_conformance.py في أي مدخل آخر ليس علامة.
و**mark_family** هو التجميع الذي يستعمله سجل المصدر dabt_marks.tsv، وقيمه: harakah وtanwin وijam وimlaiyyah وdabt وwaqf وalamat_qiraah وmustaqill. نحتفظ به لأنه ما يقوله المصدر. ويختلف عن parent في موضعين، وهذا مقصود: imlaiyyah هي كلمة السجل لما نسميه orthographic_mark، وalamat_qiraah كلمته لما نسميه qiraah_mark. والفرق أن parent تصنيف المعيار، بينما mark_family تصنيف المصدر.
13. للأنواع والقيم مداخل مستقلة
إذا كان للمفهوم أنواع أو قيم مهمة، فلكل نوع وقيمة مدخل مستقل في القاموس باسمه البرمجي الحقيقي، ولا نكتفي بتعريف الأب:
revelation_classification
├── makki
├── madani
└── disputed
و:
recitation_style
├── murattal
├── mujawwad
└── muallim
و:
recitation_pace
├── tahqiq
├── tadwir
└── hadr
و:
ayah_numbering_system
├── madani_first
├── madani_last
├── makki
├── basri
├── dimashqi
└── kufi
وهذه الـ6 مداخل لأن لكل واحد منها تعريفًا، ومعرّفاتها ayah_numbering_kufi وayah_numbering_makki وهكذا، لأن makki وحدها معرّف قيمة النزول أصلًا؛ ويبين §14 لماذا يختلف الاسم البرمجي عن المعرّف. وما يخزنه البرنامج هو الاسم البرمجي.
وتصنيفات التجويد، وهي الأحكام وأنواع المد وعلاقة الحرفين، ولكل منها قيمه:
tajwid_ruling madd
├── izhar ├── madd_tabii
├── idgham ├── madd_muttasil
├── iqlab ├── madd_munfasil
├── ikhfa ├── madd_lazim
└── qalqalah ├── madd_arid_li_al_sukun
├── madd_al_lin
letter_relation ├── madd_al_badal
├── mutamathilan ├── madd_al_silah
└── mutajanisan └── madd_al_iwad
وتصنيفان للوقف، أحدهما للعلامة والآخر للموضع:
waqf_mark_type waqf_ruling
├── waqf_lazim ├── waqf_tamm
├── waqf_mamnu ├── waqf_kafi
├── waqf_jaiz_mustawi_al_tarafayn ├── waqf_hasan
├── waqf_jaiz_wasl_awla └── waqf_qabih
├── waqf_jaiz_waqf_awla
└── waqf_al_muanaqah
ولكل قيمة من هذه القيم مدخل مستقل، ولو كان تمثيلها البرمجي قيمة enum. ويرفض tools/check_conformance.py تصنيفًا بلا قيم.
متى نسجل الأفراد في سجل بدل المداخل
ليس لأفراد المجموعة المغلقة مداخل، بل لكل مجموعة سجل: ملف مفصول بالجدولة في standards/terminology/registries/، فيه سطر لكل فرد.
والفرق بين القيمة والفرد أن القيمة مفهوم. فلـrevelation_classification 3 قيم، وإذا سأل القارئ ما معنى makki وجد جوابًا يشرح المعنى. أما qiraah فليست لها قيم بهذا المعنى، بل لها 10 أفراد، وعاصم شخص وليس مفهومًا، ولا جواب للسؤال عن معناه غير الإشارة إليه.
والسجلات الحالية:
qiraah, rawi, riwayah → registries/qiraat.tsv القراءات الـ10 و19 راويًا و20 رواية
tariq → registries/tariq.tsv الطرق الـ4 التي تخزنها التطبيقات
surah → registries/surahs.tsv السور الـ114
sajdah → registries/sajdah.tsv السجدات الـ15
ayah_numbering_system → registries/ayah_numbering.tsv, ayah_counts.tsv
tajwid_ruling → registries/tajwid_rules.tsv أحكام التجويد
ويبقى للمفهوم مدخل يسمي سجله:
concept: qiraah
kind: concept
registry: qiraat
ونفرق بين المدخل والسطر بسؤال واحد: هل يحتاج الشيء إلى definition وpurpose وboundaries؟ إذا احتاج إليها فهو مفهوم له مدخل. وإذا كان كل ما نقوله فيه هو اسمه وموقعه من المجموعة وموضع وروده، فهو فرد يأخذ سطرًا في السجل.
والسجل ليس أقل شأنًا من المدخل. فكل سطر فيه يفحصه tools/check_registries.py، وله مصدر كما للمدخل، ويُفهرس حتى تُردّ كل تهجئة لفرد إلى موضعه. ويذكر عمود verified في السطر ما الذي تحققنا منه في مصدر، وno قيمة مقبولة فيه.
وتعرض السجلات في صفحة خاصة بها: السجلات.
أحكام التجويد كما يطبقها المحرك في سجل
حالات أحكام التجويد كما يطبقها المحرك، أي كل حالة من الإظهار والإدغام والإقلاب والإخفاء والمد مع موضع انطباقها ومصدرها، سطور في registries/tajwid_rules.tsv. ويولَّد هذا السجل من data/tajweed_engine_rules.json، ويسميه المدخل tajwid_ruling. أما الأحكام بوصفها مفاهيم، مثل izhar وidgham وأنواع madd، فهي قيم لتصنيفاتها وتبقى مداخل، وكذلك المفاهيم التي يقوم عليها الحكم مثل noon_sakinah وtanwin وmaddah. ونفرق بين الحكم وموضع وقوعه في النص: فالحكم سطر في السجل، والموضع مدى من النص (§21) موسوم بالاسم البرمجي للحكم.
أسماء الحروف في جدول بيانات التهجئة
الحروف الـ28 أفراد كذلك، لكننا لا نفهرسها كالسجل. فدالة الاشتقاق نفسها تقرأ أسماءها، لذلك نضعها في standards/terminology/data/letter_names.tsv بجوار جداول التهجئة الأخرى. ونشير إلى الحرف في الكود باسمه من ذلك الجدول: noon وmeem وsaad.
اسم الشخص يكتب كما جرت كتابته
لا نشتق اسم الشخص بقواعد الأقسام 4 إلى 8، بل نكتبه كما جرت كتابته، مع أن كل مصطلح في القاموس يمر بتلك القواعد:
hafs warsh qalun ibn_dhakwan
والسبب أن الاشتقاق وُضع للمصطلح، والمصطلح كلمة لها معنى، والاشتقاق يبقي المعرف موصولًا بهذا المعنى. أما اسم الشخص فلا معنى فيه، واشتقاقه يعطي تهجئة لا يكتبها أحد.
ويشمل هذا الاستثناء أسماء الأشخاص وحدها. أما اسم السورة فكلمة لها معنى وتشتق، مثل fatihah وbaqarah وnisa، ويعيد tools/check_registries.py اشتقاق أسماء السور الـ114 في كل تشغيل.
وعبارة «كما جرت كتابته» تحتاج إلى شاهد. فيسجل السجل الصورة العلمية الإنجليزية للاسم بعلامات النقل، ويكون الاسم المستعمل هو تلك الصورة بلا علامات. وإذا خالفت هذه الصورة قاعدة نص عليها المعيار قدمنا القاعدة: فنكتب shubah وليس shuba، لأن §5 يحكم التاء المربوطة.
قد يشترك الفرد والمفهوم في الاسم
يجوز أن يحمل الفرد اسم مفهوم، ولا نغير أحد الاسمين. فحمزة اسم مقرئ، وhamzah اسم العلامة كذلك. والطارق اسم سورة، وtariq اسم درجة في سلسلة النقل.
ولا يضر هذا الاشتراك لأن الاسمين في مجالين مختلفين بالمعنى المذكور في §25، فإحدى الحمزتين في dabt والأخرى في qiraat، ولا يطلبهما طلب واحد. ولا يلزم تفرد الاسم إلا حيث يمكن أن يقع اللبس.
ونفهرس أسماء الأفراد بحسب kind، لأن من يقرأ البيانات يعرف نوع ما في العمود: فهو يعرف أن العمود يحمل رواية مثلًا، ولا يعده شيئًا من مجال القراءات.
hamzah → العلامة
qiraah:hamzah → المقرئ
tariq → درجة النقل
surah:tariq → السورة
ويُردّ الاسم المجرد إلى المفهوم دائمًا. ومن يملأ عمودًا معلوم النوع يبحث داخل namespace ذلك النوع. ويبقى aliases.json للمفاهيم، وregistry_aliases.json للأفراد.
14. الأب والابن (parent)
عندما يكون المفهوم جزءًا من تصنيف هرمي، يجب تحديد علاقته بالمفهوم الأب.
مثلًا:
concept: makki
kind: classification_value
parent: revelation_classification
أو:
concept: murattal
kind: classification_value
parent: recitation_style
الهدف أن يعرف المطور معنى makki، وأن يعرف كذلك:
makkiنوع من ماذا؟
الفرق بين parent وpart_of
يذكر parent ما يكون الشيء نوعًا منه، ولا يذكر ما يكون الشيء جزءًا منه. فربع الحزب ليس نوعًا من الحزب، بل جزء منه، ونسجل الاحتواء في حقل مستقل:
concept: rubu_al_hizb
kind: entity
part_of: hizb
وpart_of اختياري، ويشير إلى كيان. أما parent فلازم في كل classification_value وفي كل علامة لها عائلة.
اسم القيمة يشتق من اسم الأب
اسم القيمة هو اسم الأب ومعه الكلمات التي تميزها. ويبقى الاسم العربي كاملًا بحروف ربطه، ويسقط الاشتقاق حروف الربط (§8):
الوَقْف الجَائِز مَعَ كَوْنِ الوَصْل أَوْلَى → waqf_jaiz_wasl_awla
الوَقْف الجَائِز مَعَ كَوْنِ الوَقْف أَوْلَى → waqf_jaiz_waqf_awla
الوَقْف اللَّازِم → waqf_lazim
ولا نكرر اسم الأب إذا لم يضف تمييزًا، فقيم revelation_classification تبقى makki وmadani وليست revelation_classification_makki. واسم القيمة فريد داخل تصنيفه لا في القاموس كله. فقيم ayah_numbering_system هي kufi وbasri وdimashqi وmakki وmadani_first وmadani_last، وmakki قيمة كذلك من قيم revelation_classification. ولا يجمع عمود واحد قيم تصنيفين، فلا يقع اللبس بينهما.
وإذا اشتركت قيمتان في اسم، صار معرّف المدخل اسم الأب مع الاسم البرمجي: ayah_numbering_makki. والمعرّف هو ملف المدخل ومرساه وما يشير إليه related وparent، وتحمله مداخل العد الـ6 كلها اطرادًا. أما الاسم البرمجي فهو ما يخزنه البرنامج.
وهذه الـ6 هي العائلة الوحيدة التي لا يشتق اسمها البرمجي من العربية: فاشتقاق «العَدّ» يعطي add وهو فعل إنجليزي، فالاسم البرمجي اسم المدرسة. والسبب في سجل القرارات.
ويفحص tools/check_conformance.py أن لكل تصنيف قيمًا، وأن كل parent وpart_of يسمي مدخلًا.
15. التعريف (definition)
يحمل كل مدخل حقل definition.
ويجيب definition عن:
ما هذا المفهوم؟
ويجب أن:
- يعرّف المفهوم نفسه.
- يكون دقيقًا ومختصرًا.
- يحدد حدوده عند الحاجة.
- لا يعتمد على الاسم نفسه في تعريف دائري.
- لا يحتوي على تفاصيل التنفيذ.
- يستند إلى مصدر مناسب عندما يكون المفهوم علميًا أو اصطلاحيًا.
مثلًا:
concept: ayah
definition: >
الآية وحدة من النص القرآني تقع داخل سورة ولها حدود محددة. وقد يختلف رقمها أو بعض حدودها
باختلاف نظام عد الآي.
وليس:
ayah: A Quranic verse.
وهذه قواعد للكاتب، ولا تفحصها أداة.
16. الغرض (purpose)
ويحمل كل مدخل كذلك حقل purpose.
ويجيب purpose عن:
لماذا نحتاج هذا المفهوم في البرمجيات القرآنية؟
ويشرح:
- دوره في نموذج البرمجيات.
- ما الذي نستخدمه لتمثيله أو ربطه.
- لماذا يحتاج المطور إلى التمييز بينه وبين غيره.
مثلًا:
concept: ayah
purpose: >
نستخدمها وحدة أساسية للإشارة إلى النص القرآني، ولربط الترجمات والتفاسير والتلاوات والتحليلات
والبيانات الأخرى بموضع محدد من القرآن.
الفرق
definition → ما هذا المفهوم؟
purpose → لماذا نمثله في البرمجيات؟
لا يعيد purpose صياغة definition، ولا نضع تفاصيل الاستخدام البرمجي داخل definition. وهذه قواعد للكاتب ولا تفحصها أداة، والمثال المخالف أن يكتب في purpose: «الآية وحدة من النص القرآني»، فهذا تعريف أعيدت صياغته.
إذا لم يكن للمفهوم غرض برمجي واضح، فلنسأل قبل إدخاله: هل يحتاج القاموس الأساسي إليه أصلًا؟
17. حدود المفهوم
عند وجود احتمال حقيقي للالتباس، يذكر المدخل ما لا يشمله المفهوم في حقل boundaries، ويسمي المفهوم المجاور في related.
مثلًا:
mushaf ≠ quran
word ≠ token
letter ≠ character
glyph ≠ character
rawi ≠ reciter
tajwid ≠ mujawwad
tartil ≠ murattal
sajdah ≠ sajdah_mark
waqf_mark_type ≠ waqf_ruling
والهدف منع استخدام اسم واحد لمفهومين مختلفين في البيانات والكود، وليس توثيق الفروق اللغوية فقط. وهذه قاعدة للكاتب ولا تفحصها أداة، والمثال المخالف أن يكتب في boundaries: «يختلف عن word في المعنى»، دون أن يذكر أي المفهومين يخزنه البرنامج في العمود.
18. الفصل بين المفاهيم المتشابهة
لا ندمج مفهومين لمجرد أن ترجمتيهما متشابهتان. وهذه قاعدة للكاتب ولا تفحصها أداة،
والمثال المخالف مخطط فيه جدول word واحد يحمل الكلمات والـtokens معًا، وهو ما
وُضعت boundaries المدخلين لمنعه.
العلامة وما تدل عليه
العلامة المرسومة في المصحف مفهوم مستقل عما تدل عليه:
saktah_mark العلامة المرسومة mark
saktah السكتة نفسها concept
sajdah_mark علامة السجدة mark
sajdah الموضع والسجود عنده concept
ayah_mark العلامة المرسومة mark
ayah_ending خاتمة الآية concept
فالسجدة مفهومان اثنان: العلامة المرسومة في المصحف، والموضع الذي يسجد عنده. والموضع والسجود عنده مفهوم واحد، لأن البرامج لا تخزن الفعل بمعزل عن موضعه، و«السجدات الخمس عشرة» تسمي الاثنين معًا؛ ويبين سجل القرارات لماذا فرقت مسودة سابقة بينهما.
هوية العلامة والمحرف
لا يصلح codepoint معرفًا للعلامة، لسببين ثابتين في يونيكود:
المحرف الواحد قد يقع لعلامتين، فلا تتحدد العلامة إلا بالمحرف وموضعه معًا:
ۜ U+06DC ARABIC SMALL HIGH SEEN → saktah_mark أو seen_al_qiraah
۬ U+06EC ROUNDED HIGH STOP → ishmam أو tashil
وعلامة واحدة لها أكثر من محرف:
sukun ْ U+0652 و ۡ U+06E1
tanwin_al_fath ً U+064B و ࣰ U+08F0
maddah ٓ U+0653 و ۤ U+06E4
لذلك codepoint خاصية من خصائص العلامة وليس مفتاحًا لها.
النص
نفرق بين الكلمة وما ينتجه التقسيم وما ينتجه التحليل الصرفي، فلكل واحد منها مدخله:
word
token
morpheme
lemma
root
التمثيل الرقمي
نفرق بين الحرف في اللغة والمحرف في يونيكود وما يرسمه الخط، فهذه 5 مفاهيم لا مفهوم واحد:
letter
character
codepoint
grapheme
glyph
القرآن والمصحف
القرآن هو الكلام المنزل، والمصحف هو الكتاب الذي كتب فيه، ولا يقوم أحدهما مقام الآخر:
quran
mushaf
المحتوى والعرض
ما يحمله النص غير ما يظهر به على الصفحة، فلا نخلط مفاهيم المحتوى بمفاهيم العرض:
المحتوى:
surah
ayah
word
العرض:
page
line
layout
font
glyph
النص والتحليل
الكلمة في النص غير ما يستخرج منها بالتحليل، فالتحليل طبقة مشتقة لها مفاهيمها:
النص:
word
التحليل:
root
lemma
morphology
irab
19. الاسم والتهجئة البديلة والمقابل الإنجليزي حقول منفصلة
يجب التفريق بين:
names.code
alternative_spellings
english_glosses
deprecated
مثلًا:
concept: ayah
names:
code: ayah
alternative_spellings:
- aya
- ayat
- ayaat
english_glosses:
- Verse
aya تهجئة بديلة لـayah، أما Verse فمقابل إنجليزي وليس تهجئة بديلة.
وكذلك:
concept: tajwid
names:
code: tajwid
alternative_spellings:
- tajweed
- tajwīd
ولا يوجد حقل واحد يجمع هذه العلاقات، ولا نضيف حقلًا كهذا.
ويفحص tools/check_conformance.py أن المقابل الإنجليزي غير مسجل تهجئةً بديلة.
20. الأسماء البديلة والمهجورة والخاطئة
نفرق بين:
Alternative
صيغة أخرى صحيحة أو شائعة:
tajweed → alternative spelling of tajwid
Deprecated
اسم صحيح للمفهوم، لكننا لا نوصي به في المشاريع الجديدة. نسجله في deprecated، ويبقى مردودًا إلى مفهومه عبر هذا الحقل، لأن aliases.json يفهرس التهجئات وحدها.
Incorrect
اسم يشير إلى مفهوم مختلف أو يؤدي إلى معنى غير صحيح. لا نسجله في المدخل الذي لا ينتمي إليه، بل نذكر موضع اللبس في boundaries المدخل الصحيح.
فقد تكون verse ترجمة إنجليزية صحيحة لـayah، لكنها ليست الاسم المعتمد في المعيار.
كيف نسجل تغيير الاسم
إذا تغير الاسم البرمجي لمفهوم أو دُمج مدخلان، نضع الاسم القديم في deprecated في المدخل الباقي، ونذكر في note متى تغير ولماذا مع إحالة إلى سجل القرارات. ويبقى الاسم القديم مردودًا إلى مفهومه، حتى لا ينقطع مشروع اعتمده، ويرى القارئ أنه كان اسمًا للمفهوم يومًا:
# في sajdah_mark.yml
deprecated:
- alamat_mawdi_al_sajdah
note: >
دُمج من alamat_mawdi_al_sajdah الذي كان يعرّف العلامة نفسها.
سجل القرارات: «المفهومان المكرران يدمجان».
والمدخل الذي نسحبه كله نسمه بـstatus: deprecated ونبقيه، حتى لا يعود اسمه البرمجي يومًا بمعنى آخر.
21. المعرفات والأرقام والترتيب
لكل لاحقة معنى ثابت.
id
id هو المعرف الداخلي لصف قاعدة البيانات. نستخدمه للربط بين الجداول، ولا نعرضه للقارئ ولا نبني عليه إحالة خارجية:
surah_id
ayah_id
word_id
mushaf_id
number
number هو الرقم المعتمد للشيء داخل مجاله. نعرضه للقارئ ونبني عليه الإحالة الخارجية، فهو الرقم الذي يعرفه ويستشهد به:
surah_number
ayah_number
page_number
position
position هو موضع العنصر داخل أبيه أو داخل تسلسل. نستخدمه للترتيب داخل التسلسل، ولا نتخذه إحالة ثابتة، لأنه يتغير كلما تغير التسلسل:
word_position
token_position
line_position
order
order هو الترتيب الذي يقرره المعنى. نستخدمه حين يختلف الترتيب المقصود عن موضع العنصر في التسلسل:
revelation_order
display_order
ولا نستخدم هذه اللواحق مترادفات:
id
number
position
order
key: المفتاح المركب المقروء
key هو الإحالة المركبة المتعارف عليها. نكتبها ليقرأها الناس، وتبقى ثابتة عبر الأنظمة:
ayah_key 2:255 surah_number:ayah_number
word_key 2:255:3 ayah_key:word_position
ولا معنى للمفتاح ما لم يُذكر معه نظام عد الآي. فيذكر dataset الذي يستخدم المفاتيح أي نظام عد يتبع، ويكون النظام kufi إذا لم يذكر. أما الفهرس العام للآيات (من 1 إلى 6,236) فهو position وليس مفتاحًا، وهو كذلك يتبع نظام عد.
مفتاح المدى الصوتي
نسمي المدى من الصوت باسم وحدة النص التي يقابلها، وننسبه إلى تلاوة:
ayah_timing مدى آية في تسجيل واحد recitation_id, ayah_key, start_ms, end_ms
word_timing مدى كلمة في تسجيل واحد recitation_id, word_key, start_ms, end_ms
ويعرِّف recitation_id التسجيل. والتلاوة هي قارئ واحد يقرأ برواية واحدة بنمط واحد، ونسجل هذه الـ3 حقولًا في التلاوة، ولا ندخلها في اسم المدى الصوتي.
22. العلاقات
العلاقة تسمى باسم المفهوم المرتبط مباشرة.
نفضل:
surah.ayahs
ayah.surah
ayah.words
mushaf.pages
page.lines
ونستخدم المفرد لعلاقة الواحد والجمع لعلاقة المتعدد.
ولا نستخدم أسماء إجرائية عندما تكون العلاقة مجرد علاقة بيانات:
getAyahList()
fetchRelatedSurah()
retrieveWords()
ما دامت الأسماء المباشرة تكفي:
ayahs
surah
words
23. العمليات والأفعال
كما نوحد أسماء الكيانات، نوحد أسماء العمليات المتكررة.
مثل:
normalize
parse
tokenize
segment
transliterate
annotate
render
validate
compare
convert
نستخدم الفعل نفسه للعملية نفسها.
ونتجنب:
process
handle
do
عندما يوجد فعل أدق.
مثلًا:
tokenizeText()
normalizeText()
renderAyah()
validateMushaf()
أفضل من:
processText()
handleAyah()
وهذه الأفعال اصطلاح من اصطلاحات المعيار وليست مداخل في القاموس، لذلك لا تفحصها أداة. وتحتفظ أسماء العمليات بتهجئتها الإنجليزية في الكود (normalize)، أما في شرح الصفحة فنكتب الكلمة العربية (التطبيع).
24. التصنيفات وboolean
التصنيفات تحمل أسماء خاصة بمجالها، ولكل تصنيف مدخل:
waqf_mark_type
waqf_ruling
tajwid_ruling
madd
letter_relation
recitation_style
recitation_pace
revelation_classification
بدل:
quran_type
item_type
data_type
أما boolean فيجب أن يظهر من اسمه أنه سؤال جوابه نعم أو لا:
has_sajdah
is_active
is_included
ولا نمثل تصنيفًا متعدد القيم بمجموعة من boolean عندما يكون تصنيف واحد أكثر دقة.
وهذا القسم، مثل الأقسام 21 إلى 23، اصطلاح خارج المصدر المقروء آليًا.
25. تنظيم المجالات
ينظم القاموس حسب مجالات واضحة، وليس في قائمة واحدة لا مراتب فيها.
المجالات المعتمدة هي نفسها أقسام القاموس، حتى لا توجد قائمتان مختلفتان. وهي مسجلة في standards/terminology/schema.json، ويفحصها tools/validate.py:
core القرآن والمصحف
structure السورة والآية والكلمة
text وحدات النص وتمثيله الرقمي
divisions الجزء والحزب والربع
surah_classification الطوال والمئون والمثاني والمفصل
mushaf الطبعة والتخطيط والصفحة والرسم
dabt الضبط: الحركات والتنوين وكل علامة في المصحف
ayah_numbering أنظمة عد الآي
revelation النزول وترتيبه وتصنيفه
qiraat القراءات والروايات والطرق
recitation التلاوة والقراء
recitation_pace التحقيق والتدوير والحدر
recitation_style المرتل والمجود والمعلم
tajwid التجويد وأحكامه والمد وسجل الأحكام
waqf الوقف وأحكامه
linguistics الجذر و`lemma` والصرف والإعراب
translation الترجمة
tafsir التفسير
quranic_sciences النسخ وغريب القرآن والمتشابهات
ولا يضاف مجال قبل أن توجد مفاهيم تنتمي إليه، لأن المجال الفارغ يوهم القارئ أن المعيار يسمي ما لا يسميه.
26. الاتساق بين طبقات النظام
نستخدم المفردات المعتمدة نفسها في كل طبقات النظام قدر الإمكان.
إذا اعتمدنا:
surah
ayah
word
فيكون المتوقع:
النماذج:
Surah
Ayah
Word
قاعدة البيانات:
surahs
ayahs
words
المفاتيح الأجنبية:
surah_id
ayah_id
API:
/surahs
/surahs/{surah_number}/ayahs
/ayahs/{ayah_key}/words
ونتجنب أن يختلف اسم المفهوم الواحد من طبقة إلى طبقة:
قاعدة البيانات: surah
API: chapter
الحزمة: quran_section
ويمكن لواجهة المستخدم أن تترجم الاسم أو تعرضه بصورة مختلفة، بينما تبقى المفردات الداخلية المعتمدة ثابتة.
انقل الاسم الذي لا يملكه المشروع كما هو
يشير المشروع إلى أسماء لا يملكها: أسماء حزم المورد وملفاته، وعناوين أعمدة ملف يقرؤه، والاسم الرسمي لمحرف في يونيكود، وعنوان مستودع آخر. هذه معرِّفات موضع، تدل على شيء خارج المشروع، وتغيير حرف منها يقطع الإحالة، فتكتب كما يكتبها صاحبها مهما بعدت عن هذا المعيار.
UthmanicHafs-v-3.0.zip حزمة الناشر: تنقل كما هي
row["aya_text_emlaey"] عمود الناشر: ينقل كما هو
"ARABIC START OF RUB EL HIZB" اسم ۞ في يونيكود: ينقل كما هو
quranpedia/qiraat-ayah-map مستودع آخر: ينقل كما هو
والذي يقرره المشروع لنفسه هو ما يسمي به الشيء بعد قراءته: الحقل والمتغير والمفتاح المنشور. فالاسم المنقول لا يصير اسمًا لمفهوم، والاسم الذي نختاره نحن لا يبقى على تهجئة المورد لمجرد أنه جاء مع بياناته.
ويعرَّف المدقق بالأسماء المنقولة ليقرأ ما بعدها بدل أن يطلب تغييرًا يقطع الإحالة:
external_names في .terminology.json.
حالة الأحرف في كل طبقة
يكتب الاسم البرمجي بصيغة snake_case، وتكتب كل طبقة هذا الاسم الواحد بحالة أحرفها:
snake_case جداول قاعدة البيانات وأعمدتها، ومفاتيح JSON، وقيم enum، وأسماء الملفات
ayah_numbering_system, waqf_lazim
PascalCase الأصناف والأنواع AyahNumberingSystem, WaqfMarkType
camelCase حيث تفرضه اللغة على أسماء الحقول والدوال ayahNumber
kebab-case مسارات `URL` وحدها /waqf-marks/waqf-lazim
وصورة kebab طريقة لعرض الاسم البرمجي في الـURL وليست تهجئة، لذلك لا نسجلها في alternative_spellings.
27. بنية المدخل في القاموس
يستخدم القاموس الناتج عن هذا المعيار بنية موحدة، وفيه ملف لكل مفهوم. ونسمي الملف باسم المفهوم، فيحمل ayah.yml السطر concept: ayah، ويرفض tools/validate.py ملفًا يختلف اسمه عن مفهومه.
الحد الأدنى:
concept:
kind:
category:
origin:
tier:
status:
names:
code:
display:
definition:
purpose:
definition_en:
purpose_en:
وتضاف عند الحاجة:
parent: # لازم إذا كان kind قيمة تصنيف، أو علامة لها عائلة
part_of: # الاحتواء؛ يشير إلى كيان
registry: # السجل الذي يعدد أفراد هذا المفهوم
plural: # الاسم البرمجي مع s
symbol: # المحرف الذي ترسم به العلامة
mark_family: # تجميع سجل المصدر؛ للعلامات والقيم المرسومة فقط
names:
display_evidence: # لازم قبل adopted
transliteration: # اختياري؛ ALA-LC أو DIN 31635
arabic:
vocalized: # لازم إذا كان origin هو quranic
singular:
plural:
dabt:
by_shape:
mushaf_introduction:
unicode:
unicode: # مولد من قاعدة يونيكود، لا يكتب باليد
alternative_spellings:
english_glosses:
deprecated:
boundaries:
boundaries_en: # ترجمة boundaries، سطرًا بسطر
related:
sources:
note:
note_en: # ترجمة note
origin يبين من أين جاء اسم المفهوم. نكتب quranic للمصطلح القرآني أو العلمي المتخصص، وborrowed للمصطلح العام الذي استقر تعريفه عند غيرنا، وstandard للمفهوم الذي حدده هذا المعيار للنمذجة ولا نظير له في التراث.
tier يبين أهمية المفهوم عمليًا. نكتب core لما تخزنه التطبيقات اليوم، وextended للمفهوم الثابت الذي يندر تمثيله أو تختلف حدوده.
status يبين حال المدخل. يبدأ draft، ثم proposed بعد النقاش، ثم adopted بعد الاعتماد. والمدخل الذي يسحب بعد اعتماده يصير deprecated ويبقى (§20). ولا نضع adopted لمدخل ليس له مصدر، ولا لمدخل ليس له display_evidence.
arabic لازم في كل مدخل origin: quranic. أما المصطلح المستعار فنكتب له الاسم العربي إذا كان له اسم مستقر، حتى لا نولّد مصطلحات عربية جديدة دون قصد.
related يحتوي على أسماء مداخل مرتبطة بالمفهوم. ويجعل البناء هذه الروابط متبادلة، فإذا ذكر waqf_lazim المدخل waqf_mark ظهر waqf_lazim في waqf_mark كذلك.
المدخل بلغتين
المدخل واحد ونصه بلغتين. فلكل حقل عربي حقل إنجليزي يقابله: definition_en وpurpose_en وboundaries_en وnote_en. ونولد صفحة القاموس الإنجليزية من هذه الحقول كما نولد الصفحة العربية من الحقول العربية، فلا يفترق النصان.
والحقل الإنجليزي ترجمة وليس تعريفًا ثانيًا. فما يقرره أحدهما يقرره الآخر، ولا يزيد الإنجليزي قيدًا ولا يسقط قيدًا. وتترجم حدود المفهوم سطرًا بسطر، فلكل سطر عربي سطر إنجليزي في موضعه، ويفحص tools/check_conformance.py أن القائمتين على طول واحد.
وفي الترجمة نلتزم 4 أمور:
- نذكر المصطلح باسمه المعتمد، أي بتهجئة
codeبحروف صغيرة كما تُكتب سائر الأسماء في جملة إنجليزية (ayahلاverse، وmushafلاcodex). والمقابل الإنجليزي فيenglish_glossesقيمة للبحث، ولا نستعمله اسمًا في النص. - نكتب الاسم البرمجي كما هو بين علامتي
`، ولا نترجمه ولا نعرّبه. - نترجم الصيغة المكررة بصيغة مكررة: فمداخل عد الآي الـ6 تشترك في جملة غرض واحدة بالعربية، لذلك تشترك في جملة واحدة بالإنجليزية بلفظها.
- لا نترك في الحقل الإنجليزي نصًا عربيًا إلا اسمًا عربيًا يتحدث عنه المدخل نفسه، ونضعه بين «…». ويتحقق
tools/check_conformance.pyمن ذلك.
ولا نقدم هذه الترجمة على أنها ترجمة معتمدة للنص الشرعي، وإنما هي بيان للمفهوم بلغة ثانية لمن يبني عليه.
مثال
هذا هو المدخل standards/terminology/concepts/waqf_lazim.yml كما هو في المستودع. ويفحص البناء أن هذا المقطع والملف متطابقان:
concept: waqf_lazim
names:
code: waqf_lazim
display: Waqf Lazim
arabic:
vocalized: الوَقْف اللَّازِم
singular: الوقف اللازم
dabt: المِيم — عَلَامَة الوَقْف اللَّازِم
by_shape: مِيم
mushaf_introduction: عَلَامَة الوَقْف اللَّازِم
unicode: ARABIC SMALL HIGH MEEM INITIAL FORM
kind: classification_value
category: dabt
parent: waqf_mark_type
origin: quranic
tier: core
status: draft
symbol: م
definition: الوقف اللازم علامة تدل على أن الوقف لازم، لأن وصل ما بعده بما قبله يوهم خلاف المعنى
المراد.
definition_en: 'A compulsory stop: continuing across it would suggest a meaning other than
the one intended.'
purpose: نستخدمها قيمة من قيم نوع علامة الوقف، فنبني عليها العرض والتلقين والتنبيه في التطبيقات
بدلًا من قراءة صورة الرمز.
purpose_en: Used as a value of the waqf mark type, so that rendering, teaching and warnings
in applications branch on it rather than on the shape of the sign.
alternative_spellings:
- waqf-lazim
related:
- waqf
- waqf_mark
unicode:
- cp: U+06D8
name: ARABIC SMALL HIGH MEEM INITIAL FORM
category: Mn
combining_class: 230
block: Arabic
unidata: 13.0.0
mark_family: waqf
sources:
- id: hafs_svg_registry
ref: standard!waqf-lazim
- id: quranpedia_tajweed
ref: '122'
url: https://tajweed.quranpedia.net/term/show/122
- id: qattan_mabahith
ref: 1/152
28. مصادر التعريفات
المصطلحات العلمية والاصطلاحية يجب أن تستند إلى مصادر مناسبة.
المصدر يوثق المفهوم وتعريفه، وليس بالضرورة اختيار الاسم البرمجي.
فمثلًا قد يثبت المصدر معنى ayah، أما اختيار الاسم:
ayah
بدل:
verse
فقرار يتخذه هذا المعيار.
يجب الفصل بين:
domain fact ما يثبته المصدر
standard convention ما يقرره هذا المعيار
المصادر المعتمدة
المصادر مسجلة في standards/terminology/sources.yml، ومع كل مصدر صيغة الإحالة الخاصة به، مثل رقم الصفحة في الكتاب ورقم المصطلح في المعجم. ولا نكتب قائمة المصادر في هذه الصفحة حتى لا يكون لها موضعان.
ويفحص البناء أن كل مصدر يحال إليه، من sources[].id في مدخل أو من ref في سطر سجل، يسمي مصدرًا موجودًا في ذلك الملف.
ولا نسم مدخلًا بـadopted وهو بلا مصدر يثبت تعريفه.
29. القاموس مقروء آليًا
المصدر الأساسي للقاموس مقروء آليًا: ملف YAML لكل مفهوم، ومخطط JSON، وسجلات مفصولة بالجدولة.
ومن المصدر نفسه نولد اليوم:
- صفحتي القاموس وصفحة السجلات
aliases.jsonوregistry_aliases.json، حتى تُردّ كل تهجئة إلى مفهومها- مهارة الوكلاء في
skills/quranic-terminology/
وننوي أن نولد:
- مخططات الـ
API - تلميحات المحرر
- أدوات التدقيق
- تنبيهات المصطلحات المهجورة
- جداول الترحيل
ونولد الصفحات التي يقرؤها الناس من المصدر نفسه حيثما أمكن، ولا نحفظها نسخةً منفصلة.
إصدارات القاموس
ليس للقاموس رقم إصدار خاص به، وإصداره هو لقطة المهارة المولدة. فيختم كل بناء skills/quranic-terminology/ بقيمة SHA-256 لمدخلاته، وهي المداخل والسجلات وجداول التهجئة وهذا المعيار، ويضيف الإصدار المنشور رقم commit. ويسجل المشروع الذي يعتمد على القاموس الختم الذي بنى عليه، ويخبره scripts/update_check.py في المهارة إن كان الختم حديثًا.
ونسجل كل تغيير يغير اسمًا برمجيًا أو يسحبه في المدخل (§20) وفي سجل القرارات بتاريخه. وإذا قُرئ سجل القرارات بترتيبه كان هو سجل التغييرات. ويبقى الاسم البرمجي المسحوب مردودًا إلى مفهومه عبر حقل deprecated في المدخل، ولا يُردّ عبر aliases.json لأنه يفهرس التهجئات وحدها.
30. قاعدة قبول أي مصطلح جديد
أولًا: هل يدخل المفهوم في نطاق المعيار
يدخل المفهوم في هذا المعيار إذا لم يمكن تعريفه دون الرجوع إلى القرآن أو المصحف.
وما سوى ذلك مما يخزنه التطبيق جائز، لكن المعيار لا يسميه:
داخل:
sajdah موضع من النص القرآني يسجد عنده
ayah_timing مدى من الصوت يقابل آية
word_meanings معنى لفظة قرآنية
mutashabihat ألفاظ تتكرر داخل القرآن
خارج:
book, author, chapter, category, tag, language, attachment, source
radio, stream, thumbnail, user, subscription
fatwa, hadith, athar, topic
فبث التلاوة بث كأي بث، والفتوى من علوم الإسلام وليست مفهومًا من مفاهيم النص القرآني، والكتاب له اسمه في اللغة. ونقول ذلك صراحة لأن المشروع يبقى محتاجًا إلى أسماء لكتبه ووسومه، والمعيار لا يعطيه إياها. وسبب هذا الحد والبديل المرفوض في سجل القرارات.
يسمي المعيار مفاهيم النص القرآني وعلومه، ولا يسمي ما يخزنه التطبيق سواها.
توسيع القاموس في مشروع
المشروع الذي يحتاج إلى أسماء لا يعطيها المعيار يكتبها بالطريقة نفسها في مجلد مفاهيم خاص به، ويضع لها origin: standard وقيم category خاصة به، ويشغّل عليها الأدوات نفسها. ويقرأ فحص المهارة مجلد المشروع بجوار مجلد المعيار، فيفحص المفهوم المحلي دون أن ينبه عليه. وإذا تبين أن مفهومًا محليًا من مفاهيم النص القرآني، اقترحه المشروع هنا في مسألة (issue)، وانتقل إلى هذا القاموس إذا قُبل.
ولا يعيد المشروع تعريف مفهوم يعرّفه هذا القاموس، ولا يستعمل اسمًا برمجيًا منه لشيء آخر.
ثانيًا: المدخل نفسه
قبل إدخال أي مدخل إلى القاموس يجب الإجابة عن:
- ما المفهوم؟
- ما تعريفه؟
- ما الغرض البرمجي من تمثيله؟
- ما حدوده وما المفاهيم التي قد يختلط بها؟
- ما
kindالخاص به؟ - إلى أي
categoryينتمي؟ - هل له
parentأوpart_of؟ - هل هو مفهوم قرآني متخصص أم مفهوم تقني عام؟
- ما أنسب اسم معتمد له؟
- إذا كان عربي الأصل، هل تتبع تهجئته
Canonical Code Spelling؟ - هل يكون مجموعةً يومًا، وما جمعه البرمجي إن كان؟
- ما التهجئات البديلة؟
- ما الترجمات أو المقابلات الإنجليزية؟
- هل توجد أسماء مهجورة؟
- هل يستقيم الاسم في الكود والـ
APIوقاعدة البيانات؟ - ما المصدر الذي يثبت تعريف المفهوم؟
إذا لم نستطع تعريف المفهوم أو بيان الغرض البرمجي منه بوضوح، فلا يعتمد حتى تتضح الحاجة إليه.
31. المبادئ الأساسية
يرجع المعيار إلى هذه المبادئ، ومع كل واحد منها صيغته الإنجليزية كما تقتبس في المراجعة:
- نحدد المفهوم قبل اسمه.
Concept before name. - لكل مفهوم اسم معتمد واحد.
One concept, one canonical name. - المفهوم القرآني يحتفظ باسمه القرآني، والمفهوم العام يأخذ الإنجليزية التقنية الطبيعية.
Quran-specific concepts retain Quranic names; general concepts use natural technical English. - المصطلح العربي له تهجئة برمجية واحدة بسيطة، تُشتق ولا تُختار.
Arabic-derived terms use one simple Canonical Code Spelling, derived and not chosen. - يشرح
definitionما المفهوم، ويشرحpurposeلماذا تمثله البرمجيات.definition explains what the concept is; purpose explains why software models it. - لكل مدخل
kindوcategoryمحددان.Every entry has a defined kind and category. - الأنواع والقيم المهمة مداخل مستقلة بتعريفاتها، وأفراد المجموعة المغلقة سطور في سجل.
Important types and values are first-class dictionary entries with their own definitions; members of a closed set are registry rows. - علاقة الأب بالابن مصرح بها، والاحتواء حقل مستقل.
Parent–child relationships are explicit, and containment is a separate field. - المفهومان المختلفان يبقيان مختلفين ولو تشابهت أسماؤهما أو ترجماتهما.
Different concepts remain different even when their names or translations are similar. - الأسماء المعتمدة والتهجئات البديلة والترجمات والأسماء المهجورة حقول منفصلة.
Canonical names, alternative spellings, translations and deprecated names are kept separate. - المفردات نفسها تجري في الكود والـ
APIsوقواعد البيانات والـdatasetsوالتوثيق.The same vocabulary is used consistently across code, APIs, databases, datasets and documentation. - القاموس مقروء آليًا، وقواعده تفحصها الأدوات.
The dictionary is machine-readable, and its rules are checked by tools.
المصدر: quran-ws/docs، عند d1d6be33be9d. ما لم يُوسم «معتمد» فهو مقترح للنقاش، ولا يُبنى عليه بعد.