Working markdown post title

This commit is contained in:
Nathan McCarty 2025-01-21 01:31:33 -05:00
parent ec491f6c98
commit 0b199cf9b9
4 changed files with 46 additions and 7 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
.env/ .env/
.direnv/ .direnv/
**/.precomp/

8
blog
View file

@ -1 +1,9 @@
#!/usr/bin/env raku #!/usr/bin/env raku
use DB;
my $example-post = DB::MarkdownPost.new:
source => "../Idris/advent/src/Util/Digits.md".IO,
posted-at => DateTime.now;
say $example-post.title;

26
lib/DB.rakumod Normal file
View file

@ -0,0 +1,26 @@
#| Post database
unit module DB;
use Pandoc;
#| Shared post meta-data
role Post {
#| The location of the source file for the post
has IO::Path:D $.source is required;
#| The time to display for the creation of the post
has DateTime:D $.posted-at is required;
#| An optional list of edit times for the post
has DateTime:D @.edited-at is rw = [];
#| Get the title for this post, intended to be extracted from whatever
#| document produced it
method title(--> Str:D) {...}
}
#| A plain markdown post
class MarkdownPost does Post {
method title(--> Str:D) {
markdown-title($!source)
}
}

View file

@ -5,7 +5,7 @@ use JSON::Fast;
sub markdown-title(IO::Path:D $file --> Str:D) is export { sub markdown-title(IO::Path:D $file --> Str:D) is export {
# Call into pandoc # Call into pandoc
my $pandoc = run 'pandoc', '-t', 'JSON', $file, :out, :err; my $pandoc = run 'pandoc', '-f', 'gfm', '-t', 'JSON', $file, :out, :err;
my $output = $pandoc.out.slurp: :close; my $output = $pandoc.out.slurp: :close;
my $stderr = $pandoc.err.slurp: :close; my $stderr = $pandoc.err.slurp: :close;
@ -16,25 +16,29 @@ sub markdown-title(IO::Path:D $file --> Str:D) is export {
# Parse out output from pandoc, we are making an executive decision to trust # 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 # pandoc here, so we won't do any error handling for pandoc's output
my $parsed = from-json $output; my %parsed = from-json $output;
# Extract a list of top level headers from the pandoc output, this should # 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 # only have one element in it, but as this is user input, its untrusted and
# we need to do some error handling # we need to do some error handling
my @headers = $parsed.blocks.grep(*.t == "Header").grep(*.c[0] == 1); my sub is-header($v) {
$v ~~ Associative && $v<t> ~~ "Header"
}
my @headers = %parsed<blocks>.grep(&is-header).grep(*<c>[0] == 1);
if @headers.elems > 1 { if @headers.elems > 1 {
die "More than one top level header in $file"; die "More than one top level header in $file";
}; };
if @headers.elems == 0 { if @headers.elems == 0 {
die "No top level hearders in $file"; die "No top level headers in $file";
}; };
# Extract the header and process it into a string # Extract the header and process it into a string
my @header = @headers[0].c[2]; my @header = @headers[0]<c>[2].flat;
my $title = ""; my $title = "";
for @header -> $component { for @header -> $component {
given $component.t { next unless $component ~~ Associative;
given $component<t> {
when "Str" { when "Str" {
$title = $title ~ $component.c; $title = $title ~ $component<c>;
} }
when "Space" { when "Space" {
$title = $title ~ " "; $title = $title ~ " ";