APEX 21.2 quickie: syntax highlighting with prism.js

To show (not to edit) pretty code inside an APEX application in the past I had used the libraries that were deployed along with APEX, like CodeMirror (see https://svenweller.wordpress.com/2015/12/07/apex-5-syntax-highlighting/) and CkEditor. In APEX 21 CkEditor got a new version and CodeMirror is not supplied anymore since several APEX versions now. But there is a new very lightweight alternative, which is prism.

In my use case I need this to quickly present currently running edition based plsql code.

Implementation

Step 1) Load code into a hidden page item

I use a before region process to load the data (=code) into an item. Assuming item name P1_CODE for further references.

Step 2) Add prism files to the page

Javascript file urls

#PRISMJS_DIRECTORY#prism.js

CSS file urls

#PRISMJS_DIRECTORY#prism.css

Note that the substitution variable PRISMJS_DIRECTORY is automatically provided and resolved to the path “/i/libraries/prismjs/1.24.1/” and is updated in future versions.

Step 3) Show item in html region and choose the language

Add this to the html code section of a static region.

Note that you should set the correct language that you want to show. In my case it is language-plsql.

<pre><code class="language-plsql">&P1_CODE.</code></pre>

The value in the item is automatically html escaped. In case the logic that loads the code into the item did already escape it, you can also choose not to escape it again, by using an escape filter like &P1_CODE!RAW. . Just be aware of potential security issues, if you do not do that correctly.

A list of possible languages can be found here. However not all of those languages are added in the APEX deployment.

Step 4) Customize a few colors

I didn’t like the coloring for plsql or sql code. Especially I prefer to show comments in green. This can be changed with a few lines of css.

Add this to the inline css section of the page

/* prism plsql colorization */
.token.comment {
  color: #119b01;
}
.token.string {
  color: #0c6cb97c;
}
.token.keyword {
  color: #8C009B;
  font-weight: bold;
}

Very quick and easy to implement.

If you want different settings, simply inspect the code snippet using the browser. That is one of the advantages of prism. The code is tokenized using span tags and the appropriate classes. We can easily see what kind of token a certain element is and simply change the style for the class we want.

Result

Here is a crude overview how the result looks like

Additional considerations

prism has the possibility to add many additional features. However those features come as plugins that are packed directly into the .css and .js files. To use them, one would have to add/replace the library that is used by APEX. I didn’t investigate in detail, which plugins are already inclued. For example line numbering does NOT seem to work out of the box.

This would do the trick with the line numbers, if the line-numbers plugin is integrated.

<pre class="line-numbers" data-start="50"><code class="language-plsql">&P1_CODE.</code></pre>

Conclusion

For simple requirements prism allows a very easy and quick way to add syntax highlighting to code. For more complex requirements (like editing code) a different library might be better suited. The possibility to have dedicated subtitution strings for several libraries is very welcome.

One additional note. I tried to use the markdown editor item type as an alternative, but the effort to make it work for my simple requirements, was too high. A markdown editor simply serves a different purpose.

2 thoughts on “APEX 21.2 quickie: syntax highlighting with prism.js

  1. Hi Sven

    Nice blog post! Do note that a lot has changed around the distribution of prismjs in APEX 22.1. I have some good news, and some bad news for you. Here they are, in no particular order:

    1) There is no longer a #PRISMJS_DIRECTORY#. We took it out. The reasoning was as follows:
    – It was never documented!
    – We don’t provide such a substitution string for all other libraries, and we wish to stay somewhat consistent.
    – Performance. Each such string adds a tiny bit of overhead whenever performing substitutions- which happens all over the place.

    2) However, you can now load the library in a pre-rendering process, as such:
    apex_javascript.add_3rd_party_library_file( p_library => ‘markedjs’ );
    Note that this is also not documented, for now.

    3) There is no longer a prism.css file. We weren’t happy with the CSS provided by the library, so we took matters into our own hands. The styling was refactored and is now included globally, in Core.css. Some styles are overridden at theme/ theme style level. For example, Vita – Dark overrides these global styles.

    4) We’ve updated the colors! Please take another look, maybe you’ll find they look better now.

    5) Indeed. Our distribution of this library is very slim. That’s by design. We only make use of it in a few select places, so we didn’t need the extra bells and whistles. There’s also a security aspect. This library receives a significant amount of community contributions- which is not always a good thing. So in order to reduce the possibility of a CVE being filed against our product, which would mean we need to get a PSE out, we chose to limit the extra bits as much as possible.
    Currently- we don’t ship any of the extra plug-ins, and the languages we do ship are the following:
    HTML, CSS, JavaScript, JSON, Markdown, SQL, PL/SQL
    We might add new plug-ins and languages in the future.

    With such a small library, you can always build and ship your own, configured per your needs- but of course it is nice when you can hook into something that already comes with APEX. I get that!

    But wait, there’s more:
    There might be use-cases where you don’t wish to trigger highlighting on page load. We needed this for our Markdown Editor. Prism provides a way to do this by appending a “data-manual” attribute on the library’s script tag. So far, it wasn’t possible to customize the script tag of File URLs in APEX, but it is now. If you ever need to do this, apex_javascript/css.add_library/add_3rd_party_library_file now have a new parameter, named p_attributes. Maybe this will come in handy for you at some point 🙂

    Nice to see people tinkering with these things, and do let me know of any questions or feedback.
    – Stefan

    • Hi Stefan,

      thank you for your feedback and providing such a detailed look behind the scenes. I will certainly have a look at the implications.

      I really liked the substitution variable (not sure how I found out about it, maybe it was is some bug notes). And indeed I was hoping that the same will exist for all the other libraries. But I agree that if there is a small performance impact (on each page?) that this is a considerable price to pay.

      Regards Sven

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.