جدول المحتويات
طريقة الوسم
هذه مجردة صفحة لمناقشة الأفكار.
الهدف في النهاية الحصول على كائن بأبسط صوره يكون عبارة عن منظومة أو قائمة list بالعقد nodes كل واحدة عبارة عن عنصرين هما المحتوى وهو نص صرف والوسوم وهي قاموس من المفاتيح وقيمها والعنصر الأخير هو العقد الفرعية. مثل هذا الكائن في بايثون يكون بالأنواع المبنية في اللغة نفسها built-in types هكذا
nodes=[ ['this is text body', {'tag1': 'value1', 'tag2': 'value2'}, [ ['this is a text', {'tag1': 'value1'}, []], ['click here', {'href': 'http://www.ojuba.org'}, []], ['this is a text', {'tag1': 'value1'}, []] ] ] ]
من البدائل الموجودة أمامنا هي أن يكون لكل باب صف واحد به خلية فيها المحتويات بهيئة ويكي أو أي هيئة أخرى مثل xml. لكن بصرف النظر عن طريقة التحسين optimization فإن لدينا طريقتين للوسم
- إما أن تكون العقد صفوفا بها علاقات مع جدول الوسوم.
- وإما أن تكون في هيئة خاصة مزروعة نصا في تلك الصفوف.
عيوب استخدام صيغتين
استخدام طريقتين للوسم واحد من خلال صيغة الويكي وأخرى من خلال صفوف في جداول قاعدة البيانات يعني
- وجود كود مضاعف يحوّل من هذه إلى تلك أو إلى هيئة وسيطة.
- الجهد اللازم لمزامنة التطورات في كود هذه الأجزاء.
- إعماء كود الاستعلام عن العقد الموسومة من خلال قاعدة البيانات
مثلا لو كان هناك عقدة تحمل وسم يدل على رقم الصفحة في المطبوع موجودة في كود ويكي أو xml ثم أردنا القفز لصفحة معينة من خلال استعلام في قاعدة البيانات لن نجدها. (وطبعا السير على كل العقد التي تحتوي xml بحثا عن رقم الصفحة لن يكون مجديا)
على مبدأ أن الحل التوفيقي بين حلين هو الحل الذي يجمع عيوبهما .
محددات تقييم الطريقة البديلة
في الكثير من الأحيان يكون من الأجدى عدم استخدام وسوم على النص بل استخدام رموز ويكي مثلا عوضا عن عمل وسم للفقرة يمكن استخدام تتابع علامتي سطر جديد كعلامة للفقرة. هذا الأمر يكون مفيدا جدا إن كانت كثرة هذا الوسم ستضيف كمًا كبيرا من الصفوف في قاعدة البيانات بشرط أن تكون هناك أهمية للبحث عن هكذا وسم من ناحية دلالية.
محددات اختيار هذه الرموز
- أن تكون سهلة القراءة دون وسيط
- سهلة الحفظ والاستخدام من قبل المحررين
- أن تكون سهلة التخطي escape
- أن لا يؤثر على الفهرسة أي أن يتم إزالة هذه الرموز الخاصة عند فهرسة البحث
أمثلة على الاستخدام الأمثل لمثل هذه الأشياء
- تظليل أماكن خاصة من النص مثلا
- رموز القُراء في الشاطبية
- الكلمة الحالية أو المشتقة من الجذر الحالي في المعاجم
- مصطلحات فنية
- الاختصارات ومفكوكها
- هوامش للمراجع وأشباه ذلك
- عناوين داخل الصفحة الواحدة (التي لا يليق أن تفصل في أبواب)
- السؤال وجوابه
- الجذر والكلمات المرتبطة به ومعانيها
- صدر بيت الشعر وعجزه
- روابط خارجية أي إلى موقع آخر
أمثلة قد تكون مفيدة على شكل ويكي ومن الأفضل أن تكون على شكل وسوم (بحاجة لقرار)
- روابط داخل نفس الكتاب
- روابط بينية أي إلى كتاب آخر داخل ثواب
- فوائد ويكي: اختزال صفوف من الجداول
- فوائد الوسوم: إمكانية إحصاء الترابط بين الصفحات أو الكتب دون المرور على النص عبر صفوف الجداول. (تشكيك: يتم إحصاء الروابط عند التحرير فلا يعود هناك مبرر لإعادة إحصائها لاحقا لأنها لا تتغير)
- جلب مقطع من آية (في التفاسير)
- جلب مقطع من كتاب آخر للتعليق عليه (في الشروح)
الويكي
المشاكل المتوقعة
عدد من صيغ الويكي
هيئة XML
يمكن أن يكون الكود المكتوب بهيئة xml على هذه الصيغة العامة
<node tag1="value1" tag2="value2">this is text body <node tag1="value1" tag2="value2">this is text body</node> <node href="http://www.ojuba.org">click here</node> <node tag1="value1" tag2="value2">this is text body</node> </node>
يمكن توليد كود xml من بايثون بهذه الطريقة:
from lxml import etree n=etree.Element("node", tag1="value1", tag2="value2") n.append(etree.Element("node", tag1="value1", tag2="value2")) n.append(etree.Element("node", href="http://www.ojuba.org")) n.append(etree.Element("node", tag1="value1", tag2="value2")) n.attrib['foo']='foobar' print etree.tostring(n,encoding='UTF-8' , pretty_print=True)
للعملية العكسية نعمل
root = etree.XML(s) print root.tag print root.attrib print root.text for i in root: print i.tag print i.attrib print i.text
وليس بالضرورة أن نحوّله إلى كائن من الأنواع المبنيّة في اللغة لأن lxml تدعم كل الخصائص التي نريدها.
يمكن تحويل هذه الصيغة إلى أي صيغة بما فيها التصدير إلى html من خلال XSLT هكذا
xslt_doc = etree.XML(s) # or etree.fromstring(s) or etree.parse(some_file_like) transform = etree.XSLT(xslt_doc) result_tree = transform(doc, param1=value1)
للمزيد انظر
حسنات هذه الطريقة
- يمكن استخدام كود XSLT الذي يحوّل إلى html في أي لغة أخرى
- يفترض أن عملية التحويل سريعة جدا وقليلة الاستهلاك للذاكرة.
- عمل validation عبر RELAX NG
عيوب الطريقة
- مكتبة lxml في بايثون ليست صرفة وتعتمد على مكتبات بلغة سي (هذا قد يسبّب مشكلة عند عمل المكتبة على الأجهزة الخلوية إلا أن تكون جافا عندها لا مشكلة)
- معالجة ترابط المواضيع الخارجية مثلا إن كان هناك عقدة تعني استيراد نص من مصدر خارجي (كتاب آخر مثلا) كيف يمكن عمل ذلك في XSLT
- أني لا أتقن XSLT تماما
هيئة Yaml
طريقة تحويل نص Yaml إلى كائن
import yaml s="""\ - - 'this is text body' - {'tag1': 'value1', 'tag2': 'value2'} - - - 'this is a text' - {'tag1': 'value1'} - [] - - 'click here' - {'href': 'http://www.ojuba.org'} - [] - - 'this is a text' - {'tag1': 'value1'} - [] """ nodes=yaml.load(s)
للقيام بالعملية العكسية
s=yaml.dump(nodes)
هيئة JSON
مجموعة جزئية subset من YAML يعني ليس كل YAML يعتبر JSON لكن كل كائن JSON يعتبر YAML
للتحويل من كائن بايثوني إلى JSON
import json nodes=[ ['this is text body', {'tag1': 'value1', 'tag2': 'value2'}, [ ['this is a text', {'tag1': 'value1'}, []], ['click here', {'href': 'http://www.ojuba.org'}, []], ['this is a text', {'tag1': 'value1'}, []] ] ] ] print json.dumps(nodes)
للعملية العكسية
s='''[["this is text body", {"tag1": "value1", "tag2": "value2"}, [["this is a text", {"tag1": "value1"}, []], ["click here", {"href": "http://www.ojuba.org"}, []], ["this is a text", {"tag1": "value1"}, []]]]]''' nodes=json.loads(s)
حسنات هذه الهيئة
- البنية الطبيعية للبيانات في جافاسكربت (لا تحتاج تحويل)
- أصبحت جزءا رسميا من بايثون 2.6
- يوجد منها تنفيذات سريعة على سي ومنها تنفيذات على بايثون لا تعتمد على سي (مما يعني أنها تعمل على أي منصة)
عيوبها
- قد لا تكون آمنة إن لم نضمن مصدر كائن json (يعني قد يعمل أحدهم مستودع كتب يرسل كائنات json تحتوي على كود جافاسكربت خبيث) وحلّها باستعمال مكتبة جافاسكربت تعمل على فحص الكود قبل تحويله إلى كائن.
- كود التحويل إلى هيئة html يجب أن يكتب لكل لغة.