% -------------------------------------------------------------------------- % Package: styleitems % Version: v1.0 (2025-08-13) % -------------------------------------------------------------------------- % Author: Faris Hameed % Email: classsec81@gmail.com % Requires: XeLaTeX or LuaLaTeX % License: LaTeX Project Public License (LPPL) v1.3c or later % -------------------------------------------------------------------------- % % Description: % styleitems provides an independent auto-numbering system with % TikZ-based decorative labels. Unlike 'enumitem', this package is % fully self-contained and designed for creating highly customizable % list markers, including geometric shapes, arrows, stars, and callouts. % % Features: % • Independent counters per nesting level (no interference between lists). % • TikZ-drawn shapes with adjustable colors, sizes, and line styles. % • Vertical (multi-line) and inline numbering modes. % • Compatible with Arabic (bidi) and Latin scripts. % • Simple commands for defining and reusing label styles. % • Supports unlimited nesting depth via an internal counter stack. % % Requirements: % • tikz % • xparse % • etoolbox % • xcolor % • bidicontour % • graphicx % % Usage: % \usepackage{styleitems} % % Basic example: % \begin{AutoCircleList}[blue][arabic] % \MSAutoLine{First item} % \MSAutoLine{Second item} % \end{AutoCircleList} % % Nested example: % \begin{AutoCircleList}[blue][arabic] % \MSAutoLine{Outer item one} % \begin{AutoStarList}[Gold][aralph] % \MSAutoLine{Inner item one} % \MSAutoLine{Inner item two} % \end{AutoStarList} % \MSAutoLine{Outer item two} % ← correctly continues from 2 % \end{AutoCircleList} % % Numbering styles: % arabic | indic | alph | Alph | roman | Roman | aralph | aralphabjad % % -------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{styleitems}[2025-08-13 v1.0 Independent numbering + TikZ (nested fix)] % =========================== % [§1] REQUIRED PACKAGES % ---------------------------- % tikz : رسم الأشكال الهندسية (دائرة، نجمة، سهم...) % xcolor : دعم الألوان بأسماء SVG و X11 و dvipsnames % xparse : تعريف بيئات وأوامر بمعاملات اختيارية متعددة % etoolbox : أدوات برمجية مساعدة (ifstrequal...) % bidicontour : إضافة حدود بيضاء حول النص داخل الشكل % graphicx : تدوير وتحجيم النص (\rotatebox, \scalebox) % =========================== \RequirePackage{tikz} \usetikzlibrary{shapes.geometric,shapes.misc,shapes.callouts,shapes.arrows} % shapes.geometric : مضلعات منتظمة (مثلث، خماسي، سداسي...) % shapes.misc : أشكال متنوعة (نجمة، مستطيل مدوّر...) % shapes.callouts : فقاعات الكلام (ellipse callout, cloud callout) % shapes.arrows : أشكال الأسهم (single arrow) \RequirePackage[svgnames,dvipsnames,x11names]{xcolor} \RequirePackage{xparse} \RequirePackage{etoolbox} \RequirePackage[outline]{bidicontour} \RequirePackage{graphicx} % =========================== % [§2] STROKE (BIDICONTOUR) SETUP % ---------------------------- % bidicontour يرسم نسخاً متعددة من النص حول المركز % لإنشاء تأثير "حدود بيضاء" حول الأرقام داخل الأشكال % بديلاً عن \textcontour لأنه يدعم النصوص العربية (RTL) % % \bidicontourlength : سُمك الحد (0.2pt = رفيع جداً وغير مبالغ به) % \bidicontournumber : عدد النسخ الموزّعة على الدائرة (42 = ناعم) % =========================== \bidicontourlength{0.2pt} \bidicontournumber{42} % =========================== % [§3] RTL/LTR DIRECTION WRAPPERS % ---------------------------- % \TeXXeTstate=1 : يُفعّل وضع TeX--XeT الذي يدعم تغيير اتجاه النص % \LR{} : يجبر النص على الاتجاه من اليسار لليمين (للأرقام اللاتينية) % \RL{} : يجبر النص على الاتجاه من اليمين لليسار (للأرقام العربية) % % ملاحظة: \providecommand تتحقق أولاً هل الأمر معرّف مسبقاً، % إن كان كذلك لا تُعيد تعريفه (تجنباً لتعارض مع حزم bidi أخرى) % =========================== \TeXXeTstate=1 \providecommand{\LR}[1]{\beginL #1\endL} \providecommand{\RL}[1]{\beginR #1\endR} % =========================== % [§4] NAMED COLORS (CUSTOM DEFINITIONS) % ---------------------------- % هذه الألوان غير موجودة في xcolor بالاسم الدقيق أو تختلف قيمها، % لذا نعرّفها يدوياً بقيم RGB محددة. % \providecolor : تعريف اللون فقط إن لم يكن معرّفاً مسبقاً % % RawSienna : بني-برتقالي داكن → للمستطيلات (افتراضي) % DeepSkyBlue : أزرق سماوي فاتح → للمربعات والخماسيات (افتراضي) % ForestGreen : أخضر غابة → للسداسيات والأسهم لأعلى (افتراضي) % Crimson : أحمر قرمزي → للمثلثات والأسهم لأسفل (افتراضي) % Orange : برتقالي → للنجوم والأسهم لليمين (افتراضي) % Purple : بنفسجي → للأشكال الثمانية والأسهم لليسار (افتراضي) % =========================== \providecolor{RawSienna} {rgb}{0.78,0.38,0.08} \providecolor{DeepSkyBlue}{rgb}{0.00,0.75,1.00} \providecolor{ForestGreen}{rgb}{0.13,0.55,0.13} \providecolor{Crimson} {rgb}{0.86,0.08,0.24} \providecolor{Orange} {rgb}{1.00,0.65,0.00} \providecolor{Purple} {rgb}{0.50,0.00,0.50} \makeatletter % ملاحظة: \makeatletter يجعل الرمز @ صالحاً في أسماء الأوامر الداخلية % جميع الأوامر التي تبدأ بـ \SI@ هي أوامر داخلية خاصة بالحزمة % =========================== % [§5] NESTING INDENT CONTROL % ---------------------------- % \SI@nestindent : المسافة التي تُزاح بها كل قائمة متداخلة لليسار % القيمة الافتراضية 0.3cm لكل مستوى تداخل % % للتعديل من ملف المستخدم: % \SISetNestedIndent{0.5cm} ← قبل بدء القائمة % =========================== \newdimen\SI@nestindent \SI@nestindent=0.3cm \newcommand{\SISetNestedIndent}[1]{\SI@nestindent=#1\relax} % =========================== % [§6] COUNTER + NESTING STACK % ---------------------------- % المشكلة: عداد واحد مشترك يتلف عداد القائمة الأب عند دخول قائمة فرعية % % الحل: نظام "مكدس" (Stack) بسيط باستخدام مستوى التداخل كمفتاح % % SInum : العداد الرئيسي للترقيم (يُعاد تصفيره لكل قائمة جديدة) % \SI@nestlevel : مستوى التداخل الحالي (يزيد عند الدخول، ينقص عند الخروج) % % آلية الحفظ والاسترجاع: % عند بدء قائمة جديدة (\SI@beginlist): % 1. زيادة \SI@nestlevel بمقدار 1 % 2. حفظ قيمة SInum الحالية في \SI@saved@<المستوى> % 3. تصفير SInum للقائمة الجديدة % % عند إنهاء القائمة (\SI@endlist): % 1. استرجاع قيمة SInum من \SI@saved@<المستوى> % 2. تقليل \SI@nestlevel بمقدار 1 % % مثال على التداخل: % قائمة خارجية (مستوى 1): SInum=2 → حُفظ في SI@saved@1 % قائمة داخلية (مستوى 2): SInum=0,1,2,3 % عودة للخارجية: SInum يُستعاد = 2 ← يكمل من حيث توقف ✓ % =========================== \newcounter{SInum} \newcount\SI@nestlevel \SI@nestlevel=0 % ---- بدء قائمة جديدة: حفظ العداد الأب + تصفير + إنشاء بيئة list ---- % المعامل #1: المسافة العمودية بين العناصر (itemsep) % المعامل #2: لون الشكل الذي يُخزَّن في \SI@color \newcommand\SI@beginlist[2]{% \advance\SI@nestlevel by 1\relax % حفظ قيمة العداد الحالية في اسم ديناميكي: SI@saved@1, SI@saved@2, ... \expandafter\xdef\csname SI@saved@\the\SI@nestlevel\endcsname {\the\value{SInum}}% \setcounter{SInum}{0}% % إنشاء بيئة list بإعدادات مخصصة (بدون تسميات تلقائية) \begin{list}{}{% \labelwidth=0pt \labelsep=0pt % حساب الإزاحة اليسرى بناءً على عمق التداخل \ifnum\@listdepth>0\relax \leftmargin=\dimexpr\numexpr\@listdepth\relax\SI@nestindent\relax \else \leftmargin=0pt \fi \itemindent=0pt \listparindent=0pt \itemsep=#1\relax \parsep=0pt \topsep=0pt \partopsep=0pt }% \def\SI@color{#2}% } % ---- إنهاء القائمة: استرجاع العداد الأب + تقليل المستوى ---- \newcommand\SI@endlist{% \end{list}% \setcounter{SInum}{\csname SI@saved@\the\SI@nestlevel\endcsname}% \advance\SI@nestlevel by -1\relax } % =========================== % [§7] NUMBERING STYLE SELECTOR % ---------------------------- % \SI@setstyle{<نمط>} يُعيّن: % \SI@print : الأمر الذي يطبع الرقم (يختلف حسب النمط) % \SI@wrap : غلاف الاتجاه (\LR أو \RL حسب اللغة) % % الأنماط المتاحة: % arabic → 1, 2, 3 ... (لاتيني، LR) % indic → ١, ٢, ٣ ... (عربي-هندي، RL) % alph → a, b, c ... (لاتيني صغير، LR) % Alph → A, B, C ... (لاتيني كبير، LR) % roman → i, ii, iii ... (روماني صغير، LR) % Roman → I, II, III ... (روماني كبير، LR) % aralph → أ, ب, ت ... (هجائي) (عربي، RL) % aralphabjad → أ, ب, ج ... (أبجدي) (عربي، RL) % % طريقة المقارنة: \ifx يقارن بين \SI@code والنمط المطلوب % (لا يمكن استخدام \ifstrequal هنا لأن المتغيرات مُوسّعة) % =========================== \newcommand\SI@setstyle[1]{% \def\SI@code{#1}% % الإعداد الافتراضي: أرقام عربية، اتجاه LR \def\SI@wrap##1{\LR{##1}}% \let\SI@print\SI@printArabic % تعريف ثوابت للمقارنة \def\C@arabic {arabic}% \def\C@indic {indic}% \def\C@alph {alph}% \def\C@Alph {Alph}% \def\C@roman {roman}% \def\C@Roman {Roman}% \def\C@aralph {aralph}% \def\C@aralphabjad{aralphabjad}% \ifx\SI@code\C@indic \def\SI@wrap##1{{\arabicfont\RL{##1}}}\let\SI@print\SI@printIndic \fi \ifx\SI@code\C@alph \let\SI@print\SI@printAlph \fi \ifx\SI@code\C@Alph \let\SI@print\SI@printALPH \fi \ifx\SI@code\C@roman \let\SI@print\SI@printRoman \fi \ifx\SI@code\C@Roman \let\SI@print\SI@printROMAN \fi \ifx\SI@code\C@aralph \def\SI@wrap##1{{\arabicfont\RL{##1}}}\let\SI@print\SI@printArHijai \fi \ifx\SI@code\C@aralphabjad \def\SI@wrap##1{{\arabicfont\RL{##1}}}\let\SI@print\SI@printArAbjad \fi } % =========================== % [§8] NUMBER PRINTERS % ---------------------------- % كل أمر \SI@printXxx يطبع قيمة SInum بالتنسيق المناسب % \SI@curr : اختصار لـ \number\value{SInum} (القيمة الرقمية الخام) % =========================== \newcommand{\SI@curr}{\number\value{SInum}} %--- أرقام عربية (1,2,3) --- % الأبسط: يطبع الرقم مباشرة \newcommand{\SI@printArabic}{\SI@curr} %--- أرقام عربية-هندية (١,٢,٣) --- % \SI@digitIndic : تحويل رقم واحد (0-9) إلى مقابله العربي-الهندي % \SI@printIndicInt : معالجة الأرقام متعددة الخانات بالتكرار (recursion) % \SI@printIndic : نقطة الدخول الرئيسية \newcommand{\SI@digitIndic}[1]{% \ifcase#1 ٠\or١\or٢\or٣\or٤\or٥\or٦\or٧\or٨\or٩\fi} \newcommand{\SI@printIndicInt}[1]{% \ifnum#1<10\relax \SI@digitIndic{#1}% \else \expandafter\SI@printIndicInt\expandafter{\number\numexpr #1/10\relax}% \SI@digitIndic{\number\numexpr #1-10*(#1/10)\relax}% \fi} \newcommand{\SI@printIndic}{\SI@printIndicInt{\SI@curr}} %--- حروف لاتينية صغيرة/كبيرة (a,b,c / A,B,C) --- % نظام "bijective base-26": لا يوجد صفر، بعد z تأتي aa, ab... % \SI@alphChar : يحوّل رقماً (0-25) إلى حرف لاتيني صغير % \SI@ALPHChar : يحوّل رقماً (0-25) إلى حرف لاتيني كبير % \SI@alphAux : معالجة الأرقام >26 بالتكرار \newcommand{\SI@alphChar}[1]{\char\numexpr`a+#1\relax} \newcommand{\SI@ALPHChar}[1]{\char\numexpr`A+#1\relax} \newcommand{\SI@alphAux}[1]{% \ifnum#1>26\relax \expandafter\SI@alphAux\expandafter{\number\numexpr(#1-1)/26\relax}% \fi \SI@alphChar{\number\numexpr(#1-1)-26*((#1-1)/26)\relax}} \newcommand{\SI@ALPHAux}[1]{% \ifnum#1>26\relax \expandafter\SI@ALPHAux\expandafter{\number\numexpr(#1-1)/26\relax}% \fi \SI@ALPHChar{\number\numexpr(#1-1)-26*((#1-1)/26)\relax}} \newcommand{\SI@printAlph}{\SI@alphAux{\SI@curr}} \newcommand{\SI@printALPH}{\SI@ALPHAux{\SI@curr}} %--- أرقام رومانية صغيرة/كبيرة (i,ii / I,II) --- % \romannumeral : أمر TeX مدمج يحوّل الرقم لروماني صغير % \uppercase : يحوّل النتيجة لحروف كبيرة % ? : يُطبع عند SInum=0 (لم يبدأ العد بعد) \newcommand{\SI@printRoman}{% \ifnum\value{SInum}<1 ?\else\romannumeral\value{SInum}\fi} \newcommand{\SI@printROMAN}{% \ifnum\value{SInum}<1 ?\else \uppercase\expandafter{\romannumeral\value{SInum}}\fi} %--- حروف عربية هجائية (أ,ب,ت,ث...) --- % الترتيب الهجائي هو الترتيب الأبجدي المعتاد في المعاجم العربية الحديثة % نظام bijective base-28 (28 حرفاً عربياً) \newcommand{\SI@ArHijai}[1]{% \ifcase#1 ?\or أ\or ب\or ت\or ث\or ج\or ح\or خ\or د\or ذ\or ر\or ز\or س\or ش\or ص\or ض\or ط\or ظ\or ع\or غ\or ف\or ق\or ك\or ل\or م\or ن\or هـ\or و\or ي% \else ?\fi} %--- حروف عربية أبجدية (أ,ب,ج,د...) --- % الترتيب الأبجدي هو الترتيب التاريخي القديم (أبجد هوز...) \newcommand{\SI@ArAbjad}[1]{% \ifcase#1 ?\or أ\or ب\or ج\or د\or هـ\or و\or ز\or ح\or ط\or ي\or ك\or ل\or م\or ن\or س\or ع\or ف\or ص\or ق\or ر\or ش\or ت\or ث\or خ\or ذ\or ض\or ظ\or غ% \else ?\fi} % \SI@modXXVIII : باقي القسمة على 28 (للتعامل مع الأرقام >28) % \SI@hijAux / \SI@abjAux : معالجة الأرقام الكبيرة بالتكرار \newcommand{\SI@modXXVIII}[1]{\number\numexpr #1-28*(#1/28)\relax} \newcommand{\SI@hijAux}[1]{% \ifnum#1>27\relax \expandafter\SI@hijAux\expandafter{\number\numexpr #1/28-1\relax}% \fi \SI@ArHijai{\number\numexpr\SI@modXXVIII{#1}+1\relax}} \newcommand{\SI@abjAux}[1]{% \ifnum#1>27\relax \expandafter\SI@abjAux\expandafter{\number\numexpr #1/28-1\relax}% \fi \SI@ArAbjad{\number\numexpr\SI@modXXVIII{#1}+1\relax}} \newcommand{\SI@printArHijai}{% \ifnum\value{SInum}<1 ?\else \SI@hijAux{\number\numexpr\value{SInum}-1\relax}\fi} \newcommand{\SI@printArAbjad}{% \ifnum\value{SInum}<1 ?\else \SI@abjAux{\number\numexpr\value{SInum}-1\relax}\fi} % =========================== % [§9] STROKE HELPER % ---------------------------- % \SI@Stroke{<نص>} يُضيف هالة بيضاء حول النص لتمييزه عن خلفية الشكل % % الآلية: % 1. يُعيّن اللون إلى أبيض % 2. يستدعي \bidicontour{white}{النص} الذي يرسم % 42 نسخة من النص موزّعة حول الأصل بمقدار 0.2pt % 3. النتيجة: تأثير "outline" أبيض ناعم حول الرقم % % ملاحظة: \begingroup...\endgroup لعزل تغيير اللون % حتى لا يؤثر على النص الخارجي % =========================== \newcommand{\SI@Stroke}[1]{% \begingroup \color{white}% \bidicontour{white}{#1}% \endgroup } % =========================== % [§10] ROTATE / SCALE CONTROLS % ---------------------------- % هذه الأوامر تتحكم في مظهر النص داخل الشكل: % % \SI@rot : زاوية دوران النص (الافتراضي: 0 = بدون دوران) % \SI@scale : معامل تحجيم النص (الافتراضي: 1 = الحجم الأصلي) % % للتعديل من ملف المستخدم (قبل بدء القائمة): % \SISetTextRotate{45} ← نص مائل 45 درجة % \SISetTextScale{1.5} ← نص أكبر بـ 50% % % أو مباشرة في معاملات البيئة: % \begin{AutoCircleList}[red][arabic][45][1.2] % =========================== \def\SI@rot{0} \def\SI@scale{1} \newcommand{\SISetTextRotate}[1]{\def\SI@rot{#1}} \newcommand{\SISetTextScale} [1]{\def\SI@scale{#1}} % =========================== % [§11] LABEL TEXT RENDERER % ---------------------------- % \SI@RenderLabelText : يُجمّع كل تحولات النص في تسلسل صحيح: % % 1. \rotatebox{\SI@rot}{...} ← يُدير النص حول مركزه % 2. \scalebox{\SI@scale}{...} ← يُحجّم النص % 3. \SI@Stroke{...} ← يُضيف الحد الأبيض (§9) % 4. \SI@wrap{\SI@print} ← يطبع الرقم بالاتجاه والنمط الصحيح % % ترتيب التطبيق مهم: التحجيم يأتي قبل الدوران لنتائج متوقعة % =========================== \newcommand{\SI@RenderLabelText}{% \rotatebox{\SI@rot}{% \scalebox{\SI@scale}{% \SI@Stroke{\SI@wrap{\SI@print}}% }% }% } % =========================== % [§12] LABEL SHAPES (TikZ DRAWINGS) % ---------------------------- % كل شكل يتكون من عقدتين (nodes) داخل بيئة tikz: % % العقدة (b) : الشكل الهندسي (فارغ من النص) % مسماة بـ (b) لاستخدامها كمرجع للعقدة الثانية % % العقدة الثانية : النص (الرقم) مرسوم فوق مركز الشكل % at (b.center) تضمن أن النص دائماً في المنتصف % % baseline : يُحدد كيفية محاذاة الشكل مع سطر النص المجاور % [yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax] % → هذه الصيغة الرياضية تضمن أن مركز الشكل يُحاذي منتصف % ارتفاع السطر بدقة 100%، بدلاً من القيم اليدوية التقريبية % % \SI@color!70!black : لون الحدود = 70% من لون الشكل + 30% أسود % يُعطي تأثير ظل خفيف للحدود % \SI@color!60!black : نسبة أكثر قتامة للحدود (للأشكال الأخرى) % =========================== %--- Circle (دائرة) --- % minimum size : قطر الدائرة = 0.6cm \newcommand{\SI@LabelCircle}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[circle, draw=\SI@color!70!black, fill=\SI@color, line width=1pt, minimum size=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[anchor=center] at (b.center){% \bfseries\fontsize{12pt}{7pt}\selectfont\SI@RenderLabelText}; }% } %--- Star 5-point (نجمة خماسية) --- % star point ratio=2.2 : نسبة طول رأس النجمة / نصف قطر الحلقة الداخلية % minimum size=0.85cm : أكبر من الدائرة لأن النجمة تحتاج مساحة أوسع \newcommand{\SI@LabelStar}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[star, star points=5, star point ratio=2.2, draw=\SI@color!60!black, fill=\SI@color, line width=0.75pt, minimum size=0.85cm, inner sep=0pt, outer sep=0pt ](b){}; \node[anchor=center] at (b.center){% \bfseries\fontsize{12pt}{7pt}\selectfont\SI@RenderLabelText}; }% } %--- Diamond (معين) --- % minimum width/height غير متساويين → شكل معين ممدود أفقياً \newcommand{\SI@LabelDiamond}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[diamond, draw=\SI@color!70!black, fill=\SI@color, line width=1pt, minimum width=0.8cm, minimum height=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Rectangle rounded (مستطيل بزوايا مدوّرة) --- % rounded corners=2pt : تدوير خفيف لزوايا المستطيل % الأبعاد 0.7cm × 0.6cm : غير متساوية → شكل مستطيل وليس مربعاً \newcommand{\SI@LabelRectangle}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[rounded corners=2pt, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum width=0.7cm, minimum height=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Square (مربع) --- % بدون rounded corners → زوايا حادة % minimum size=0.6cm : متساوي الأبعاد (مربع) \newcommand{\SI@LabelSquare}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum size=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Hexagon (سداسي منتظم) --- % regular polygon sides=6 : سداسي منتظم % minimum size=0.6cm : قطر الدائرة المحيطة \newcommand{\SI@LabelHexagon}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[regular polygon, regular polygon sides=6, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum size=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Octagon (ثماني منتظم) --- % regular polygon sides=8 : ثماني منتظم (شكل علامة التوقف) \newcommand{\SI@LabelOctagon}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[regular polygon, regular polygon sides=8, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum size=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Star 12-point (نجمة ثنائية عشر) --- % star points=12 : نجمة بـ 12 رأساً % minimum size=0.90cm : أكبر من النجمة الخماسية \newcommand{\SI@LabelStarTwelve}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[star, star points=12, star point ratio=2.2, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum size=0.90cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Triangle (مثلث متساوي الأضلاع) --- % regular polygon sides=3 : مثلث منتظم % minimum size=0.85cm : أكبر لأن المثلث يبدو أصغر بصرياً \newcommand{\SI@LabelTriangle}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[regular polygon, regular polygon sides=3, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum size=0.85cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Pentagon (خماسي منتظم) --- % regular polygon sides=5 : خماسي منتظم (يختلف عن النجمة) \newcommand{\SI@LabelPentagon}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[regular polygon, regular polygon sides=5, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum size=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Ellipse Callout Right (فقاعة بيضاوية - ذيل لليمين) --- % callout relative pointer={(0.2,-0.1)} : موضع الذيل نسبياً للشكل % (0.2, ): يمين المركز % (-0.1) : أسفل قليلاً → ذيل يميني سفلي \newcommand{\SI@LabelEllipseCalloutRight}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[ellipse callout, callout relative pointer={(0.2,-0.1)}, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum width=0.8cm, minimum height=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Ellipse Callout Left (فقاعة بيضاوية - ذيل لليسار) --- % callout relative pointer={(-0.2,-0.1)} : ذيل يساري سفلي \newcommand{\SI@LabelEllipseCalloutLeft}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[ellipse callout, callout relative pointer={(-0.2,-0.1)}, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum width=0.8cm, minimum height=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Cloud Callout Right (فقاعة سحابية - ذيل لليمين) --- % cloud callout : حواف متموجة تشبه السحابة \newcommand{\SI@LabelCloudCalloutRight}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[cloud callout, callout relative pointer={(0.2,-0.1)}, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum width=0.8cm, minimum height=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Cloud Callout Left (فقاعة سحابية - ذيل لليسار) --- \newcommand{\SI@LabelCloudCalloutLeft}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[cloud callout, callout relative pointer={(-0.2,-0.1)}, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, minimum width=0.8cm, minimum height=0.6cm, inner sep=0pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Arrow Right (سهم لليمين) --- % single arrow : شكل سهم من مكتبة shapes.arrows % single arrow head extend : طول رأس السهم = 2pt % scale=1.75 : تكبير الشكل ليكون مناسباً % inner sep=4pt : مساحة داخلية للنص (السهم يحتاج مساحة أكبر) \newcommand{\SI@LabelArrowRight}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[single arrow, single arrow head extend=2pt, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, scale=1.75, inner sep=4pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Arrow Up (سهم لأعلى) --- % rotate=90 + transform shape : يُدير الشكل كاملاً (بما فيه الرأس) 90 درجة \newcommand{\SI@LabelArrowUp}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[single arrow, single arrow head extend=2pt, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, scale=1.75, rotate=90, transform shape, inner sep=4pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Arrow Left (سهم لليسار) --- % rotate=180 : قلب السهم أفقياً \newcommand{\SI@LabelArrowLeft}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[single arrow, single arrow head extend=2pt, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, scale=1.75, rotate=180, transform shape, inner sep=4pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } %--- Arrow Down (سهم لأسفل) --- % rotate=270 : السهم نحو الأسفل (أو rotate=-90) \newcommand{\SI@LabelArrowDown}{% \tikz[baseline={([yshift=-\dimexpr(\ht\strutbox-\dp\strutbox)/2\relax]b.center)}]{% \node[single arrow, single arrow head extend=2pt, draw=\SI@color!60!black, fill=\SI@color, line width=1pt, scale=1.75, rotate=270, transform shape, inner sep=4pt, outer sep=0pt ](b){}; \node[font=\bfseries\fontsize{12pt}{7pt}\selectfont] at (b.center){% \SI@RenderLabelText}; }% } % =========================== % [§13] PUBLIC ITEM COMMANDS % ---------------------------- % هذان الأمران هما واجهة المستخدم لإضافة العناصر: % % \MSAutoLine{نص} : عنصر عمودي (سطر كامل) % 1. \stepcounter{SInum} ← زيادة العداد % 2. \item[] ← عنصر بدون تسمية تلقائية % 3. \leavevmode ← السماح بوضع TikZ في بداية العنصر % 4. \SI@Label ← رسم الشكل (المُحدد حسب البيئة) % 5. \hskip .5em ← مسافة أفقية 0.5em بين الشكل والنص % 6. #1 ← نص المستخدم % % \MSAutoInline{نص} : عنصر مضمّن (على نفس السطر مع غيره) % مشابه لـ MSAutoLine لكن بدون \item ومع فاصل أفقي بعد النص % =========================== \NewDocumentCommand{\MSAutoLine}{ m }{% \stepcounter{SInum}% \item[]\leavevmode\SI@Label\hskip .5em #1% } \NewDocumentCommand{\MSAutoInline}{ m }{% \leavevmode \stepcounter{SInum}% \SI@Label\hskip .5em #1\SI@inlinesep } % =========================== % [§14] INLINE SEPARATOR % ---------------------------- % \SI@inlinesep : المسافة بين عناصر القائمة المضمّنة % الافتراضي: 1em (مسافة واسعة لتمييز العناصر) % % للتعديل: % \SISetInlineSep{2em} ← مسافة أوسع % \SISetInlineSep{\quad} ← مسافة quad % \SISetInlineSep{,\ } ← فاصلة + مسافة % =========================== \def\SI@inlinesep{\hskip1em} \newcommand{\SISetInlineSep}[1]{\def\SI@inlinesep{#1}} % =========================== % [§15] INLINE ENVIRONMENT HELPERS % ---------------------------- % \SI@begininline : إعداد بيئة inline (مشابه لـ \SI@beginlist لكن بدون \begin{list}) % المعاملات: {لون}{نمط الترقيم}{زاوية الدوران}{معامل التحجيم} % يحفظ العداد ويُصفّره ويُعيّن كل الإعدادات % % \SI@endinline : إنهاء بيئة inline % يسترجع العداد المحفوظ ويُقلّل مستوى التداخل % % ملاحظة: البيئات المضمّنة تستخدم \begingroup...\endgroup % بدلاً من \begin{list}...\end{list} لأنها لا تحتاج سطراً جديداً % =========================== \newcommand\SI@begininline[4]{% \advance\SI@nestlevel by 1\relax \expandafter\xdef\csname SI@saved@\the\SI@nestlevel\endcsname {\the\value{SInum}}% \setcounter{SInum}{0}% \def\SI@color{#1}% \SI@setstyle{#2}% \SISetTextRotate{#3}% \SISetTextScale{#4}% } \newcommand\SI@endinline{% \setcounter{SInum}{\csname SI@saved@\the\SI@nestlevel\endcsname}% \advance\SI@nestlevel by -1\relax } % =========================== % [§16] VERTICAL LIST ENVIRONMENTS % ---------------------------- % توقيع جميع البيئات الأساسية (4 معاملات اختيارية): % [#1: لون] [#2: نمط الترقيم] [#3: دوران] [#4: تحجيم] % % مثال: % \begin{AutoCircleList} ← كل الافتراضيات % \begin{AutoCircleList}[blue] ← لون أزرق، باقي افتراضي % \begin{AutoCircleList}[red][arabic] ← أحمر + أرقام عربية % \begin{AutoCircleList}[red][arabic][45][1.2] ← مائل ومكبّر % % البيئات الخاصة بالـ Callouts (5 معاملات): % [#1: لون] [#2: نمط] [#3: اتجاه right|left] [#4: دوران] [#5: تحجيم] % % ملاحظة: #3 للـ Callouts هو الاتجاه وليس الدوران! % لذا الدوران هو #4 والتحجيم #5 (لا #3 و#4) % =========================== %--- Basic shapes (عمودية أساسية) --- \NewDocumentEnvironment{AutoCircleList}{ O{Salmon} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelCircle}% }{\SI@endlist} \NewDocumentEnvironment{AutoStarList}{ O{Orange} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelStar}% }{\SI@endlist} \NewDocumentEnvironment{AutoDiamondList}{ O{Purple} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelDiamond}% }{\SI@endlist} \NewDocumentEnvironment{AutoRectangleList}{ O{RawSienna} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelRectangle}% }{\SI@endlist} \NewDocumentEnvironment{AutoSquareList}{ O{DeepSkyBlue} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelSquare}% }{\SI@endlist} \NewDocumentEnvironment{AutoHexList}{ O{ForestGreen} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelHexagon}% }{\SI@endlist} \NewDocumentEnvironment{AutoOctagonList}{ O{Purple} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelOctagon}% }{\SI@endlist} \NewDocumentEnvironment{AutoStar12List}{ O{Orange} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelStarTwelve}% }{\SI@endlist} \NewDocumentEnvironment{AutoTriangleList}{ O{Crimson} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelTriangle}% }{\SI@endlist} \NewDocumentEnvironment{AutoPentagonList}{ O{DeepSkyBlue} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelPentagon}% }{\SI@endlist} %--- Callouts (فقاعات - بمعامل اتجاه إضافي) --- % #3 = right (افتراضي) أو left ← يُحدد جهة ذيل الفقاعة \NewDocumentEnvironment{AutoEllipseCalloutList}{ O{Orange} O{alph} O{right} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#4}\SISetTextScale{#5}% \SI@beginlist{1.2ex}{#1}% \ifstrequal{#3}{left} {\def\SI@Label{\SI@LabelEllipseCalloutLeft}}% {\def\SI@Label{\SI@LabelEllipseCalloutRight}}% }{\SI@endlist} \NewDocumentEnvironment{AutoCloudCalloutList}{ O{DeepSkyBlue} O{alph} O{right} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#4}\SISetTextScale{#5}% \SI@beginlist{1.2ex}{#1}% \ifstrequal{#3}{left} {\def\SI@Label{\SI@LabelCloudCalloutLeft}}% {\def\SI@Label{\SI@LabelCloudCalloutRight}}% }{\SI@endlist} %--- Arrows (أسهم عمودية) --- \NewDocumentEnvironment{AutoArrowRightList}{ O{Orange} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelArrowRight}% }{\SI@endlist} \NewDocumentEnvironment{AutoArrowUpList}{ O{ForestGreen} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelArrowUp}% }{\SI@endlist} \NewDocumentEnvironment{AutoArrowLeftList}{ O{Purple} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelArrowLeft}% }{\SI@endlist} \NewDocumentEnvironment{AutoArrowDownList}{ O{Crimson} O{alph} O{0} O{1} }{% \SI@setstyle{#2}\SISetTextRotate{#3}\SISetTextScale{#4}% \SI@beginlist{1.2ex}{#1}\def\SI@Label{\SI@LabelArrowDown}% }{\SI@endlist} % =========================== % [§17] INLINE ENVIRONMENTS % ---------------------------- % نفس بيئات §16 لكن للاستخدام المضمّن داخل الفقرة % الفرق الجوهري: % • تستخدم \begingroup...\endgroup بدلاً من \begin{list}...\end{list} % • \ignorespaces في البداية: يتجاهل المسافات بعد \begin{...} % • \unskip في النهاية: يُزيل المسافة الأخيرة قبل \end{...} % % توقيع البيئات الأساسية: [لون][نمط][دوران][تحجيم] % توقيع بيئات Callout: [لون][نمط][اتجاه][دوران][تحجيم] % % استخدام نموذجي: % المطلوب: % \begin{AutoCircleInline}[blue][arabic] % \MSAutoInline{أولاً} % \MSAutoInline{ثانياً} % \MSAutoInline{ثالثاً} % \end{AutoCircleInline} % =========================== %--- Basic shapes (مضمّنة أساسية) --- \NewDocumentEnvironment{AutoCircleInline}{ O{Salmon} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelCircle}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoStarInline}{ O{Orange} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelStar}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoDiamondInline}{ O{Purple} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelDiamond}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoRectangleInline}{ O{RawSienna} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelRectangle}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoSquareInline}{ O{DeepSkyBlue} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelSquare}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoHexInline}{ O{ForestGreen} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelHexagon}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoOctagonInline}{ O{Purple} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelOctagon}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoStar12Inline}{ O{Orange} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelStarTwelve}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoTriangleInline}{ O{Crimson} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelTriangle}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoPentagonInline}{ O{DeepSkyBlue} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelPentagon}\ignorespaces }{\unskip\SI@endinline\endgroup} %--- Callouts inline (فقاعات مضمّنة) --- % ملاحظة: #3=اتجاه، لذا الدوران=#4 والتحجيم=#5 \NewDocumentEnvironment{AutoEllipseCalloutInline}{ O{Orange} O{alph} O{right} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#4}{#5}% \ifstrequal{#3}{left} {\def\SI@Label{\SI@LabelEllipseCalloutLeft}}% {\def\SI@Label{\SI@LabelEllipseCalloutRight}}% \ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoCloudCalloutInline}{ O{DeepSkyBlue} O{alph} O{right} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#4}{#5}% \ifstrequal{#3}{left} {\def\SI@Label{\SI@LabelCloudCalloutLeft}}% {\def\SI@Label{\SI@LabelCloudCalloutRight}}% \ignorespaces }{\unskip\SI@endinline\endgroup} %--- Arrows inline (أسهم مضمّنة) --- \NewDocumentEnvironment{AutoArrowRightInline}{ O{Orange} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelArrowRight}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoArrowUpInline}{ O{ForestGreen} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelArrowUp}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoArrowLeftInline}{ O{Purple} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelArrowLeft}\ignorespaces }{\unskip\SI@endinline\endgroup} \NewDocumentEnvironment{AutoArrowDownInline}{ O{Crimson} O{alph} O{0} O{1} }{% \begingroup\SI@begininline{#1}{#2}{#3}{#4}% \def\SI@Label{\SI@LabelArrowDown}\ignorespaces }{\unskip\SI@endinline\endgroup} \makeatother % ملاحظة: \makeatother يُعيد @ إلى حالته الطبيعية (غير صالح في أسماء الأوامر) \endinput % \endinput : يوقف قراءة الملف هنا (أي شيء بعده يُتجاهل)