prism-react-renderer icon indicating copy to clipboard operation
prism-react-renderer copied to clipboard

Add support for diff-highlight

Open rrousselGit opened this issue 5 years ago • 4 comments

Related to https://github.com/FormidableLabs/prism-react-renderer/issues/2 and https://github.com/facebook/docusaurus/issues/3318

Prism comes with a useful plugin: diff-highlight for combining syntax highlighting and diff highlighting.

Since prism-react-renderer does not support plugins, it would be interesting to reimplement this plugin directly in prism-react-renderer. This can increase quite significantly the readability of diffs.

rrousselGit avatar Aug 21 '20 09:08 rrousselGit

Interested! I'd like to have diff + javascript for instance.

kud avatar Jan 31 '21 20:01 kud

this is my code

const isDiff = language.startsWith('diff-')

  let highlightStyle = []

  let code = children
  if (isDiff) {
    code = []
    language = language.substr(5)
    highlightStyle = children.split('\n').map((line) => {
      if (line.startsWith('+')) {
        code.push(line.substr(1))
        return 'inserted'
      }
      if (line.startsWith('-')) {
        code.push(line.substr(1))
        return 'deleted'
      }
      code.push(line)
    })
    code = code.join('\n')
  }

https://github.com/maqi1520/mdx-editor/blob/main/src/components/MDX/CodeBlock.jsx

image

maqi1520 avatar Apr 21 '22 03:04 maqi1520

You can check my solution for this docusaurus issue facebook/docusaurus#3318 on a possible apporach to remiplement prism plugins for prism-react-renderer using hooks "before-tokenize" and "after-tokenize"

thefat32 avatar Apr 19 '24 00:04 thefat32

You don't need to rewrite the plugins to make this work. I got my plugins to work with a few lines of code, I hope this will help everyone that has been waiting for so long:

I assign the tokens to a ref and then run the 'complete' hook that calls the plugins registered to prism in useLayoutEffect as I need a reference to my code element.

const codeBlock: string = 'hello world';
const editorLanguage:string = 'my-custom-lang';
const tokensRef = React.useRef<Token[][]>([]);

useLayoutEffect(() => {
        Prism.hooks.run('complete', {
            code: codeBlock,
            grammar: Prism.languages[editorLanguage],
            language: editorLanguage,
            tokens: tokensRef.current,
            element: codeRef.current,
        });
}, [tokensRef.current]);
    
return  (
<Highlight code={codeBlock} language={editorLanguage} prism={Prism} theme={talkwalkerTheme}>
  {({ className, style, tokens, getLineProps, getTokenProps }) => {
      tokensRef.current = tokens;

      return (
          <pre className="prism-highlighting" aria-hidden="true">
              <code
                  className={`${className} match-braces rainbow-braces no-keep-markup`} // class names used by plugins
                  ref={codeRef}>
                  {tokens.map((line, i) => line.map((token, key) => <span key={key} {...getTokenProps({ token })} />))}
              </code>
          </pre>
      );
  }}
</Highlight>
);

nabak9 avatar Apr 23 '24 08:04 nabak9