colorisation



Amélioration du CMS : colorisation syntaxique des blocs de code

Les articles comportant des exemples de code sont plus lisibles lorsque la syntaxe est colorisée.
Dans l’éditeur, un bloc de code est inséré entre de simples balises <pre><code>...</code></pre>. Mais il n’y a pas de de colorisation syntaxique en fonction du type de code inséré.

Comment l'améliorer ?

Le CMS utilise l'éditeur Tiptap, ce dernier a déjà un grand nombre d'extensions intéressantes. CodeBlockLowlight a retenu notre attention car il utilise le module Lowlight pour la colorisation syntaxique. Malheureusement, cette extension n'était pas incluse dans l'éditeur du CMS.

Etapes de la réalisation

Ajouter une extension à l'éditeur

L’ajout d’une extension n’est pas si évidente au premier abord. Il a fallu créer un module qui contenait les différents réglages ainsi qu’un code javascript pour son implantation. Le CMS propose un exemple d'intégration sous la forme d'un module incorporant les extensions typography : rich-text-example-extensions.

En se basant sur ce dernier, nous avons implémenté un module d'extension CodeBlockLowlight.

module.exports = {
  improve: '@apostrophecms/rich-text-widget',
  options: {
    CodeBlockConfig: {}
  },
  extendMethods(self) {
    return {
      getBrowserData(_super, req) {
        const initialData = _super(req);
        const finalData = {
          ...initialData,
          aposCodeBlockConfig: self.options.CodeBlockConfig
        }
        return finalData;
      }
    }
  }
};


Ce nouveau module a ensuite été intégré à l'installation de base du CMS.

Il a également fallu modifier le widget richtext pour ignorer l'ancien module codeblock et incorporer le nouveau dans la barre d’outils.

Le CMS étant utilisé en mode “headless”, il restait à implémenter l’affichage côté frontend.

Ajouter un renderer au frontend

Pour implémenter le rendu coté frontend, le widget richtext a du accueilir du code complémentaire pour convertir la mise en forme.

// ...
function highlightCodeBlock(input) {
    const lowlight = createLowlight(common);
    // the CMS sanitizer insist to convert & to &amp; before storing -> have to reverse it
    const withoutamp = input
        .replace(/&amp;/g, "&")
        .replace(/>/g, ">")
        .replace(/</g, "<");
    const tree = lowlight.highlightAuto(withoutamp);
    const output = toHtml(tree, {
        omitOptionalTags: true,
    });
    return output;
}
const newOutput = newcontent.replaceAll(
    new RegExp(/(<pre><code>)([\s\S]*?)(<\/code><\/pre>)/gm),
    (match, p1, p2, p3, offset) => {
        return p1 + highlightCodeBlock(p2) + p3;
    },
);
newcontent = newOutput;
// ...


Le style nécessaire a été incorporé à la mise en forme du code sous forme d’un bloc de style intégré dans le modèle Astro du widget RichText.

Le CMS comporte désormais une colorisation syntaxique des blocs de code.