File Coverage

blib/lib/App/sdview/Parser/Markdown.pm
Criterion Covered Total %
statement 116 128 90.6
branch 37 42 88.1
condition 20 27 74.0
subroutine 13 15 86.6
pod 0 4 0.0
total 186 216 86.1


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2021-2023 -- leonerd@leonerd.org.uk
5              
6 4     4   546283 use v5.26;
  4         21  
7 4     4   33 use warnings;
  4         10  
  4         385  
8              
9 4     4   1645 use Object::Pad 0.807;
  4         28098  
  4         311  
10              
11             package App::sdview::Parser::Markdown 0.20;
12             class App::sdview::Parser::Markdown :strict(params);
13              
14 2     2   2429 apply App::sdview::Parser;
  2         8  
  2         127  
15              
16 4     4   3822 use File::Slurper 'read_text';
  4         111304  
  4         565  
17              
18 4     4   2815 use String::Tagged::Markdown 0.05;
  4         63274  
  4         465  
19              
20 4     4   72 use constant format => "Markdown";
  4         10  
  4         440  
21 4     4   30 use constant sort_order => 20;
  4         12  
  4         21121  
22              
23             =head1 NAME
24              
25             C - parse Markdown files for L
26              
27             =head1 SYNOPSIS
28              
29             $ sdview README.md
30              
31             $ sdview -f Markdown my-document
32              
33             =head1 DESCRIPTION
34              
35             This parser module adds to L the ability to parse input text in
36             Markdown formatting.
37              
38             It uses a custom in-built parser for the block-level parts of the formatting,
39             able to handle comments, verbatim blocks, headings in both C<#>-prefixed and
40             C<=>-underlined styles, bullet and numbered lists, and tables.
41              
42             It uses L to parse the inline-level formatting,
43             supporting bold, italic, strikethrough, and fixed-width styles, and links.
44              
45             =cut
46              
47 0     0 0 0 sub find_file ( $class, $name ) { return undef }
  0         0  
  0         0  
  0         0  
  0         0  
48              
49 1         4 sub can_parse_file ( $class, $file )
50 1     1 0 12627 {
  1         3  
  1         3  
51 1         17 return $file =~ m/\.(?:md|markdown)$/;
52             }
53              
54 0     0 0 0 method parse_file ( $fh )
  0         0  
  0         0  
  0         0  
55             {
56 0         0 return $self->parse_string( read_text $fh );
57             }
58              
59             field @_paragraphs;
60              
61             sub _split_table_row ( $str )
62 19     19   40 {
  19         37  
  19         30  
63 19 50       112 $str =~ m/^\s*\|/ or return undef;
64 19 50       96 $str =~ m/\|\s*$/ or return undef;
65              
66 19         85 my @cols = split m/\|/, $str, -1;
67 19         37 shift @cols; pop @cols;
  19         38  
68              
69 19         2792 s/^\s+//, s/\s+$// for @cols;
70              
71 19         124 return \@cols;
72             }
73              
74 18     18 0 50 method parse_string ( $str )
  18         55  
  18         40  
  18         32  
75             {
76 18         47 my $in_verb;
77              
78             my @lines;
79              
80 18         145 foreach ( split( m/\n/, $str ), "" ) {
81 121         265 my $line = $_; # So we have a copy, because foreach my ... will alias the readonly ""
82              
83 121 100       335 if( $in_verb ) {
84 8         18 my $para = $_paragraphs[-1];
85              
86 8 100       28 if( $line =~ m/^\`\`\`/ ) {
87 2         6 undef $in_verb;
88             next
89 2         7 }
90              
91 6 100       27 length $para->text and
92             $para->text->append( "\n" );
93              
94 6         220 $para->text->append( $line );
95 6         285 next;
96             }
97              
98 113 100       299 if( $line =~ s/^\`\`\`// ) {
99 2         17 my $language = $line =~ s/^\s+|\s+$//gr;
100 2 50       71 push @_paragraphs, App::sdview::Para::Verbatim->new(
101             language => ( length $language ? $language : undef ),
102             text => String::Tagged->new,
103             );
104 2         6 $in_verb++;
105 2         7 next;
106             }
107              
108 111 100       267 if( length $line ) {
109 66         166 push @lines, $line;
110 66         186 next;
111             }
112              
113 45         147 while( @lines ) {
114 50 50 100     793 if( $lines[0] =~ m/^