Amélioration de la réduction d'email (aucune réduction dans les blocs de code)

J’ai également ouvert un problème GitHub à ce sujet, mais je voulais le publier ici aussi au cas où plus de personnes suivraient :

Je pense qu’il serait formidable que la logique de suppression des e-mails puisse être améliorée pour éviter de supprimer le contenu à l’intérieur des blocs de code. Par exemple, dans un e-mail contenant :

```
# Ceci ne devrait pas être supprimé
#
# Ou coupé
# C'est du code
####
Code code code
```

Tout ce qui se trouve après le premier ‘#’ est supprimé. C’est un peu gênant, car beaucoup de gens utilisent des marqueurs de commentaires pour diviser des sections de leur code, parfois même dans des chaînes multilignes pour l’impression. Cela a également pour avantage pratique que si les gens veulent copier-coller la sortie d’un programme dans un e-mail et que cette sortie inclut de telles lignes, l’e-mail ne sera pas coupé à ces endroits si la sortie du programme est encadrée par des guillemets. Y a-t-il une chance que ce soit un problème suffisamment courant pour que quelqu’un ait un moment pour voir s’il pourrait être amélioré ? Je suis allé jusqu’à l’expression régulière où la correspondance se produit, mais je ne sais pas à quel point il serait complexe d’ajouter une exception pour les blocs de code.

Merci !

Ok, j’ai dû apprendre un peu de Ruby, mais :

La discussion est la bienvenue !

3 « J'aime »

Pour que nous soyons sur la même longueur d’onde, reformulons votre problème afin que nous parlions de la même chose :wink:

Vous souhaitez pouvoir gérer correctement les blocs de code clôturés dans les réponses par e-mail, surtout s’ils contiennent le symbole #, qui est souvent utilisé comme délimiteur (de signature) et est donc tronqué.

Ainsi, si vous deviez envoyer la réponse par e-mail suivante

Voici mon patch

```
# Ceci est un commentaire
####

answer = 42
```

Est-ce que ça vous semble bien ?

Il devrait être suffisamment « intelligent » pour reconnaître que les lignes entre les ``` sont du code réel et doivent donc être « ignorées » du traitement normal.

Si c’est le cas, je recommanderais une solution / approche différente. Il serait peut-être préférable de remonter tous les blocs de code dans la fonction preprocess! et de les réinjecter ensuite.

Les blocs de code clôturés sont quelque peu difficiles à analyser correctement à l’aide d’une expression régulière, mais pour une solution suffisamment bonne, cela devrait fonctionner

def hoist_code_blocks(text)
  blocks = {}
  pattern = /^```\\w*$\\n.*?^```$/m
  
  text.gsub(pattern) do |block|
    token = SecureRandom.hex
    blocks[token] = block
    token
  end

  [text, blocks]
end

Cette méthode remplacera tous les blocs de code par une valeur aléatoire et conservera la correspondance entre la valeur aléatoire et le contenu du bloc dans le hachage blocks.

Vous pouvez l’appeler comme ceci

text = "some text\n```ruby\ndef foo\nend\n```\nmore text"
new_text, blocks = hoist_code_blocks(text)

Et ensuite, vous pouvez « restaurer » les blocs de code avec le code suivant

blocks.each { |token, block| new_text.gsub!(token, block) }

Merci pour votre réponse ! Vous avez bien compris le problème que je rencontre, oui.

J’ai pensé à faire quelque chose de similaire, et je serais ravi que cela soit implémenté si cela fonctionne et correspond le plus fidèlement possible au comportement de l’analyseur dans le navigateur. Par exemple, dans l’interface du navigateur, j’ai le droit d’avoir des espaces avant ma déclaration de langage, et j’ai le droit d’avoir des espaces après ma fermeture :

int x=42;<br>
```         (beaucoup d'espaces ici)

Cela s'affiche toujours correctement comme :
```                    c++
int x=42;

Dans le PR ci-dessus, j’ai essayé de suivre les règles que j’ai pu identifier dans l’analyseur.

Les deux autres questions que je poserais concernant votre implémentation sont : est-ce que cela devrait vraiment être fait dans preprocess!, de sorte que les blocs doivent également être transmis ou conservés par la classe EmailReplyTrimmer (et quelle serait la préférence), et pourrait-il y avoir un bug là-dedans, car le text qui y est retourné est le même que le texte original, sans aucune substitution effectuée (semble-t-il que gsub retourne un énumérateur des correspondances, mais vous n’effectuez pas réellement le remplacement ici ?).

Dans tous les cas, je suis heureux que vous utilisiez le test qui a été ajouté dans ma pull request ci-dessus si vous préférez ajouter ce code à l’analyseur vous-même, ou si vous m’informez des quelques problèmes ci-dessus, je peux créer une nouvelle pull request. Vous avez absolument bien compris le problème, et il semble que votre solution soit proche, je ne suis juste pas tout à fait sûr de la manière dont vous aimeriez qu’elle soit finalisée.

Merci !

Ouais, ça commence à devenir compliqué… C’est faisable, mais il y aura toujours des cas limites par rapport à un vrai analyseur.

Vous pouvez aussi avoir plus de 3 \ , 3 étant le minimum :wink:

Vous pouvez aussi le faire dans la fonction trim, juste après l’appel à preprocess! et faire l’étape de “post-traitement” vers la fin.

C’est vrai, c’était surtout du pseudo-code :sweat_smile:

Vous pouvez probablement utiliser gsub! ou faire text = text.gsub....

Ok, super — j’ai ouvert une nouvelle PR ici :

Merci encore !

3 « J'aime »

Bumpé la version dans Discourse également :up:

3 « J'aime »

Ce sujet a été automatiquement fermé après 39 heures. Les nouvelles réponses ne sont plus autorisées.