Syntax highlighting of PureScript code in Halogen app with PrismJS

Does anyone know what additional steps one needs to get PrismJS to work inside a Halogen app?

PrismJS has a PureScript syntax plugin and it works fine in a simple index.html that includes the prism.js and prism.css files.

But the most naive implementation in Halogen doesn’t work, for reasons i can guess at but can’t investigate right now, so i’m wondering if anybody has already solved it?

(i know that preprocessing the code works, as documented in other threads on this Discourse, but for something like a blog with lots of code snippets PrismJS seems better)

Looks like it is possible to simply call the Prism API from an FFI function (Prism - Documentation) i don’t quite have that working just now but will post a snippet later when i do

For future reference if anybody else is trying to do this:

  1. Generate your desired prism.js and prism.css files
  2. Include the prism.css in <head> of your index.html (obviously)
  3. Include the prism.js before your own app bundle:
<body>
  <script src="/code-examples/prism.js"></script>
  <script src="./bundle.js"></script>
</body>
  1. Make yourself a little FFI function:
exports.highlightString_ = codetext => {
  const highlightedCode = Prism.highlight(codetext, Prism.languages.purescript, 'purescript');
  return highlightedCode
}
  1. Install: (thanks for the tip, @kritzcreek)
    GitHub - rnons/purescript-html-parser-halogen: A library to render HTML string into Halogen views

  2. Use this function to wrap quoted PureScript code (or a string containing PureScript code that you’ve read from somewhere else, but be careful with that route) and you can now do stuff like:

                [ HH.pre 
                  [ HP.class_ $ HH.ClassName "language-purescript" ]  
                  [ HH.code_ [ RH.render_ $ highlightString_ codetext ] ]
                ]
  1. Profit!
1 Like

For reference, the Prism API is here: Prism - Documentation

Correct me if I’m wrong but, you may want to run the Effect for Prism.highlight on the initialize phase of your Halogen component. This would allow you to save the highlight text to the state so it doesn’t have to get re-rendered. In this incantation, if you had a state change, the component would rerender causing the highlighting to be recalculated which is wasteful. Another benefit is that you could leverage the async option for the highlighter and show the user the current status if the calculation is slow data Status = Calculating | Calculated String | Errored(?); ran syncrhonously this could cause the UI to hang.

excellent points - i’d say you are right on all counts and i will try to do at least the first point when i implement the cookbook recipe for this.

1 Like