Functional syntax highlighting for rust
This commit is contained in:
parent
731d7aa19c
commit
19e06488c4
7 changed files with 299 additions and 5 deletions
|
@ -1,9 +1,13 @@
|
|||
use v6.e.PREVIEW;
|
||||
|
||||
use Pandoc;
|
||||
use JSON::Class:auth<zef:vrurg>;
|
||||
use Pygments;
|
||||
use DB::Post;
|
||||
|
||||
|
||||
use JSON::Class:auth<zef:vrurg>;
|
||||
use File::Temp;
|
||||
|
||||
#| A plain markdown post
|
||||
unit class MarkdownPost does Post is json(:pretty);
|
||||
|
||||
|
@ -20,7 +24,17 @@ method title(--> Str:D) {
|
|||
|
||||
# Simply provide our source file to pandoc
|
||||
method render-html(--> Str:D) {
|
||||
markdown-to-html $!source
|
||||
# Test to see if this posts contains any fenced code blocks, if so,
|
||||
# pygmentize it through a temporary file
|
||||
my $contents = $!source.slurp;
|
||||
if $contents ~~ /'```'/ {
|
||||
my $output = highlight-code $contents;
|
||||
my ($filename, $filehandle) = tempfile;
|
||||
$filehandle.spurt: $output, :close;
|
||||
markdown-to-html $filename.IO
|
||||
} else {
|
||||
markdown-to-html $!source
|
||||
}
|
||||
}
|
||||
|
||||
# Return our summary, if we have one, otherwise extract the first paragraph of
|
||||
|
|
|
@ -6,7 +6,7 @@ use JSON::Fast;
|
|||
#| Run pandoc with the given arguments, dieing on failure
|
||||
sub pandoc(*@args --> Str:D) {
|
||||
# Call into pandoc
|
||||
my $pandoc = run 'pandoc', @args, :out, :err;
|
||||
my $pandoc = run 'pandoc', '--no-highlight', @args, :out, :err;
|
||||
|
||||
# Collect the output
|
||||
my $output = $pandoc.out.slurp: :close;
|
||||
|
|
40
lib/Pygments.rakumod
Normal file
40
lib/Pygments.rakumod
Normal file
|
@ -0,0 +1,40 @@
|
|||
#| 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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue