Search code examples
jekyllkramdown

How do I prevent Kramdown from getting confused by a C++ include?


I have written this plugin:

module Jekyll
    module Tags
        class Prism < Liquid::Block
            def initialize(tag_name, text, tokens)
                @arg = text.strip
                super
            end

            def render(context)
                output = super(context)
                "<pre><code class=\"language-#{@arg}\">#{output}</code></pre>"
            end
        end
    end
end 

Liquid::Template.register_tag('prism', Jekyll::Tags::Prism)

This is how I use it:

{% prism cpp %}
#include <iostream>

// Hello World
int main()
{
    cout << "hello world" << endl;
    int a = 10;
}
{% endprism %}

Now, the problem is, that I mostly use C++ Code on my website. When I now generate this markdown with Jekyll, then all text after {% endprism %} would still be within the <pre> Tag, because Kramdown is getting confused by <iostream> If I escape it, (\<iostream\>), then my plugin works as expected, but my Javascript Highlighter is getting confused.

How can I solve this situation without enabling Jekyll's highlighter?


Solution

  • There is a function in the CGI Module, that allows for escaping HTML much like htmlspecialchars from PHP. I changed the liquid plugin to this and it works:

    require 'cgi'
    
    module Jekyll
        module Tags     
            class Prism < Liquid::Block
                def initialize(tag_name, text, tokens)
                    @arg = text.strip
                    super
                end
    
                def render(context)
                    output = super(context)
                    output = CGI.escapeHTML(output);
                    "<pre><code class=\"language-#{@arg}\">#{output}</code></pre>"
                end
            end
        end
    end 
    
    Liquid::Template.register_tag('prism', Jekyll::Tags::Prism)
    

    It escapes all <> to html special chars. Therefore Kramdown does not get confused and prism.js is still able to highlight the code correctly.

    Screenshot of highlighting