@khaister/expressive-code-word-wrap
v1.0.0
Published
An Expressive Code plugin that adds a button to manually toggle word wrap on individual code blocks.
Maintainers
Readme
expressive-code-word-wrap
An Expressive Code plugin that adds a button to every code block, letting readers manually toggle word wrap on and off — similar to the built-in "Copy to clipboard" button.
Expressive Code already supports word wrap, but only as a static, build-time setting (wrap: true in a code fence's meta string, or as a defaultProps config). This plugin adds a client-side toggle on top of that, so wrap can be turned on or off per code block at read time, regardless of how (or whether) wrap was configured for that block.
Installation
npm install @khaister/expressive-code-word-wrapUsage
Import the plugin's initialization function and add it to your Expressive Code configuration's plugins array.
Astro (astro-expressive-code)
// astro.config.mjs
import { defineConfig } from 'astro/config';
import astroExpressiveCode from 'astro-expressive-code';
import { pluginWordWrap } from '@khaister/expressive-code-word-wrap';
export default defineConfig({
integrations: [
astroExpressiveCode({
plugins: [pluginWordWrap()],
}),
],
});Starlight
// astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import { pluginWordWrap } from '@khaister/expressive-code-word-wrap';
export default defineConfig({
integrations: [
starlight({
title: 'My Docs',
expressiveCode: {
plugins: [pluginWordWrap()],
},
}),
],
});Plain Expressive Code (e.g. Next.js via remark-expressive-code)
import { pluginWordWrap } from '@khaister/expressive-code-word-wrap';
const config = {
plugins: [pluginWordWrap()],
};It composes with @expressive-code/plugin-frames — if you use both, the button joins the same button group as "Copy to clipboard", matching its size, spacing, and hover auto-hide behavior exactly. Plugin order in the plugins array doesn't matter.
Options
pluginWordWrap({
// Set to `false` to hide the button and only compute the CSS
// variables word wrap needs (useful if you want to build your own UI)
// Default: true
showButton: true,
// Keep wrapped lines aligned with their original indentation level,
// matching the built-in `preserveIndent` option
// Default: true
preserveIndent: true,
});Styling
This plugin registers a wordWrap style setting namespace that can be customized via Expressive Code's styleOverrides config option, the same way you'd customize any other plugin's styles:
astroExpressiveCode({
plugins: [pluginWordWrap()],
styleOverrides: {
wordWrap: {
// icon: createInlineSvgUrl([...]),
},
},
});How it works
Expressive Code's built-in word wrap is a CSS class flip: a wrap class on the code block's <pre> element switches white-space from pre to pre-wrap. This plugin:
- Always computes the
--ecMaxLineand (optionally)--ecIndentCSS variables that Expressive Code's wrap styles rely on, even for blocks that weren't statically configured withwrap: true. - Renders a toggle button into each code block via the
postprocessRenderedBlockhook. - Ships a small client-side script (
jsModules) that toggles thewrapclass on the nearest<pre>when the button is clicked, and re-initializes buttons after client-side navigation (including Astro view transitions).
Credits
The default button icon is the text-wrap icon from Lucide, used under Lucide's ISC License.
