How to specify a custom language parser alias for rouge in Jekyll 3?
Asked Answered
G

1

5

How does one configure Jekyll & Rouge to specify that one language should be highlighted using the parser of another language.

For example, I want to be able to do this in my markdown source files:

```nodejs-repl
> foo();
Uncaught ReferenceError: foo is not defined
```

... but have that code block syntax highlighted using the same syntax highlighter Javascript language parser.

I want to do this for a couple of reasons:

  1. Semantic correctness in the source files
  2. Be able to run tools such as prettier and have them bypass these code blocks

Rouge already does have the concept of language aliases (see example below), however is it possible to specify a custom language alias via Jekyll, and if so how can this be done?


Details:

(1)

I am using Jekyll 3.8.5 with Rouge 3.11.0.

(2)

The following is the relevant part of my Jekyll config file:

highlighter: rouge

(3)

So as to be really clear about what "language aliases" refers to, I'll provide an example:

For Javascript, you can use both js and javascript after the code fences, as they are language aliases by default in Rouge. Thus, the following two code blocks are identical:

Using language alias js:

```js
foo();
```

Using language alias javascript:

```javascript
foo();
```
Geiger answered 15/5, 2020 at 8:24 Comment(0)
H
7

I was able to "extend" the Rogue highlighter by utilizing Jekyll's _plugins directory.

Much of my research came from rogue-ruby's GitHub Issue #1392 and the source code for LinkedIn's rest-li jekyll-based website.

Steps

  1. Create a _plugins directory in your Jekyll root directory
  2. Create a ruby file in the _plugins directory
  3. Use the following code to inherit the existing Rogue Javascript code and "extend" (aka overwrite) the list of aliases.
# This "hook" is executed right before the site's pages are rendered
Jekyll::Hooks.register :site, :pre_render do |site|
  puts "Adding more JavaScript Markdown aliases..."
  require "rouge"

  # This class defines the PDL lexer which is used to highlight "pdl" code snippets during render-time
  class MoreJSLexer < Rouge::Lexers::Javascript
    title 'MoreJS'
    aliases 'js', 'nodejs-repl'
  end
end
  1. Run jekyll serve and note the custom log line "Adding more JavaScript Markdown aliases..."
 Incremental build: disabled. Enable with --incremental
      Generating... 
       Jekyll Feed: Generating feed for posts
Adding more JavaScript Markdown aliases...
                    done in 0.637 seconds.
 Auto-regeneration: enabled for '/Users/kueng/work/sandboxes/minima'
    Server address: http://127.0.0.1:4000
  Server running... press ctrl-c to stop.

Testing

I used the minima GitHub repository as my sandbox and jekyll 3.8.7. I created a _plugins/more_javascript.rb Ruby file using the code in step 3. I edited one of the markdown files with the markdown snippet below and noticed only js and nodejs-repl had syntax highlighting.

```nodejs
var a, b, c;
a = 5; b = 6; c = a + b;
document.getElementById("demo1").innerHTML = c;
```
```js
var a, b, c;
a = 5; b = 6; c = a + b;
document.getElementById("demo1").innerHTML = c;
```
```nodejs-repl
var a, b, c;
a = 5; b = 6; c = a + b;
document.getElementById("demo1").innerHTML = c;
```
Hixon answered 19/5, 2020 at 2:34 Comment(6)
Hey @Hixon this looks like it is a viable solution... however, I have a feeling that it may not work on Github pages thanks to its employment of custom Ruby code. I'm aware now that I didn't specify Github pages in my original question - just wanted to check if you have had any luck with that/ any ideas around that?Geiger
Hey @bguiz. In my experience with GitHub pages, I don't see any major blockers with my approach with custom Ruby code. However, I only have experience with use a CI/CD tool (e.g. TravisCI) to handle the build step for Jekyll-based websites. What TravisCI will do is run jekyll build and push the _site directory to a branch (e.g. gh-pages) used by GitHub pages. I've also ran jekyll build and used a manual git push to gh-pages branch. I ran jekyll build on my example above and noticed that the RAW html only adds class=highlighter-rouge to the js and nodejs-repl sections.Hixon
Con't. Since the raw HTML is showing the expected Rogue styling on the new custom nodejs-repl, I suspect the only unknown from getting my solution to work is how GitHub handles jekyll build process. My experience predates all the new GitHub CI/CD tools. I did find some supporting documentation about the _plugins Jekyll directory here jekyllrb.com/docs/continuous-integration/github-actions/…Hixon
Yeah makes sense. I've just tried this out locally in my repo - no Github pages involved yet - and the plugin doesn't appear to trigger at all. I don't even get the Adding more JavaScript Markdown aliases... from the puts, which is strange. EDIT: this is my Gemfile: gist.github.com/bguiz/f585e0cd4b5c4777283e3eb74749101cGeiger
In my testing, I did not specify any highlighter in _config.yml. I let Jekyll default to Rogue. I normally run jekyll 4.0, so I had to create a Gemfile to downgrade the minima code sandbox to Jekyll 3.x. The Gemfile only had gem "jekyll", "~> 3.8.5" and gem "minima". I used bundle install and bundle exec jekyll s to run the minima sandbox.Hixon
Hey @kin I got this working, thank you very much. Turns out the issue was that the github pages gem was interfering with this (and any other plugin not on its whitelist), and once I figured that out, it started working locally. Getting this to work on github pages is still a work in progress, however. Anyway, bounty goes to you!Geiger

© 2022 - 2024 — McMap. All rights reserved.