Transform HTML to text/plain - Le Hollandais Volant
2026-04-01T20:08:45+02:00Mon code en PHP qui mange du HTML et sort du text/plain, sans les tags, mais en conservant au mieux les retours à la ligne, retirant les liens du corps du texte pour les lister tout à la fin.
C’est beaucoup moins trivial que ça n’y parait (encore une fois).
En particulier, il s’agit ici de parser des e-mails au format HTML, et de les convertir en text/plain. Problème : beaucoup d’e-mails HTML sont fait avec des tableaux et beaucoup de bruit bien dégueulasse.
La logique est :
– on nettoie les éléments parasites (faux espaces, éléments inutiles, entités)
– on grep les liens (qu’on placera à la fin)
– on grep les blockquotes (qu’on l’on sanitize à part)
– on vire touts les espaces et retours à la ligne : ceux qui vont apparaître dans le résultat final sont ceux correspondant aux éléments HTML (les P, UL, TABLE…).
– on nettoie à la fin les surplus d’espaces.
– c’est prêt.
Ce qui reste à faire :
– gérer les blockquotes imbriquées (ainsi que le fait que ça plante le wordwrap() à chaque nouveau niveau de "> " devant les lignes. Je suppose que je peux simplement faire un wordwrap() uniquement si la quote n’est pas déjà dans une autre quote, en diminuant la longueur du wrap() autant de fois que le niveau d’imbrications.
– je suppose qu’on peut aussi transformer les tableaux en tableaux dessinés en ASCII, et pareil pour d’autres éléments.
Mais ce n’est pas ce que je veux. J’ai fait les listes (ul/ol/dl), les images (remplacées par leur ALT) et les HR ; et c’est bien assez.
– virer les preg_replace_callback() car je n’aime pas cette logique. Je préfère une boucle, bien plus lisible.
Ça utilise les API DOM, mais aussi des Regex. J’ai malgré tout fait tout le DOM() en premier, pour ne pas avoir à jongler constamment de l’un à l’autre.
C’est loin d’être parfait mais c’est déjà pas mal fonctionnel.
J’aurais aussi pu examiner le source de Thunderbird par exemple, qui a une fonction du genre (c’est bien obligé).
Les IA m’ont un peu aidés sur le coup, notamment pour expliquer des Regex ou des fonctions internes de PHP, mais franchement, aucun n’a été capable de me pondre un truc qui soit au mieux fonctionnel (et c’est moyennement étonnant).
Les lib existantes ne m’ont pas tellement aidées non plus, car je voulais surtout appliquer mon code aux e-mails.
— (permalink)