الجداول العادية في تخفيض السعر


الجداول تخفيض السعر هي الجهنمية:


  1. لا يمكنك كتابة نص في خلايا أطول من كلمتين ، وحتى قائمة أقل.
  2. إذا سمحت لهجة الفقرة 1 ، فمن غير المناسب التنسيق.
  3. إذا لم تتم محاذاة الخلايا ، فلن يمكن قراءة الجدول.
  4. لا يوجد دعم للجداول من نفس النوع والأتمتة ، مثل ترقيم الأسطر.

لقد حان الوقت لكتابة مرشح لـ Pandoc يرسم جداول من YAML المهيكل ، مع ترقيم الصف ، والاتجاه الأفقي ، وأنماط الرسم البياني ، وفي الوقت نفسه معرفة كيفية كتابة عوامل تصفية Lua.


عادة ما أكتب النصوص في تخفيض السعر وتحويلها إلى التنسيق الهدف باستخدام Pandoc. هذا هو البرنامج الذي يحول المستندات بين التنسيقات ، على سبيل المثال ، من Markdown يمكنك الحصول على HTML ولهجة أخرى من MD و DOCX و PDF (أكثر من 30 إدخال وأكثر من 50 تنسيق إخراج). يحتوي Pandoc Markdown على العديد من الإضافات الملائمة للروابط والحواشي والتوقيعات والصيغ.


يعمل Pandoc بمثابة تركيبة للوظائف (كان من المفترض أن يكون مكتوبًا في Haskell): تنسيق إدخال محدد ← تمثيل مجردة للمستند ← تنسيق إخراج محدد. يمكن تعديل تمثيل مجردة باستخدام مرشحات مكتوبة في لوا. لا تحتاج المرشحات إلى معرفة تنسيق الإخراج ، لكن يمكنهم أخذها في الاعتبار.


سيبحث عامل التصفية الخاص بنا عن كتل مجردة من التعليمات البرمجية في table اللغة الشرطية في تمثيل الملخص ، وقراءة YAML بداخلها وإنشاء تمثيلات مجردة للجداول التي ستنتجها Pandoc بنفسها في التنسيق الهدف.


 pandoc --lua-filter table.lua input.md -o output.html 

ما هي البدائل ولماذا هي أسوأ؟


  • الجداول HTML تعمل فقط في تخفيض السعر ويتم تحويلها فقط إلى HTML ؛ يتم حل مشكلة التنسيق الغني في الخلايا فقط.
  • تتطلب مولدات الجدول التبديل من محرر نصوص ؛ من غير المناسب تحرير محتويات الخلايا الموجودة فيها ( مثال ).
  • الإضافات المحررة ( Emacs Org-Mode ، الإضافات VIM ) ليست عالمية وغير متوفرة دائمًا.

في المقابل ، pandoc-crossref وجميع الكعك Pandoc مع عامل التصفية لجداول الملخص. يمكن استخدام المرشح أيضًا لإنشاء جداول Markdown قياسية عن طريق تحديد تنسيق الإخراج المناسب. من العيوب:


  • لا يمكن دمج الخلايا ؛ لا يدعم Pandoc هذا (حتى الآن).
  • للجداول الأفقية ، يجب أن يتم الأسلوب باستخدام تنسيق الإخراج ، على سبيل المثال ، من خلال CSS.

يتضمن وصف الجدول ثلاثة أجزاء:


  1. هيكل الجدول


    قائمة مرتبة من الرسوم البيانية (الأعمدة):


    • كحد أدنى ، يجب أن يكون العمود عنوان.
    • حتى تتمكن من إعادة ترتيب الأعمدة دون لمس البيانات ، يجب تحديد سمة السجل المعروضة في العمود ( id ).
    • لا تملك الأعمدة الخاصة معرّفًا ، لكن لها وصفًا لكيفية ملؤها. تحتاج أولاً إلى رقم تسلسلي (رقم special: number ).
    • محاذاة العمود ( align ).

    أيضا ، يمكن أن يكون الجدول عمودي أو أفقي ( orientation ). في الحالة الأخيرة ، ستكون الرسوم البيانية عبارة عن صفوف.


  2. خصائص الجدول: معرف الروابط ( id ) والتوقيع ( caption ). يتيح لك Pandoc توقيع الجداول ، ولكن ليس كتل التعليمات البرمجية.


  3. البيانات في شكل مجموعة من القواميس YAML.



يمكن أن تكون البنية شائعة في العديد من الجداول ، بحيث يمكنك وصفها مباشرة مع الجدول ، ومرة ​​واحدة في البيانات الأولية (المادة الأمامية) ، ثم الرجوع إلى القالب المحدد.


خطة التنفيذ:


  1. من البيانات الأولية للوثيقة ، نشكل قاموسًا للقوالب.


  2. لكل كتلة من التعليمات البرمجية مع table الفصل الدراسي:


    1. نحن تحليل الجداول YAML.
    2. إذا تم تحديد قالب ، فإننا نأخذه من القاموس ، وإلا فإننا نملأ القالب من YAML.
    3. نحن نملأ الخصائص الفردية للجدول من YAML.
    4. نقوم بتكوين إدخالات الجدول من YAML (السجل عبارة عن صف في جدول عادي أو عمود في عمود أفقي).
    5. نحن "نرسم" جدولًا وفقًا للقالب والخصائص والسجلات.


يتم تنفيذ المستوى العلوي كما هو مكتوب (كل رمز متاح في الرابط في نهاية المقال):


 function Pandoc(doc) local meta_templates = doc.meta['table-templates'] if meta_templates then for name, value in pairs(meta_templates) do templates[name] = parse_template(value) end end local blocks = pandoc.walk_block(pandoc.Div(doc.blocks), { CodeBlock = create_table }) return pandoc.Pandoc(blocks, doc.meta) end 

تقوم parse_template() بتحويل تنسيق البيانات parse_template() قليلاً. يمثل Pandoc قيمهم MetaBlock و MetaInline . إما أن يتم إنشاء خطوط بسيطة pandoc.utils.stringify() (على سبيل المثال ، الاتجاه) ، أو العناصر المرئية (على سبيل المثال ، كتلة نص في عنوان العمود).


حول تصحيح الأخطاء. هناك العديد من الأمثلة في وثائق Pandoc ، لكن الأنواع ليست مفصلة للغاية. بالنسبة لعوامل تصفية الأخطاء ، من الملائم الحصول على وظيفة تفريغ متغيرة. تقوم المكتبات الجادة بطباعة الكثير من التفاصيل ، أفضل أحد الخيارات البسيطة.


وظائف لتحويل البيانات الأولية إلى عناصر الوثيقة
 local function to_inlines(content) if content == nil then return {} elseif type(content) == 'string' then return {pandoc.Str(content)} elseif type(content) == 'number' then return to_inlines(tostring(content)) elseif content.t == 'MetaInlines' then inlines = {} for i, item in ipairs(content) do inlines[i] = item end return inlines end end local function to_blocks(content) if (type(content) == 'table') and content.t == 'MetaBlocks' then return content else return {pandoc.Plain(to_inlines(content))} end end 

يتم create_table() الدالة create_table() لكل كتلة من التعليمات البرمجية في backtics الثلاثي.


نحن مهتمون فقط بكتل الشفرة "بلغة" table :


 if not contains('table', block.classes) then return block end 

لتحليل YAML داخل كتلة تعليمات برمجية ، نقوم بإنشاء مستند يتكون فقط من بيانات YAML الأولية ، وتحليلها مع Pandoc وترك البيانات الأولية فقط:


 local meta = pandoc.read('---\n' .. block.text .. '\n---').meta 

بعد ذلك ، من التعريف meta ارتباط إلى قالب أو بنية جدول وخصائص جدول معين.


تقرأ الدالة fill_table() من بيانات التعريف في السمات المحددة في وصف الرسم البياني. في نفس المرحلة ، إذا تم وضع علامة العمود على أنه خاص ، فسيتم إنشاء محتوياته:


 local data = {} for i, serie in ipairs(template.series) do if serie.special == 'number' then data[i] = to_blocks(#datum + 1) else data[i] = to_blocks(item[serie.id]) end end 

تشكل الدالة format_table() صفيف الخلايا الناتج وفقًا لاتجاه الجدول وتقوم بإنشاء كائن جدول تجريدي. تجدر الإشارة إلى أنه إذا كان يجب تعيين العروض أو الرؤوس لجميع الأعمدة أو لا شيء ، وإلا فلن يقوم Pandoc ببساطة بإنشاء جدول.


يمكنك وضع البرنامج النصي النهائي في ~/.local/share/pandoc ( دليل بيانات ~/.local/share/pandoc ) للوصول إليه بالاسم من أي مكان.


PS


حول محاسبة عوامل تصفية تنسيق الإخراج. على سبيل المثال ، أنا أكتب المفسدين في Pandoc مثل هذا:


 ::: {.spoiler title=""}  . ::: 

لا يوجد مفسدون في نموذج مستند Pandoc ، لذلك يجب أن ينتج المرشح كتلًا خامسة بالطريقة التالية تقريبًا. بالطبع ، يجب أن تأخذ الشفرة الحقيقية ( spoiler.lua ) في الاعتبار تنسيق الإخراج من خلال متغير FORMAT ، وليس ميكانيكيا: الجزء أدناه ينتج كتل أولية في HTML ، على الرغم من أن تنسيق الإخراج هو تخفيض السعر.


 function Div(el) if not el.attr or not contains('spoiler', el.attr.classes) then return el end local title = el.attr.attributes['title'] or '' table.insert(el.content, 1, pandoc.RawBlock('html', '<' .. 'spoiler title="' .. title .. '">', 'RawBlock')) table.insert(el.content, pandoc.RawBlock('html', '<' .. '/spoiler>', 'RawBlock')) return el.content end 

مراجع


Source: https://habr.com/ru/post/ar474826/


All Articles