2025-01-20 22:22:33 -05:00
|
|
|
#| Interaction with pandoc
|
|
|
|
unit module Pandoc;
|
|
|
|
|
|
|
|
use JSON::Fast;
|
|
|
|
|
|
|
|
sub markdown-title(IO::Path:D $file --> Str:D) is export {
|
|
|
|
# Call into pandoc
|
2025-01-21 01:31:33 -05:00
|
|
|
my $pandoc = run 'pandoc', '-f', 'gfm', '-t', 'JSON', $file, :out, :err;
|
2025-01-20 22:22:33 -05:00
|
|
|
my $output = $pandoc.out.slurp: :close;
|
|
|
|
my $stderr = $pandoc.err.slurp: :close;
|
|
|
|
|
|
|
|
# Throw an error if pandoc failed
|
|
|
|
if !$pandoc {
|
|
|
|
die "Pandoc exited with {$pandoc.exitcode}\nout: $output\nerr: $stderr";
|
|
|
|
}
|
|
|
|
|
|
|
|
# Parse out output from pandoc, we are making an executive decision to trust
|
|
|
|
# pandoc here, so we won't do any error handling for pandoc's output
|
2025-01-21 01:31:33 -05:00
|
|
|
my %parsed = from-json $output;
|
2025-01-20 22:22:33 -05:00
|
|
|
# Extract a list of top level headers from the pandoc output, this should
|
|
|
|
# only have one element in it, but as this is user input, its untrusted and
|
|
|
|
# we need to do some error handling
|
2025-01-21 01:31:33 -05:00
|
|
|
my sub is-header($v) {
|
|
|
|
$v ~~ Associative && $v<t> ~~ "Header"
|
|
|
|
}
|
|
|
|
my @headers = %parsed<blocks>.grep(&is-header).grep(*<c>[0] == 1);
|
2025-01-20 22:22:33 -05:00
|
|
|
if @headers.elems > 1 {
|
|
|
|
die "More than one top level header in $file";
|
|
|
|
};
|
|
|
|
if @headers.elems == 0 {
|
2025-01-21 01:31:33 -05:00
|
|
|
die "No top level headers in $file";
|
2025-01-20 22:22:33 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
# Extract the header and process it into a string
|
2025-01-21 01:31:33 -05:00
|
|
|
my @header = @headers[0]<c>[2].flat;
|
2025-01-20 22:22:33 -05:00
|
|
|
my $title = "";
|
|
|
|
for @header -> $component {
|
2025-01-21 01:31:33 -05:00
|
|
|
next unless $component ~~ Associative;
|
|
|
|
given $component<t> {
|
2025-01-20 22:22:33 -05:00
|
|
|
when "Str" {
|
2025-01-21 01:31:33 -05:00
|
|
|
$title = $title ~ $component<c>;
|
2025-01-20 22:22:33 -05:00
|
|
|
}
|
|
|
|
when "Space" {
|
|
|
|
$title = $title ~ " ";
|
|
|
|
}
|
|
|
|
default {
|
|
|
|
die "Invalid component type: $_";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $title;
|
|
|
|
}
|