Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement yaml metadata hook #3

Merged
merged 7 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/Markdown/Perl.pm
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ sub set_mode {
return;
}

Readonly::Array my @VALID_HOOKS => qw(resolve_link_ref);
Readonly::Array my @VALID_HOOKS => qw(resolve_link_ref yaml_metadata);

sub set_hooks {
my ($this, %hooks) = &_get_this_and_args; ## no critic (ProhibitAmpersandSigils)
Expand Down Expand Up @@ -324,6 +324,8 @@ optionally a C<title> key containing the title of the key. The hash-ref can also
contain a C<content> key, in which case its value should be a span of HTML which
will replace whatever would have been used for the link content.

C<yaml_metadata>: this hook will trigger if there is valid (!) YAML metadata in the file and will give you a YAML::Tiny object as an argument.
adriaandens marked this conversation as resolved.
Show resolved Hide resolved
mkende marked this conversation as resolved.
Show resolved Hide resolved

=back

=head1 AUTHOR
Expand Down
3 changes: 3 additions & 0 deletions lib/Markdown/Perl/BlockParser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ sub _parse_yaml_metadata {
pos($this->{md}) = 0;
adriaandens marked this conversation as resolved.
Show resolved Hide resolved
return;
}
if(exists($this->{pmarkdown}) && exists($this->{pmarkdown}->{hooks}->{yaml_metadata})) {
adriaandens marked this conversation as resolved.
Show resolved Hide resolved
my $hook_result = $this->{pmarkdown}->{hooks}->{yaml_metadata}->($metadata);
}
}

return;
Expand Down
32 changes: 32 additions & 0 deletions t/501-hooks-yaml-metadata.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use strict;
use warnings;
use utf8;

use Markdown::Perl 'convert', 'set_hooks';
use Test2::V0;

my $p = Markdown::Perl->new();
my $page = <<EOF;
---
name: Mark is down
draft: false
number: 42
---
# Mark is down!

I repeat: "Mark is down!"
EOF

# Test 1: Check if we can get a string value
{
sub hook_is_name_mark {
my $x = shift;
ok(exists($x->[0]->{name}) && $x->[0]->{name} eq 'Mark is down', "key 'name' was retrieved and validated as being 'Mark is down'");
adriaandens marked this conversation as resolved.
Show resolved Hide resolved
}
$p->set_hooks(yaml_metadata => \&hook_is_name_mark);
$p->convert($page);
}

# Test 2: Validate that hook is not called if yaml is invalid
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you missing this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, i forgot to git add the test file.
I also tried adding tests for the carp behaviour with Test::Carp but somehow that causes a different codepath to be taken and does not give the expected result whatever I try. :(

For example below, for unknown reasons to me, it does not call the hook (but if i run it as $p->convert($page) it does).

# Test 4: What happens if inside the hook we die()
use Test::Carp;

{
  sub hook_die {
    print "Dying ongoing...\n";
    die "We just die\n";
  }
  $p->set_hooks(yaml_metadata => \&hook_die);
  does_carp_that_matches($p->can("convert"), $page, qr/Hook.+crash/);
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect that this is because Test::Carp is incompatible with Test2 (so the hook is called but not caught by the test util). Instead you can use Test2::Tools::Warnings (which I believe is already included automatically by Test2::V0.

Also it might be because I expect that the current code dies in the call to convert because it’s dereferencing an undef $blocks returned by _parse (this will problem will go away once the exception is just propagated to the caller).


done_testing;