diff options
Diffstat (limited to 'Bugzilla/Markdown/GFM')
-rw-r--r-- | Bugzilla/Markdown/GFM/Node.pm | 33 | ||||
-rw-r--r-- | Bugzilla/Markdown/GFM/Parser.pm | 109 | ||||
-rw-r--r-- | Bugzilla/Markdown/GFM/SyntaxExtension.pm | 31 | ||||
-rw-r--r-- | Bugzilla/Markdown/GFM/SyntaxExtensionList.pm | 23 |
4 files changed, 196 insertions, 0 deletions
diff --git a/Bugzilla/Markdown/GFM/Node.pm b/Bugzilla/Markdown/GFM/Node.pm new file mode 100644 index 000000000..da5af1a68 --- /dev/null +++ b/Bugzilla/Markdown/GFM/Node.pm @@ -0,0 +1,33 @@ +package Bugzilla::Markdown::GFM::Node; + +use 5.10.1; +use strict; +use warnings; + +sub SETUP { + my ($class, $FFI) = @_; + + $FFI->custom_type( + markdown_node_t => { + native_type => 'opaque', + native_to_perl => sub { + bless \$_[0], $class if $_[0]; + }, + perl_to_native => sub { ${ $_[0] } }, + } + ); + + $FFI->attach( + [ cmark_node_free => 'DESTROY' ], + [ 'markdown_node_t' ] => 'void' + ); + + $FFI->attach( + [ cmark_render_html => 'render_html' ], + [ 'markdown_node_t', 'markdown_options_t', 'markdown_syntax_extension_list_t'] => 'string', + ); +} + +1; + +__END__ 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 diff --git a/Bugzilla/Markdown/GFM/SyntaxExtension.pm b/Bugzilla/Markdown/GFM/SyntaxExtension.pm new file mode 100644 index 000000000..56efa177a --- /dev/null +++ b/Bugzilla/Markdown/GFM/SyntaxExtension.pm @@ -0,0 +1,31 @@ +package Bugzilla::Markdown::GFM::SyntaxExtension; + +use 5.10.1; +use strict; +use warnings; + +sub SETUP { + my ($class, $FFI) = @_; + + $FFI->custom_type( + markdown_syntax_extension_t => { + native_type => 'opaque', + native_to_perl => sub { + bless \$_[0], $class if $_[0]; + }, + perl_to_native => sub { $_[0] ? ${ $_[0] } : 0 }, + } + ); + $FFI->attach( + [ cmark_find_syntax_extension => 'find' ], + [ 'string' ] => 'markdown_syntax_extension_t', + sub { + my $c_func = shift; + return $c_func->($_[1]); + } + ); +} + +1; + +__END__ diff --git a/Bugzilla/Markdown/GFM/SyntaxExtensionList.pm b/Bugzilla/Markdown/GFM/SyntaxExtensionList.pm new file mode 100644 index 000000000..06a9798c2 --- /dev/null +++ b/Bugzilla/Markdown/GFM/SyntaxExtensionList.pm @@ -0,0 +1,23 @@ +package Bugzilla::Markdown::GFM::SyntaxExtensionList; + +use 5.10.1; +use strict; +use warnings; + +sub SETUP { + my ($class, $FFI) = @_; + + $FFI->custom_type( + markdown_syntax_extension_list_t => { + native_type => 'opaque', + native_to_perl => sub { + bless \$_[0], $class if $_[0]; + }, + perl_to_native => sub { $_[0] ? ${ $_[0] } : 0 }, + } + ); +} + +1; + +__END__ |