Prism: How to use line-number plugin with webpack

Created on 19 Jul 2018  路  14Comments  路  Source: PrismJS/prism

I hava code link this. But it not show line number

const Prism = require('prismjs/components/prism-core.js');
require('prismjs/plugins/line-numbers/prism-line-numbers.js');
require('prismjs/themes/prism.css');
require('prismjs/components/prism-javascript');
const code = 'var a = 1;';

render() {
    <pre className="line-numbers" data-start="0">
        <code className="language-javascript" dangerouslySetInnerHTML={{ __html: code }} />
    </pre>
}
plugins support

Most helpful comment

@mAAdhaTTah Awesome man! It works, thanks here is the complete working code:

import React, { useEffect } from "react";
import Prism from "prismjs";
import "../../node_modules/prism-themes/themes/prism-vsc-dark-plus.css";
import { compose } from "js-utl";
import { classNames } from "react-js-utl/utils";
import { useUniqueKey } from "react-js-utl/hooks";
import "prismjs/plugins/line-numbers/prism-line-numbers";
import "../../node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css";

const PrismCode = compose(React.memo)(function PrismCode({
  className = void 0,
  codeClassName = void 0,
  children,
  withLineNumbers = true,
} = {}) {
  const id = useUniqueKey();

  useEffect(() => {
    Prism.highlightAllUnder(document.getElementById(id));
  }, [id, children]);

  return (
    <div id={id} className={classNames("prism-code", className)}>
      <pre
        className={classNames(codeClassName, withLineNumbers && "line-numbers")}
      >
        <code className={codeClassName}>{children}</code>
      </pre>
    </div>
  );
});
PrismCode.displayName = "PrismCode";
export default PrismCode;

All 14 comments

If you're using webpack, we recommend configuring with the babel plugin: https://github.com/mAAdhaTTah/babel-plugin-prismjs

Thanks, i will try it

Hi. I have used babel-plugin-prismjs. But it still not show line numbers.
Debug code found that it has never executed the Prism.plugins.lineNumbers.getLine method.

.babelrc

[
    "prismjs", {
        "languages": ["clike", "javascript", "typescript", "java", "c", "cpp", "python", "ruby", "markup", "markup-templating", "php", "go", "csharp", "css", "markdown", "sql", "json" ],
        "plugins": ["line-numbers"],
        "theme": "default",
        "css": true
    }
]

use

import Prism from 'prismjs';
const html = Prism.highlight(rawCode, Prism.languages[language]);

render() {
    <pre className="line-numbers language-javascript" data-start="0">
            <code className={`language-javascript`} dangerouslySetInnerHTML={{ __html: html }} />
    </pre>
}
setTimeout(() => {
    Prism.highlightAll();
}, 0);

If I add this code after Prism.highlight(), It can display the line number correctly.

@yinxin630 why it need a setTimeout ?

Is magic

Thanks a lot @yinxin630 !

I had a similar problem: using Vue.js, in my HTML page, in the left part, I've an editor allowing to type markdown content and in the right part, the rendered html.

By displaying the page the first time, the rendering was correct like here below

2019-01-22_18h19_02

By typing something in the editor, the HTML is automatically refreshed by Vue and the style is lost

2019-01-22_18h20_41

But, by adding the timeout, the style is correctly applied.

setTimeout(() => {
    Prism.highlightAll();
}, 0);

2019-01-22_18h21_28

I also am having a problem with this. Trying to use line numbers with VueJS. I've tried doing it with es6 imports:

import Prism from "prismjs"
import "prismjs/plugins/line-numbers/prism-line-numbers"
import "prismjs/components/prism-markup-templating"
import "prismjs/components/prism-swift"
import "prismjs/components/prism-typescript"
import "prismjs/components/prism-php"
import "prismjs/themes/prism-tomorrow.css"
import "prismjs/plugins/line-numbers/prism-line-numbers.css"
...
let html = Prism.highlight(source, Prism.languages[lang], lang)

and I've tried using babel

plugins: [
    [
      "prismjs",
      {
        languages: ["javascript", "css", "markup"],
        plugins: ["line-numbers"],
        theme: "twilight",
        css: true,
      },
    ],
  ],

But no luck, no lines.

First, if you're using the plugin, you only need the import Prism from 'prismjs' line, as the plugin will inject the rest. Second, if you're highlighting server-side or otherwise in Node, line-numbers won't work as it needs an actual DOM. Third, if you can provide a reproducible example, that would be easier to take a look at.

@yinxin630 It can be even more succinct:

setTimeout(Prism.highlightAll);

And it works because of how the event loop in JavaScript works. Prism is manipulating DOM, which in turn triggers a repaint (asynchronous operation abstracted by the browser) that invokes from a queue of tasks. By using setTimeout, it makes sure that highlightAll queues up _after_ the repaint, so everything is ready-to-go before a another manipulation is done.

In Vue.js Components

<template>
      <div>
        <pre class="line-numbers language-markup"><code v-html="codeData"></code></pre>
      </div>
</template>

<script>
import Prism from 'prismjs'
import 'prismjs/plugins/line-numbers/prism-line-numbers.js'
import 'prismjs/plugins/line-numbers/prism-line-numbers.css'
import 'prismjs/themes/prism-tomorrow.css'

export default {
 data () {
    return {
      codeData: '',
    }
  },
 methods: {
    /**
     * show highlight code
     * @param {string} data
     */
 showCode (data) {
      this.codeData = data
      this.codeData = Prism.highlight(data, Prism.languages.markup)
      // key code
      this.$nextTick(() => {
        Prism.highlightAll()
      })
    }
}
}

ReView

QQ鎴浘20200311172539

Others

babel-plugin-prismjs, i don't know it how to work?馃槀

Cannot make it work with React (create-react-app) and ES6, below the code I am using:

import React, { useEffect } from "react";
import Prism from "prismjs";
import "../../node_modules/prism-themes/themes/prism-vsc-dark-plus.css";
import { compose } from "js-utl";
import { classNames } from "react-js-utl/utils";
import { useUniqueKey } from "react-js-utl/hooks";
import "prismjs/plugins/line-numbers/prism-line-numbers";

const PrismCode = compose(React.memo)(function PrismCode({
  className = void 0,
  codeClassName = void 0,
  children,
  withLineNumbers = true,
} = {}) {
  const id = useUniqueKey();

  useEffect(() => {
    setTimeout(() => {
      // Prism.highlightAllUnder(document.getElementById(id));
      Prism.highlightAll();
    });
  }, [id, children]);

  return (
    <div id={id} className={classNames("prism-code", className)}>
      <pre
        className={classNames(codeClassName, withLineNumbers && "line-numbers")}
      >
        <code className={codeClassName}>{children}</code>
      </pre>
    </div>
  );
});
PrismCode.displayName = "PrismCode";
export default PrismCode;

<pre> is rendered with line-numbers class, but no line numbers are displayed? Any idea?

Thank you!

@tonix-tuft Line numbers has a css file.

@mAAdhaTTah Awesome man! It works, thanks here is the complete working code:

import React, { useEffect } from "react";
import Prism from "prismjs";
import "../../node_modules/prism-themes/themes/prism-vsc-dark-plus.css";
import { compose } from "js-utl";
import { classNames } from "react-js-utl/utils";
import { useUniqueKey } from "react-js-utl/hooks";
import "prismjs/plugins/line-numbers/prism-line-numbers";
import "../../node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css";

const PrismCode = compose(React.memo)(function PrismCode({
  className = void 0,
  codeClassName = void 0,
  children,
  withLineNumbers = true,
} = {}) {
  const id = useUniqueKey();

  useEffect(() => {
    Prism.highlightAllUnder(document.getElementById(id));
  }, [id, children]);

  return (
    <div id={id} className={classNames("prism-code", className)}>
      <pre
        className={classNames(codeClassName, withLineNumbers && "line-numbers")}
      >
        <code className={codeClassName}>{children}</code>
      </pre>
    </div>
  );
});
PrismCode.displayName = "PrismCode";
export default PrismCode;
Was this page helpful?
0 / 5 - 0 ratings

Related issues

timgoeller picture timgoeller  路  4Comments

sheljohn picture sheljohn  路  4Comments

kopax picture kopax  路  8Comments

RunDevelopment picture RunDevelopment  路  5Comments

nterray picture nterray  路  4Comments