Skip to content

Instantly share code, notes, and snippets.

@MattIPv4
Created December 28, 2021 20:32
Show Gist options
  • Save MattIPv4/06d3b72fd546c945ade182e45918ee09 to your computer and use it in GitHub Desktop.
Save MattIPv4/06d3b72fd546c945ade182e45918ee09 to your computer and use it in GitHub Desktop.

Prism Patch

Rough guide to patch Prism such that it doesn't globally pollute.

Get Prism

script/prism.sh

#!/bin/sh

set -e -u -o pipefail

# Clean out existing vendor-ed PrismJS
rm -rf vendor/prismjs

# Fetch latest PrismJS source
FILE=$(npm pack prismjs)
FILE_DIR="vendor/prismjs"

# Extract PrismJS
mkdir -p $FILE_DIR
tar -xzf $FILE -C $FILE_DIR
rm $FILE

# Locate the inner directory
FILE_DIR_INNER=$(find $FILE_DIR -type d -mindepth 1 -maxdepth 1 -print | head -n1)

# Move up a directory
mv $FILE_DIR_INNER/* $FILE_DIR
rm -rf $FILE_DIR_INNER

# Remove all minified JS
find $FILE_DIR -type f -name '*.min.js' -exec rm {} +

# Run the patch script
node script/prism.js

Patch Prism

script/prism.js

const fs = require('fs');
const path = require('path');

const getFilesInDir = dir => fs.readdirSync(dir, { withFileTypes: true })
  .flatMap(file => (file.isDirectory() ? getFilesInDir(path.join(dir, file.name)) : path.join(dir, file.name)));

const base = path.join(process.cwd(), 'vendor', 'prismjs');

// Patch the core to not use `window` or `global`
let core = fs.readFileSync(path.join(base, 'prism.js'), 'utf8');
core = core.replace(/\nvar _self = [^;]+;\n/, '\nvar _self = {};\n');
core = core.replace(/\/\/\/ <reference lib="WebWorker"\/>\n+/, '');
core = core.replace(/global\.Prism = Prism;/, '// global.Prism = Prism;');
fs.writeFileSync(path.join(base, 'prism.js'), core);

// Remove the auto-loader
fs.unlinkSync(path.join(base, 'components', 'index.js'));

// Patch all the components + plugins to export functions
const components = getFilesInDir(path.join(base, 'components')).filter(f => f.endsWith('.js'));
const plugins = getFilesInDir(path.join(base, 'plugins')).filter(f => f.endsWith('.js'));
for (const file of components.concat(plugins)) {
  let source = fs.readFileSync(file, 'utf8');
  source = `module.exports = Prism => {\n\t${source.trim().replace(/\n/g, '\n\t')}\n};\n`;
  fs.writeFileSync(file, source);
}

Use Prism

import Prism from './vendor/prismjs';
import prismCopyToClipboard from './vendor/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';
import prismToolbar from './vendor/prismjs/plugins/toolbar/prism-toolbar';
import prismRuby from './vendor/prismjs/components/prism-ruby';

// Register plugins
prismToolbar(Prism);
prismCopyToClipboard(Prism);

// Register languages
prismRuby(Prism);

// Run Prism
Prism.highlightAllUnder(elm);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment