summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Markdown/GFM/Parser.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Markdown/GFM/Parser.pm')
-rw-r--r--Bugzilla/Markdown/GFM/Parser.pm109
1 files changed, 109 insertions, 0 deletions
diff --git a/Bugzilla/Markdown/GFM/Parser.pm b/Bugzilla/Markdown/GFM/Parser.pm
new file mode 100644
index 000000000..5307b49c1
--- /dev/null
+++ b/Bugzilla/Markdown/GFM/Parser.pm
@@ -0,0 +1,109 @@
+package Bugzilla::Markdown::GFM::Parser;
+
+use 5.10.1;
+use strict;
+use warnings;
+
+use FFI::Platypus::Buffer qw( scalar_to_buffer buffer_to_scalar );
+
+sub new {
+ my ($class, $options) = @_;
+ my $extensions = delete $options->{extensions} // [];
+ my $parser = $class->_new($options);
+ $parser->{_options} = $options;
+
+ eval {
+ foreach my $name (@$extensions) {
+ my $extension = Bugzilla::Markdown::GFM::SyntaxExtension->find($name)
+ or die "unknown extension: $name";
+ $parser->attach_syntax_extension($extension);
+ }
+ };
+
+ return $parser;
+}
+
+sub render_html {
+ my ($self, $markdown) = @_;
+ $self->feed($markdown);
+ my $node = $self->finish;
+ return $node->render_html($self->{_options}, $self->get_syntax_extensions);
+}
+
+sub SETUP {
+ my ($class, $FFI) = @_;
+
+ $FFI->custom_type(
+ markdown_parser_t => {
+ native_type => 'opaque',
+ native_to_perl => sub {
+ bless { _pointer => $_[0] }, $class;
+ },
+ perl_to_native => sub { $_[0]->{_pointer} },
+ }
+ );
+
+ $FFI->attach(
+ [ cmark_parser_new => '_new' ],
+ [ 'markdown_options_t' ] => 'markdown_parser_t',
+ sub {
+ my $c_func = shift;
+ return $c_func->($_[1]);
+ }
+ );
+
+ $FFI->attach(
+ [ cmark_parser_free => 'DESTROY' ],
+ [ 'markdown_parser_t' ] => 'void'
+ );
+
+ $FFI->attach(
+ [ cmark_parser_feed => 'feed'],
+ ['markdown_parser_t', 'opaque', 'int'] => 'void',
+ sub {
+ my $c_func = shift;
+ $c_func->($_[0], scalar_to_buffer $_[1]);
+ }
+ );
+
+ $FFI->attach(
+ [ cmark_parser_finish => 'finish' ],
+ [ 'markdown_parser_t' ] => 'markdown_node_t',
+ );
+
+ $FFI->attach(
+ [ cmark_parser_attach_syntax_extension => 'attach_syntax_extension' ],
+ [ 'markdown_parser_t', 'markdown_syntax_extension_t' ] => 'void',
+ );
+
+ $FFI->attach(
+ [ cmark_parser_get_syntax_extensions => 'get_syntax_extensions' ],
+ [ 'markdown_parser_t' ] => 'markdown_syntax_extension_list_t',
+ );
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Bugzilla::Markdown::GFM::Parser - Transforms markdown into HTML via libcmark_gfm.
+
+=head1 SYNOPSIS
+
+ use Bugzilla::Markdown::GFM;
+ use Bugzilla::Markdown::GFM::Parser;
+
+ my $parser = Bugzilla::Markdown::GFM::Parser->new({
+ extensions => [qw( autolink tagfilter table strikethrough )]
+ });
+
+ say $parser->render_html(<<'MARKDOWN');
+ # My header
+
+ This is **markdown**!
+
+ - list item 1
+ - list item 2
+ MARKDOWN