Jinja: le filtre wordwrap ignore les nouvelles lignes existantes

Créé le 5 févr. 2013  ·  9Commentaires  ·  Source: pallets/jinja

Salut,

J'ai remarqué que lors de l'utilisation de ce filtre pour (par exemple) garantir qu'un message électronique est toujours encapsulé à 72 caractères (dans la mesure du possible) pour en assurer un affichage agréable aussi souvent que possible, nous avons remarqué que wordwrap n'utiliserait pas les nouvelles lignes existantes dans le message comme indice mais insérerait à la place des retours à la ligne strictement tous les 72 caractères.

C'est notre solution de contournement

## Workaround bug in do_wordwrap where it disregards existing linebreaks 
## when wrapping text

from jinja2.filters import environmentfilter
import re
<strong i="8">@environmentfilter</strong>
def do_wordwrap(environment, s, width=79, break_long_words=True):
    """
    Return a copy of the string passed to the filter wrapped after
    ``79`` characters.  You can override this default using the first
    parameter.  If you set the second parameter to `false` Jinja will not
    split words apart if they are longer than `width`.
    """
    import textwrap
    accumulator = []
    # Workaround: pre-split the string
    for component in re.split(r"\r?\n", s):
        # textwrap will eat empty strings for breakfirst. Therefore we route them around it.
        if len(component) is 0:
            accumulator.append(component)
            continue
        accumulator.extend(
            textwrap.wrap(component, width=width, expand_tabs=False,
                replace_whitespace=False,
                break_long_words=break_long_words)
        )
    return environment.newline_sequence.join(accumulator)

Pas agréable et complet mais fonctionne pour nous.

J'aimerais que ceci (ou quelque chose de similaire) soit inclus dans jinja2 proprement dit, car cela rend le filtre wordrwap beaucoup plus utile.

Qu'est-ce que tu penses?

Tous les 9 commentaires

Je ne pense pas que ce soit un bug. Wordwrap semble simplement supposer que votre texte n'est pas encore enveloppé.

Je ne pense pas que ce soit un bug. Wordwrap semble simplement supposer que votre texte n'est pas encore enveloppé.

Bien évidemment. Mais cela le rend vraiment difficile à utiliser dans un environnement où vous avez besoin d'un habillage mais où le texte que vous souhaitez encapsuler contient déjà une certaine forme de mise en forme (pour séparer des paragraphes par exemple).

Des nouvelles de celui-ci ? Nous avons des e-mails en texte brut où nous devons nous assurer que les paragraphes sont encapsulés à la fin, mais nous voulons que les lignes du paragraphe soient encapsulées automatiquement. Cela semble être un cas d'utilisation courant. En fait, cette zone de commentaire dans laquelle je tape ce message fait la même chose. Ces lignes sont automatiquement enveloppées, mais lorsque j'appuie sur double entrée

un nouveau paragraphe commence.

Ne pourriez-vous pas utiliser le module de messagerie stdlib pour cela ?

A quel moment l'inséreriez-vous ?
Nous utilisons Jinja2 pour générer et localiser les mails et après avoir compilé le modèle, transmettons la chaîne résultante à pyramid_mailer/repoze_sendmail.

Un modèle d'e-mail en texte brut ressemble à ceci :

{%- filter wordwrap(width=72, break_long_words=False) -%}
{% block greeting -%}
{% trans full_name = _(user.full_name) %}Hello {{ full_name }},{% endtrans %}
{% endblock -%}

{% block message_intro %}
{% endblock -%}

{% trans -%}
This may be a very long text in another language, depending on what a translator put into the gettext localization. It may even have its own paragraphs.
{%- endtrans %}

...

J'ai également rencontré ce problème et une recherche Google m'a conduit ici. L'utilisation du correctif de @dwt fonctionne pour moi. Je vote également pour que ce changement soit intégré dans la base de code.

Idem ici, ce serait génial d'intégrer le correctif dans le maître !

Notez que wrapstring disparu dans le patch

J'ai soumis une demande d'extraction qui contourne ce comportement quelque peu inattendu de textwrap.wrap() lorsqu'il s'agit de plusieurs paragraphes.

wrapstring et les lignes vides sont conservées.

Nous utilisons cette fonctionnalité pour générer des corps d'e-mail dans le cadre d'une autre application et souhaitons envelopper l'entrée dans 80 colonnes.

Je rencontre également ce problème dans mon modèle nbconvert. Ce serait super d'avoir fusionné #766 car si je dois écrire mon propre filtre, je pense que je devrai écrire un exportateur personnalisé pour nbconvert, ce que j'essaie d'éviter pour la facilité d'utilisation.

Cette page vous a été utile?
0 / 5 - 0 notes