Custom Rouge Themes and How to Fix the Ruby Rouge::Theme uninitialized constant problem

After the most recent changes to the Copper programming language and a switch to a newer computer, I decided to finally rebuild the documentation. I have been using the Slate static site generator creating with Ruby on Rails which uses redcarpet and rouge. Sadly, on a new machine, I had to set up everything again. As you may have discovered, rouge, despite its popularity, has really crappy documentation. Ruby itself is crappy in my opinion and I hate working with it, but there has been some nice stuff created with it. Slate is one example. However, after the headache of trying to dig up the documentation, I may switch to using Copper to generate its own documentation. Not a bad idea, no? Anyways, I decided it would be useful to share my tidbits of knowledge with others who will stumble on this problem while creating custom themes for rouge.

To build Slate, you must run the command:

$ bundle exec middleman build --verbose --clean

But suppose you want a custom theme for Rogue. I wanted a custom theme for changing the color of my syntax. The Ruby file for Copper syntax highlighting goes in the directory:

[rouge main directory]/lib/rouge/lexers

NOTE: If you have installed rouge, the main directory will be something like:

/var/lib/gems/2.7.0/gems/rouge-2.0.7/

You can copy one of the many files in there and make the necessary changes. I won’t go into details since it’s best to look at the examples.

To create a custom theme, you need to add a new custom ruby file to the directory:

[rouge main directory]/lib/rouge/themes

Again, look at the examples in that folder and create a file with similar contents. Name it “mytheme.rb” and give it a class name MyTheme.

Then, inside the slate folder, you need to go to the sub folder: source/layouts and modify the layout.erb file to contain:

<%= Rouge::Themes::MyTheme.render(:scope => '.highlight') %>

where “MyTheme” needs to be replaced by the class name of your theme.

At this point, the docs fail us. After compiling with, we get an error message:

error build/index.html
uninitialized constant Rouge::Themes::MyTheme
layouts/layout.erb:35:in `block in singleton class'

Note that you could use:

<%= Rouge::Theme.find('mytheme').render(:scope => '.highlight') %>

However, this makes the error message report:

undefined method `render' for nil:NilClass

It turns out, your custom theme is not automatically added to or read by rouge. Go figure. To fix the problem, go to the directory:

[rouge main directory]/lib

and there you will see the file “rouge.rb”.

Open that file, and at the bottom, you should find a list of themes being added to the engine. Here, you can add your theme with the line:

load load_dir.join('rouge/themes/mytheme.rb')

Viola! It should work now.

Notably, there are a number of warnings that will arise. I’m working with Ruby 2.7.0, but in the future, more stuff is going to break. Therefore, though I will end up losing the very sleek form of Slate, it might be wiser for me to recreate the documentation website in Copper, especially since in its current state in Ruby, the Slate version is too complicated to easily modify.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s