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

formatting code:

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