website/lib/Pygments.rakumod

40 lines
1.3 KiB
Raku

#| Interaction with pygments
unit module Pygments;
my token fence { '```' }
my token info-string { \w+ }
# TODO: Be more precise about this so we can handle backticks in code blocks
my token code { <-[`]>+ }
my token code-block {
<&fence> <info-string> \h* \v
<code>
<&fence>
}
sub pygment(Str:D $code, Str:D $lang --> Str:D) {
my $pygments = run <pygmentize -f html -l>, $lang, :out, :in;
$pygments.in.spurt: $code, :close;
$pygments.out.slurp: :close;
}
sub highlight-code(Str:D $input --> Str:D) is export {
my $text = $input;
# TODO: Figure out a way to exclude idris code so we can process both in the
# same file
while $text ~~ &code-block {
my $match = $/;
# Extract the match and have pygments colorize the code
my $code = $match<code>.Str;
my $lang = $match<info-string>.Str;
my $out = pygment $code, $lang;
## Mangle the html to meet our needs
# Delete the existing div and construct a <code></code> inside the <pre>
$out ~~ s:g/'<' \/? 'div' <-[>]>* '>'//;
$out ~~ s:g/'<pre>'/<pre><code class="{$lang}-code">/;
$out ~~ s:g/'</pre>'/<\/code><\/pre>/;
# Rename the classes to match our needs
$out ~~ s:g/'span class="' (\w+) '"'/span class="hl-{$/[0].lc}"/;
$text = $match.replace-with: $out;
}
$text
}