Aller au contenu
Cragdoo Blog

Blocs de code & coloration syntaxique avec Expressive Code

Titres de cadre, boutons de copie, marqueurs de lignes, diffs, cadres terminal, retour à la ligne et sections repliables — toutes les fonctionnalités Expressive Code exposées par ce thème.

Rédaction 2 min de lecture

Tous les blocs de code de ce site sont rendus à la compilation par Expressive Code, propulsé par Shiki. Cela signifie un HTML accessible, copiable, rendu côté serveur sans coloriseur côté client — seulement un petit script pour le bouton de copie.

L’intégration est configurée dans astro.config.mjs avec deux thèmes : github-light pour chirpy-light, et github-dark-dimmed pour chirpy-dark. Basculer le thème du site bascule instantanément la palette du code.

Trois backticks plus un identifiant de langage :

function saluer(nom: string) {
return `Bonjour, ${nom} !`;
}

Si vous souhaitez écrire du HTML brut dans un bloc de code markdown et le faire rendre directement au lieu de le coloriser comme du code, utilisez l’identifiant de langage ashtml. Un plugin remark personnalisé convertit ces blocs en nœuds HTML bruts lors de la compilation.

```ashtml
<div class="alert alert-success">
<span>Voici du HTML brut rendu magnifiquement !</span>
</div>
```

Rendu final :

Voici du HTML brut rendu magnifiquement !

Si vous voulez des composants d’alerte daisyUI directement depuis Markdown/MDX, utilisez l’identifiant de langage alert. Un plugin remark dédié convertit chaque bloc en markup d’alerte compatible daisyUI.

```alert
type: success
style: soft
icon: lucide:check-circle
title: Achat confirmé !
description: Votre commande a été passée avec succès.
```

Pour la matrice complète des variantes (type, style, direction, icon, title, description, class), consultez Plugin alert : démonstration de toutes les variantes.

Ajoutez title="..." pour étiqueter le bloc — il apparaît dans une barre de titre style fenêtre :

src/utils/saluer.ts
function saluer(nom: string) {
return `Bonjour, ${nom} !`;
}

Utilisez frame="terminal" pour les snippets shell — Expressive Code bascule sur un chrome de type terminal :

Terminal
bun install
bun run dev

Pour forcer le cadre code sur quelque chose qu’Expressive Code détecterait comme un terminal :

echo "traité comme un fichier code, pas un terminal"

Surlignez, marquez, insérez ou supprimez des lignes spécifiques.

import { defineCollection, z } from 'astro:content';
export const collections = {
posts: defineCollection({ schema: z.object({ title: z.string() }) }),
};

import { defineCollection, z } from 'astro:content';
export const collections = {
posts: defineCollection({
schema: z.object({ title: z.string() }),
}),
};

const ancien = 'à supprimer';
const obsolete = 'moi aussi';
const conserve = 'survit';

Surligner chaque occurrence d’un littéral :

import { useTranslations } from '../i18n/utils';
const t = useTranslations(locale);
const titre = t('post.comments');

Le langage diff est supporté nativement. Les lignes commençant par + et - sont colorées automatiquement.

Refactor : source d'image hero
const heroSrc = typeof img === 'string' ? img : img?.src;
const heroSrc = heroImageSrc(post);
const showHero = shouldShowHero(post);

Long fichier ? Repliez les parties non pertinentes pour focaliser le lecteur. Utilisez collapse={start-end} :

src/utils/posts.ts
import { getCollection, type CollectionEntry } from 'astro:content';
import { SITE, type Locale } from '../config';
// utilitaires d'aide au-dessus
function detectLocale(id: string): Locale {
return id.startsWith('fr/') ? 'fr' : 'en';
}
export async function getPosts(locale: Locale) {
const all = await getCollection('posts');
return all.filter((p) => detectLocale(p.id) === locale);
}

Cliquez sur l’indicateur de lignes repliées pour développer le bloc.

Les longues lignes défilent normalement à l’horizontale. Pour les faire passer à la ligne, ajoutez wrap :

const valeurTresLongue =
'une chaîne qui causerait normalement un défilement horizontal mais qui passe à la ligne sur les viewports étroits';

Chaque bloc dispose d’un bouton de copie en haut à droite. L’icône passe à une coche quand la copie réussit, puis se réinitialise. Les chaînes de traduction proviennent de src/i18n/ui.ts (code.copy, code.copied), donc le build français affiche un libellé français.

Expressive Code ne montre pas les numéros de ligne par défaut — Chirpy non plus. Si vous les voulez, ajoutez le plugin @expressive-code/plugin-line-numbers à astro.config.mjs et activez-le par bloc avec showLineNumbers.

Un bloc réaliste combine plusieurs modificateurs :

src/utils/seo.ts
import type { CollectionEntry } from 'astro:content';
import type { Locale } from '../config';
export function buildSeo(entry: CollectionEntry<'posts'>, locale: Locale) {
const canonical = entry.data.canonicalURL ?? defaultCanonical(entry, locale);
const ogImage = entry.data.heroImage ?? ogDefaultImg.src;
const lang = entry.data.lang ?? locale;
return { canonical, ogImage, lang };
}

Ouvrez astro.config.mjs et modifiez les options expressiveCode pour changer de thèmes :

astro.config.mjs
expressiveCode({
themes: ['github-light', 'github-dark-dimmed'],
themeCssSelector: (theme) =>
theme.name === 'github-light' ? '[data-theme="chirpy-light"]' : '[data-theme="chirpy-dark"]',
styleOverrides: { borderRadius: '0.5rem' },
});

Choisissez n’importe quel thème Shiki — les deux thèmes doivent être listés pour que le CSS double mode soit émis.