العروض العربية التي تُنشأ بالكود تبدو في الغالب شبه صحيحة: الحروف سليمة، لكن النقاط تقع في الطرف الخطأ من السطر، وعلامات التعداد على اليسار، والجداول معكوسة. والسبب واحد في أغلب الحالات: الملف لا يذكر في أي موضع أن النص من اليمين إلى اليسار.
تعرض هذه الصفحة المواضع التي يخزّن فيها ملف .pptx الاتجاه، وأكواداً تعمل لـpython-pptx وPptxGenJS، وما كتبه كل أسلوب حين شغّلناه. جرى الاختبار يوم 12 نوفمبر 2026 على python-pptx 1.0.2 وPptxGenJS 4.0.1.
الخلاصة
- الاتجاه يُضبط على الفقرة:
<a:pPr rtl="1">. اضبطه على كل فقرة. - المحاذاة خاصية منفصلة:
algn="r". النص المحاذى إلى اليمين ليس بالضرورة نصاً من اليمين إلى اليسار. - العربية تُرسم بـخط الخطوط المعقّدة
<a:cs typeface="…">لا بالخط اللاتيني. - لـالجدول علامة خاصة به
<a:tblPr rtl="1">تجعل العمود الأول على اليمين، وتبقى فقرات خلاياه بحاجة إلىrtl="1". - علامة
rtlعلى مستوى العرض لا تغيّر أي نص.
ما الذي يخزّنه الملف
ملف .pptx أرشيف مضغوط من ملفات XML. هذه فقرة صحيحة من اليمين إلى اليسار في ppt/slides/slide1.xml:
<a:p>
<a:pPr algn="r" rtl="1"/>
<a:r>
<a:rPr lang="ar-SA">
<a:cs typeface="Tahoma"/>
</a:rPr>
<a:t>ارتفعت الإيرادات إلى 1,500,000 ريال (SAR).</a:t>
</a:r>
</a:p>
| الموضع | الخاصية | وظيفتها |
|---|---|---|
الفقرة <a:pPr> |
rtl="1" |
الاتجاه الأساسي للفقرة. هذه هي الخاصية الحاسمة. |
الفقرة <a:pPr> |
algn="r" |
المحاذاة فقط، وهي مستقلة عن الاتجاه. |
المقطع <a:rPr> |
lang="ar-SA" |
لغة المقطع، وتُستخدم في التدقيق. |
المقطع <a:rPr> |
<a:cs typeface="…"/> |
الخط المستخدم للعربية وسائر الخطوط المعقّدة. |
الجدول <a:tblPr> |
rtl="1" |
ترتيب الأعمدة ابتداءً من اليمين. |
مربع النص <a:bodyPr> |
rtlCol="1" |
ترتيب أعمدة النص المتعددة ابتداءً من اليمين. |
العرض <p:presentation> |
rtl="1" |
إعداد عرض خاص بالتطبيق، ولا يغيّر النص. |
الفقرة التي لا تضبط rtl ترثها من نمط القائمة في مربع النص، ثم من تخطيط الشريحة، ثم من الشريحة الرئيسية، ثم من إعدادات العرض الافتراضية. والقوالب المعدّة للإنجليزية لا تضبط شيئاً من ذلك، فتكون النتيجة من اليسار إلى اليمين.
خزّن النص بترتيبه المنطقي، أي كما تكتبه. لا تعكسه ولا تُعد ترتيب العربية والإنجليزية المختلطتين بنفسك: بوربوينت يطبّق خوارزمية يونيكود للنص ثنائي الاتجاه عند رسم السطر، ويحتاج إلى اتجاه الفقرة ليفعل ذلك بشكل صحيح.
python-pptx
لا توفّر python-pptx خاصية عامة لاتجاه الفقرة، فتُضبط الخاصية على XML مباشرة. وfont.name تضبط الخط اللاتيني فقط، فيُضاف خط العربية بالطريقة نفسها.
from lxml import etree
from pptx import Presentation
from pptx.enum.lang import MSO_LANGUAGE_ID
from pptx.enum.text import PP_ALIGN
from pptx.oxml.ns import qn
from pptx.util import Inches
def make_rtl(paragraph, font=None):
"""Mark one paragraph right-to-left, right-aligned and Arabic."""
paragraph.alignment = PP_ALIGN.RIGHT
paragraph._p.get_or_add_pPr().set("rtl", "1")
for run in paragraph.runs:
run.font.language_id = MSO_LANGUAGE_ID.ARABIC # written as lang="ar-SA"
if font:
# font.name only sets the Latin font; Arabic text uses <a:cs>.
properties = run._r.get_or_add_rPr()
for old in properties.findall(qn("a:cs")):
properties.remove(old)
etree.SubElement(properties, qn("a:cs")).set("typeface", font)
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[1])
slide.shapes.title.text = "تقرير الربع الثالث"
body = slide.placeholders[1].text_frame
body.text = "ارتفعت الإيرادات إلى 1,500,000 ريال (SAR)."
body.add_paragraph().text = "انتقلت الأنظمة من Microsoft Azure إلى Google Cloud."
for shape in (slide.shapes.title, slide.placeholders[1]):
for paragraph in shape.text_frame.paragraphs:
make_rtl(paragraph, font="Tahoma")
table_slide = prs.slides.add_slide(prs.slide_layouts[5])
table = table_slide.shapes.add_table(2, 2, Inches(1), Inches(2), Inches(6), Inches(1.5)).table
for r, row in enumerate([["المؤشر", "الربع الثالث"], ["الإيرادات", "1,500,000"]]):
for c, value in enumerate(row):
table.cell(r, c).text = value
for paragraph in table.cell(r, c).text_frame.paragraphs:
make_rtl(paragraph)
table._tbl.tblPr.set("rtl", "1") # first column on the right
prs.save("deck.pptx")
استدعِ make_rtl بعد وضع النص. إسناد قيمة إلى text_frame.text أو cell.text يستبدل الفقرات، فتضيع الخصائص التي ضُبطت قبله.
PptxGenJS
في PptxGenJS خيار اسمه rtlMode، ويعمل على النصوص وعلى كل خلية جدول بمفردها.
import pptxgen from "pptxgenjs";
const pptx = new pptxgen();
const slide = pptx.addSlide();
const rtl = { rtlMode: true, align: "right", lang: "ar-SA", fontFace: "Tahoma" };
slide.addText("ارتفعت الإيرادات إلى 1,500,000 ريال (SAR).", { x: 0.5, y: 0.5, w: 9, h: 1, ...rtl });
slide.addText(
[
{ text: "افتتاح مكتب في الرياض", options: { ...rtl, bullet: true, breakLine: true } },
{ text: "توظيف 12 مهندساً", options: { ...rtl, bullet: true } },
],
{ x: 0.5, y: 1.7, w: 9, h: 1.5 },
);
// Tables: rtlMode has to go on every cell. The table itself is not mirrored,
// so list the columns in the order they should appear from left to right.
const cell = (text) => ({ text, options: rtl });
slide.addTable(
[
[cell("الربع الثالث"), cell("المؤشر")],
[cell("1,500,000"), cell("الإيرادات")],
],
{ x: 0.5, y: 3.5, w: 9 },
);
await pptx.writeFile({ fileName: "deck.pptx" });
ثلاث ملاحظات من فحص ناتج الإصدار 4.0.1:
- الخيار
fontFaceيكتب الخط اللاتيني وخط الخطوط المعقّدة معاً، فتأخذ العربية الخط المحدد. - وضع
rtlModeفي خياراتaddTableلم يصل إلى الخلايا: كانت فقراتها محاذاة إلى اليمين دونrtl="1". وضعه على كل خلية حلّ المشكلة. - عنصر الجدول كُتب دون
rtl="1"في الحالتين، فالأعمدة لا تنعكس. رتّبها بنفسك كما في الكود.
ماذا كتب كل أسلوب
أنشأنا ملفاً بكل أسلوب وعددنا الفقرات العربية التي يعلّمها الملف باتجاه اليمين إلى اليسار.
| الأسلوب | معلَّمة من اليمين إلى اليسار | غير محاذاة لليسار |
|---|---|---|
| PptxGenJS بلا خيارات | 0 من 1 | 0 من 1 |
PptxGenJS مع align: "right" فقط |
0 من 1 | 1 من 1 |
PptxGenJS مع pptx.rtlMode = true فقط |
0 من 1 | 0 من 1 |
PptxGenJS مع rtlMode على النص، وعلى الجدول بدل خلاياه |
3 من 6 | 6 من 6 |
PptxGenJS مع rtlMode على النص وعلى كل خلية (الكود أعلاه) |
6 من 6 | 6 من 6 |
python-pptx مع make_rtl على كل فقرة (الكود أعلاه) |
6 من 6 | 6 من 6 |
الصفان الثاني والثالث هما الفخّان الشائعان: المحاذاة إلى اليمين وحدها، أو مفتاح العرض وحده، يتركان كل فقرة من اليسار إلى اليمين.
Open XML SDK (لغة C#)
لم نشغّل هذا الجزء. أسماء الخصائص التالية من مرجع مايكروسوفت للـSDK، مع رابط لكل خاصية.
| الإعداد | الخاصية |
|---|---|
| اتجاه الفقرة | ParagraphProperties.RightToLeft |
| اتجاه الجدول | TableProperties.RightToLeft |
| ترتيب أعمدة النص | BodyProperties.RightToLeftColumns |
| علامة العرض | Presentation.RightToLeft |
خمسة أخطاء تُبقي النص من اليسار إلى اليمين
- الاكتفاء بالمحاذاة إلى اليمين. يلتصق النص بالحافة اليمنى لكن اتجاهه الأساسي يبقى من اليسار إلى اليمين، فتقع علامات الترقيم والأقواس في الطرف الخطأ.
- الاعتماد على علامة العرض.
<p:presentation rtl="1">لا تمسّ الفقرات. - ضبط الاتجاه على الفقرة الأولى فقط. لكل فقرة خاصيتها، وكل بند تعداد فقرة مستقلة.
- نسيان خلايا الجدول. نص الخلية فقرات قائمة بذاتها، وعلامة الجدول تعكس الأعمدة لا غير.
- ضبط الخط اللاتيني وحده. العربية تُرسم بخط الخطوط المعقّدة، وإن لم يُضبط استخدم بوربوينت الخط الافتراضي للقالب ولم يظهر خطك المختار.
افحص ملفاً
يطبع هذا الكود لكل شريحة عدد الفقرات التي تضبط rtl="1" مباشرة:
import re
import sys
import zipfile
with zipfile.ZipFile(sys.argv[1]) as deck:
slides = sorted(n for n in deck.namelist() if re.fullmatch(r"ppt/slides/slide\d+\.xml", n))
for name in slides:
xml = deck.read(name).decode("utf-8")
paragraphs = [p for p in re.findall(r"<a:p>.*?</a:p>", xml, flags=re.S) if "<a:t>" in p]
marked = [p for p in paragraphs if re.search(r'<a:pPr[^>]*\brtl="1"', p)]
print(f"{name}: {len(marked)} of {len(paragraphs)} paragraphs marked right-to-left")
هذا فحص سريع لا شامل: لا يتتبّع الوراثة من التخطيط والشريحة الرئيسية، ويعدّ كل الفقرات لا العربية وحدها. والقالب الذي يضبط الاتجاه مرة واحدة في شريحته الرئيسية سيُظهر صفراً هنا وهو صحيح.
روابط ذات صلة
- صانع العروض التقديمية العربية
- صيغ الأرقام والتواريخ والعملات في الدول العربية
- تشغيل أكواد python-pptx في المتصفح (بالإنجليزية)
- ما الذي يتعطل في أكواد بوربوينت المكتوبة بالذكاء الاصطناعي (بالإنجليزية): بيانات من 27,600 عملية تنفيذ