From 0b199cf9b9367b765b1c1a65b93888dbe1011f17 Mon Sep 17 00:00:00 2001 From: Nathan McCarty Date: Tue, 21 Jan 2025 01:31:33 -0500 Subject: [PATCH] Working markdown post title --- .gitignore | 1 + blog | 8 ++++++++ lib/DB.rakumod | 26 ++++++++++++++++++++++++++ lib/Pandoc.rakumod | 18 +++++++++++------- 4 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 lib/DB.rakumod diff --git a/.gitignore b/.gitignore index 27f3667..4190565 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .env/ .direnv/ +**/.precomp/ diff --git a/blog b/blog index e8c2cb5..eb271a0 100755 --- a/blog +++ b/blog @@ -1 +1,9 @@ #!/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; diff --git a/lib/DB.rakumod b/lib/DB.rakumod new file mode 100644 index 0000000..a12deb4 --- /dev/null +++ b/lib/DB.rakumod @@ -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) + } +} diff --git a/lib/Pandoc.rakumod b/lib/Pandoc.rakumod index 8d4be45..1cbd52f 100644 --- a/lib/Pandoc.rakumod +++ b/lib/Pandoc.rakumod @@ -5,7 +5,7 @@ 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 $pandoc = run 'pandoc', '-f', 'gfm', '-t', 'JSON', $file, :out, :err; my $output = $pandoc.out.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 # 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 # 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); + my sub is-header($v) { + $v ~~ Associative && $v ~~ "Header" + } + my @headers = %parsed.grep(&is-header).grep(*[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"; + die "No top level headers in $file"; }; # Extract the header and process it into a string - my @header = @headers[0].c[2]; + my @header = @headers[0][2].flat; my $title = ""; for @header -> $component { - given $component.t { + next unless $component ~~ Associative; + given $component { when "Str" { - $title = $title ~ $component.c; + $title = $title ~ $component; } when "Space" { $title = $title ~ " ";