This is another post where I’m working on Hugo capabilities. This time, though, I’m mostly dealing with expanding highlight.js, which is the highlighting tool used by the PaperMod theme.

Terminal in color

This shows my terminal prompt in approximately the colors that I see.

gvollink@javavm [GIT: (✅) master]:0
🏠/src/web/hugo-blog$ 

The above, in source, has embedded ANSI escape codes. To do this I created a language called terminal for highlight.js and an accompanying PlugIn. The language definition recognizes the 8 basic colors control codes, and the PlugIn erases them from the view.

Here is my prompt when I have unchecked-in git changes.

gvollink@javavm [GIT: (🚨) master]:0
🏠/src/web/hugo-blog$ color_test.sh
red
green
orange
blue
magenta
cyan
gray
white

The same color palette is shared across all highlight.js supported languages, across the whole site. As such, color support is limited to foreground only, and ~8 colors only. Note the same colors in the JavaScript below.

The bright escapes are also accepted for 1-6, but will give the same colors (with gray and white being the only exceptions).

CodeColor
<esc>[30mblack (shown as gray anyway)
<esc>[31mred
<esc>[32mgreen
<esc>[33morange
<esc>[34mblue
<esc>[35mmagenta
<esc>[36mcyan
<esc>[37mgray
<esc>[97mwhite

This supports bold and italic, too, but they end up in magenta.

Also, no control codes areas may overlap (the first one wins).

More Detail

The highlight.js theme I’m using is customized specifically so that I can have a shade of all 8 colors represnted. The color categories were then carefully selected as the classnames for the expansions shown below…

JavaScript

var terminal=(()=>{
    "use strict";
    return e=>{
        return{
            name:"Terminal Colors",
            aliases:["terminal"],
            case_insensitive:!0,
            contains:[
                { // RED
                    className:'meta',
                    begin: /\[[39]1m/,
                    end: /\[0?m/
                },
                { // GREEN
                    className:'string',
                    begin: /\[[39]2m/,
                    end: /\[0?m/
                },
                { // ORANGE
                    className:'literal',
                    begin: /\[[39]3m/,
                    end: /\[0?m/
                },
                { // BLUE
                    className:'title.function',
                    begin: /\[[39]4m/,
                    end: /\[0?m/
                },
                { // MAGENTA
                    className:'type',
                    begin: /\[[39]5m/,
                    end: /\[0?m/
                },
                { // CYAN
                    className:'regexp',
                    begin: /\[[39]6m/,
                    end: /\[0?m/
                },
                { // GRAY
                    className:'tag',
                    begin: /\[3[07]m/,
                    end: /\[0?m/
                },
                { // WHITE
                    className:'strong',
                    begin: /\[97m/,
                    end: /\[0?m/
                },
                { // BOLD
                    scope:'keyword',
                    begin: /\[1m/,
                    end: /\[0?m/
                },
                { // ITALIC
                    scope:'emphasis',
                    begin: /\[3m/,
                    end: /\[0?m/
                }
            ]
        }
    }
})();
function do_plugin() {
    hljs.addPlugin({
        'after:highlight': ( result ) => {
            if ( result.language == "terminal" ) {
                var seek = /\[[0-9;]*m/g;
                var chk = result.value.match( seek );
                if ( chk ) {
                    var val = result.value;
                    result.value = val.replace( seek, '');
                }
            }
            return;
        }
    });
    hljs.registerLanguage('terminal',terminal);
    hljs.highlightAll();
}
var existCondition = setInterval(function() {
        if ( typeof hljs != "undefined" ) {
            clearInterval(existCondition);
            do_plugin();
        }
}, 100);