لغة قوالب calibre

لغة قوالب calibre هي لغة خاصة بـ calibre تُستخدم في جميع أنحاء calibre لمهام مثل تحديد مسارات الملفات، وتنسيق القيم، و حساب القيمة للأعمدة المحددة من قبل المستخدم. أمثلة:

  • تحديد هيكل المجلد وأسماء الملفات عند حفظ الملفات من مكتبة calibre إلى القرص أو قارئ الكتب الإلكترونية.

  • تحديد قواعد لإضافة الأيقونات والألوان إلى قائمة كتب calibre.

  • تحديد أعمدة افتراضية تحتوي على بيانات من أعمدة أخرى.

  • بحث متقدم في المكتبة.

  • بحث واستبدال متقدم للبيانات الوصفية.

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

القوالب الأساسية

يتكون القالب الأساسي من تعبير أو أكثر من تعبيرات القالب. يتكون تعبير القالب من نص وأسماء داخل أقواس معقوفة ({}) يتم استبدالها بالبيانات الوصفية المقابلة من الكتاب الذي تتم معالجته. على سبيل المثال، القالب الافتراضي في calibre المستخدم لحفظ الكتب على الجهاز يحتوي على 4 تعبيرات قالب:

{author_sort}/{title}/{title} - {authors}

بالنسبة لكتاب "المؤسسة" لـ "إسحاق أسيموف" سيصبح:

Asimov, Isaac/The Foundation/The Foundation - Isaac Asimov

الشرطات المائلة ليست تعبيرات قالب لأنها تقع بين {}. هذا النص يُترك حيث يظهر. على سبيل المثال، إذا كان القالب هو:

{author_sort} Some Important Text {title}/{title} - {authors}

فبالنسبة لـ "المؤسسة"، ينتج القالب:

Asimov, Isaac Some Important Text The Foundation/The Foundation - Isaac Asimov

يمكن لتعبير القالب الوصول إلى جميع البيانات الوصفية المتاحة في calibre، بما في ذلك الأعمدة المخصصة (الأعمدة التي تنشئها بنفسك)، باستخدام اسم البحث الخاص بالعمود. للعثور على اسم البحث لـ عمود (يُسمى أحيانًا حقول)، مرر الماوس فوق رأس العمود في قائمة كتب calibre. تبدأ أسماء البحث للأعمدة المخصصة دائمًا بـ #. بالنسبة لأعمدة نوع السلسلة، يوجد حقل إضافي يسمى #اسم_البحث_فهرس وهو فهرس السلسلة لذلك الكتاب في السلسلة. على سبيل المثال، إذا كان لديك عمود سلسلة مخصص يسمى #myseries، فسيكون هناك أيضًا عمود يسمى #myseries_index. فهرس عمود السلسلة القياسي يسمى series_index.

بالإضافة إلى الحقول المستندة إلى الأعمدة القياسية، يمكنك أيضًا استخدام:

  • {formats} - قائمة بالتنسيقات المتاحة في مكتبة calibre لـ كتاب

  • {identifiers:select(isbn)} - الرقم المعياري الدولي للكتاب (ISBN) الخاص بالكتاب

إذا لم يتم تعريف البيانات الوصفية للحقل لكتاب معين، فسيتم استبدال الحقل في القالب بسلسلة فارغة (''). على سبيل المثال، النظر في القالب التالي:

{author_sort}/{series}/{title} {series_index}

إذا كان كتاب أسيموف "المؤسسة الثانية" ضمن سلسلة "المؤسسة"، فإن القالب ينتج:

Asimov, Isaac/Foundation/Second Foundation 3

إذا لم يتم إدخال سلسلة للكتاب، فإن القالب ينتج:

Asimov, Isaac/Second Foundation

يزيل معالج القوالب تلقائيًا الشرطات المائلة المتعددة والمسافات البادئة أو اللاحقة.

تنسيق متقدم

بالإضافة إلى استبدال البيانات الوصفية، يمكن للقوالب تضمين نص إضافي بشكل شرطي والتحكم في كيفية تنسيق البيانات المستبدلة.

تضمين النص بشكل شرطي

أحيانًا ترغب في ظهور نص في الإخراج فقط إذا لم يكن الحقل فارغًا. حالة شائعة هي series و series_index حيث تريد إما لا شيء أو القيمتين مفصولتين بشرطة. يتعامل calibre مع هذه الحالة باستخدام صيغة خاصة لـ تعبير القالب.

على سبيل المثال، وباستخدام مثال المؤسسة أعلاه، افترض أنك تريد أن ينتج القالب Foundation - 3 - Second Foundation. ينتج هذا القالب هذا الإخراج:

{series} - {series_index} - {title}

ومع ذلك، إذا لم يكن للكتاب سلسلة، فسينتج القالب - - العنوان، وهو على الأرجح ليس ما تريده. بشكل عام، يريد الناس أن تكون النتيجة العنوان بدون الشرطات الزائدة. يمكنك تحقيق ذلك باستخدام صيغة القالب التالية:

{field:|نص_بادئة|نص_لاحقة}

يقول تعبير القالب هذا أنه إذا كان field يحتوي على القيمة XXXX فإن النتيجة ستكون نص_بادئةXXXXXنص_لاحقة. إذا كان field فارغًا (لا يحتوي على قيمة) فستكون النتيجة سلسلة فارغة (لا شيء) لأن البادئة واللاحقة يتم تجاهلهما. يمكن أن تحتوي البادئة واللاحقة على مسافات فارغة.

لا تستخدم القوالب الفرعية (``{ ... }``) أو الدوال (انظر أدناه) في البادئة أو اللاحقة.

باستخدام هذه الصيغة، يمكننا حل مشكلة عدم وجود سلسلة أعلاه باستخدام القالب:

{series}{series_index:| - | - }{title}

سيتم تضمين الشرطات فقط إذا كان الكتاب يحتوي على فهرس سلسلة، وهو ما يحدث فقط إذا كان يحتوي على سلسلة. استمرارًا لمثال المؤسسة مرة أخرى، سينتج القالب Foundation - 1 - Second Foundation.

ملاحظات:

  • يجب عليك تضمين النقطتين بعد اسم البحث إذا كنت تستخدم بادئة أو لاحقة.

  • يجب عليك استخدام إما لا شيء أو كلا حرفي |. استخدام حرف واحد، كما في {field:| - }، غير مسموح به.

  • لا بأس بتقديم نص فارغ للبادئة أو اللاحقة، كما في {series:|| - }. القالب {title:||} هو نفسه {title}.

التنسيق

افترض أنك تريد تنسيق series_index بثلاثة أرقام مع أصفار بادئة. هذا يؤدي الغرض:

{series_index:0>3s} - ثلاثة أرقام مع أصفار بادئة

للأصفار اللاحقة، استخدم:

{series_index:0<3s} - ثلاثة أرقام مع أصفار لاحقة

إذا كنت تستخدم فهارس سلسلة ذات قيم كسرية، على سبيل المثال، 1.1، فقد ترغب في محاذاة النقاط العشرية. على سبيل المثال، قد ترغب في ظهور الفهارس 1 و 2.5 كـ 01.00 و 02.50 بحيث يتم فرزها بشكل صحيح على جهاز يقوم بالفرز المعجمي. للقيام بذلك، استخدم:

{series_index:0>5.2f} - خمسة أحرف تتكون من رقمين مع أصفار بادئة، نقطة عشرية، ثم رقمين بعد النقطة العشرية.

إذا كنت تريد فقط الحرفين الأولين من البيانات، استخدم:

{author_sort:.2} - أول حرفين فقط من اسم ترتيب المؤلف

يأتي جزء كبير من تنسيق لغة قوالب calibre من Python. لمزيد من التفاصيل حول صيغة عمليات التنسيق المتقدمة هذه، راجع وثائق Python.

استخدام القوالب لتعريف الأعمدة المخصصة

يمكن استخدام القوالب لعرض معلومات غير موجودة في البيانات الوصفية لـ calibre، أو لعرض البيانات الوصفية بشكل مختلف عن التنسيق العادي لـ calibre. على سبيل المثال، قد ترغب في عرض ISBN، وهو حقل لا يعرضه calibre. يمكنك تحقيق ذلك بإنشاء عمود مخصص من نوع عمود مبني من أعمدة أخرى (يُشار إليه فيما بعد بـ الأعمدة المركبة) و توفير قالب لإنشاء النص المعروض. سيعرض العمود نتيجة تقييم القالب. على سبيل المثال، لعرض ISBN، أنشئ العمود وأدخل {identifiers:select(isbn)} في مربع القالب. لعرض عمود يحتوي على قيم عمودين مخصصين من السلسلة، مفصولين بفاصلة، استخدم {#series1:||,}{#series2}.

يمكن للأعمدة المركبة استخدام أي خيار قالب، بما في ذلك التنسيق.

ملاحظة: لا يمكنك تحرير البيانات المعروضة في عمود مركب. بدلاً من ذلك، تقوم بتحرير الأعمدة المصدر. إذا قمت بتحرير عمود مركب، على سبيل المثال عن طريق النقر المزدوج عليه، فسيفتح calibre القالب للتحرير، وليس البيانات الأساسية.

القوالب ولوحات التوصيل

تُستخدم لوحات التوصيل لتغيير البيانات الوصفية المكتوبة في الكتب أثناء عمليات الإرسال إلى الجهاز والحفظ على القرص. تسمح لك لوحة التوصيل بتحديد قالب لتوفير البيانات التي ستُكتب في البيانات الوصفية للكتاب. يمكنك استخدام لوحات التوصيل لتعديل الحقول التالية: المؤلفون، ترتيب المؤلفين، اللغة، الناشر، العلامات، العنوان، ترتيب العنوان. تساعد هذه الميزة الأشخاص الذين يرغبون في استخدام بيانات وصفية مختلفة في الكتب على الأجهزة لحل مشاكل الفرز أو العرض.

عند إنشاء لوحة توصيل، تحدد التنسيق والجهاز الذي ستُستخدم لوحة التوصيل من أجله. يتم توفير جهاز خاص، save_to_disk، يُستخدم عند حفظ التنسيقات (على عكس إرسالها إلى جهاز). بمجرد اختيار التنسيق والجهاز، تختار حقول البيانات الوصفية التي سيتم تغييرها، وتوفر قوالب لتوفير القيم الجديدة. هذه القوالب متصلة بحقولها الوجهة، ومن هنا جاء اسم لوحات التوصيل. يمكنك بالطبع استخدام الأعمدة المركبة في هذه القوالب.

لوحات التوصيل مرنة للغاية ويمكن كتابتها في وضع الدالة الواحدة، وضع برنامج القالب، وضع البرنامج العام، أو وضع قالب بايثون.

عندما قد تنطبق لوحة توصيل (خادم المحتوى، الحفظ على القرص، أو الإرسال إلى الجهاز)، يبحث calibre في لوحات التوصيل المحددة لاختيار الصحيحة للتنسيق والجهاز المعنيين. على سبيل المثال، للعثور على لوحة التوصيل المناسبة لكتاب EPUB يتم إرساله إلى جهاز ANDROID، يبحث calibre في لوحات التوصيل باستخدام ترتيب البحث التالي:

  • لوحة توصيل تتطابق تمامًا مع التنسيق والجهاز، على سبيل المثال، EPUB و ANDROID

  • لوحة توصيل تتطابق تمامًا مع التنسيق وخيار أي جهاز الخاص، على سبيل المثال، EPUB و أي جهاز

  • لوحة توصيل مع خيار أي تنسيق الخاص ومطابقة دقيقة لـ الجهاز، على سبيل المثال، أي تنسيق و ANDROID

  • لوحة توصيل مع أي تنسيق و أي جهاز

يتم التعامل مع حقلي العلامات والمؤلفين بشكل خاص، لأن كلا هذين الحقلين يمكن أن يحملا أكثر من عنصر واحد. يمكن أن يحتوي الكتاب على العديد من العلامات والعديد من المؤلفين. عندما تحدد أن أحد هذين الحقلين سيتم تغييره، يتم فحص نتيجة القالب لمعرفة ما إذا كان هناك أكثر من عنصر واحد. بالنسبة للعلامات، يتم تقسيم النتيجة حيثما يجد calibre فاصلة. على سبيل المثال، إذا أنتج القالب القيمة Thriller, Horror، فستكون النتيجة علامتين، Thriller و Horror. لا توجد طريقة لوضع فاصلة في منتصف علامة.

يحدث نفس الشيء للمؤلفين، ولكن باستخدام حرف مختلف للقطع، وهو & (علامة العطف) بدلاً من الفاصلة. على سبيل المثال، إذا أنتج القالب القيمة Blogs, Joe&Posts, Susan، فسينتهي الأمر بالكتاب بمؤلفين، Blogs, Joe و Posts, Susan. إذا أنتج القالب القيمة Blogs, Joe;Posts, Susan، فسيحتوي الكتاب على مؤلف واحد باسم غريب نوعًا ما.

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

استخدام الدوال في القوالب - وضع الدالة الواحدة

افترض أنك تريد عرض قيمة حقل بأحرف كبيرة عندما يكون هذا الحقل عادةً بحالة عنوان. يمكنك القيام بذلك باستخدام دوال القالب. على سبيل المثال، لعرض العنوان بأحرف كبيرة استخدم دالة uppercase، كما في {title:uppercase()}. لعرضه بحالة عنوان، استخدم {title:titlecase()}.

توضع الدوال في جزء التنسيق من القالب، بعد : و قبل أول | أو القوس الختامي } إذا لم يتم استخدام بادئة/لاحقة. إذا كان لديك كل من تنسيق ومرجع دالة، فإن الدالة تأتي بعد : ثانية. تعيد الدوال قيمة العمود المحدد في القالب، معدلة بشكل مناسب.

صيغة استخدام الدوال هي إحدى:

{lookup_name:function(arguments)}
{lookup_name:format:function(arguments)}
{lookup_name:function(arguments)|prefix|suffix}
{lookup_name:format:function(arguments)|prefix|suffix}

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

يتم تقييم الدوال قبل مواصفات التنسيق والبادئة/اللاحقة. انظر أدناه للحصول على مثال لاستخدام كل من التنسيق والدالة.

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

لا تستخدم القوالب الفرعية (``{ ... }``) كوسائط دالة. بدلاً من ذلك، استخدم وضع برنامج القالب و وضع البرنامج العام.

ملاحظات حول استدعاء الدوال في وضع الدالة الواحدة:

  • عند استخدام الدوال في وضع الدالة الواحدة، يتم استبدال المعامل الأول، value، تلقائيًا بمحتوى الحقل المحدد في القالب. على سبيل المثال، عندما يتم معالجة القالب {title:capitalize()}، يتم تمرير محتوى حقل title كمعامل value إلى دالة capitalize.

  • في وثائق الدالة، تعني الرموز [شيء]* أن الشيء يمكن أن يتكرر صفرًا أو أكثر من المرات. وتعني الرموز [شيء]+ أن الشيء يتكرر مرة واحدة أو أكثر (يجب أن يوجد مرة واحدة على الأقل).

  • تستخدم بعض الدوال تعبيرات نمطية. في لغة القوالب، مطابقة التعبيرات النمطية غير حساسة لحالة الأحرف.

تم توثيق الدوال في مرجع دالة القالب. تخبرك الوثائق بالوسائط التي تتطلبها الدوال وما تفعله الدوال. على سبيل المثال، إليك وثائق دالة ifempty.

  • ifempty(value, text_if_empty) -- إذا لم تكن value فارغة، فتعيد value، وإلا فتعيد text_if_empty.

ترى أن الدالة تتطلب وسيطين، value و text_if_empty. ومع ذلك، نظرًا لأننا نستخدم وضع الدالة الواحدة، فإننا نحذف الوسيط value، ونمرر فقط text_if_empty. على سبيل المثال، هذا القالب:

{tags:ifempty(No tags on this book)}

يعرض علامات الكتاب، إن وجدت. إذا لم يكن لديه علامات، فإنه يعرض لا توجد علامات على هذا الكتاب.

الدوال التالية قابلة للاستخدام في وضع الدالة الواحدة لأن معاملها الأول هو value.

  • capitalize(value) -- يقوم بإرجاع value حيث يكون الحرف الأول بأحرف كبيرة والباقي بأحرف صغيرة.

  • ceiling(value) -- يعيد أصغر عدد صحيح أكبر من أو يساوي value.

  • cmp(value, y, lt, eq, gt) -- يقارن value و y بعد تحويل كلاهما إلى أرقام.

  • contains(value, pattern, text_if_match, text_if_not_match) -- تتحقق مما إذا كانت القيمة تطابق التعبير النمطي pattern

  • date_arithmetic(value, calc_spec, fmt) -- احسب تاريخًا جديدًا من value باستخدام calc_spec.

  • encode_for_url(value, use_plus) -- تُرجع القيمة المُرمَّزة للاستخدام في عنوان URL كما هو مُحدَّد بواسطة use_plus. القيمة مُرمَّزة في البداية لعنوان URL. بعد ذلك، إذا كانت use_plus تساوي 0، فسيتم استبدال المسافات بعلامة + (زائد). إذا كانت 1، فسيتم استبدال المسافات بـ %20.

  • floor(value) -- يعيد أكبر عدد صحيح أقل من أو يساوي value.

  • format_date(value, format_string) -- نسّق value، والتي يجب أن تكون سلسلة تاريخ، باستخدام format_string، مع إرجاع سلسلة نصية.

  • format_duration(value, template, [largest_unit]) -- format the value, a number of seconds, into a string showing weeks, days, hours, minutes, and seconds. If the value is a float then it is rounded to the nearest integer.

  • format_number(value, template) -- يُفسر القيمة كرقم، ويُنسّق هذا الرقم باستخدام قالب تنسيق بايثون مثل {0:5.2f} أو {0:,d} أو ${0:5,.2f}.

  • fractional_part(value) -- يعيد الجزء من القيمة بعد النقطة العشرية.

  • human_readable(value) -- يتوقع أن تكون value رقمًا ويعيد سلسلة تمثل هذا الرقم بالكيلوبايت والميجابايت والجيجابايت وما إلى ذلك.

  • ifempty(value, text_if_empty) -- إذا لم تكن value فارغة، فتعيد value، وإلا فتعيد text_if_empty.

  • language_strings(value, localize) -- تعيد أسماء اللغات لرموز اللغات (انظر هنا للأسماء والرموز) الممررة في value.

  • list_contains(value, separator, [ pattern, found_val, ]* not_found_val) -- يفسر value كقائمة من العناصر مفصولة بـ separator، ويتحقق من pattern مقابل كل عنصر في القائمة.

  • list_count(value, separator) -- يفسر القيمة كقائمة من العناصر مفصولة بـ separator ويعيد عدد العناصر في القائمة.

  • list_count_matching(value, pattern, separator) -- يفسر value كقائمة من العناصر مفصولة بـ separator، ويعيد عدد العناصر في القائمة التي تطابق التعبير النمطي pattern.

  • list_item(value, index, separator) -- يفسر value كقائمة من العناصر مفصولة بـ separator، ويعيد العنصر ذي الفهرس 'index'.

  • list_sort(value, direction, separator) -- إرجاع value مرتبةً باستخدام ترتيب معجمي غير حساس لحالة الأحرف.

  • lookup(value, [ pattern, key, ]* else_key) -- سيتم التحقق من الأنماط مقابل value بالترتيب

  • lowercase(value) -- يقوم بإرجاع value بأحرف صغيرة.

  • mod(value, y) -- يعيد floor باقي قسمة value / y.

  • rating_to_stars(value, use_half_stars) -- تُرجع value كسلسلة من أحرف النجمة ().

  • re(value, pattern, replacement) -- إرجاع value بعد تطبيق التعبير النمطي.

  • re_group(value, pattern [, template_for_group]*) --  يعيد سلسلة نصية تم إنشاؤها عن طريق تطبيق التعبير النمطي pattern على value واستبدال كل مثيل مطابق

  • round(value) -- يعيد أقرب عدد صحيح إلى value.

  • select(value, key) -- فسّر value كقائمة عناصر مفصولة بفواصل، بحيث يكون لكل عنصر الصيغة id:id_value (تنسيق identifier الخاص بـ calibre).

  • shorten(value, left_chars, middle_text, right_chars) -- تعيد نسخة مختصرة من value

  • str_in_list(value, separator, [ string, found_val, ]+ not_found_val) -- يفسر value كقائمة من العناصر مفصولة بـ separator ثم يقارن string مقابل كل قيمة في القائمة.

  • subitems(value, start_index, end_index) -- تُجزئ هذه الدالة قوائم العناصر الهرمية الشبيهة بالوسوم، مثل الأنواع.

  • sublist(value, start_index, end_index, separator) -- فسّر value كقائمة عناصر مفصولة بفاصل، مع إرجاع قائمة جديدة مكونة من العناصر من start_index إلى end_index.

  • substr(value, start, end) -- يعيد الأحرف من الموضع start حتى الموضع end من value

  • swap_around_articles(value, separator) -- تعيد value مع المقالات التي تم نقلها إلى النهاية، مفصولة بفاصلة منقوطة.

  • swap_around_comma(value) -- بالنظر إلى value من الشكل B, A، تعيد A B.

  • switch(value, [patternN, valueN,]+ else_value) -- لكل زوج patternN, valueN، يتحقق مما إذا كانت value تطابق التعبير النمطي patternN

  • test(value, text_if_not_empty, text_if_empty) -- تعيد text_if_not_empty إذا كانت القيمة غير فارغة، وإلا تعيد text_if_empty.

  • titlecase(value) -- يعيد value في حالة العنوان.

  • transliterate(value) -- إرجاع سلسلة نصية بأبجدية لاتينية مُشكَّلة عن طريق تقريب صوت الكلمات في value.

  • uppercase(value) -- يعيد value بأحرف كبيرة.

استخدام الدوال والتنسيق في نفس القالب

افترض أن لديك عمودًا مخصصًا من نوع عدد صحيح #myint وتريد عرضه بأصفار بادئة، كما في 003. إحدى الطرق للقيام بذلك هي استخدام تنسيق 0>3s. ومع ذلك، افتراضيًا إذا كان الرقم (صحيح أو عشري) يساوي صفرًا، فإن القيمة تُعرض كسلسلة فارغة، لذا ستنتج القيم الصفرية سلسلة فارغة، وليس 000. إذا كنت تريد رؤية قيم 000، فاستخدم سلسلة التنسيق ودالة ifempty لتغيير القيمة الفارغة مرة أخرى إلى صفر. سيكون القالب:

{#myint:0>3s:ifempty(0)}

لاحظ أنه يمكنك استخدام البادئة واللاحقة أيضًا. إذا كنت تريد أن يظهر الرقم كـ [003] أو [000]، فاستخدم القالب:

{#myint:0>3s:ifempty(0)|[|]}

وضع البرنامج العام

وضع البرنامج العام (GPM) يستبدل تعبيرات القالب بـ برنامج مكتوب بلغة القالب. يتم تعريف صيغة اللغة بالقواعد النحوية التالية:

program         ::= 'program:' expression_list
expression_list ::= top_expression [ ';' top_expression ]*
top_expression  ::= or_expression
or_expression   ::= and_expression [ '||' and_expression ]*
and_expression  ::= not_expression [ '&&' not_expression ]*
not_expression  ::= [ '!' not_expression ]* | concatenate_expr
concatenate_expr::= compare_expr [ '&' compare_expr ]*
compare_expr    ::= add_sub_expr [ compare_op add_sub_expr ]
compare_op      ::= '==' | '!=' | '>=' | '>' | '<=' | '<' |
                    'in' | 'inlist' | 'inlist_field' |
                    '==#' | '!=#' | '>=#' | '>#' | '<=#' | '<#'
add_sub_expr    ::= times_div_expr [ add_sub_op times_div_expr ]*
add_sub_op      ::= '+' | '-'
times_div_expr  ::= unary_op_expr [ times_div_op unary_op_expr ]*
times_div_op    ::= '*' | '/'
unary_op_expr   ::= [ add_sub_op unary_op_expr ]* | expression
expression      ::= identifier | constant | function | assignment | field_reference |
                    if_expr | for_expr | break_expr | continue_expr |
                    '(' expression_list ')' | function_def
field_reference ::= '$' [ '$' ] [ '#' ] identifier
identifier      ::= id_start [ id_rest ]*
id_start        ::= letter | underscore
id_rest         ::= id_start | digit
constant        ::= " string " | ' string ' | number
function        ::= identifier '(' expression_list [ ',' expression_list ]* ')'
function_def    ::= 'def' identifier '(' top_expression [ ',' top_expression ]* ')' ':'
                    expression_list 'fed'
assignment      ::= identifier '=' top_expression
if_expr         ::= 'if' condition 'then' expression_list
                    [ elif_expr ] [ 'else' expression_list ] 'fi'
condition       ::= top_expression
elif_expr       ::= 'elif' condition 'then' expression_list elif_expr | ''
for_expr        ::= for_list | for_range
for_list        ::= 'for' identifier 'in' list_expr
                    [ 'separator' separator_expr ] ':' expression_list 'rof'
for_range       ::= 'for' identifier 'in' range_expr ':' expression_list 'rof'
range_expr      ::= 'range' '(' [ start_expr ',' ] stop_expr
                    [ ',' step_expr [ ',' limit_expr ] ] ')'
list_expr       ::= top_expression
break_expr      ::= 'break'
continue_expr   ::= 'continue'
separator_expr  ::= top_expression
start_expr      ::= top_expression
stop_expr       ::= top_expression
step_expr       ::= top_expression
limit_expr      ::= top_expression

ملاحظات:

  • لـ تعبير_أعلى دائمًا قيمة. قيمة قائمة_التعبيرات هي قيمة آخر تعبير_أعلى في القائمة. على سبيل المثال، قيمة قائمة التعبيرات 1;2;'foobar';3 هي 3.

  • في سياق منطقي، أي قيمة غير فارغة هي True

  • في سياق منطقي، القيمة الفارغة هي False

  • يمكن استخدام السلاسل والأرقام بالتبادل. على سبيل المثال، 10 و '10' هما نفس الشيء.

  • Comments are lines starting with a '#' character, possibly preceded by blanks or tabs.

أسبقية العوامل

أسبقية العوامل (ترتيب التقييم) من الأعلى (يتم تقييمه أولاً) إلى الأدنى (يتم تقييمه أخيرًا) هي:

  • استدعاءات الدوال، الثوابت، التعبيرات بين قوسين، تعبيرات الجمل، تعبيرات الإسناد، مراجع الحقول.

  • الجمع الأحادي (+) والطرح الأحادي (-). يتم تقييم هذه العوامل من اليمين إلى اليسار.

    تعيد هذه العوامل وجميع العوامل الحسابية الأخرى أعدادًا صحيحة إذا كانت النتيجة تحتوي على جزء كسري يساوي صفرًا. على سبيل المثال، إذا كان التعبير يعيد 3.0 فإنه يتغير إلى 3.

  • الضرب (*) والقسمة (/). هذه العوامل ترابطية و تُقيّم من اليسار إلى اليمين. استخدم الأقواس إذا كنت ترغب في تغيير ترتيب التقييم.

  • الجمع (+) والطرح (-). هذه العوامل ترابطية و تُقيّم من اليسار إلى اليمين.

  • المقارنات العددية والنصية. تعيد هذه العوامل '1' إذا نجحت المقارنة، وإلا فإنها تعيد السلسلة الفارغة (''). المقارنات ليست ترابطية: a < b < c هو خطأ في الصيغة.

  • سلسلة الربط (&). تعيد عامل التشغيل & سلسلة مكونة من ربط التعبيرات اليسرى واليمنى. مثال: 'aaa' & 'bbb' يعيد 'aaabbb'. عامل التشغيل ترابطي ويُقيّم من اليسار إلى اليمين.

  • النفي المنطقي الأحادي (!). يعيد هذا العامل '1' إذا كان التعبير خاطئًا (يُقيّم إلى سلسلة فارغة)، وإلا فإنه يعيد ''.

  • المنطقي و (&&). يعيد هذا العامل '1' إذا كان كلا التعبيرين الأيسر و الأيمن صحيحين، أو السلسلة الفارغة '' إذا كان أحدهما خاطئًا. إنه ترابطي، يُقيّم من اليسار إلى اليمين، ويقوم بـ التقصير.

  • المنطقي أو (||). يعيد هذا العامل '1' إذا كان التعبير الأيسر أو الأيمن صحيحًا، أو '' إذا كان كلاهما خاطئًا. إنه ترابطي، يُقيّم من اليسار إلى اليمين، ويقوم بـ التقصير. إنه أو شامل، يعيد '1' إذا كان كلا التعبيرين الأيسر والأيمن صحيحين.

مراجع الحقول

يُقيّم field_reference إلى قيمة حقل البيانات الوصفية المسمى بواسطة اسم البحث الذي يتبع $ أو $$. استخدام $ يعادل استخدام دالة field. استخدام $$ يعادل استخدام دالة raw_field. أمثلة:

* $authors ==> field('authors')
* $#genre ==> field('#genre')
* $$pubdate ==> raw_field('pubdate')
* $$#my_int ==> raw_field('#my_int')

تعبيرات الشرط (If)

تعبيرات If تُقيّم أولاً الشرط. إذا كان الشرط صحيحًا (قيمة غير فارغة) فسيتم تقييم قائمة_التعبيرات في بند then. إذا كان خاطئًا، فسيتم تقييم قائمة_التعبيرات في بند elif أو else إن وجدت. أجزاء elif و else اختيارية. الكلمات if، then، elif، else، و fi محجوزة؛ لا يمكنك استخدامها كأسماء معرفات. يمكنك وضع أسطر جديدة ومسافات بيضاء حيثما يكون ذلك منطقيًا. الشرط هو تعبير_أعلى وليس قائمة_تعبيرات؛ لا يُسمح بالفواصل المنقوطة. قوائم_التعبيرات هي تسلسلات مفصولة بفاصلة منقوطة من تعبيرات_أعلى. يعيد تعبير if نتيجة آخر تعبير_أعلى في قائمة_التعبيرات التي تم تقييمها، أو سلسلة فارغة إذا لم يتم تقييم أي قائمة تعبيرات.

أمثلة:

* program: if field('series') then 'yes' else 'no' fi
* program:
      if field('series') then
          a = 'yes';
          b = 'no'
      else
          a = 'no';
          b = 'yes'
      fi;
      strcat(a, '-', b)

مثال if المتداخل:

program:
  if field('series') then
    if check_yes_no(field('#mybool'), '', '', '1') then
      'yes'
    else
      'no'
    fi
  else
    'no series'
  fi

كما ذكر أعلاه، ينتج if قيمة. هذا يعني أن جميع ما يلي متكافئ:

* program: if field('series') then 'foo' else 'bar' fi
* program: if field('series') then a = 'foo' else a = 'bar' fi; a
* program: a = if field('series') then 'foo' else 'bar' fi; a

على سبيل المثال، يعيد هذا البرنامج قيمة عمود series إذا كان الكتاب يحتوي على سلسلة، وإلا فإنه يعيد قيمة عمود title:

program: field(if field('series') then 'series' else 'title' fi)

تعبيرات For

تعبير for يتكرر على قائمة من القيم، ويعالجها واحدة تلو الأخرى. يجب أن تُقيّم list_expression إما إلى حقل بيانات وصفية اسم البحث، على سبيل المثال، tags أو #genre، أو إلى قائمة من القيم. تُنشئ range قائمة من الأرقام. إذا كانت النتيجة اسم بحث صالحًا، فسيتم جلب قيمة الحقل واستخدام الفاصل المحدد لنوع الحقل هذا. إذا لم تكن النتيجة اسم بحث صالحًا، فإنها تُفترض أنها قائمة من القيم. تُفترض القائمة أنها مفصولة بفاصلات ما لم يتم توفير الكلمة المفتاحية الاختيارية separator، وفي هذه الحالة يجب فصل قيم القائمة بنتيجة تقييم separator_expr. لا يمكن استخدام الفاصل إذا تم إنشاء القائمة بواسطة range(). يتم تعيين كل قيمة في القائمة إلى المتغير المحدد ثم يتم تقييم expression_list. يمكنك استخدام break للقفز خارج الحلقة، و continue للقفز إلى بداية الحلقة لـ التكرار التالي.

مثال: يقوم هذا القالب بإزالة الاسم الهرمي الأول لكل قيمة في النوع (#genre)، مكونًا قائمة بالأسماء الجديدة:

program:
  new_tags = '';
  for i in '#genre':
    j = re(i, '^.*?\.(.*)$', '\1');
    new_tags = list_union(new_tags, j, ',')
  rof;
  new_tags

إذا كان النوع الأصلي هو History.Military, Science Fiction.Alternate History, ReadMe، فإن القالب يعيد Military, Alternate History, ReadMe. يمكنك استخدام هذا القالب في calibre's تحرير البيانات الوصفية بالجملة  →  بحث واستبدال مع تعيين البحث عن إلى template لإزالة المستوى الأول من التسلسل الهرمي وتعيين القيمة الناتجة إلى النوع.

ملاحظة: السطر الأخير في القالب، new_tags، ليس ضروريًا تمامًا في هذه الحالة لأن for يعيد قيمة آخر تعبير علوي في قائمة التعبيرات. قيمة التعيين هي قيمة تعبيره، لذا فإن قيمة عبارة for هي ما تم تعيينه لـ new_tags.

تعريف الدالة

إذا كان لديك رمز متكرر في قالب، فيمكنك وضع هذا الرمز في دالة محلية. تبدأ الكلمة المفتاحية def التعريف. تتبعها اسم الدالة، قائمة الوسائط، ثم الرمز في الدالة. ينتهي تعريف الدالة بالكلمة المفتاحية fed.

الوسائط موضعية. عند استدعاء دالة، تتم مطابقة الوسائط المقدمة من اليسار إلى اليمين مع المعلمات المحددة، مع تعيين قيمة الوسيط إلى المعلمة. يعد خطأً توفير عدد من الوسائط أكثر من المعلمات المحددة. يمكن أن تحتوي المعلمات على قيم افتراضية، مثل a = 25. إذا لم يتم توفير وسيط لتلك المعلمة، فسيتم استخدام القيمة الافتراضية، وإلا فسيتم تعيين المعلمة إلى سلسلة فارغة.

يمكن استخدام عبارة return في دالة محلية.

يجب تعريف الدالة قبل استخدامها.

مثال: يحسب هذا القالب مدة تقريبية بالسنوات والأشهر والأيام من عدد من الأيام. تقوم الدالة to_plural() بتنسيق القيم المحسوبة. لاحظ أن المثال يستخدم أيضًا عامل التشغيل &:

program:
      days = 2112;
      years = floor(days/360);
      months = floor(mod(days, 360)/30);
      days = days - ((years*360) + (months * 30));

      def to_plural(v, str):
              if v == 0 then return '' fi;
              return v & ' ' & (if v == 1 then str else str & 's' fi) & ' '
      fed;

      to_plural(years, 'year') & to_plural(months, 'month') & to_plural(days,'day')

عوامل التشغيل العلائقية

تعيد عوامل التشغيل العلائقية '1' إذا كانت المقارنة صحيحة، وإلا فإنها تعيد السلسلة الفارغة ('').

هناك شكلان من عوامل التشغيل العلائقية: مقارنات السلاسل و مقارنات الأرقام.

تقوم مقارنات السلاسل بمقارنة سلاسل غير حساسة لحالة الأحرف باستخدام الترتيب المعجمي. عوامل مقارنة السلاسل المدعومة هي ==، !=، <، <=، >، >=، in، inlist، و inlist_field. بالنسبة لـ عوامل التشغيل in، inlist، و inlist_field، يتم تفسير نتيجة التعبير الأيسر كنمط تعبير نمطي. وهي صحيحة إذا كانت قيمة التعبير النمطي الأيسر تطابق قيمة التعبير الأيمن. التعبيرات النمطية غير حساسة لحالة الأحرف.

عامل التشغيل inlist يكون صحيحًا إذا كان التعبير النمطي الأيسر يطابق أي عنصر من العناصر في القائمة اليمنى حيث يتم فصل العناصر في القائمة بفاصلات. عامل التشغيل inlist_field يكون صحيحًا إذا كان التعبير النمطي الأيسر يطابق أي من العناصر في الحقل (العمود) المسمى بواسطة التعبير الأيمن، باستخدام الفاصل المحدد للحقل. ملاحظة: يتطلب عامل التشغيل inlist_field أن يُقيّم التعبير الأيمن إلى اسم حقل، بينما يتطلب عامل التشغيل inlist أن يُقيّم التعبير الأيمن إلى سلسلة تحتوي على قائمة مفصولة بفاصلات. بسبب هذا الاختلاف، inlist_field أسرع بكثير من inlist لأنه لا يتم إجراء تحويلات سلاسل أو إنشاء قوائم.

عوامل المقارنة العددية هي ==#، !=#، <#، <=#، >#، >=#. يجب أن تُقيّم التعبيرات اليسرى واليمنى إلى قيم عددية باستثناءين: كل من القيمة النصية "None" (حقل غير معرف) والسلسلة الفارغة تُقيّم إلى القيمة صفر.

أمثلة:

  • program: field('series') == 'foo' يعيد '1' إذا كانت سلسلة الكتاب هي foo، وإلا ''.

  • program: 'f.o' in field('series') يعيد '1' إذا كانت سلسلة الكتاب تطابق التعبير النمطي f.o (مثل foo, Off Onyx, إلخ)، وإلا ''.

  • program: 'science' inlist $#genre يعيد '1' إذا كانت أي من القيم المستردة من أنواع الكتاب تطابق التعبير النمطي science، مثل Science, History of Science, Science Fiction إلخ، وإلا ''.

  • program: '^science$' inlist $#genre يعيد '1' إذا كانت أي من أنواع الكتاب تطابق تمامًا التعبير النمطي ^science$، مثل Science، وإلا ''. لا تتطابق أنواع History of Science و Science Fiction.

  • program: 'asimov' inlist $authors يعيد '1' إذا كان أي مؤلف يطابق التعبير النمطي asimov، مثل Asimov, Isaac أو Isaac Asimov، وإلا ''.

  • program: 'asimov' inlist_field 'authors' يعيد '1' إذا كان أي مؤلف يطابق التعبير النمطي asimov، مثل Asimov, Isaac أو Isaac Asimov، وإلا ''.

  • program: 'asimov$' inlist_field 'authors' يعيد '1' إذا كان أي مؤلف يطابق التعبير النمطي asimov$، مثل Isaac Asimov، وإلا ''. لا يطابق Asimov, Isaac بسبب علامة $ في التعبير النمطي.

  • program: if field('series') != 'foo' then 'bar' else 'mumble' fi يعيد 'bar' إذا لم تكن سلسلة الكتاب foo. وإلا فإنه يعيد 'mumble'.

  • program: if field('series') == 'foo' || field('series') == '1632' then 'yes' else 'no' fi يعيد 'yes' إذا كانت السلسلة إما foo أو 1632، وإلا 'no'.

  • program: if '^(foo|1632)$' in field('series') then 'yes' else 'no' fi يعيد 'yes' إذا كانت السلسلة إما foo أو 1632، وإلا 'no'.

  • program: if 11 > 2 then 'yes' else 'no' fi يعيد 'no' لأن عامل التشغيل > يقوم بمقارنة معجمية.

  • program: if 11 ># 2 then 'yes' else 'no' fi يعيد 'yes' لأن عامل التشغيل ># يقوم بمقارنة عددية.

الدوال في وضع البرنامج العام

راجع مرجع دالة القالب للحصول على قائمة بالدوال المضمنة في لغة القوالب.

ملاحظات:

  • على عكس وضع الدالة الواحدة، في وضع البرنامج العام يجب عليك تحديد المعامل الأول value.

  • جميع المعلمات هي expression_lists (انظر القواعد النحوية أعلاه).

برامج أكثر تعقيدًا في تعبيرات القوالب - وضع برنامج القالب

وضع برنامج القالب (TPM) هو مزيج من وضع البرنامج العام و وضع الدالة الواحدة. يختلف TPM عن وضع الدالة الواحدة في أنه يسمح بكتابة تعبيرات القالب التي تشير إلى حقول بيانات وصفية أخرى، وتستخدم دوال متداخلة، وتعديل المتغيرات، وتقوم بالعمليات الحسابية. يختلف عن وضع البرنامج العام في أن القالب محتوى بين أحرف { و } ولا يبدأ بالكلمة program:. جزء البرنامج من القالب هو قائمة تعبيرات وضع البرنامج العام.

مثال: افترض أنك تريد قالبًا لعرض سلسلة كتاب إذا كان لديه واحدة، وإلا فعرض قيمة حقل مخصص #genre. لا يمكنك القيام بذلك في وضع الدالة الواحدة لأنه لا يمكنك الإشارة إلى حقل بيانات وصفية آخر ضمن تعبير قالب. في TPM يمكنك ذلك، كما يوضح التعبير التالي:

{series:'ifempty($, $#genre)'}

يوضح المثال عدة أمور:

  • يُستخدم TPM إذا بدأ التعبير بـ :' وانتهى بـ '}. يُفترض أن أي شيء آخر هو في وضع الدالة الواحدة.

    إذا كان القالب يحتوي على بادئة ولاحقة، ينتهي التعبير بـ '| حيث | هو الفاصل للبادئة. مثال:

    {series:'ifempty($, $#genre)'|prefix | suffix}
    
  • يجب إعطاء الدوال جميع وسائطها. على سبيل المثال، الدوال المدمجة القياسية يجب أن تُعطى المعامل الأولي value.

  • المتغير $ قابل للاستخدام كوسيط value ويمثل قيمة الحقل المسمى في القالب، series في هذه الحالة.

  • يتم تجاهل المسافات البيضاء ويمكن استخدامها في أي مكان داخل التعبير.

  • السلاسل الثابتة محاطة بعلامات اقتباس متطابقة، إما ' أو ".

في TPM، يمكن أن يؤدي استخدام الأحرف { و } في السلاسل الحرفية إلى أخطاء أو نتائج غير متوقعة لأنها تربك معالج القوالب. فهو يحاول التعامل معها كحدود لتعبير القالب، وليس كأحرف. في بعض الحالات وليس كلها، يمكنك استبدال { بـ [[ و } بـ ]]. نصيحة: إذا كان برنامجك يحتوي على أحرف { و }، يجب عليك استخدام وضع البرنامج العام.

وضع قالب بايثون

يسمح لك وضع قالب بايثون (PTM) بكتابة القوالب باستخدام بايثون الأصلي و واجهة برمجة تطبيقات calibre. ستكون واجهة برمجة تطبيقات قاعدة البيانات الأكثر فائدة؛ المزيد من المناقشة خارج نطاق هذا الدليل. قوالب PTM أسرع ويمكنها القيام بعمليات أكثر تعقيدًا ولكن يجب عليك معرفة كيفية كتابة التعليمات البرمجية في بايثون باستخدام واجهة برمجة تطبيقات calibre.

يبدأ قالب PTM بـ:

python:
def evaluate(book, context):
    # book is a calibre metadata object
    # context is an instance of calibre.utils.formatter.PythonTemplateContext,
    # which currently contains the following attributes:
    # db: a calibre legacy database object.
    # globals: the template global variable dictionary.
    # arguments: is a list of arguments if the template is called by a GPM template, otherwise None.
    # funcs: used to call Built-in/User functions and Stored GPM/Python templates.
    # Example: context.funcs.list_re_group()

    # your Python code goes here
    return 'a string'

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

يدعم كائن السياق str(context) الذي يعيد سلسلة من محتويات السياق، و context.attributes الذي يعيد قائمة بأسماء السمات في السياق.

تسمح السمة context.funcs باستدعاء دوال القوالب المدمجة والمستخدمة، وقوالب GPM/Python المخزنة، بحيث يمكنك تنفيذها مباشرة في التعليمات البرمجية الخاصة بك. يتم استرداد الدوال باستخدام أسمائها. إذا تعارض الاسم مع كلمة مفتاحية في Python، أضف شرطة سفلية إلى نهاية الاسم. أمثلة:

context.funcs.list_re_group()
context.funcs.assert_()

إليك مثال لقالب PTM ينتج قائمة بجميع المؤلفين لسلسلة. يتم تخزين القائمة في عمود مبني من أعمدة أخرى، يتصرف مثل العلامات. يظهر في تفاصيل الكتاب ويحتوي على على أسطر منفصلة محدد (في التفضيلات → المظهر و الشعور → تفاصيل الكتاب). يتطلب هذا الخيار أن تكون القائمة مفصولة بفاصلات. لتلبية هذا الشرط، يقوم القالب بتحويل الفواصل في أسماء المؤلفين إلى فواصل منقوطة ثم يبني قائمة مفصولة بفاصلات من المؤلفين. يتم فرز المؤلفين بعد ذلك، وهذا هو السبب في أن القالب يستخدم author_sort.

python:
def evaluate(book, context):
    if book.series is None:
        return ''
    db = context.db.new_api
    ans = set()
    # Get the list of books in the series
    ids = db.search(f'series:"={book.series}"', '')
    if ids:
        # Get all the author_sort values for the books in the series
        author_sorts = (v for v in db.all_field_for('author_sort', ids).values())
        # Add the names to the result set, removing duplicates
        for aus in author_sorts:
            ans.update(v.strip() for v in aus.split('&'))
    # Make a sorted comma-separated string from the result set
    return ', '.join(v.replace(',', ';') for v in sorted(ans))

الإخراج في تفاصيل الكتاب يبدو كالتالي:

مربع حوار تحويل الكتاب الإلكتروني

القوالب وعناوين URL

يمكنك استخدام القوالب لإنشاء عناوين URL. يتم وصف حالتين هنا:

  • أعمدة مخصصة تفاصيل الكتاب عناوين URL للبحث

  • مخطط عنوان URL لـ calibre

عناوين URL للبحث في تفاصيل الكتاب في العمود المخصص

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

عند النقر على عنصر يحتوي على قالب بحث في تفاصيل الكتاب، يتم تقييم القالب. يتم توفير البيانات الوصفية العادية للكتاب. كما يتم توفير ثلاثة حقول إضافية:

  • item_value: قيمة العنصر الذي تم النقر عليه.

  • item_value_quoted: قيمة العنصر الذي تم النقر عليه، مشفرة لعنوان URL. يتم الهروب من الأحرف الخاصة لجعلها صالحة في عناوين URL ويتم استبدال المسافات بـ علامات '+' (زائد).

  • item_value_no_plus: قيمة العنصر الذي تم النقر عليه، مشفرة لعنوان URL. يتم الهروب من الأحرف الخاصة لجعلها صالحة في عناوين URL ويتم استبدال المسافات بـ %20، وليس علامة زائد.

هناك عدة طرق لإنشاء عنوان URL. تستخدم الأمثلة التالية ويكيبيديا كـ مثال.

الأبسط هو قالب أساسي:

https://en.wikipedia.org/w/index.php?search={item_value_encoded}

في بعض الحالات قد ترغب في إجراء المزيد من المعالجة. هناك أربع دوال قالب يمكنك استخدامها، اعتمادًا على تعقيد المعالجة.

  • make_url(path, [query_name, query_value]+) -- هذه الدالة هي أسهل طريقة لإنشاء رابط استعلام. تستخدم path، أي موقع الويب والصفحة التي تريد الاستعلام عنها، وزوجي query_name و``query_value`` اللذين يُبنى منهما الاستعلام.

    بشكل عام، يجب ترميز query_value برابط URL. في هذه الدالة، يتم ترميزها دائمًا، وتُستبدل المسافات دائمًا بعلامة +.

  • make_url_extended(...) -- هذه الدالة مشابهة لـ make_url()، ولكنها تمنحك تحكمًا أكبر في مكونات عنوان URL. مكونات عنوان URL هي:

    scheme:://authority/path?query string.

    للمزيد من التفاصيل، راجع Uniform Resource Locator على ويكيبيديا.

    تحتوي هذه الدالة على نسختين:

    make_url_extended(scheme, authority, path, [query_name, query_value]+)
    

    و

    make_url_extended(scheme, authority, path, query_string)
    
  • query_string([query_name, query_value, how_to_encode]+) -- تُرجع سلسلة استعلام عنوان URL مُنشأة من ثلاثيات query_name, query_value, how_to_encode.

    سلسلة الاستعلام هي سلسلة من العناصر، حيث يبدو كل عنصر كما يلي query_name=query_value حيث يتم ترميز query_value باستخدام عنوان URL وفقًا للتعليمات. تُفصل عناصر الاستعلام بعلامة "&" (علامة العطف).

  • encode_for_url(value, use_plus) -- تُرجع القيمة المُرمَّزة للاستخدام في عنوان URL كما هو مُحدَّد بواسطة use_plus. القيمة مُرمَّزة في البداية لعنوان URL. بعد ذلك، إذا كانت use_plus تساوي 0، فسيتم استبدال المسافات بعلامة + (زائد). إذا كانت 1، فسيتم استبدال المسافات بـ %20.

على سبيل المثال، افترض أن لديك عمودًا مخصصًا المترجمون (#translators) حيث الأسماء هي اسم العائلة، الاسم الأول. قد تحتاج إلى تحويل الاسم إلى الاسم الأول اسم العائلة عند إنشاء عنوان URL. يمكنك استخدام دالة make_url للقيام بذلك:

program: make_url('https://en.wikipedia.org/w/index.php', 'search', swap_around_comma($item_value))

إذا افترضنا أن اسم المترجم هو Boy-Żeleński, Tadeusz، فإن القالب أعلاه ينتج الرابط:

https://en.wikipedia.org/w/index.php?search=Tadeusz+Boy-%C5%BBele%C5%84ski

لاحظ أن الاسم الأول للشخص أصبح الآن أولاً، والمسافة أصبحت علامة زائد، و أن الأحرف غير الإنجليزية في اسم العائلة مشفرة لعنوان URL.

قد تكون الدوال make_url_extended، query_string، و encode_for_url مفيدة اعتمادًا على أي تعقيد معالجة إضافي.

مخطط عنوان URL لـ calibre

يدعم Calibre عدة عناوين URL مختلفة للتنقل في مكتبات calibre الخاصة بك. يوضح هذا القسم كيفية استخدام القوالب لإنشاء بعض عناوين URL. راجع مخطط عنوان URL لـ calibre:// للحصول على تفاصيل حول عناوين URL المتاحة.

  • التبديل إلى مكتبة معينة. صيغة عنوان URL هذا هي:

    calibre://switch-library/Library_Name
    

    يجب استبدال Library_Name باسم مكتبة calibre التي ترغب في فتحها. يظهر اسم المكتبة في شريط عنوان النافذة. إنه اسم بسيط، وليس مسار الملف إلى المكتبة. يجب أن تكتبه كما يظهر في شريط العنوان، بما في ذلك حالة الأحرف. الحرف _ (شرطة سفلية) يرمز إلى المكتبة الحالية. إذا كان الاسم يحتوي على أي مسافات أو أحرف خاصة، فيجب ترميزه سداسيًا عشريًا باستخدام دالة to_hex، كما في المثال التالي:

    program: strcat('calibre://switch-library/_hex_-', to_hex(current_library_name()))
    

    ينشئ القالب عنوان URL:

    calibre://switch-library/_hex_-4c6962726172792e746573745f736d616c6c
    

    يمكنك استبدال دالة current_library_name() بالاسم الفعلي للمكتبة، كما في:

    program: strcat('calibre://switch-library/_hex_-', to_hex('Library.test_small'))
    
  • روابط لعرض الكتب. تحدد هذه الروابط كتابًا في مكتبة calibre. صيغة عنوان URL هذا هي:

    calibre://show-book/Library_Name/book_id
    

    معرف book id هو معرف calibre الرقمي للكتاب، متاح لـ القوالب كـ $id. كما هو الحال أعلاه، قد يحتاج اسم المكتبة إلى ترميز سداسي عشري. إليك مثال:

    program: strcat('calibre://show-book/_hex_-', to_hex(current_library_name()), '/', $id)
    

    ينتج عنوان URL:

    calibre://show-book/_hex_-4c6962726172792e746573745f736d616c6c/1353
    
  • البحث عن الكتب. تبحث هذه الروابط عن الكتب في مكتبة calibre المحددة. صيغة عنوان URL هذا هي:

    calibre://search/Library_Name?q=query
    calibre://search/Library_Name?eq=hex_encoded_query
    

    حيث query هو أي تعبير بحث صالح في calibre. يجب عليك ترميز سداسي عشري لأي استعلام يحتوي على مسافات أو أحرف خاصة، مما يعني عمومًا جميعها. على سبيل المثال، تعبير البحث في calibre للبحث عن علامة هرمية تبدأ بـ 'AA' هو tags:"=.AA". ينشئ هذا القالب عنوان URL للبحث عن هذا التعبير:

    program: strcat('calibre://search/_hex_-', to_hex(current_library_name()), '?eq=', to_hex('tags:"=.AA"'))
    

    عنوان URL الناتج هو:

    calibre://search/_hex_-4c6962726172792e746573745f736d616c6c?eq=746167733a223d2e414122
    

    إليك مثال على نفس عنوان URL تم إنشاؤه باستخدام دالة :ref:ff_make_url_extended بدلاً من strcat:

    program: make_url_extended('calibre', '', 'search/_hex_-' & to_hex(current_library_name()),
                               'eq', to_hex('tags:"=.AA"'))
    
  • فتح نافذة تفاصيل كتاب لكتاب في مكتبة ما. صيغة عنوان URL هذا هي:

    calibre://book-details/Library_Name/book_id
    

    مثال على قالب هو:

    program: strcat('calibre://book-details/_hex_-', to_hex(current_library_name()), '/', $id)
    

    الذي ينتج عنوان URL:

    calibre://book-details/_hex_-4c6962726172792e746573745f736d616c6c/1353
    
  • فتح الملاحظات المرتبطة بمؤلف/سلسلة/إلخ. صيغة عنوان URL هي:

    calibre://book-details/Library_Name/Field_Name/id_Item_Id
    calibre://book-details/Library_Name/Field_Name/hex_Hex_Encoded_Item_Name
    

    Field_Name هو اسم البحث للحقل. إذا كان الحقل عمودًا مخصصًا، فاستبدل الحرف # بشرطة سفلية (_). Item_Id هو المعرف الرقمي الداخلي للقيمة في الحقل. لا توجد دالة قالب تعيد Item_Id، لذا ستستخدم القوالب عادةً الشكل الثاني، Hex_Encoded_Item_Name. إليك قالب مثال يفتح الملاحظة للشخص Boy-Żeleński, Tadeusz في الحقل #authtest:

    program: strcat('calibre://show-note/_hex_-', to_hex(current_library_name()),
                    '/_authtest/hex_', to_hex('Boy-Żeleński, Tadeusz'))
    

    الذي ينتج عنوان URL:

    calibre://show-note/_hex_-4c6962726172792e746573745f736d616c6c/_authtest/hex_426f792dc5bb656c65c584736b692c205461646575737a
    

القوالب المخزنة

يدعم كل من وضع البرنامج العام و وضع قالب بايثون حفظ القوالب واستدعاء تلك القوالب من قالب آخر، تمامًا مثل استدعاء الدوال المخزنة. يمكنك حفظ القوالب باستخدام التفضيلات → متقدم → دوال القوالب. يتم توفير المزيد من المعلومات في هذا الحوار. يمكنك استدعاء قالب بنفس الطريقة التي تستدعي بها دالة، مع تمرير الوسائط الموضعية إذا رغبت في ذلك. يمكن أن يكون الوسيط أي تعبير. أمثلة على استدعاء قالب، بافتراض أن القالب المخزن يسمى foo:

  • foo() -- استدعاء القالب دون تمرير أي وسائط.

  • foo(a, b) استدعاء القالب مع تمرير قيم المتغيرين a و b.

  • foo(if field('series') then field('series_index') else 0 fi) -- إذا كان الكتاب يحتوي على سلسلة، فمرر series_index، وإلا فمرر القيمة 0.

في GPM، تسترد الوسائط التي تم تمريرها في استدعاء القالب المخزن باستخدام دالة arguments. إنها تعلن وتهيئ المتغيرات المحلية، وهي في الواقع معلمات. المتغيرات موضعية؛ تحصل على قيمة المعلمة المعطاة في الاستدعاء في نفس الموضع. إذا لم يتم توفير المعلمة المقابلة في الاستدعاء، فإن arguments تعين هذا المتغير القيمة الافتراضية المقدمة. إذا لم تكن هناك قيمة افتراضية، فإن المتغير يتم تعيينه إلى سلسلة فارغة. على سبيل المثال، دالة arguments التالية تعلن متغيرين، key، alternate:

arguments(key, alternate='series')

أمثلة، بافتراض مرة أخرى أن القالب المخزن يسمى foo:

  • foo('#myseries') -- يتم تعيين الوسيط key للقيمة 'myseries' ويتم تعيين الوسيط alternate للقيمة الافتراضية 'series'.

  • foo('series', '#genre') يتم تعيين المتغير key للقيمة 'series' ويتم تعيين المتغير alternate للقيمة '#genre'.

  • foo() -- يتم تعيين المتغير key للسلسلة الفارغة ويتم تعيين المتغير alternate للقيمة 'series'.

في PTM، يتم تمرير الوسائط في المعامل arguments، وهو قائمة من السلاسل. لا توجد أي طريقة لتحديد قيم افتراضية. يجب عليك التحقق من طول قائمة arguments للتأكد من أن عدد الوسائط هو ما تتوقعه.

طريقة سهلة لاختبار القوالب المخزنة هي استخدام مربع حوار اختبار القوالب. لسهولة الوصول، امنحه اختصار لوحة مفاتيح في التفضيلات → متقدم → اختصارات لوحة المفاتيح → اختبار القوالب. إعطاء مربع حوار القوالب المخزنة اختصارًا سيساعد في التبديل بسرعة أكبر بين المختبر وتحرير الكود المصدري للقالب المخزن.

توفير معلومات إضافية للقوالب

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

المطور: كيفية تمرير معلومات إضافية

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

يتم تمرير هذا القاموس إلى معالج القوالب (formatter) باستخدام المعامل المسمى global_vars=your_dict. توقيع الدالة الكامل هو:

def safe_format(self, fmt, kwargs, error_value, book,
                column_name=None, template_cache=None,
                strip_results=True, template_functions=None,
                global_vars={})

كاتب القالب: كيفية الوصول إلى المعلومات الإضافية

يمكنك الوصول إلى المعلومات الإضافية (قاموس globals) في قالب باستخدام دالة القالب:

globals(id[=expression] [, id[=expression]]*)

حيث id هو أي اسم متغير قانوني. تتحقق هذه الدالة مما إذا كانت المعلومات الإضافية المقدمة من المطور تحتوي على الاسم. إذا كانت تحتوي عليه، فإن الدالة تعين القيمة المقدمة لمتغير محلي للقالب بهذا الاسم. إذا لم يكن الاسم موجودًا في المعلومات الإضافية وإذا تم توفير expression، يتم تقييم expression و يتم تعيين النتيجة للمتغير المحلي. إذا لم يتم توفير قيمة ولا تعبير، فإن الدالة تعين السلسلة الفارغة ('') لـ المتغير المحلي.

يمكن للقالب تعيين قيمة في قاموس globals باستخدام دالة القالب:

set_globals(id[=expression] [, id[=expression]]*)

تقوم هذه الدالة بتعيين زوج المفتاح:القيمة id:value في قاموس globals حيث value هي قيمة المتغير المحلي للقالب id. إذا لم يكن هذا المتغير المحلي موجودًا، فسيتم تعيين value إلى نتيجة تقييم expression.

ملاحظات حول الفرق بين الأوضاع

تعمل أوضاع البرمجة الثلاثة، وضع الدالة الواحدة (SFM)، وضع برنامج القالب (TPM)، و وضع البرنامج العام (GPM)، بشكل مختلف. يهدف SFM إلى أن يكون 'بسيطًا' لذا فإنه يخفي الكثير من أجزاء لغة البرمجة.

الفروقات:

  • في SFM، يتم دائمًا تمرير قيمة العمود كوسيط أول 'غير مرئي' لدالة مضمنة في القالب.

  • لا يدعم SFM الفرق بين المتغيرات والسلاسل؛ جميع القيم هي سلاسل.

  • يعيد قالب SFM التالي إما اسم السلسلة أو السلسلة النصية "لا توجد سلسلة":

    {series:ifempty(no series)}
    

    القالب المكافئ في TPM هو:

    {series:'ifempty($, 'no series')'}
    

    القالب المكافئ في GPM هو:

    program: ifempty(field('series'), 'no series')
    

    الوسيط الأول لدالة ifempty هو قيمة الحقل series. الوسيط الثاني هو السلسلة النصية no series. في SFM، يتم تمرير الوسيط الأول، وهو قيمة الحقل، تلقائيًا (الوسيط غير المرئي).

  • العديد من دوال القوالب، على سبيل المثال booksize() و current_library_name()، لا تأخذ أي وسائط. بسبب 'الوسيط غير المرئي'، لا يمكنك استخدام هذه الدوال في SFM.

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

    {series:uppercase(substr(0,5))}
    
  • يدعم TPM و GPM الدوال المتداخلة. القالب أعلاه في TPM سيكون:

    {series:'uppercase(substr($, 0,5))'}
    

    في GPM سيكون:

    program: uppercase(substr(field('series'), 0,5))
    
  • كما هو مذكور في قسم وضع برنامج القالب أعلاه، يمكن أن يؤدي استخدام الأحرف { و } في سلاسل TPM الحرفية إلى أخطاء أو نتائج غير متوقعة لأنها تربك معالج القوالب. فهو يحاول التعامل معها كحدود للقالب، وليس كأحرف. في بعض الحالات وليس كلها، يمكنك استبدال { بـ [[ و } بـ ]]. بشكل عام، إذا كان برنامجك يحتوي على أحرف { و }، فيجب عليك استخدام وضع البرنامج العام.

دوال قالب بايثون المعرفة من قبل المستخدم

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

ملاحظات خاصة لاستخدام القوالب في سياقات مختلفة

في واجهة المستخدم الرسومية (الأعمدة المصنوعة من أعمدة أخرى و عمليات البحث بالقالب):

  • تعمل قوالب GPM كما كانت من قبل.

  • تتمتع قوالب بايثون بوصول كامل إلى قاعدة بيانات calibre.

في قواعد الأيقونات:

  • لا تحتوي قوالب قواعد الأيقونات على بيانات كتاب، لذا فإن الدوال المستندة إلى الحقول مثل format_date_field، list_count_field، و check_yes_no لن تعمل.

في خادم المحتوى:

  • تتمتع القوالب بالوصول إلى واجهة برمجة التطبيقات الجديدة ولكن ليس إلى واجهة برمجة التطبيقات القديمة (LibraryDatabase).

  • بسبب ما سبق، لا يُضمن عمل دوال التنسيق التالية في قوالب GPM (الأعمدة المركبة، قواعد الأيقونات، إلخ) ويجب تجنبها إذا كنت تستخدم خادم المحتوى:

ملاحظات خاصة لقوالب الحفظ/الإرسال

يتم تطبيق معالجة خاصة عند استخدام قالب في قالب حفظ إلى القرص أو إرسال إلى الجهاز. يتم تنظيف قيم الحقول، واستبدال الأحرف الخاصة بأنظمة الملفات بشرطات سفلية، بما في ذلك الشرطات المائلة. هذا يعني أنه لا يمكن استخدام نص الحقل لإنشاء مجلدات. ومع ذلك، لا تتغير الشرطات المائلة في سلاسل البادئة أو اللاحقة، لذا ستؤدي الشرطات المائلة في هذه السلاسل إلى إنشاء مجلدات. بسبب هذا، يمكنك إنشاء هيكل مجلدات بعمق متغير.

على سبيل المثال، افترض أننا نريد هيكل المجلد سلسلة/فهرس_السلسلة - عنوان، مع ملاحظة أنه إذا لم تكن السلسلة موجودة، فيجب أن يكون العنوان في المجلد العلوي. القالب للقيام بذلك هو:

{series:||/}{series_index:|| - }{title}

تظهر الشرطة المائلة والواصلة فقط إذا لم تكن السلسلة فارغة.

تتيح لنا دالة البحث القيام بمعالجة أكثر تعقيدًا. على سبيل المثال، افترض أنه إذا كان الكتاب يحتوي على سلسلة، فإننا نريد هيكل المجلد سلسلة/فهرس السلسلة - عنوان.fmt. إذا لم يكن للكتاب سلسلة، فإننا نريد هيكل المجلد نوع/ترتيب_المؤلف/عنوان.fmt. إذا لم يكن للكتاب نوع، فإننا نريد استخدام 'غير معروف'. نريد مسارين مختلفين تمامًا، اعتمادًا على قيمة السلسلة.

لتحقيق ذلك، نقوم بـ:

  1. إنشاء حقل مركب (إعطائه اسم بحث #aa) يحتوي على {series}/{series_index} - {title}. إذا لم تكن السلسلة فارغة، فإن هذا القالب سينتج سلسلة/فهرس_السلسلة - عنوان.

  2. إنشاء حقل مركب (إعطائه اسم بحث #bb) يحتوي على {#genre:ifempty(Unknown)}/{author_sort}/{title}. ينتج هذا القالب نوع/ترتيب_المؤلف/عنوان، حيث يتم استبدال النوع الفارغ بـ غير معروف.

  3. تعيين قالب الحفظ إلى {series:lookup(.,#aa,#bb)}. يختار هذا القالب الحقل المركب #aa إذا لم تكن السلسلة فارغة، والحقل المركب #bb إذا كانت السلسلة فارغة. لذلك لدينا مساران حفظ مختلفان تمامًا، اعتمادًا على ما إذا كانت السلسلة فارغة أم لا.

نصائح

  • استخدم "اختبار القوالب" لاختبار القوالب. أضف المختبر إلى قائمة السياق للكتب في المكتبة و/أو امنحه اختصار لوحة مفاتيح.

  • يمكن للقوالب استخدام قوالب أخرى عن طريق الإشارة إلى أعمدة مركبة تم إنشاؤها باستخدام القالب المطلوب. بدلاً من ذلك، يمكنك استخدام القوالب المخزنة.

  • في لوحة التوصيل، يمكنك تعيين حقل إلى فارغ (أو ما يعادله) باستخدام القالب الخاص {}. سيُقيّم هذا القالب دائمًا إلى سلسلة فارغة.

  • التقنية الموصوفة أعلاه لعرض الأرقام حتى لو كانت قيمتها صفرًا تعمل مع حقل series_index القياسي.

مرجع دالة القالب