Highlighting cpp in Pelican

The first question that needs an answer is how does pelican generate cpp code-blocks?
So when we generate a cpp code block which as of this moment turns into

#include <iostream>

#include "bar.hpp"
#include "./baz.hpp"

class foo {
    int32_t example;
};

// Resolves to false value each time. Necessary for static_assert use
template<typename T>
static constexpr bool always_false_v = false;

int main(int argc, char** argv){
    /**
     * Silence warnings
     */
    (void) argc;
    (void) argv;

    foo f;

    f.example = 0;

    int32_t a = 1;

    int32_t b = f.example + a;

    std::cout<<"Result: "<<b<<std::endl;

    {
        using namespace std;
        string ex = "string";

        cout<<"Also throwing in a scoped namespace use with a "<<ex<<endl;
    }

    {
        const int16_t meh = 1;
    }

    return 0;
}

The interesting part is what pelican generates in the end. So we get

<pre>
<span>
</span>
<code>
<span class="cp">#include</span>
<span class="w"> </span>
<span class="cpf">&lt;iostream&gt;</span>
<span class="cp">#include</span>
<span class="w"> </span>
<span class="cpf">"bar.hpp"</span>
<span class="cp">#include</span>
<span class="w"> </span>
<span class="cpf">"./baz.hpp"</span>
<span class="k">class</span>
<span class="w"> </span>
<span class="nc">foo</span>
<span class="w"> </span>
<span class="p">{</span>
<span class="w">    </span>
<span class="kt">int32_t</span>
<span class="w"> </span>
<span class="n">example</span>
<span class="p">;</span>
<span class="p">};</span>
<span class="c1">// Resolves to false value each time. Necessary for static_assert use</span>
<span class="k">template</span>
<span class="o">&lt;</span>
<span class="k">typename</span>
<span class="w"> </span>
<span class="nc">T</span>
<span class="o">&gt;</span>
<span class="k">static</span>
<span class="w"> </span>
<span class="k">constexpr</span>
<span class="w"> </span>
<span class="kt">bool</span>
<span class="w"> </span>
<span class="n">always_false_v</span>
<span class="w"> </span>
<span class="o">=</span>
<span class="w"> </span>
<span class="nb">false</span>
<span class="p">;</span>
<span class="kt">int</span>
<span class="w"> </span>
<span class="nf">main</span>
<span class="p">(</span>
<span class="kt">int</span>
<span class="w"> </span>
<span class="n">argc</span>
<span class="p">,</span>
<span class="w"> </span>
<span class="kt">char</span>
<span class="o">**</span>
<span class="w"> </span>
<span class="n">argv</span>
<span class="p">){</span>
<span class="w">    </span>
<span class="cm">/**</span>
<span class="cm">     * Silence warnings</span>
<span class="cm">     */</span>
<span class="w">    </span>
<span class="p">(</span>
<span class="kt">void</span>
<span class="p">)</span>
<span class="w"> </span>
<span class="n">argc</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="p">(</span>
<span class="kt">void</span>
<span class="p">)</span>
<span class="w"> </span>
<span class="n">argv</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="n">foo</span>
<span class="w"> </span>
<span class="n">f</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="n">f</span>
<span class="p">.</span>
<span class="n">example</span>
<span class="w"> </span>
<span class="o">=</span>
<span class="w"> </span>
<span class="mi">0</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="kt">int32_t</span>
<span class="w"> </span>
<span class="n">a</span>
<span class="w"> </span>
<span class="o">=</span>
<span class="w"> </span>
<span class="mi">1</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="kt">int32_t</span>
<span class="w"> </span>
<span class="n">b</span>
<span class="w"> </span>
<span class="o">=</span>
<span class="w"> </span>
<span class="n">f</span>
<span class="p">.</span>
<span class="n">example</span>
<span class="w"> </span>
<span class="o">+</span>
<span class="w"> </span>
<span class="n">a</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="n">std</span>
<span class="o">::</span>
<span class="n">cout</span>
<span class="o">&lt;&lt;</span>
<span class="s">"Result: "</span>
<span class="o">&lt;&lt;</span>
<span class="n">b</span>
<span class="o">&lt;&lt;</span>
<span class="n">std</span>
<span class="o">::</span>
<span class="n">endl</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="p">{</span>
<span class="w">        </span>
<span class="k">using</span>
<span class="w"> </span>
<span class="k">namespace</span>
<span class="w"> </span>
<span class="nn">std</span>
<span class="p">;</span>
<span class="w">        </span>
<span class="n">string</span>
<span class="w"> </span>
<span class="n">ex</span>
<span class="w"> </span>
<span class="o">=</span>
<span class="w"> </span>
<span class="s">"string"</span>
<span class="p">;</span>
<span class="w">        </span>
<span class="n">cout</span>
<span class="o">&lt;&lt;</span>
<span class="s">"Also throwing in a scoped namespace use with a "</span>
<span class="o">&lt;&lt;</span>
<span class="n">ex</span>
<span class="o">&lt;&lt;</span>
<span class="n">endl</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="p">}</span>
<span class="w">    </span>
<span class="p">{</span>
<span class="w">        </span>
<span class="k">const</span>
<span class="w"> </span>
<span class="kt">int16_t</span>
<span class="w"> </span>
<span class="n">meh</span>
<span class="w"> </span>
<span class="o">=</span>
<span class="w"> </span>
<span class="mi">1</span>
<span class="p">;</span>
<span class="w">    </span>
<span class="p">}</span>
<span class="w">    </span>
<span class="k">return</span>
<span class="w"> </span>
<span class="mi">0</span>
<span class="p">;</span>
<span class="p">}</span>
</code>
</pre>

So now we got a "nice" collection of generated span tags with some class attributes.
For now we're estimating what those mean.

Class Attribute Associated context
cp C Preprocessor
w Whitespace
cpf C Preprocessor file
k Keyword
kt Keyword and Type
c1 One line comment
cm Multi line comment
o Operator
n Name and also class types
cn Class name definition
p Block control
s String Literal
mi Numerical Constant / Magic int
nc Name of Template Parameter
nb Name of Boolean
nn Name of Namespace
nf Name of Function

Using our collected info the can now try to use some minor css to highlight our cpp code.

/*
 * Code block css
 */
pre {
    font-family: monospace;
    display: block;
  background-color: #fdf6e3;
    color: #657b83;
    padding: 1em;
    border: 1px solid #666;
    border-radius: 3px;
    word-wrap: break-word;
}

code > span.cp
{
    color: #cb4b16;
}

code > span.nf,
code > span.k
{
    color: #859900;
}

code > span.c1,
code > span.cm
{
    color: #93a1a1;
}

code > span.nb,
code > span.cpf,
code > span.mi,
code > span.s
{
    color: #2aa198;
}

code > span.kt
{
    color: #b58900;
}
Published on Thu 04 April 2024
Author: Claudius "keldu" Holeksa
IPv6 Certification Badge for keldu