دليل الاستخدام

التثبيت

ثبت الحزمة في بيئة kernel الذي تستخدمه:

python -m pip install "jupyter-lecture-studio[notebook,highlight]"

تنظيم العمل

احتفظ بمجلد lecture-studio كمشروع مستقل. ثبت المكتبة مرة واحدة في بيئة Jupyter التي تستخدمها. لكل محاضرة، أنشئ كائن LectureDeck في أول خلية، ثم استدعِ مكونًا في كل خلية عرض. بذلك يبقى الشرح مقسمًا ويمكن التنقل إليه من فهرس Jupyter.

from jupyter_lecture_studio import LectureDeck

deck = LectureDeck(course="الذكاء الاصطناعي", series="AI SERIES", lesson="03")

إعادة تنفيذ خلية الإنشاء تبدأ مجموعة جديدة. إعادة تنفيذ خلية عرض منفردة تزيد ترقيم الشرائح وتضيف مكونًا آخر إلى مجموعة التصدير. قبل تصدير النسخة النهائية، أعد تشغيل خلايا المحاضرة بالترتيب بدءًا من خلية الإنشاء. استخدم deck.clear() لتصفير المجموعة يدويًا إذا احتجت.

الغلاف

deck.cover(
    "البحث في فضاء الحالات",
    "نحوّل المشكلة إلى حالات وانتقالات.\nنقارن طرق الوصول إلى الحل.",
    kicker="الوحدة الثانية",
    tags=["نمذجة", "استكشاف", "تحليل"],
    sections=[
        {"title": "01 / نفهم", "description": "الحالات والهدف والانتقالات"},
        {"title": "02 / نطبق", "description": "تتبع البحث على رسم بياني"},
    ],
    hero_code="start → explore → goal",
    hero_result="Solution found",
    hero_label="SEARCH LAB",
)

\n يضع سطرًا جديدًا. لا تحدد مسافات يدوية لمحاذاة النص. البطاقة المتحركة اختيارية: احذف hero_code وhero_result ليصبح الغلاف نصيًا ويتوسع تلقائيًا. لا تحتوي المكتبة على مدد أو أوقات للأقسام.

بطاقات الشرح

deck.slide(
    "استراتيجية البحث",
    "اختيار العقدة التالية يحدد طريقة الاستكشاف.",
    subtitle="مقارنة مبنية على حالة واحدة",
    cards=[
        {"title": "الفكرة", "explanation": "نحتفظ بالعقد التي لم نستكشفها بعد."},
        {"title": "جرّب", "explanation": "غيّر ترتيب العناصر ولاحظ الفرق.",
         "code": "frontier = [start]", "reason": "ترتيب الجبهة يؤثر في مسار البحث."},
    ],
)

الكود يحتفظ بالمسافات والأسطر ويعرض من اليسار إلى اليمين. لغة الكود الافتراضية هي language في الهوية؛ غيّرها لكل بطاقة باستخدام language="java" أو "cpp" أو "sql". تلوين بايثون مدمج، واللغات الأخرى تستخدم Pygments عند تثبيت الإضافة highlight، وإلا يظهر الكود كنص واضح. اسم لغة غير معروف يعرض كنص كذلك.

رسم لأي مادة

deck.slide(
    "من السؤال إلى القرار",
    diagram={
        "title": "مسار التحليل",
        "direction": "rtl",
        "nodes": [
            {"value": "سؤال", "note": "ما المشكلة؟"},
            {"value": "بيانات", "note": "نجمع الأدلة"},
            {"value": "تحليل", "note": "نختبر الفكرة", "selected": True},
            {"value": "قرار", "note": "نفسر النتيجة"},
        ],
        "caption": "يمكن مراجعة كل خطوة قبل الانتقال إلى التالية.",
    },
)

يتكيف الرسم مع عرض المخرجات. selected=True تبرز عقدة. arrows=False يعرض عناصر دون أسهم. اتجاه الرسم مستقل عن اتجاه المادة، لذا يمكن شرح عربي مع رسم رياضي أو برمجي من اليسار إلى اليمين. لإعادة الحركة، أغلق «المشهد التوضيحي» ثم افتحه.

رسومات بايثون الجاهزة اختيارية:

from jupyter_lecture_studio import diagram_names
print(diagram_names())
deck.slide("تحويل النوع", diagram="cast")

الأسماء: journey, names, cast, arithmetic, index, decision, loop, list, collections, function, error. أمثلتها ثابتة ومخصصة لمفاهيم بايثون؛ لرسم آخر استخدم قاموسك الخاص.

سؤال وإجابة مخفية

deck.slide(
    "توقّع ثم فسّر",
    activity={
        "question": "ماذا يحدث عند تغيير ترتيب الشروط؟",
        "code": "grade = 95\nprint(grade >= 60)",
        "answer": "الشرط صحيح. نحتاج ترتيب الشروط بما يطابق التصنيف المطلوب.",
        "label": "ناقش مع زميلك",
        "reveal": "عرض التفسير",
    },
)

الإجابة مغلقة عند العرض. يعمل زر الكشف بلوحة المفاتيح، دون JavaScript. النص المخفي موجود في ملف HTML ويمكن الوصول إليه من المصدر؛ استخدمه للشرح والتدريب، وليس لحفظ إجابات امتحان سري.

ملاحظة أو جدول

deck.note("قاعدة مهمة", "وضح الافتراضات قبل اختيار الحل.\nاختبر النتيجة بحالة مختلفة.")
deck.table("مقارنة", ["الطريقة", "الفكرة"], [["BFS", "حسب المستوى"], ["DFS", "حسب العمق"]])

عدد القيم في كل صف يجب أن يساوي عدد الأعمدة. الجداول تسمح بالتمرير الأفقي عند الحاجة.

تخصيص الهوية والثيم

from jupyter_lecture_studio import Brand, Theme

deck = LectureDeck(
    brand=Brand(course="هندسة البرمجيات", series="SOFTWARE DESIGN", lesson="04", language="java"),
    theme=Theme(
        preset="ocean",        # gold / emerald / ocean
        accent="#B8D5FF",      # لون التمييز: ست خانات
        background="#101828", # خلفية المكونات الداكنة
        motion=True,
        direction="rtl",      # rtl / ltr
        max_width=1280,
        notebook_style=False,
        external_fonts=False,
    ),
)

تغير الألوان المخصصة تفاصيل الهوية والخلفية الرئيسية، وتبقى ألوان الكود والحالات الدلالية متسقة. motion=False يعطل الانميشن والانتقالات. إعداد «تقليل الحركة» في النظام يعطلها أيضًا. المعلومات لا تعتمد على الحركة لتصبح مفهومة.

notebook_style=True ينسق خلفية الدفتر وخلايا Markdown والكود ونتائجها، داخل JupyterLab فقط. هذا اختيار يطبق على الدفتر الذي يحتوي المخرجات، وليس على واجهة التطبيق. إذا استخدمت عدة decks في نفس الدفتر، اجعل هذا الخيار موحدًا بينها. التصميم الأساسي الافتراضي معزول ولا يغير الخلايا الأخرى.

المكتبة تضمّن خط Cairo للعربية وJetBrains Mono للكود داخل CSS افتراضيًا، ولذلك يبقى الخط الأصلي حاضرًا دون اتصال، بما في ذلك ملفات HTML المصدّرة. لا تحتاج إلى تثبيت الخط على الجهاز. external_fonts=True خيار لتحميلهما من Google Fonts عبر الشبكة بدل التضمين المحلي.

HTML والنصوص

كل النصوص تُعرض كنص آمن افتراضيًا، حتى لو احتوت < أو &. لا تكتب HTML للاستخدام العادي. عندما تحتاج تنسيقًا متقدمًا من تأليفك، استخدم RichText صراحة:

from jupyter_lecture_studio import RichText

deck.slide(
    "تقطيع النص",
    RichText('الصيغة <code>start:stop:step</code>، والنهاية غير مشمولة.'),
)

RichText يقبل HTML موثوقًا من مؤلف المحاضرة دون تنقية؛ لا تستخدمه لمدخلات الطلاب أو نصوص خارجية غير موثوقة. ملفات JSON تقبل نصوصًا عادية فقط.

ملف محتوى مستقل

deck = LectureDeck.from_file("lecture.json")

هيكل الملف:

{
  "brand": {"course": "اسم المادة", "series": "SERIES", "lesson": "01", "language": "python"},
  "theme": {"preset": "gold", "motion": true, "direction": "rtl"},
  "components": [
    {"type": "cover", "title": "عنوان المحاضرة", "description": "مقدمة"},
    {"type": "slide", "title": "المفهوم", "cards": [{"title": "تطبيق", "code": "print(1)"}]}
  ]
}

تدعم المكونات cover, slide, note, table. لا يلزم تغيير كود الدفتر بعد تعديل محتوى JSON؛ أعد تنفيذ خلية from_file فقط.

التصدير والطباعة

deck.export("output/lecture.html")

يصدر المكونات التي أضفتها إلى هذا الكائن بالترتيب. الملف يتضمن CSS، ويعمل في متصفح حديث دون اتصال أو تثبيت، ما دامت الخطوط الخارجية معطلة. يستبدل ملف التصدير إذا كان موجودًا. خلايا Jupyter التنفيذية ومخرجاتها المستقلة ليست جزءًا من هذا التصدير.

للحصول على PDF افتح HTML ثم استخدم طباعة المتصفح. لا يوجد تحويل PDF آلي داخل المكتبة. تتوقف الحركة عند الطباعة، وتبقى الإجابات المغلقة مخفية. افتح الإجابات قبل الطباعة إذا أردت نسخة تحتوي الحلول.

حل المشاكل

المشكلة

الحل

ModuleNotFoundError

ثبت المكتبة بواسطة %pip داخل kernel الحالي ثم أعد تشغيله.

HTML يظهر دون تنسيق

استخدم دفترًا موثوقًا؛ أعد تنفيذ خلايا العرض بنفسك.

تكرر الترقيم أو المكونات المصدرة

أعد إنشاء deck وشغل خلايا العرض بالترتيب.

لون مكتبة قديم بعد تعديل المصدر

أعد تشغيل kernel لأن ملفات CSS تُخزن مؤقتًا داخل العملية.

اختلاف الخط في ملف قديم

حدّث المكتبة إلى 0.1.1 وأعد تنفيذ الخلايا أو تصدير HTML؛ الخطوط مضمنة افتراضيًا.

كود Java أو SQL دون تلوين

ثبت إضافة highlight؛ العرض النصي يعمل دونها.

الجوانب ضيقة

أغلق لوحة الفهرس عند العرض، أو استخدم HTML المستقل؛ البطاقات تتكيف تلقائيًا.

التصميم يستهدف JupyterLab والمتصفحات الحديثة. قد تنقي بعض بيئات الدفاتر السحابية CSS أو تتجاهل تنسيق الخلايا المحيطة؛ العرض في تلك البيئات غير متحقق. لا تتطلب المكتبة تشغيل JavaScript.

الحفاظ على تصميم الغلاف الأصلي

الثيم gold دون ألوان مخصصة يحافظ على تدرجات وألوان التصميم الأصلي. استخدم footer_label="PYTHON / FOUNDATIONS" في deck.cover(...) لتحديد النص الصغير أسفل الغلاف مستقلًا عن اسم المحاضرة. أسطر الكود التي تبدأ بـ >>> تحصل تلقائيًا على لون المؤشر الذهبي.