File Coverage

blib/lib/Text/Markdown/PerlExtensions.pm
Criterion Covered Total %
statement 63 65 96.9
branch 11 16 68.7
condition 1 2 50.0
subroutine 14 14 100.0
pod 2 3 66.6
total 91 100 91.0


line stmt bran cond sub pod time code
1             package Text::Markdown::PerlExtensions;
2             $Text::Markdown::PerlExtensions::VERSION = '0.04';
3 3     3   1926 use strict;
  3         6  
  3         115  
4 3     3   15 use warnings;
  3         4  
  3         81  
5 3     3   35 use 5.8.0;
  3         27  
  3         154  
6              
7 3     3   3282 use parent qw(Text::Markdown Exporter);
  3         1064  
  3         15  
8 3     3   165517 use Text::Balanced qw(extract_bracketed);
  3         7  
  3         2851  
9              
10             our @EXPORT_OK = qw(markdown add_formatting_code);
11             my %handler =
12             (
13             'M' => \&_formatting_code_module,
14             'A' => \&_formatting_code_author,
15             'D' => \&_formatting_code_distribution,
16             'P' => \&_formatting_code_perlfunc,
17             );
18              
19             sub markdown
20             {
21 45     45 1 17962 my ( $self, $text, $options ) = @_;
22              
23             # Detect functional mode, and create an instance for this run
24 45 100       129 unless (ref $self) {
25 15 50       51 if ( $self ne __PACKAGE__ ) {
26 15         73 my $ob = __PACKAGE__->new();
27             # $self is text, $text is options
28 15         30 $ob->{ handlers } = \%handler;
29 15         57 return $ob->markdown($self, $text);
30             }
31             else {
32 0         0 croak('Calling ' . $self . '->markdown (as a class method) is not supported.');
33             }
34             }
35              
36 30   50     160 $options ||= {};
37              
38 30         294 %$self = (
39 30         40 %{ $self->{params} },
40             %$options,
41             params => $self->{params},
42             handlers => $self->{handlers}
43             );
44              
45 30         133 $self->_CleanUpRunData($options);
46              
47 30         341 return $self->_Markdown($text);
48             }
49              
50             sub add_formatting_code
51             {
52 6 100   6 0 82 if (@_ == 2) {
    50          
53 2         6 my ($code, $handler_function) = @_;
54 2         7 $handler{$code} = $handler_function;
55             } elsif (@_ == 3) {
56 4         9 my ($self, $code, $handler_function) = @_;
57 4 50       14 $self->{ handlers } = {} if not exists $self->{ handlers };
58 4         41 $self->{ handlers }->{ $code } = $handler_function;
59             } else {
60 0         0 croak('wrong number of args to add_handler()');
61             }
62             }
63              
64             sub _RunSpanGamut {
65 30     30   16340 my ($self, $text) = @_;
66              
67 30         122 $text = $self->SUPER::_RunSpanGamut($text);
68 30         12640 return $self->_DoExtendedMarkup($text);
69             }
70              
71             sub new
72             {
73 18     18 1 2860 my ($class, %p) = @_;
74 18         109 my $self = $class->SUPER::new(%p);
75              
76 18 50       439 return undef unless defined($self);
77 18         73 $self->{ handlers } = \%handler;
78              
79 18         42 return $self;
80             }
81              
82             sub _DoExtendedMarkup
83             {
84 102     102   202 my ($self, $text) = @_;
85 102         98 my $regexp = join('|', keys %{ $self->{ handlers }});
  102         401  
86              
87 102 100       787 if ($text =~ m!\A(.*?)($regexp)(<[^/].*)\z!ms) {
88 36         271 my $prefix = $1;
89 36         62 my $code = $2;
90 36         58 my $tail = $3;
91 36         139 my ($extracted, $remainder) = extract_bracketed($tail, '<>');
92 36 50       4272 if (defined($extracted)) {
93             # Need to be able to handled I and B>,
94             # which is why we're using extract_bracketed, and recurse on the contents
95 36         223 $extracted =~ s/\A<|>\z//msg;
96 36         128 $extracted = $self->_DoExtendedMarkup($extracted);
97 36         129 my $result = $self->{handlers}->{$code}->( $extracted );
98 36         150 return $prefix.$result.$self->_DoExtendedMarkup($remainder);
99             }
100             }
101              
102 66         153 $text =~ s!\bRT#([0-9]+)\b!RT#$1!msg;
103              
104 66         239 return $text;
105             }
106              
107             sub _formatting_code_distribution
108             {
109 2     2   4 my $dist_name = shift;
110              
111 2         24 return qq{$dist_name};
112             }
113              
114             sub _formatting_code_module
115             {
116 8     8   10 my $module_name = shift;
117              
118 8         23 return qq{$module_name};
119             }
120              
121             sub _formatting_code_author
122             {
123 6     6   10 my $author_id = shift;
124              
125 6         17 return qq{$author_id};
126             }
127              
128             sub _formatting_code_perlfunc
129             {
130 2     2   4 my $function_name = shift;
131              
132 2         12 return qq{$function_name};
133             }
134              
135             1;
136              
137             =encoding utf8
138              
139             =head1 NAME
140              
141             Text::Markdown::PerlExtensions - markdown converter that supports perl-specific extensions
142              
143             =head1 SYNOPSIS
144              
145             In your markdown:
146              
147             You might P M in D by A.
148              
149             And to convert that:
150              
151             use Text::Markdown::PerlExtensions qw(markdown);
152             $html = markdown($markdown);
153              
154             =head1 DESCRIPTION
155              
156             Text::Markdown::PerlExtensions provides a function for converting markdown
157             to HTML.
158             It is a subclass of L that provides three additional
159             features:
160              
161             =over 4
162              
163             =item *
164              
165             Four pod-style formatting codes, used for distribution names,
166             module names, PAUSE author IDs, and Perl's built-in functions.
167             These generate links to the relevant pages on L
168             or L.
169              
170             =item *
171              
172             A mechanism for adding further pod-style formatting codes.
173              
174             =item *
175              
176             References to RT issues in the format RT#1234 will be hyperlinked to the issue on RT.
177              
178             =back
179              
180             I wrote this module to use with my blogging engine.
181             I found that I was constantly writing links to MetaCPAN,
182             and wanted a terser notation.
183              
184             The following sections describe each of the extensions,
185             one by one.
186              
187             =head2 Module
188              
189             To refer to a module on CPAN, you use the B formatting code.
190             If you write:
191              
192             M
193              
194             This generates:
195              
196             Module::Path
197              
198             The link is given a class, so you can style module names.
199              
200             =head2 Distribution
201              
202             To refer to a distribution, use the B formatting code.
203             If you write
204              
205             D
206              
207             this generates:
208              
209             Dancer
210              
211             =head2 CPAN Author
212              
213             Similarly, to refer to a CPAN author, use the B formatting code.
214             If you write:
215              
216             A
217              
218             This generates:
219              
220             NEILB
221              
222             =head2 Perl built-in function
223              
224             To link to documentation for one of Perl's built-in functions,
225             use the B

formatting code:

226              
227             P
228              
229             This example would produce:
230              
231             require
232              
233             I really wanted to use the B formatting code for this,
234             but that's already taken in the L,
235             used for highlighting file names.
236              
237             Note: this doesn't check whether the function name given is actually a
238             Perl built-in.
239              
240             =head2 Markdown
241              
242             All other syntax is as supported by L.
243             You shouldn't find any clashes between the Pod-like extensions;
244             I haven't found any so far, but please let me know if you
245             experience any problems.
246              
247             =head1 Adding formatting codes
248              
249             You can add your own pod-style formatting codes.
250             For each code you define a function that takes one text argument
251             and returns the transformed version of that text.
252              
253             The following shows how you could define B and B formatting codes,
254             for italic and bold respectively:
255              
256             use Text::Markdown::PerlExtensions qw(markdown add_formatting_code);
257            
258             sub format_italic
259             {
260             my $text = shift;
261            
262             return "$text";
263             }
264            
265             sub format_bold
266             {
267             my $text = shift;
268            
269             return "$text";
270             }
271            
272             add_formatting_code('I' => \&format_bold);
273             add_formatting_code('B' => \&format_bold);
274              
275             my $md = 'Highlight with B and I.';
276             my $text = markdown($md);
277              
278             =head1 SEE ALSO
279              
280             L - the base class for this module.
281              
282             L - the original spec
283             for markdown syntax.
284              
285             =head1 REPOSITORY
286              
287             L
288              
289             =head1 AUTHOR
290              
291             Neil Bowers Eneilb@cpan.orgE
292              
293             =head1 COPYRIGHT AND LICENSE
294              
295             This software is copyright (c) 2014 by Neil Bowers .
296              
297             This is free software; you can redistribute it and/or modify it under
298             the same terms as the Perl 5 programming language system itself.
299              
300             =cut
301