package Classy::Dialect::SpanParser; use strict; use warnings; use namespace::autoclean; our $VERSION = '0.10'; use Markdent::Event::StartHTMLTag; use Markdent::Event::EndHTMLTag; use Markdent::Event::HTMLTag; use Markdent::Event::StartOrderedList; use Markdent::Event::EndOrderedList; use Markdent::Event::HorizontalRule; use Markdent::Event::StartLink; use Markdent::Event::EndLink; use Markdent::Event::Text; use Markdent::Types; use Moose::Role; with 'Markdent::Dialect::GitHub::SpanParser'; has _notes_by_id => ( traits => ['Hash'], is => 'ro', isa => t( 'HashRef', of => t('Str') ), default => sub { {} }, init_arg => undef, handles => { _add_fn_by_id => 'set', _get_fn_by_id => 'get', _reset_footnotes => 'clear', }, ); has _note_idx_map => ( traits => ['Array'], is => 'ro', isa => t( 'ArrayRef', of => t('Str') ), default => sub { [] }, handles => { _add_fn_to_map => 'push', _get_fn_list => 'get', _fn_list_count => 'count', _reset_fn_map => 'clear', }, ); # Footnotes are kinda like links, but IDs are prefixed with a caret (^) around extract_link_ids => sub { my $orig = shift; my $self = shift; my $text = shift; ${$text} =~ s/ ^ \p{SpaceSeparator}{0,3} \[ \^ ([^]]+) \] : \p{SpaceSeparator}* \n? \p{SpaceSeparator}* ( (.|\n[^\n])+ ) (?:\n\n|$) / $self->_process_id_for_fn( $1, $2 ); '' /egxm; $self->$orig($text); }; around _possible_span_matches => sub { my $orig = shift; my $self = shift; my @look_for = $self->$orig(); unshift @look_for, 'footnote'; return @look_for; }; sub _process_id_for_fn { my $self = shift; my $id = shift; my $id_text = shift; $id_text =~ s/\s+$//; $id_text =~ s/\n+/ /g; $self->_debug_parse_result( $id, 'footnote', [ text => $id_text ], ) if $self->debug; $self->_add_fn_by_id( $id => $id_text ); } # Matches the inline footnote sub _match_footnote { my $self = shift; my $text = shift; my $pos = pos ${$text} || 0; return unless ${$text} =~ / \G \[ \^ ([^]]+) \] # footnote id /xgc; my $fn_id = $1; $self->_add_fn_to_map($fn_id); my $fn_idx = $self->_fn_list_count; # [idx] my $start_sup = $self->_make_event( StartHTMLTag => { tag => "sup" }); my $start_brack = '['; my $end_brack = ']'; my $end_sup = $self->_make_event( EndHTMLTag => { tag => "sup" }); my $start_link = $self->_make_event( StartHTMLTag => { tag => 'a', attributes => { href => "#fn:$fn_id", id => "fnref:$fn_id", }, }); my $end_link = $self->_make_event('EndLink'); $self->_markup_event($start_sup); $self->_parse_text( \$start_brack ); $self->_markup_event($start_link); $self->_parse_text( \$fn_idx ); $self->_markup_event($end_link); $self->_parse_text( \$end_brack ); $self->_markup_event($end_sup); return 1; } 1; __END__