I've just released a plugin for Markdown-It. I wanted to have tighter control over how my code blocks were displayed on my site, adding a "Copy" button as well.
Maybe it's over-engineered. Maybe it's a niche need. But I certainly don't want to have to loop over my compiled code and edit every block to add a button to it. And given the options I saw weren't sufficient for me in terms of customisation, well, here we are.
Now, if I say customisation, you say "Eleventy"! At least I doโฆ anyways! You can give the plugin a big ol' configuration object to customise the codeblock wrapper, the button, the copy button and even add a "toolbar". You can find a list of the options on the aforementioned NPM or GitHub links.
For this site, the configuration looks like this (and look, you can copy it!):
Thanks to how tokens[idx].info is handled, I can actually type ```js:.eleventy.js and it will change the toolbar to .eleventy.js instead of simply "JS" (or JavaScript with that switch case). This is not standard (which is also why the info property is reset after parsing the filename) and only a little nicety I'm adding for me, which is why it is not part of the plugin's code.
Given I set inlineCopyHandler: false, the onclick handler on the button is gone. So now I need to set up my own handler. In Eleventy, I do this with a transform that checks if a button exists, or rather, in this case, a specific data attribute, data-codewrap-copy-button. (there would be other ways to do this but this is the easiest) If that string exists (which I don't use anywhere else โ the button gets its own CSS class name), I can assume there is a copy button in a code block, and inject a script in the <head>. Note that I actually use a slightly different approach, but the end result is pretty much the same:
Give it a go, let me know what you think, and if you see any missing features that could be added!