admin管理员组

文章数量:1415139

The prism.js documentation states

Prism forces you to use the correct element for marking up code: <code>. On its own for inline code, or inside a <pre> for blocks of code -

We're using a document management system, that does not allow any HTML code inside a <pre> tag

  • <pre>some code</pre> - formatting is correct, but no syntax highlighing
  • <code>some code</code> - syntax highlighing works, but all line breaks/indentations are removed by the CMS
  • <pre><code>some code</code></pre> - transformed to <pre>&lt;code&gt;some code</pre> by the CMS

Is there a way to have prism.js add syntax highlighting to a <pre> tag, like this:

<pre class="language-javascript">
if (test) {
  someCode();
}
</pre>

Maybe there's a plugin or a JS configuration to tell prism.js to highlight those <pre> tags.

The prism.js documentation states

Prism forces you to use the correct element for marking up code: <code>. On its own for inline code, or inside a <pre> for blocks of code - https://prismjs./#features-full

We're using a document management system, that does not allow any HTML code inside a <pre> tag

  • <pre>some code</pre> - formatting is correct, but no syntax highlighing
  • <code>some code</code> - syntax highlighing works, but all line breaks/indentations are removed by the CMS
  • <pre><code>some code</code></pre> - transformed to <pre>&lt;code&gt;some code</pre> by the CMS

Is there a way to have prism.js add syntax highlighting to a <pre> tag, like this:

<pre class="language-javascript">
if (test) {
  someCode();
}
</pre>

Maybe there's a plugin or a JS configuration to tell prism.js to highlight those <pre> tags.

Share Improve this question asked Mar 27, 2021 at 17:35 PhilippPhilipp 11.4k9 gold badges69 silver badges74 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

I was able to do it. Here is the code, I don't think you need the language-js how I do it later...

<pre class="language-js">
  var cheese = sandwich;
  function(){
    return "hello!";
  }
</pre>

First I init prism and follow the Manual Highlighting from the docs:

<script>
  window.Prism = window.Prism || {};
  window.Prism.manual = true;
</script>
<script src="https://cdnjs.cloudflare./ajax/libs/prism/1.23.0/prism.min.js"></script>

Now nothing happens by default. Further down the docs, they show an example under Usage with Node

// The code snippet you want to highlight, as a string
const code = `var data = 1;`;

// Returns a highlighted HTML string
const html = Prism.highlight(code, Prism.languages.javascript, 'javascript');

So in my example I do the following:

<script>
  // Get the pre element
  let pre = document.querySelector("pre");
  // Grab the text out of it
  let code = pre.innerText;
  // Highlight it
  let highlighted = Prism.highlight(code, Prism.languages.javascript, 'javascript');
  // Now put that back in, but as HTML
  pre.innerHTML = highlighted
</script>

Example here:

https://codepen.io/EightArmsHQ/pen/f9023daaa6499786e25899cb62f4d6c2?editors=1010

I'm sure you can figure out how to querySelectorAll the pre tags and loop through each formatting them : )

Solution 1 (original answer)

Here's the code that I came up with, based on the reply by Djave:

<script>
  // Enable the "manual" mode to prevent prism from instantly firing.
  window.Prism = window.Prism || {};
  window.Prism.manual = true;
</script>

<script src="https://cdnjs.cloudflare./ajax/libs/prism/1.23.0/prism.min.js" defer></script>

<script>
  // Use the hook "before-highlightall" to register the custom CSS selectors:
  Prism.hooks.add('before-highlightall', function (env) {
    env.selector += ', pre[class*="language-"], pre[class*="lang-"]';
  });

  // Highlight code, when the page finished loading (using jQuery here)
  jQuery(Prism.highlightAll);
</script>

Notes:

  • Maybe the code can be written even shorter (I'm not sure if the first block is really required). However, this solution seems to be very reliable and works stable on all our documents.
  • In my tests, the code also works when "prism.min.js" is loaded using the defer or async flags.

Solution 2 (remended)

I've found, that the missing code tag has some other (minor) problems with prism.js plugins, such as the line-number plugin.

We now use the following snippet in our CMS to automatically insert the code tag where it's missing:

<script>
  // Enable the "manual" mode to prevent prism from instantly firing.
  window.Prism = window.Prism || {};
  window.Prism.manual = true;
</script>

<script src="https://cdnjs.cloudflare./ajax/libs/prism/1.23.0/prism.min.js" defer></script>

<script>
  // THE FOLLOWING BLOCK CHANGED:

  jQuery(function() {
    // Wrap the code inside the required <code> tag, when needed:
    jQuery('pre[class*="language-"], pre[class*="lang-"]').each(function() {
      if (1 !== jQuery(this).children('code').length) {
        jQuery(this).wrapInner('<code>');
      }
    });

    // Highlight code, when the page finished loading (using jQuery here)
    Prism.highlightAll()
  });
</script>

本文标签: javascriptConfigure prismjs to recognize ltpregt tags (without ltcodegt tag)Stack Overflow