Prism: Using the plugins in NodeJS

Created on 2 Aug 2017  Â·  22Comments  Â·  Source: PrismJS/prism

How can the plugins be used in NodeJS when importing like:
import Prism from 'prismjs';

I tried to access the line-numbers plugin, but when I do Prism.plugins it's an empty object.

Any ideas?

enhancement

Most helpful comment

AFAICT currently some plugins are using Node's global object to pick up Prism and register the plugins. The following two work, but other plugins do not do this. Ultimately the best solution is probably to copy the body of the IIFEs in those files in to the file where you require Prism.

global.Prism = require('prismjs');
require('prismjs/plugins/normalize-whitespace/prism-normalize-whitespace');
require('prismjs/plugins/data-uri-highlight/prism-data-uri-highlight');

Object.keys(Prism.plugins); // [ 'NormalizeWhitespace', 'dataURIHighlight' ]

All 22 comments

This doesn't work:

var prism = require('prismjs');
require('prismjs/plugins/keep-markup/prism-keep-markup.js');

In node doesn't work for me either. This is awful.
I really wish I could use the Keep Markup plugin with node.

What I did was to copy the entire JS file into my static folder, and use it from there... Not the most elegant thing to do...

@florinpop17 Thank you! Good advice. I was about to go down that path but I've given up for now. Not sure how document.createRange can even be used from the keep-markup plugin in NodeJs so I'm stuck until deeper investigation.

@megamindbrian both import 'prismjs' and require('prismjs') should work. They create Prism object.

To check if you are able to access the properties of the created Prism object, open the DevTools Console and type Prism (it's case sensitive). Initially, Prism.plugins is an empty object {}.

Everytime you require Prism's plugin it injects itself into the Prism.plugins object.
Take a look at prism-keep-markup.js file, line 7:

Prism.plugins.KeepMarkup = true;

In conclusion, this should work for you:

import 'prismjs';
import 'prismjs/plugins/keep-markup/prism-keep-markup.js';

Maybe you should check your bundler's paths - what directories are being searched when resolving modules and if the node_modules directory is being taken into account.

Thank you for circling back. I'll try that but I am trying to run from
node. Basically trying to combine prism with node diff to get an even
prettier output than GitHub gives you in code compare.

On Sep 13, 2017 5:35 AM, "schwastek" notifications@github.com wrote:

@megamindbrian https://github.com/megamindbrian both import 'prismjs'
and require('prismjs') should work. They create Prism object.

To check if you are able to access the properties of the created Prism
object, open the DevTools Console and type Prism (it's case sensitive).
Initially, Prism.plugins is an empty object {}.

Everytime you require Prism's plugin it injects itself into the
Prism.plugins object.
Take a look at prism-keep-markup.js file, line 7:

Prism.plugins.KeepMarkup = true;

In conclusion, this should work for you:

import 'prismjs';import 'prismjs/plugins/keep-markup/prism-keep-markup.js';

Maybe you should check your bundler's paths - what directories are being
searched when resolving modules and if the node_modules directory is
being taken into account.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/PrismJS/prism/issues/1171#issuecomment-329153509, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AX5XblYzCBK4228K8jHrYJwBWTKDuK1-ks5sh8v6gaJpZM4Ork19
.

@florinpop17 @megamindbrian At the moment, most plugins won't work on Node because they use the DOM (Line numbers and Keep markup are one of those).

Are you trying to use those with some virtual DOM node modules or something?

Haven't tried it with virtual DOM. Good idea though.

On Wed, Sep 13, 2017 at 1:21 PM, Golmote notifications@github.com wrote:

@florinpop17 https://github.com/florinpop17 @megamindbrian
https://github.com/megamindbrian At the moment, most plugins won't work
on Node because they use the DOM (Line numbers and Keep markup are one of
those).

Are you trying to use those with some virtual DOM node modules or
something?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/PrismJS/prism/issues/1171#issuecomment-329285456, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AX5XbsAgTEosEREx991pbiqHwceGZeFMks5siDk9gaJpZM4Ork19
.

Is this issue still valid? Are any of the plugins workable in Node? If they are, we could expose a loadPlugins, similar to loadComponents, for Node, but not worth doing if we can't even use them.

@mAAdhaTTah Most plugin don't work in Node indeed. From a quick look:

  • Autolinker: Should work if the before-highlight hook is run manually.
  • Autoloader: Does not work and returns early. Requires DOM.
  • Command line: Does not work and returns early. Requires DOM.
  • Copy to clipboard: Does not work and returns early. Requires DOM.
  • Custom class: Should work.
  • Data-URI highlight: Should work if the before-highlight hook is run manually.
  • File Highlight: Does not work and returns early. Requires DOM.
  • Highlight keywords: Should work.
  • JSONP highlight: Does not work and returns early. Requires DOM.
  • Keep Markup: Does not work and returns early. Requires DOM.
  • Line Highlight: Does not work and returns early. Requires DOM.
  • Line Numbers: Does not work and returns early. Requires DOM.
  • Normalize Whitespace: Should work if the before-sanity-check hook is run manually.
  • Previewers: Does not work and returns early. Requires DOM.
  • Remove initial line feed: Deprecated, but should work if the before-sanity-check hook is run manually.
  • Show invisibles: Should work if the before-highlight hook is run manually.
  • Show language: Does not work and returns early. Requires DOM.
  • Toolbar: Does not work and returns early. Requires DOM.
  • Unescaped markup: Does not work and returns early. Requires DOM.
  • WPD: Should work.

I left this issue open, because I know this is a common expectation from our users. Yet I think you are right, most of the plugins that do not work currently probably won't ever be compatible with Node in the future.

Regarding a loadPlugins function, is it something that would be useful? They usually don't have any dependency...

Regarding a loadPlugins function, is it something that would be useful? They usually don't have any dependency...

The main benefit would be not needing to know the paths. I dunno if it's _that_ beneficial, but it does at least provide some symmetry with the way loadLanguages works.

This is a major bummer especially when using something like Spectacle/react-live which relies on Node prism for the client side. Any thoughts on improving this? :slightly_smiling_face:

Right now the suggestion is to use the babel plugin: https://github.com/mAAdhaTTah/babel-plugin-prismjs/ – there are definitely still details to iron out if you're providing a library using Prism, as it suggests the consumer of the library needs to run babel over their dependencies (or at least that library), which may or may not be easy to do.

I may be incorrect but I don't think this will work for the Node API (which react-live uses for rendering server and client side) because the plugins (line numbers, line highlight) rely on DOM attributes being present, and prism node doesn't operate on DOM elements.

That's correct. May not be worth it / possible to highlight server-side in that case.

Right. The issue is that most React based libraries including this one use the node variant of a library even for the client side because it fits much better into the way React renders. So more and more consumers of popular libraries like spectacle are going to be unable to take full advantage of Prismjs's client side capabilities, which is a shame. :/

They can highlight on componentDidUpdate, so it doesn't fire on the server. They also should not be using loadLanguages in any code intended to be used on the client.

AFAICT currently some plugins are using Node's global object to pick up Prism and register the plugins. The following two work, but other plugins do not do this. Ultimately the best solution is probably to copy the body of the IIFEs in those files in to the file where you require Prism.

global.Prism = require('prismjs');
require('prismjs/plugins/normalize-whitespace/prism-normalize-whitespace');
require('prismjs/plugins/data-uri-highlight/prism-data-uri-highlight');

Object.keys(Prism.plugins); // [ 'NormalizeWhitespace', 'dataURIHighlight' ]

I was really expecting Prism's line number support to work from node. Found this issue and I'm quite bummed.

I'm using node.js to generate static html files from code, formatting them with prismjs, so there's no DOM to access.

Autolinker: Should work if the before-highlight hook is run manually

@Golmote How to run before-highlight hook manually?

You can run any hook using Prism.hooks.run('<hook name>', env);. Insert any hook name (e.g. before-highlight).
env is tricky but for Autolinker, we only need a grammar.

const code = `var foo = 0;`;
const language = 'javascript';

const grammar = Prism.languages[language];
Prism.hooks.run('before-highlight', { grammar });
const highlighted = Prism.highlight(code, grammar, language);

Please keep in mind that hooks are mostly internal at this point in time, so this code my break at any time.

TBH, Autolinker, DataURI URL, and Show Invisibles should be implemented in a way that works only with the hooks from Prism.highlight, so you don't have to manually call any hooks.

Is it possible to implement line-highlight in NodeJS? For example highlightjs (which is much less powerful) has it.
I'm building HTML5 presentations and would like to use line highlighting, but the code is almost not readable without line highlighting.

Is it possible to implement line-highlight in browser-independent way?

I think you mean NodeJS :)
Yes, I'm very much in favor of this plugin working in Node.

Line-highlighting and line-numbering are the only plugins I genuinely need for Node.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nterray picture nterray  Â·  4Comments

jiantosca picture jiantosca  Â·  4Comments

markerikson picture markerikson  Â·  3Comments

TheZoker picture TheZoker  Â·  9Comments

RunDevelopment picture RunDevelopment  Â·  5Comments