rehype-script-to-code
v1.1.0
Published
A [rehype](https://github.com/rehypejs/rehype) plugin that transforms `<script>` tags in HTML to `<pre><code>` blocks with syntax highlighting support. Perfect for documentation sites, tutorials, and blog posts where you want to display script content as
Maintainers
Readme
rehype-script-to-code
A rehype plugin that transforms <script> tags in HTML to <pre><code> blocks with syntax highlighting support. Perfect for documentation sites, tutorials, and blog posts where you want to display script content as highlighted code blocks instead of executing them.
Features
- 🔄 Automatically converts
<script>tags to<pre><code>blocks - 🎨 Preserves language information for syntax highlighting
- 🗺️ Customizable language mapping for different script types
- 🎯 Selective transformation with custom filter functions
- 📦 Preserves original attributes (id, class, data-, aria-)
- ✂️ Configurable content trimming
- 🚫 Skip external scripts and empty scripts options
- 🔧 Full TypeScript support with type definitions
Installation
npm install rehype-script-to-codeyarn add rehype-script-to-codepnpm add rehype-script-to-codeUsage
Basic Usage
import { rehype } from 'rehype';
import { rehypeScriptToCode } from 'rehype-script-to-code';
const processor = rehype()
.use(rehypeScriptToCode);
const html = `
<html>
<body>
<script type="text/javascript">
console.log('Hello, World!');
</script>
</body>
</html>
`;
const result = await processor.process(html);Output:
<html>
<body>
<pre><code class="language-javascript">console.log('Hello, World!');</code></pre>
</body>
</html>With Options
import { rehype } from 'rehype';
import { rehypeScriptToCode } from 'rehype-script-to-code';
const processor = rehype()
.use(rehypeScriptToCode, {
defaultLanguage: 'javascript',
preserveAttributes: true,
additionalClasses: ['highlight', 'script-block'],
langMap: {
'custom-script': 'javascript',
'shader': 'glsl'
},
shouldTransform: (node) => {
// Skip scripts with data-no-transform attribute
return !node.properties?.['data-no-transform'];
}
});Integration with unified
import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import rehypeStringify from 'rehype-stringify';
import { rehypeScriptToCode } from 'rehype-script-to-code';
const processor = unified()
.use(rehypeParse)
.use(rehypeScriptToCode, {
skipExternal: true,
trimContent: true
})
.use(rehypeStringify);
const result = await processor.process(htmlString);Options
defaultLanguage
- Type:
string - Default:
'javascript' - Description: Default language for code blocks when the script type cannot be determined
langMap
- Type:
Record<string, string> - Default: See default language mappings
- Description: Custom mapping from script type/lang attributes to code language identifiers
preserveAttributes
- Type:
boolean - Default:
false - Description: Preserve original script tag attributes (id, class, data-, aria-) on the pre element
additionalClasses
- Type:
string[] - Default:
[] - Description: Additional CSS classes to add to the pre element
trimContent
- Type:
boolean - Default:
true - Description: Trim whitespace from script content
shouldTransform
- Type:
(node: Element) => boolean - Default:
null - Description: Custom function to determine if a script should be transformed
skipExternal
- Type:
boolean - Default:
true - Description: Skip script tags with
srcattribute (external scripts)
skipEmpty
- Type:
boolean - Default:
true - Description: Skip empty script tags
codeBlockClass
- Type:
string - Default:
'' - Description: Additional class for the code element
Default Language Mappings
The plugin includes default mappings for common script types:
{
// MIME types
'text/javascript': 'javascript',
'application/javascript': 'javascript',
'text/ecmascript': 'javascript',
'application/ecmascript': 'javascript',
'text/typescript': 'typescript',
'application/typescript': 'typescript',
'text/jsx': 'jsx',
'text/tsx': 'tsx',
'application/json': 'json',
'application/ld+json': 'json',
// Module types
'module': 'javascript',
'importmap': 'json',
// Common shorthand
'js': 'javascript',
'ts': 'typescript',
'jsx': 'jsx',
'tsx': 'tsx',
'json': 'json',
// Template languages
'text/html': 'html',
'text/x-template': 'html',
'text/x-handlebars-template': 'handlebars',
}Advanced Examples
Preserve Attributes and Custom Classes
const processor = rehype()
.use(rehypeScriptToCode, {
preserveAttributes: true,
additionalClasses: ['code-example', 'syntax-highlight'],
codeBlockClass: 'formatted-code'
});
// Input:
// <script id="example" class="demo" data-example="true">
// const x = 10;
// </script>
// Output:
// <pre id="example" class="demo code-example syntax-highlight" data-example="true">
// <code class="language-javascript formatted-code">const x = 10;</code>
// </pre>Custom Language Detection
const processor = rehype()
.use(rehypeScriptToCode, {
langMap: {
'vertex-shader': 'glsl',
'fragment-shader': 'glsl',
'compute-shader': 'wgsl',
'custom-lang': 'javascript'
}
});
// Input:
// <script type="vertex-shader">
// attribute vec3 position;
// void main() {
// gl_Position = vec4(position, 1.0);
// }
// </script>
// Output:
// <pre><code class="language-glsl">attribute vec3 position;
// void main() {
// gl_Position = vec4(position, 1.0);
// }</code></pre>Selective Transformation
const processor = rehype()
.use(rehypeScriptToCode, {
shouldTransform: (node) => {
// Only transform scripts with specific attributes
const properties = node.properties || {};
// Transform only if has data-highlight attribute
if (properties['data-highlight']) {
return true;
}
// Or if it's a template script
if (properties.type === 'text/x-template') {
return true;
}
return false;
}
});Working with Syntax Highlighters
The plugin works seamlessly with popular syntax highlighting libraries:
With Prism.js
import { rehype } from 'rehype';
import { rehypeScriptToCode } from 'rehype-script-to-code';
import rehypePrism from 'rehype-prism';
const processor = rehype()
.use(rehypeScriptToCode)
.use(rehypePrism);With Shiki
import { rehype } from 'rehype';
import { rehypeScriptToCode } from 'rehype-script-to-code';
import rehypeShiki from '@shikijs/rehype';
const processor = rehype()
.use(rehypeScriptToCode)
.use(rehypeShiki, {
theme: 'github-dark'
});Use Cases
Documentation Sites
Transform inline script examples into highlighted code blocks for better readability:
// Perfect for MDX documentation
const processor = rehype()
.use(rehypeScriptToCode, {
preserveAttributes: true,
additionalClasses: ['example-code']
});Blog Posts
Display script content without execution:
// Prevent script execution while showing the code
const processor = rehype()
.use(rehypeScriptToCode, {
skipExternal: true,
trimContent: true
});Educational Content
Create interactive tutorials with visible code:
// Show both the code and allow selective execution
const processor = rehype()
.use(rehypeScriptToCode, {
shouldTransform: (node) => {
// Only transform scripts marked for display
return node.properties?.['data-display'] === 'true';
}
});TypeScript Support
The plugin includes full TypeScript definitions:
import { rehypeScriptToCode, RehypeScriptToCodeOptions } from 'rehype-script-to-code';
const options: RehypeScriptToCodeOptions = {
defaultLanguage: 'typescript',
preserveAttributes: true,
additionalClasses: ['code-block'],
shouldTransform: (node) => !node.properties?.['data-skip']
};
const processor = rehype()
.use(rehypeScriptToCode, options);API
rehypeScriptToCode(options?)
Transform <script> tags to <pre><code> blocks.
Parameters
options(optional): Configuration options object
Returns
A unified transformer function.
defaultLangMap
Export of the default language mappings used by the plugin.
import { defaultLangMap } from 'rehype-script-to-code';
console.log(defaultLangMap['text/javascript']); // 'javascript'Compatibility
- Node.js 14+
- ES Modules
- Works with rehype 12+ and unified 10+
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
MIT © wan-kong
Related
- rehype - HTML processor powered by plugins
- unified - Interface for processing text with syntax trees
- hast - Hypertext Abstract Syntax Tree format
Acknowledgments
Built with the unified collective ecosystem.
