Skip to main content

🎬 manim-fa

افزونه‌ی مانیم برای نمایش صحیح متن فارسی (راست‌به‌چپ)، با فونت داخلی، تبدیل فینگلیش به فارسی، و قالب‌بندیِ بولد/ایتالیک/زیرخط/هایلایت.

نصب

pip install -e .

وابستگی‌ها (manim, manimpango) به‌صورت خودکار نصب می‌شوند.

استفاده‌ی سریع

from manim import *
from manim_fa import FaText, fa_write

class Demo(Scene):
    def construct(self):
        t = FaText("به مانیم فارسی خوش آمدید!", font_size=48, color=BLUE)
        self.play(fa_write(t))   # نوشتن از راست به چپ (طبیعی برای فارسی)
        self.wait(1)

قالب‌بندیِ درون‌متنی (بولد، ایتالیک، زیرخط، هایلایت)

نیازی به دانستنِ کد یا اندیسِ کاراکتر نیست — کافی است داخلِ خودِ متن از این نشانه‌ها استفاده کنید:

نحو نتیجه
**متن** بولد
*متن* ایتالیک
__متن__ زیرخط‌دار
==متن== هایلایت با رنگ پیش‌فرض (زرد)
==متن|رنگ== هایلایت با رنگ دلخواه، مثل ==نکته‌ی مهم|orange== یا با کدِ رنگ ==نکته|#FF8800==
FaText("می‌توان **بولد**، *ایتالیک*، ـ زیرخط ـ و ==هایلایت== را باهم ترکیب کرد.")

نمونه خروجی متن ترکیبی

FaText("رنگ دلخواه: ==نکته‌ی مهم|orange==")

برای نوشتنِ خودِ نویسه‌های *، _، = به‌صورت عادی (بدون تفسیر به‌عنوان قالب‌بندی)، قبلشان یک بک‌اسلش بگذارید: \*, \_, \=.

اگر متنِ شما به‌طور طبیعی حاویِ این نویسه‌هاست و اصلاً نمی‌خواهید تفسیر شوند، از markup=False استفاده کنید:

FaText("۳*۴=۱۲", markup=False)

دقیق‌تر: markup=False یعنی نشانه‌های خودِ manim-fa (**, *, __, ==) تفسیر نمی‌شوند و متن «همان‌طور که هست» به Pango داده می‌شود. پس می‌توانید خودتان Pango Markup بنویسید (مثل <span fgcolor='red'>سدیم</span>، که manim-fa-chemistry برای رنگ‌آمیزیِ نام‌ها استفاده می‌کند)، و نویسه‌های < و & را باید خودتان escape کنید (&lt;، &amp;).

متنِ کاملاً خام: literal=True

اگر متن شامل <، &، **، == یا _ است و می‌خواهید دقیقاً همان‌طور که نوشته‌اید نمایش داده شود (فرمول، برچسب، …)، نیازی به escape نیست:

FaText("غلظت < ۳ مولار & برچسب **x** و ==y==", literal=True)

(markup=False فرق دارد: نشانه‌های manim-fa را تفسیر نمی‌کند ولی متن را به‌عنوان Pango Markup می‌خواند.)

انیمیشنِ نوشتنِ راست‌به‌چپ با fa_write

متنِ چندخطی خط‌به‌خط نوشته می‌شود: خطِ اول اول، و هر خط از راست به چپ. در خط‌های مخلوط، کلمه‌های لاتین و عددها (H2O، ۲۵، 3.14) از چپ به راست نوشته می‌شوند، مثلِ نوشتنِ دست.

از fa_write(mobject) به‌جای Write(mobject) استفاده کنید تا حروف از راست به چپ (جهتِ طبیعیِ نوشتنِ فارسی) ظاهر شوند — با همان افکتِ اصیلِ «دست‌نویسی» (اول خط‌دورِ حرف کشیده می‌شود، بعد پر می‌شود) که خودِ Write() مانیم دارد؛ چون در پسِ صحنه دقیقاً از همان مکانیزم استفاده می‌کند. تنها تفاوتش با Write(reverse=True) این است که با متنِ دارای هایلایت هم درست کار می‌کند (جعبه‌ی هایلایت همیشه همراه با متنِ خودش ظاهر می‌شود، نه با تاخیر یا جلوتر):

t = FaText("این متن ==هایلایت== و **بولد** دارد.")
self.play(fa_write(t, run_time=3))

🌀 فهرست کامل انیمیشن‌های کاربردی در Manim

نام انیمیشن کاربرد مثال
Write() نوشتن تدریجی متن self.play(Write(t))
Create() رسم کامل یک شیء از ابتدا self.play(Create(circle))
FadeIn() ظاهر شدن تدریجی شیء self.play(FadeIn(t))
FadeOut() محو شدن تدریجی شیء self.play(FadeOut(t))
FadeToColor() تغییر رنگ شیء با انیمیشن نرم self.play(FadeToColor(t, RED))
Transform() تبدیل یک شیء به شیء دیگر self.play(Transform(t1, t2))
ReplacementTransform() جایگزینی تدریجی یک شیء با دیگری self.play(ReplacementTransform(t1, t2))
Rotate() چرخش شیء به اندازه مشخص self.play(Rotate(t, angle=PI/2))
ScaleInPlace() بزرگ یا کوچک شدن در محل فعلی self.play(t.animate.scale(1.5))
MoveAlongPath() حرکت شیء روی مسیر مشخص self.play(MoveAlongPath(t, circle))
Circumscribe() ترسیم حاشیه دور شیء self.play(Circumscribe(t))
GrowFromCenter() رشد شیء از مرکز self.play(GrowFromCenter(t))
ShrinkToCenter() جمع شدن شیء به مرکز self.play(ShrinkToCenter(t))
Wiggle() لرزش یا تکان نرم self.play(Wiggle(t))
FocusOn() فوکوس با تغییر نور یا رنگ self.play(FocusOn(t))
Flash() درخشش سریع در محل شیء self.play(Flash(t))
Indicate() نمایش تأکید با رنگ و مقیاس self.play(Indicate(t))
ApplyWave() حرکت موجی روی شیء self.play(ApplyWave(t))
ApplyMethod() اجرای متد خاص روی شیء self.play(ApplyMethod(t.shift, UP))
animate.shift() جابه‌جایی شیء self.play(t.animate.shift(UP))
animate.set_color() تغییر رنگ شیء self.play(t.animate.set_color(BLUE))
animate.rotate() چرخش با انیمیشن نرم self.play(t.animate.rotate(PI/3))

سایر امکانات

متن ترکیبی (فارسی + انگلیسی + عدد)

FaText("این متن ترکیبی است: Hello 123 پایان.")

تبدیل فینگلیش به فارسی

FaText("Salam be Manim, khosh amadid", translit=True)     # سلام به مانیم، خوش آمدید
FaText("khoone", translit=True, translit_words={"khoone": "خانه"})   # فرهنگِ دلخواهِ خودتان

⚠️ توجه: این تبدیل تقریبی است، نه آوانگاری زبان‌شناختیِ کامل. برای کلمه‌های پرکاربرد (salam، khoda، be، dar، agar، …) یک فرهنگِ کوچکِ داخلی هست و «e» پایانیِ پس از همخوان به «ه» تبدیل می‌شود (khane ← «خانه»)؛ کلمه‌های دیگر حرف‌به‌حرف تبدیل می‌شوند (مثلاً «kitab» ← «کیتاب» نه «کتاب»). برای کلمه‌های مهم، خودتان با translit_words املا را تعیین کنید و خروجی را بازبینی کنید. فقط «متن» تبدیل می‌شود، نه نشانه‌های قالب‌بندی و نه نامِ رنگِ هایلایت.

جهتِ جمله‌های فارسی که با حرفِ لاتین شروع می‌شوند

FaText("pH محلول برابر ۷ است.")
FaText("H2O یک مولکول است.")

Pango جهتِ هر خط را از اولین حرفِ «قوی» می‌گیرد؛ بنابراین چنین جمله‌ای چپ‌به‌راست چیده می‌شد («pH» سمتِ چپ و نقطه سمتِ راست). manim-fa برای خط‌هایی که فارسی‌محورند ولی با حرفِ لاتین شروع می‌شوند یک نشانهٔ نامرئیِ راست‌به‌چپ می‌گذارد تا درست چیده شوند. rtl=False این را خاموش می‌کند.

فونت دلخواه

FaText("سلام", font="IRTitr")  # اگر روی سیستم نصب باشد استفاده می‌شود
FaText("سلام")                  # وگرنه از فونت داخلی «وزیرمتن» استفاده می‌شود

عیب‌یابی

فونتِ متن اشتباه است (شبیه وزیرمتن نیست)

اگر با نسخه‌های قدیمیِ manim-fa (پیش از ۱٫۲٫۰) ویدیو ساخته‌اید، مانیم متنِ اشتباه را در پوشهٔ media/texts نگه داشته و دوباره می‌خواند. یک‌بار پاکش کنید:

import manim_fa
manim_fa.clear_text_cache()

(یا پوشهٔ media/texts را دستی پاک کنید.)

ترتیبِ import

از نسخهٔ ۱٫۲٫۰ ترتیبِ import مهم نیست. (نسخه‌های قبلی اگر پلاگینی مثل manim-fa-chemistry نصب بود و اولین import برنامه import manim_fa بود، با ImportError … partially initialized module می‌شکستند.)

فونت همراه پلاگین

فونت وزیرمتن (Vazirmatn) با مجوز SIL Open Font License 1.1 همراه پلاگین توزیع می‌شود (manim_fa/fonts_data/، مجوز در همان پوشه در OFL.txt). این یک فونت مدرن با پشتیبانیِ کامل OpenType برای اتصالِ حروفِ فارسی/عربی است.

معماریِ فنی (برای مشارکت‌کنندگان)

  • manim_fa/text.py — تابعِ FaText: تبدیل فینگلیش (اختیاری) ← تفسیرِ نشانه‌های قالب‌بندی به Pango Markup ← ساختِ MarkupText با فونتِ تضمین‌شده.
  • manim_fa/markup.py — پارسرِ نحوِ ساده (**, *, __, ==) به Pango Markup، با escape کردنِ نویسه‌های XML و پشتیبانی از بک‌اسلش‌برای‌نویسه‌ی‌خام.
  • manim_fa/fonts.py — ثبتِ فونتِ داخلی نزد Pango/ManimPango هنگامِ import (نه اولین FaText؛ ثبتِ دیرهنگام بی‌اثر است) و انتخابِ بهترین فونتِ در دسترس.
  • manim_fa/cache.pyclear_text_cache(): پاک‌کردنِ کشِ متنِ مانیم.

نکتهٔ طراحی: manim_fa هنگامِ import هیچ‌چیز از manim وارد نمی‌کند (فقط موقعِ استفاده). مانیم هنگامِ بالا آمدن پلاگین‌های ثبت‌شده را بارگذاری می‌کند و آن‌ها from manim_fa import FaText می‌زنند؛ اگر manim_fa خودش هنگامِ import سراغِ manim می‌رفت، ترتیبِ import می‌توانست آن را بشکند.

  • manim_fa/translit.py — تبدیلِ قاعده‌مبنایِ فینگلیش به فارسی.
  • manim_fa/animation.py — تابعِ fa_write: نسخه‌ی راست‌به‌چپِ Write() که فقط ترتیبِ سطحِ بالا را برعکس می‌کند (نه بازگشتی) تا هم افکتِ اصیلِ دست‌نویسی حفظ شود، هم هایلایت‌ها سالم بمانند.

چرا هیچ‌جا arabic_reshaper/python-bidi استفاده نشده؟

با رندرِ واقعی و بررسیِ OCR ثابت شد که موتور متنِ خودِ مانیم (Pango + HarfBuzz) کاملاً از الگوریتم دوجهته‌ی یونیکد و اتصالِ حروفِ فارسی/عربی پشتیبانی می‌کند. اضافه‌کردنِ این کتابخانه‌ها باعثِ «پردازشِ دوباره» و درنتیجه به‌هم‌ریختنِ حروف می‌شود.

چرا fa_write به‌جای Write(reverse=True) مستقیم؟

Write(reverse=True) خودِ مانیم از mobject.invert(recursive=True) استفاده می‌کند که ترتیبِ همه‌ی سطوحِ تودرتو را برعکس می‌کند، نه فقط سطحِ بالا. این باعث می‌شد بلوکِ ادغام‌شده‌ی هایلایت (جعبه + حروفش، که در FaText عمداً در یک VGroup قرار می‌گیرند) از داخل هم برعکس شود و جعبه از متنِ خودش جدا بیفتد. به همین دلیل fa_write از یک زیرکلاسِ کوچک استفاده می‌کند که فقط ترتیبِ سطحِ بالا را برعکس می‌کند (نه بازگشتی)، تا ترتیبِ داخلیِ هر هایلایت (جعبه، سپس حروفش) همیشه دست‌نخورده بماند.

اجرای تست‌ها

pip install pytest
pytest tests/

مثال‌ها

پوشه‌ی examples/ شامل چند صحنه‌ی نمونه است:

cd examples
manim -pql demo.py Demo
manim -pql demo_formatting.py FormattingShowcase
manim -pql demo_comparison.py Comparison

محدودیت‌های شناخته‌شده

  • translit_to_fa یک تبدیلِ تقریبی است (بالا توضیح داده شد).
  • نشانه‌های قالب‌بندی (**, *, __, ==) با هم تودرتو پشتیبانی نمی‌شوند (مثلاً بولدِ ایتالیک).
  • ترکیبِ چند عبارتِ لاتین/عددیِ متوالی داخلِ یک جمله‌ی فارسی، طبقِ خودِ الگوریتمِ دوجهته‌ی یونیکد می‌تواند رفتارِ ظریفی داشته باشد. (جمله‌هایی که با حرفِ لاتین شروع می‌شوند از نسخهٔ ۱٫۲٫۰ درست چیده می‌شوند؛ بالا ببینید.)
  • ترتیبِ نوشتنِ fa_write برای خط‌های مخلوط بر اساسِ تطبیقِ «حرف با نویسه» است. اگر تطبیق ممکن نباشد (مثلاً برخی عبارت‌های عربی با لیگاتورهای خاص)، همان راست‌به‌چپِ ساده به‌کار می‌رود.
  • در literal=True، جای نشانه‌های خنثی (*، =) کنارِ حرفِ لاتین طبقِ الگوریتمِ دوجهتهٔ یونیکد ممکن است جابه‌جا دیده شود.

سازگاری

با Manim Community v0.18.1، v0.19.0 و v0.21.0 و ManimPango 0.6.1 (روی لینوکس، Python 3.12) با رندرِ واقعی تست شده است. ۲۷۵ تستِ غیرشبکه‌ایِ manim-fa-chemistry هم با آن می‌گذرد. (ویندوز و مک آزمایش نشده‌اند.)

مجوز

این پروژه تحت مجوز MIT منتشر می‌شود. ساخته‌شده توسط علی تابش برای جامعه‌ی فارسی‌زبانِ Manim.

🤝 مشارکت

Pull Request یا Issue خوش‌آمد است.

Release files for manim-fa 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for manim-fa 1.2.0
File Size Uploaded
manim_fa-1.2.0.tar.gz 232.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for manim-fa 1.2.0
File Interpreter ABI Platform
manim_fa-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 399.2 kB

Release files / manim_fa-1.2.0.tar.gz

Download URL manim_fa-1.2.0.tar.gz
Size 232.9 kB
Tags Source
SHA-256 checksum
How to use checksums
428e3de971277ddcb92305c7504843ce97d48293e8c43558208c125279f17bc7
BLAKE2b-256 checksum
How to use checksums
76bf39a549be60d48b27698bc0f8a080e7c6a8d8aa2ecea03a3c8cfb785836ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / manim_fa-1.2.0-py3-none-any.whl

Download URL manim_fa-1.2.0-py3-none-any.whl
Size 166.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4034903bfa3c4600c3ac11d9ddec94037e73bb143767a021850f90075bf36799
BLAKE2b-256 checksum
How to use checksums
42eb56738c37839163c11cae65fdfb075df8f7f8dd4e3a998f08dd25aa71d380
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.1

2 release files

0.3.6

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.2.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page