2024-04-17 11:20:27 -04:00
|
|
|
import { parse } from 'node-html-parser';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Eleventy plugin to add copy buttons to code blocks.
|
|
|
|
|
*/
|
2025-02-14 14:53:18 -05:00
|
|
|
export function copyCodePlugin(eleventyConfig, options = {}) {
|
2024-04-17 11:20:27 -04:00
|
|
|
options = {
|
|
|
|
|
container: 'body',
|
2024-12-14 17:08:29 -05:00
|
|
|
...options,
|
2024-04-17 11:20:27 -04:00
|
|
|
};
|
|
|
|
|
|
2025-02-14 14:53:18 -05:00
|
|
|
let codeCount = 0;
|
|
|
|
|
eleventyConfig.addTransform('copy-code', content => {
|
|
|
|
|
const doc = parse(content, { blockTextElements: { code: true } });
|
|
|
|
|
const container = doc.querySelector(options.container);
|
2024-04-17 11:20:27 -04:00
|
|
|
|
2025-02-14 14:53:18 -05:00
|
|
|
if (!container) {
|
|
|
|
|
return content;
|
|
|
|
|
}
|
2024-04-17 11:20:27 -04:00
|
|
|
|
2025-02-14 14:53:18 -05:00
|
|
|
// Look for code blocks
|
|
|
|
|
container.querySelectorAll('pre > code').forEach(code => {
|
|
|
|
|
const pre = code.closest('pre');
|
|
|
|
|
let preId = pre.getAttribute('id') || `code-block-${++codeCount}`;
|
|
|
|
|
let codeId = code.getAttribute('id') || `${preId}-inner`;
|
2024-04-17 11:20:27 -04:00
|
|
|
|
2025-02-14 14:53:18 -05:00
|
|
|
if (!code.getAttribute('id')) {
|
|
|
|
|
code.setAttribute('id', codeId);
|
|
|
|
|
}
|
|
|
|
|
if (!pre.getAttribute('id')) {
|
|
|
|
|
pre.setAttribute('id', preId);
|
|
|
|
|
}
|
2024-04-17 11:20:27 -04:00
|
|
|
|
2025-02-14 14:53:18 -05:00
|
|
|
// Add a copy button
|
|
|
|
|
pre.innerHTML += `<wa-icon-button href="#${preId}" class="block-link-icon" name="link"></wa-icon-button>
|
2025-04-09 16:47:40 -05:00
|
|
|
<wa-copy-button from="${codeId}" class="copy-button"></wa-copy-button>`;
|
2024-04-17 11:20:27 -04:00
|
|
|
});
|
2025-02-14 14:53:18 -05:00
|
|
|
|
|
|
|
|
return doc.toString();
|
|
|
|
|
});
|
2024-04-17 11:20:27 -04:00
|
|
|
}
|