wooorm / refractor

Lightweight, robust, elegant virtual syntax highlighting using Prism
MIT License
722 stars 33 forks source link

Allow Prism token name mappings to allow custom classNames #39

Closed DarkPurple141 closed 3 years ago

DarkPurple141 commented 3 years ago

Hi there!

Wondering what you think about this: https://github.com/react-syntax-highlighter/react-syntax-highlighter/issues/372

Essentially we're struggling the fact react-syntax-highlighter when using classnames can suffer from style leakage into code blocks. For example.

<style>.punctuation { color: 'emerald' }</style>
<span class="token punctuation">.</span>

We're trying to make this less unsafe to use in production, and noted a Prism plugin that does support remapping classnames. https://prismjs.com/plugins/custom-class/. This would nice to use, although there may be other approaches.

Do you have any thought on slightly opening/tweaking the refractor API to support className mapping?

DarkPurple141 commented 3 years ago

I'm happy to contribute a PR if need be, but wanted to canvas some approaches beforehand.

wooorm commented 3 years ago

I don’t see why that needs to land here: this project is a vdom version of Prism, I’d say this is outside of its scope. And more, you can do this yourself. You get an AST out which you can change however you please: https://unifiedjs.com/learn/recipe/tree-traversal/.

(notably: unist-util-visit and hast-util-classnames are of help)

DarkPurple141 commented 3 years ago

Sorry if I didn't explain myself well.

I have plenty of experience writing AST implementations - I'm not that keen on rewriting the core functionality of this library or forking it just to amend a configuration option.

We definitely want the VDOM approach. I feel like this feature would be well-utilised by downstream libraries like react-syntax-highlighter. I'd also prefer not to re-traverse the DOM, or the AST after refractor has already been run.

Here's what I'm suggesting at a very basic level, for example in languages/abap.js

function abap(Prism) {
  // something like
  const { classMap } = Prism.config

  Prism.languages.abap = {
    [classMap['comment']]: /^\*.*/m,
    [classMap['string']]: /(`|')(?:\\.|(?!\1)[^\\\r\n])*\1/m,
    ...
    },
...
wooorm commented 3 years ago

I'm not that keen on rewriting the core functionality of this library or forking it just to amend a configuration option.

It’s not the core of Prism. It’s a plugin there. Why can’t it be a plugin here? It doesn’t have to be a rewrite or a fork. it can be a small utility that walks the tree.

I feel like this feature would be well-utilised by downstream libraries like react-syntax-highlighter.

Sure, but that’s not an argument for it being in core.

I'd also prefer not to re-traverse the DOM, or the AST after refractor has already been run.

Why? refractor builds an AST. This is like asking Babel to ship something in core even though it has a nice plugin ecosystem. Or PostCSS. Or unified.