Jinja: الاحتفاظ ببادئة المسافة البيضاء في سلاسل متعددة الأسطر

تم إنشاؤها على ١٦ فبراير ٢٠١٣  ·  12تعليقات  ·  مصدر: pallets/jinja

في محرك StringTemplate - الذي استخدمته في بعض المشاريع لإصدار كود C - تتم إضافة بادئات المسافات البيضاء تلقائيًا في سطور الإخراج:

PrintCFunction(linesGlobal, linesLocal) ::= <<
void foo() {
    if (someRuntimeFlag) {
        <linesGlobal>
        if (anotherRuntimeFlag) {
            <linesLocal>
        }
    }
}
>>

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

void foo() {
    if (someRuntimeFlag) {
        int i;
        i=1;   // <=== whitespace prefix copied in 2nd
        i++;   // <=== and 3rd line
        if (anotherRuntimeFlag) {
            int j=i;
            j++; //  <=== ditto
        }
    }
}

أنا جديد على Jinja2 - وحاولت تكرار هذا:

#!/usr/bin/env python
from jinja2 import Template

linesGlobal='\n'.join(['int i;', 'i=1;'])
linesLocal='\n'.join(['int j=i;', 'j++;'])

tmpl = Template(u'''\
void foo() {
    if (someRuntimeFlag) {
        {{linesGlobal}}
        if (anotherRuntimeFlag) {
            {{linesLocal}}
        }
    }
}
''')

print tmpl.render(
    linesGlobal=linesGlobal,
    linesLocal=linesLocal)

.. لكن رأيته ينتج هذا:

void foo() {
    if (someRuntimeFlag) {
        int i;
i=1;
        if (anotherRuntimeFlag) {
            int j=i;
j++;
        }
    }
}

... وهو ليس ما أريده. تمكنت من جعل الإخراج يصدر بادئات مسافات بيضاء مناسبة مع هذا:

...
if (someRuntimeFlag) {
    {{linesGlobal|indent(8)}}
    if (anotherRuntimeFlag) {
        {{linesLocal|indent(12)}}
    }
}

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

هل هناك طريقة أفضل أفتقدها؟

التعليق الأكثر فائدة

عند إصدار YAML أو Python ، يصبح هذا أمرًا بالغ الأهمية.

ال 12 كومينتر

أنا مهتم في الأساس بنفس الشيء. ظهرت المشكلة أيضًا في stackoverflow: http://stackoverflow.com/questions/10821539/jinja-keep-indentation-on-include-or-macro

+1

صحيح أيضًا عند استخدام النموذج:

    {{linesGlobal|join('\n')}}

هذا النموذج لا يتصرف كما يتوقع المرء - نظرًا لأن jinja2 هو الذي ينبعث من الأسطر الجديدة ، يجب أن يتأكد من بقائها متماشية مع مستوى المسافة البادئة الأخير.

سيكون من الجميل جدا أن يكون! سيؤدي ذلك إلى نماذج أفضل بكثير وإخراج في نفس الوقت.

لماذا لا تنشئ خيار مسافة بيضاء آخر مشابه لـ {٪ + و {٪ - يسبق المسافة البادئة الحالية لأي شيء يتم تقييمه له؟ يمكن أن يكون {٪ = أو {٪ |

+1

+1

مطلوب هنا لصياغة وثائق مخطط API:

{% macro entity_one() -%}
{
    "one": 1,
    "two": 2
}
{% endmacro -%}

+ Response 200 (application/json):

        {
            "entity": [
                {{ entity_one() }}
            ]
        }

يتم تقديمه الآن:

+ Response 200 (application/json):

        {
            "entity": [
                {
    "one": 1,
    "two": 2

}

            ]
        }

عند إصدار YAML أو Python ، يصبح هذا أمرًا بالغ الأهمية.

ركض في نفس المشكلة.

هل هناك حل بديل في الوقت الحالي بخلاف تحديد ماكرو لكل نموذج مؤقت مضمن وإدخال المسافة البادئة يدويًا؟

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

kaikuchn شكرا لك يا

kaikuchn ، @ Cigizmoond-Vyhuholev Guys ، لست متأكدًا من أنني أتابع ... كما ترون في تقريري الأصلي في الجزء العلوي ، أذكر حلًا بديلًا باستخدام مرشح indent - ولكن أيضًا أذكر ذلك بوضوح لا يعالج المشكلة بالطريقة البسيطة والقوية التي يفعلها مثل StringTemplate ، لأنه يفرض عليك حساب مسافات المسافة البادئة في كل مرة تحتاج فيها إلى إصدار كتلة من الأسطر ... إذا كان عليك القيام بذلك وأنت تقوم بإنشاء رمز من أي شكل (C ، Python ، أيا كان) سوف تتخلى بسرعة عن العملية تمامًا ...

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

if (someRuntimeFlag) {
    {{linesGlobal|indent(8)}}
    if (anotherRuntimeFlag) {
        {{linesLocal|indent(12)}}
    }
}

... لأنني بحاجة إلى حساب "8" و "12" في كل قالب حيث أرسل رمزًا. بالمقارنة ، في StringTemplate ...

PrintCFunction(linesGlobal, linesLocal) ::= <<
void foo() {
    if (someRuntimeFlag) {
        <linesGlobal>
        if (anotherRuntimeFlag) {
            <linesLocal>
        }
    }
}
>>

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

إذا كان هذا لا يزال شيئًا يود المطورون الأساسيون رؤيته مطبقًا (المجتمع بالتأكيد يريده لأنه يمثل العلاقات العامة والمشكلة المفتوحة مع أكبر قدر من الإبهام) سأكون حريصًا على المساعدة وربما أحاول تنفيذ هذا بمفردي.

أود أيضا أن أرى هذه الميزة. سألاحظ أنه لا يمكن استخدام الحل البديل indent عندما يكون مستوى المسافة البادئة غير معروف. على سبيل المثال:

{{field.type}} {{field.name}}; {{field.comment|indent(??)}}

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

لدي فرضية واحدة. ماذا عن المستوى الأول من المسافة البادئة للتشذيب الأيسر في إعلان الكتلة؟

مثال:

{%- macro some_yaml_block(sub_block) ~%}
  label indented with how many spaces: 2
  amount of spaces that will be trimmed due to that "~" char above: 2
  {%- if sub_block ~%}
    "yay! we can indent ifs!": true
    the minimal indent in this if block is 2, so:
      this extra-indented value is still indented properly
  {%- endif %}
{%- endmacro -%}

now we invoke that here:
  {{ some_yaml_block(true) }}

سيكون العرض:

now we invoke that here:
  label indented with how many spaces: 2
  amount of spaces that will be trimmed due to that "~" char above: 2
  "yay! we can indent ifs!": true
  the minimal indent in this if block is 2, so:
    this extra-indented value is still indented properly

بشكل أساسي ، عند الانتهاء من كتلة بـ ~%} ، فإن Jinja:

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

إذا احتجت لاحقًا إلى تضمين هذه الكتلة مع بعض المسافة البادئة المحددة ، فكل ما تحتاجه هو تسميتها مثل some_yaml_block|indent . نظرًا لأنه تم تسوية المسافة البادئة في إعلان الكتلة ، يمكنك تحديدها لاحقًا بدون مشكلة. وستتصرف الكتلة باستمرار عبر المكالمات.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات