import { parse } from 'node-html-parser'; import { v4 as uuid } from 'uuid'; /** * Eleventy plugin to turn `` blocks into live examples. */ export function codeExamplesPlugin(options = {}) { options = { container: 'body', ...options }; return function (eleventyConfig) { eleventyConfig.addTransform('code-examples', content => { const doc = parse(content, { blockTextElements: { code: true } }); const container = doc.querySelector(options.container); if (!container) { return content; } // Look for external links container.querySelectorAll('code.example').forEach(code => { const pre = code.closest('pre'); const hasButtons = !code.classList.contains('no-buttons'); const isOpen = code.classList.contains('open') || !hasButtons; const noEdit = code.classList.contains('no-edit'); const id = `code-example-${uuid().slice(-12)}`; let preview = pre.textContent; // Run preview scripts as modules to prevent collisions const root = parse(preview, { blockTextElements: { script: true } }); root.querySelectorAll('script').forEach(script => script.setAttribute('type', 'module')); preview = root.toString(); const codeExample = parse(`
${preview}
${pre.outerHTML}
${ hasButtons ? `
${ noEdit ? '' : ` ` } ` : '' }
`); pre.replaceWith(codeExample); }); return doc.toString(); }); }; }