diff --git a/lib/Pandoc.rakumod b/lib/Pandoc.rakumod new file mode 100644 index 0000000..8d4be45 --- /dev/null +++ b/lib/Pandoc.rakumod @@ -0,0 +1,49 @@ +#| Interaction with pandoc +unit module Pandoc; + +use JSON::Fast; + +sub markdown-title(IO::Path:D $file --> Str:D) is export { + # Call into pandoc + my $pandoc = run 'pandoc', '-t', 'JSON', $file, :out, :err; + 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 + my $parsed = from-json $output; + # 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 + my @headers = $parsed.blocks.grep(*.t == "Header").grep(*.c[0] == 1); + if @headers.elems > 1 { + die "More than one top level header in $file"; + }; + if @headers.elems == 0 { + die "No top level hearders in $file"; + }; + + # Extract the header and process it into a string + my @header = @headers[0].c[2]; + my $title = ""; + for @header -> $component { + given $component.t { + when "Str" { + $title = $title ~ $component.c; + } + when "Space" { + $title = $title ~ " "; + } + default { + die "Invalid component type: $_"; + } + } + } + + return $title; +}