File Coverage

blib/lib/Perl6/Perldoc/To/Ansi.pm
Criterion Covered Total %
statement 118 337 35.0
branch 0 82 0.0
condition 0 7 0.0
subroutine 96 140 68.5
pod 0 3 0.0
total 214 569 37.6


line stmt bran cond sub pod time code
1             package Perl6::Perldoc::To::Ansi;
2             BEGIN {
3 1     1   968 $Perl6::Perldoc::To::Ansi::AUTHORITY = 'cpan:HINRIK';
4             }
5             BEGIN {
6 1     1   22 $Perl6::Perldoc::To::Ansi::VERSION = '0.11';
7             }
8              
9 1     1   8 use warnings FATAL => 'all';
  1         1  
  1         119  
10 1     1   5 use strict;
  1         13  
  1         593  
11              
12             # add fake opening/closing tags, to be processed later
13             sub add_ansi {
14 0     0 0   my ($text, $new) = @_;
15 0           return "\e[OPEN${new}m" . $text . "\e[CLOSE${new}m";
16             }
17              
18             # same, but only if the entire text is not already colored
19             sub add_ansi_only {
20 0     0 0   my ($text, $new) = @_;
21 0 0 0       return $text if $text =~ /^\e\[/ && $text =~ /\e\[0?m$/;
22 0           return add_ansi($text, $new);
23             }
24              
25             sub rewrite_ansi {
26 0     0 0   my ($text) = @_;
27             #$text = "\e[${new}m$text";
28             #$text =~ s/(?:\e\[m)*$//;
29              
30 0           my @code_stack;
31             my $current = sub {
32 0     0     my $ret = '';
33 0           $ret .= "\e[${_}m" for @code_stack;
34 0           return $ret;
35 0           };
36            
37 0           $text =~ s{( \e\[.+?m | \n )}{
38 0           my $match = $1;
39             #$match =~ s/(?:\e\[m)+//g;
40             #$match =~ s/^\e\[|m$//g;
41 0           my $subst = '';
42              
43 0 0         if ($match eq "\n") {
    0          
    0          
44             # re-apply codes because newline resets them
45 0           $subst = "\n" . $current->();
46             }
47             elsif (my ($add) = $match =~ /\e\[OPEN(.+?)m/) {
48             #print "add: $add\n";
49             # keep track of a new code
50 0           push @code_stack, $add;
51 0           $subst = "\e[${add}m";
52             }
53             elsif (my ($remove) = $match =~ /\e\[CLOSE(.+?)m/) {
54             #print "remove: $remove\n";
55             # remove this code and re-apply the rest
56 0           pop @code_stack;
57 0           for (my $i = $#code_stack; $i >= 0; $i--) {
58 0 0         if ($code_stack[$i] eq $remove) {
59 0 0         splice @code_stack, $i, 1 if $code_stack[$i];
60 0           last;
61             }
62             }
63 0           $subst = "\e[m" . $current->();
64             }
65            
66 0           $subst;
67             }egmx;
68              
69 0           $text .= "\e[m" x scalar @code_stack;
70 0           return $text;
71             }
72              
73             package Perl6::Perldoc::Parser::ReturnVal;
74             BEGIN {
75 1     1   32 $Perl6::Perldoc::Parser::ReturnVal::AUTHORITY = 'cpan:HINRIK';
76             }
77             BEGIN {
78 1     1   141 $Perl6::Perldoc::Parser::ReturnVal::VERSION = '0.11';
79             }
80              
81             sub to_ansi {
82 0     0     my ($self, $internal_state) = @_;
83              
84 0   0       $internal_state ||= {};
85              
86 0           my $text_rep = $self->{tree}->to_ansi($internal_state);
87              
88 0 0 0       if (($internal_state->{note_count}||0) > 0) {
89 0           $text_rep .= "\nNotes\n\n$internal_state->{notes}";
90             }
91              
92 0           return Perl6::Perldoc::To::Ansi::rewrite_ansi($text_rep);
93             }
94              
95             package Perl6::Perldoc::Root;
96             BEGIN {
97 1     1   21 $Perl6::Perldoc::Root::AUTHORITY = 'cpan:HINRIK';
98             }
99             BEGIN {
100 1     1   336 $Perl6::Perldoc::Root::VERSION = '0.11';
101             }
102              
103             my $INDENT = 4;
104              
105             sub add_ansi_nesting {
106 0     0     my ($self, $text, $depth) = @_;
107              
108             # Nest according to the specified nestedness of the block...
109 0 0         if (my $nesting = $self->option('nested')) {
    0          
110 0           $depth = $nesting * $INDENT;
111             }
112              
113             # Or else default to one indent...
114             elsif (!defined $depth) {
115 0           $depth = $INDENT;
116             }
117              
118 0           my $indent = q{ } x $depth;
119 0           $text =~ s{^}{$indent}gxms;
120 0           return $text;
121             }
122              
123             sub _list_to_ansi {
124 0     0     my ($list_ref, $state_ref) = @_;
125 0           my $text = q{};
126 0           for my $content ( @{$list_ref} ) {
  0            
127 0 0         next if ! defined $content;
128 0 0         if (ref $content) {
129 0           $text .= $content->to_ansi($state_ref);
130             }
131             else {
132 0           $text .= $content;
133             }
134             }
135 0           $text =~ s{\A \n+}{}xms;
136 0           $text =~ s{\n+ \z}{\n}xms;
137 0           return $text;
138             }
139              
140             sub to_ansi {
141 0     0     my $self = shift;
142 0           return $self->add_ansi_nesting(_list_to_ansi([$self->content], @_),0);
143             }
144              
145             # Representation of file itself...
146             package Perl6::Perldoc::Document;
147             BEGIN {
148 1     1   23 $Perl6::Perldoc::Document::AUTHORITY = 'cpan:HINRIK';
149             }
150             BEGIN {
151 1     1   23 $Perl6::Perldoc::Document::VERSION = '0.11';
152             }
153 1     1   6 use base 'Perl6::Perldoc::Root';
  1         2  
  1         686  
154              
155             # Ambient text around the Pod...
156             package Perl6::Perldoc::Ambient;
157             BEGIN {
158 1     1   23 $Perl6::Perldoc::Ambient::AUTHORITY = 'cpan:HINRIK';
159             }
160             BEGIN {
161 1     1   51 $Perl6::Perldoc::Ambient::VERSION = '0.11';
162             }
163              
164             sub to_ansi {
165 0     0     return q{};
166             }
167              
168             # Pod blocks...
169             package Perl6::Perldoc::Block;
170             BEGIN {
171 1     1   21 $Perl6::Perldoc::Block::AUTHORITY = 'cpan:HINRIK';
172             }
173             BEGIN {
174 1     1   45 $Perl6::Perldoc::Block::VERSION = '0.11';
175             }
176              
177             # Standard =pod block...
178             package Perl6::Perldoc::Block::pod;
179             BEGIN {
180 1     1   29 $Perl6::Perldoc::Block::pod::AUTHORITY = 'cpan:HINRIK';
181             }
182             BEGIN {
183 1     1   32 $Perl6::Perldoc::Block::pod::VERSION = '0.11';
184             }
185              
186             # Standard =para block (may be implicit)...
187             package Perl6::Perldoc::Block::para;
188             BEGIN {
189 1     1   32 $Perl6::Perldoc::Block::para::AUTHORITY = 'cpan:HINRIK';
190             }
191             BEGIN {
192 1     1   84 $Perl6::Perldoc::Block::para::VERSION = '0.11';
193             }
194              
195             sub to_ansi {
196 0     0     my $self = shift;
197 0           return "\n" . $self->SUPER::to_ansi(@_);
198             }
199              
200             # Standard =code block (may be implicit)...
201             package Perl6::Perldoc::Block::code;
202             BEGIN {
203 1     1   66 $Perl6::Perldoc::Block::code::AUTHORITY = 'cpan:HINRIK';
204             }
205             BEGIN {
206 1     1   397 $Perl6::Perldoc::Block::code::VERSION = '0.11';
207             }
208              
209             sub ansi_min {
210 0     0     my $min = shift;
211 0           for my $next (@_) {
212 0 0         $min = $next if $next < $min;
213             }
214 0           return $min;
215             }
216              
217             sub to_ansi {
218 0     0     my $self = shift;
219 0           my $text = Perl6::Perldoc::Root::_list_to_ansi([$self->content],@_);
220 0           my $left_space = ansi_min map { length } $text =~ m{^ [^\S\n]* (?= \S) }gxms;
  0            
221 0           $text =~ s{^ [^\S\n]{$left_space} }{}gxms;
222 0           $text = Perl6::Perldoc::To::Ansi::add_ansi($text, '33');
223 0           return "\n" . $self->add_ansi_nesting($text, $INDENT);
224             }
225              
226              
227             # Standard =input block
228             package Perl6::Perldoc::Block::input;
229             BEGIN {
230 1     1   25 $Perl6::Perldoc::Block::input::AUTHORITY = 'cpan:HINRIK';
231             }
232             BEGIN {
233 1     1   144 $Perl6::Perldoc::Block::input::VERSION = '0.11';
234             }
235              
236             sub to_ansi {
237 0     0     my $self = shift;
238 0           my $text = Perl6::Perldoc::Root::_list_to_ansi([$self->content],@_);
239 0           $text = Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '36');
240 0           return "\n" . $self->add_ansi_nesting($text, $INDENT);
241             }
242              
243              
244             # Standard =output block
245             package Perl6::Perldoc::Block::output;
246             BEGIN {
247 1     1   24 $Perl6::Perldoc::Block::output::AUTHORITY = 'cpan:HINRIK';
248             }
249             BEGIN {
250 1     1   133 $Perl6::Perldoc::Block::output::VERSION = '0.11';
251             }
252              
253             sub to_ansi {
254 0     0     my $self = shift;
255 0           my $text = Perl6::Perldoc::Root::_list_to_ansi([$self->content],@_);
256 0           $text = Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '36');
257 0           return "\n" . $self->add_ansi_nesting($text, $INDENT);
258             }
259              
260             # Standard =config block...
261             package Perl6::Perldoc::Config;
262             BEGIN {
263 1     1   30 $Perl6::Perldoc::Config::AUTHORITY = 'cpan:HINRIK';
264             }
265             BEGIN {
266 1     1   56 $Perl6::Perldoc::Config::VERSION = '0.11';
267             }
268              
269             sub to_ansi {
270 0     0     return q{};
271             }
272              
273             # Standard =table block...
274             package Perl6::Perldoc::Block::table;
275             BEGIN {
276 1     1   24 $Perl6::Perldoc::Block::table::AUTHORITY = 'cpan:HINRIK';
277             }
278             BEGIN {
279 1     1   103 $Perl6::Perldoc::Block::table::VERSION = '0.11';
280             }
281              
282             sub to_ansi {
283 0     0     my $self = shift;
284 0           my ($text) = $self->content;
285 0           return "\n" . $self->add_ansi_nesting($text, $INDENT);
286             }
287              
288              
289             # Standard =head1 block...
290             package Perl6::Perldoc::Block::head1;
291             BEGIN {
292 1     1   32 $Perl6::Perldoc::Block::head1::AUTHORITY = 'cpan:HINRIK';
293             }
294             BEGIN {
295 1     1   209 $Perl6::Perldoc::Block::head1::VERSION = '0.11';
296             }
297              
298             sub to_ansi {
299 0     0     my $self = shift;
300 0           my $title = $self->SUPER::to_ansi(@_);
301 0           $title =~ s{\A\s+|\s+\Z}{}gxms;
302 0           $title =~ s{\s+}{ }gxms;
303 0           my $number = $self->number;
304 0 0         if (defined $number) {
305 0           $title = "$number. $title";
306             }
307 0           return "\n" . Perl6::Perldoc::To::Ansi::add_ansi_only($title, '1') ."\n";
308             }
309              
310             # Standard =head2 block...
311             package Perl6::Perldoc::Block::head2;
312             BEGIN {
313 1     1   25 $Perl6::Perldoc::Block::head2::AUTHORITY = 'cpan:HINRIK';
314             }
315             BEGIN {
316 1     1   184 $Perl6::Perldoc::Block::head2::VERSION = '0.11';
317             }
318              
319             sub to_ansi {
320 0     0     my $self = shift;
321 0           my $title = $self->SUPER::to_ansi(@_);
322 0           $title =~ s{\A\s+|\s+\Z}{}gxms;
323 0           $title =~ s{\s+}{ }gxms;
324 0           my $number = $self->number;
325 0 0         if (defined $number) {
326 0           $title = "$number. $title";
327             }
328 0           return "\n" . Perl6::Perldoc::To::Ansi::add_ansi_only($title, '1') ."\n";
329             }
330              
331             # Standard =head3 block...
332             package Perl6::Perldoc::Block::head3;
333             BEGIN {
334 1     1   31 $Perl6::Perldoc::Block::head3::AUTHORITY = 'cpan:HINRIK';
335             }
336             BEGIN {
337 1     1   214 $Perl6::Perldoc::Block::head3::VERSION = '0.11';
338             }
339              
340             sub to_ansi {
341 0     0     my $self = shift;
342 0           my $title = $self->SUPER::to_ansi(@_);
343 0           $title =~ s{\A\s+|\s+\Z}{}gxms;
344 0           $title =~ s{\s+}{ }gxms;
345 0           my $number = $self->number;
346 0 0         if (defined $number) {
347 0           $title = "$number. $title";
348             }
349 0           return "\n" . Perl6::Perldoc::To::Ansi::add_ansi_only($title, '1') ."\n";
350             }
351              
352             # Standard =head4 block...
353             package Perl6::Perldoc::Block::head4;
354             BEGIN {
355 1     1   57 $Perl6::Perldoc::Block::head4::AUTHORITY = 'cpan:HINRIK';
356             }
357             BEGIN {
358 1     1   197 $Perl6::Perldoc::Block::head4::VERSION = '0.11';
359             }
360              
361             sub to_ansi {
362 0     0     my $self = shift;
363 0           my $title = $self->SUPER::to_ansi(@_);
364 0           $title =~ s{\A\s+|\s+\Z}{}gxms;
365 0           $title =~ s{\s+}{ }gxms;
366 0           my $number = $self->number;
367 0 0         if (defined $number) {
368 0           $title = "$number. $title";
369             }
370 0           return "\n" . Perl6::Perldoc::To::Ansi::add_ansi_only($title, '1') ."\n";
371             }
372              
373             # Implicit list block...
374             package Perl6::Perldoc::Block::list;
375             BEGIN {
376 1     1   21 $Perl6::Perldoc::Block::list::AUTHORITY = 'cpan:HINRIK';
377             }
378             BEGIN {
379 1     1   24 $Perl6::Perldoc::Block::list::VERSION = '0.11';
380             }
381 1     1   7 use base 'Perl6::Perldoc::Root';
  1         1  
  1         543  
382              
383             sub to_ansi {
384 0     0     my $self = shift;
385 0           return "\n" . $self->add_ansi_nesting($self->SUPER::to_ansi(@_));
386             }
387              
388              
389             # Standard =item block...
390             package Perl6::Perldoc::Block::item;
391             BEGIN {
392 1     1   22 $Perl6::Perldoc::Block::item::AUTHORITY = 'cpan:HINRIK';
393             }
394             BEGIN {
395 1     1   303 $Perl6::Perldoc::Block::item::VERSION = '0.11';
396             }
397              
398             sub to_ansi {
399 0     0     my $self = shift;
400              
401 0           my $counter = $self->number;
402 0 0         $counter = $counter ? qq{$counter.} : q{*};
403              
404 0           my $body = $self->SUPER::to_ansi(@_);
405              
406 0 0         if (my $term = $self->term()) {
407 0           $term = $self->term( {as_objects=>1} )->to_ansi(@_);
408 0 0         if (length $counter) {
409 0           $term =~ s{\A (\s* <[^>]+>)}{$1$counter. }xms;
410             }
411 0           my $body = $self->add_ansi_nesting($body);
412 0           $body =~ s{\A \n+}{}xms;
413 0           return "\n$term\n$body";
414             }
415              
416 0           $body = $self->add_ansi_nesting($body, 1 + length $counter);
417 0           $body =~ s{\A \n+}{}xms;
418 0           $body =~ s{\A \s*}{$counter }xms;
419              
420 0           return $body;
421             }
422              
423             # Implicit toclist block...
424             package Perl6::Perldoc::Block::toclist;
425             BEGIN {
426 1     1   30 $Perl6::Perldoc::Block::toclist::AUTHORITY = 'cpan:HINRIK';
427             }
428             BEGIN {
429 1     1   18 $Perl6::Perldoc::Block::toclist::VERSION = '0.11';
430             }
431 1     1   5 use base 'Perl6::Perldoc::Root';
  1         2  
  1         523  
432              
433             sub to_ansi {
434 0     0     my $self = shift;
435            
436             # Convert list items to text, and return in an text list...
437 0           my $text = join q{}, map {$_->to_ansi(@_)} $self->content;
  0            
438              
439 0           return $self->add_ansi_nesting($text);
440             }
441              
442              
443             # Standard =tocitem block...
444             package Perl6::Perldoc::Block::tocitem;
445             BEGIN {
446 1     1   29 $Perl6::Perldoc::Block::tocitem::AUTHORITY = 'cpan:HINRIK';
447             }
448             BEGIN {
449 1     1   99 $Perl6::Perldoc::Block::tocitem::VERSION = '0.11';
450             }
451              
452             sub to_ansi {
453 0     0     my $self = shift;
454              
455 0           my @title = $self->title;
456 0 0         return "" if ! @title;
457            
458 0           my $title = Perl6::Perldoc::Root::_list_to_ansi(\@title, @_);
459              
460 0           return "* $title\n";
461             }
462              
463             # Handle headN's and itemN's and tocitemN's...
464             for my $depth (1..100) {
465 1     1   5 no strict qw< refs >;
  1         2  
  1         112  
466              
467             @{'Perl6::Perldoc::Block::item'.$depth.'::ISA'}
468             = 'Perl6::Perldoc::Block::item';
469              
470             @{'Perl6::Perldoc::Block::tocitem'.$depth.'::ISA'}
471             = 'Perl6::Perldoc::Block::tocitem';
472              
473             next if $depth < 5;
474             @{'Perl6::Perldoc::Block::head'.$depth.'::ISA'}
475             = 'Perl6::Perldoc::Block::head4';
476             }
477             # Handle headN's and itemN's
478             for my $depth (1..100) {
479 1     1   6 no strict qw< refs >;
  1         2  
  1         69  
480             @{'Perl6::Perldoc::Block::item'.$depth.'::ISA'}
481             = 'Perl6::Perldoc::Block::item';
482             }
483              
484             # Standard =nested block...
485             package Perl6::Perldoc::Block::nested;
486             BEGIN {
487 1     1   29 $Perl6::Perldoc::Block::nested::AUTHORITY = 'cpan:HINRIK';
488             }
489             BEGIN {
490 1     1   98 $Perl6::Perldoc::Block::nested::VERSION = '0.11';
491             }
492              
493             sub to_ansi {
494 0     0     my $self = shift;
495 0           return "\n" . $self->add_ansi_nesting($self->SUPER::to_ansi(@_));
496             }
497              
498             # Standard =comment block...
499             package Perl6::Perldoc::Block::comment;
500             BEGIN {
501 1     1   22 $Perl6::Perldoc::Block::comment::AUTHORITY = 'cpan:HINRIK';
502             }
503             BEGIN {
504 1     1   52 $Perl6::Perldoc::Block::comment::VERSION = '0.11';
505             }
506              
507             sub to_ansi {
508 0     0     return q{};
509             }
510              
511             # Standard SEMANTIC blocks...
512             package Perl6::Perldoc::Block::Semantic;
513             BEGIN {
514 1     1   21 $Perl6::Perldoc::Block::Semantic::AUTHORITY = 'cpan:HINRIK';
515             }
516             BEGIN {
517 1     1   136 $Perl6::Perldoc::Block::Semantic::VERSION = '0.11';
518             }
519             BEGIN {
520 1     1   9 my @semantic_blocks = qw(
521             NAME NAMES
522             VERSION VERSIONS
523             SYNOPSIS SYNOPSES
524             DESCRIPTION DESCRIPTIONS
525             USAGE USAGES
526             INTERFACE INTERFACES
527             METHOD METHODS
528             SUBROUTINE SUBROUTINES
529             OPTION OPTIONS
530             DIAGNOSTIC DIAGNOSTICS
531             ERROR ERRORS
532             WARNING WARNINGS
533             DEPENDENCY DEPENDENCIES
534             BUG BUGS
535             SEEALSO SEEALSOS
536             ACKNOWLEDGEMENT ACKNOWLEDGEMENTS
537             AUTHOR AUTHORS
538             COPYRIGHT COPYRIGHTS
539             DISCLAIMER DISCLAIMERS
540             LICENCE LICENCES
541             LICENSE LICENSES
542             TITLE TITLES
543             SECTION SECTIONS
544             CHAPTER CHAPTERS
545             APPENDIX APPENDIXES APPENDICES
546             TOC TOCS
547             INDEX INDEXES INDICES
548             FOREWORD FOREWORDS
549             SUMMARY SUMMARIES
550             );
551              
552             # Reuse content-to-text converter
553 1         4 *_list_to_ansi = *Perl6::Perldoc::Root::_list_to_ansi;
554              
555 1         2 for my $blockname (@semantic_blocks) {
556 1     1   5 no strict qw< refs >;
  1         19  
  1         155  
557              
558 60         1004 *{ "Perl6::Perldoc::Block::${blockname}::to_ansi" }
559             = sub {
560 0     0   0 my $self = shift;
561              
562 0         0 my @title = $self->title();
563              
564 0 0       0 return "" if !@title;
565 0         0 my $title = _list_to_ansi(\@title, @_);
566              
567 0         0 return "\n" . Perl6::Perldoc::To::Ansi::add_ansi(uc $title, '1') ."\n\n"
568             . _list_to_ansi([$self->content], @_);
569 60         264 };
570             }
571             }
572              
573              
574             # Base class for formatting codes...
575              
576             package Perl6::Perldoc::FormattingCode;
577             BEGIN {
578 1     1   25 $Perl6::Perldoc::FormattingCode::AUTHORITY = 'cpan:HINRIK';
579             }
580             BEGIN {
581 1     1   35 $Perl6::Perldoc::FormattingCode::VERSION = '0.11';
582             }
583              
584             package Perl6::Perldoc::FormattingCode::Named;
585             BEGIN {
586 1     1   21 $Perl6::Perldoc::FormattingCode::Named::AUTHORITY = 'cpan:HINRIK';
587             }
588             BEGIN {
589 1     1   51 $Perl6::Perldoc::FormattingCode::Named::VERSION = '0.11';
590             }
591              
592             # Basis formatter...
593             package Perl6::Perldoc::FormattingCode::B;
594             BEGIN {
595 1     1   25 $Perl6::Perldoc::FormattingCode::B::AUTHORITY = 'cpan:HINRIK';
596             }
597             BEGIN {
598 1     1   69 $Perl6::Perldoc::FormattingCode::B::VERSION = '0.11';
599             }
600              
601             sub to_ansi {
602 0     0     my $self = shift;
603 0           return Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '1');
604             }
605              
606             # Code formatter...
607             package Perl6::Perldoc::FormattingCode::C;
608             BEGIN {
609 1     1   26 $Perl6::Perldoc::FormattingCode::C::AUTHORITY = 'cpan:HINRIK';
610             }
611             BEGIN {
612 1     1   83 $Perl6::Perldoc::FormattingCode::C::VERSION = '0.11';
613             }
614              
615             sub to_ansi {
616 0     0     my $self = shift;
617 0           return Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '33');
618             }
619              
620             # Definition formatter...
621             package Perl6::Perldoc::FormattingCode::D;
622             BEGIN {
623 1     1   26 $Perl6::Perldoc::FormattingCode::D::AUTHORITY = 'cpan:HINRIK';
624             }
625             BEGIN {
626 1     1   78 $Perl6::Perldoc::FormattingCode::D::VERSION = '0.11';
627             }
628              
629             sub to_ansi {
630 0     0     my $self = shift;
631 0           return Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '1');
632             }
633              
634              
635             # Entity formatter...
636             package Perl6::Perldoc::FormattingCode::E;
637             BEGIN {
638 1     1   22 $Perl6::Perldoc::FormattingCode::E::AUTHORITY = 'cpan:HINRIK';
639             }
640             BEGIN {
641 1     1   217 $Perl6::Perldoc::FormattingCode::E::VERSION = '0.11';
642             }
643              
644             my %is_break_entity = (
645             'LINE FEED (LF)' => 1, LF => 1,
646             'CARRIAGE RETURN (CR)' => 1, CR => 1,
647             'NEXT LINE (NEL)' => 1, NEL => 1,
648              
649             'FORM FEED (FF)' => 10, FF => 10,
650             );
651              
652             my %is_translatable = (
653             nbsp => q{ },
654             bull => q{*},
655             mdash => q{--},
656             ndash => q{--},
657             );
658              
659             # Convert E<> contents to text named or numeric entity...
660             sub _to_ansi_entity {
661 0     0     my ($spec) = @_;
662             # Is it a line break?
663 0 0         if (my $BR_count = $is_break_entity{$spec}) {
664 0           return "\n" x $BR_count;
665             }
666             # Is it a numeric codepoint in some base...
667 0 0         if ($spec =~ m{\A \d}xms) {
668             # Convert Perl 6 octals and decimals to Perl 5 notation...
669 0 0         if ($spec !~ s{\A 0o}{0}xms) { # Convert octal
670 0           $spec =~ s{\A 0d}{}xms; # Convert explicit decimal
671 0           $spec =~ s{\A 0+ (?=\d)}{}xms; # Convert implicit decimal
672             }
673              
674             # Then return the Xtext numeric code...
675 1     1   2473 use charnames ':full';
  1         52464  
  1         7  
676 0           $spec = charnames::viacode(eval $spec);
677             }
678 0 0         if (my $replacement = $is_translatable{$spec}) {
679 0           return $replacement;
680             }
681             else {
682 0           return "[$spec]";
683             }
684             }
685              
686             sub to_ansi {
687 0     0     my $self = shift;
688 0           my $entities = $self->content;
689 0           return join q{}, map {_to_ansi_entity($_)} split /\s*;\s*/, $entities;
  0            
690             }
691              
692             # Important formatter...
693             package Perl6::Perldoc::FormattingCode::I;
694             BEGIN {
695 1     1   378 $Perl6::Perldoc::FormattingCode::I::AUTHORITY = 'cpan:HINRIK';
696             }
697             BEGIN {
698 1     1   65 $Perl6::Perldoc::FormattingCode::I::VERSION = '0.11';
699             }
700              
701             sub to_ansi {
702 0     0     my $self = shift;
703 0           return Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '32');
704             }
705              
706             # Keyboard input formatter...
707             package Perl6::Perldoc::FormattingCode::K;
708             BEGIN {
709 1     1   20 $Perl6::Perldoc::FormattingCode::K::AUTHORITY = 'cpan:HINRIK';
710             }
711             BEGIN {
712 1     1   76 $Perl6::Perldoc::FormattingCode::K::VERSION = '0.11';
713             }
714              
715             sub to_ansi {
716 0     0     my $self = shift;
717 0           return Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '36');
718             }
719              
720             # Link formatter...
721             package Perl6::Perldoc::FormattingCode::L;
722             BEGIN {
723 1     1   21 $Perl6::Perldoc::FormattingCode::L::AUTHORITY = 'cpan:HINRIK';
724             }
725             BEGIN {
726 1     1   370 $Perl6::Perldoc::FormattingCode::L::VERSION = '0.11';
727             }
728              
729             my $PERLDOC_ORG = 'http://perldoc.perl.org/';
730             my $SEARCH = 'http://www.google.com/search?q=';
731              
732             sub to_ansi {
733 0     0     my $self = shift;
734 0           my $target = $self->target();
735 0 0         my $text = $self->has_distinct_text ? $self->SUPER::to_ansi(@_) : undef;
736             my $add_color = sub {
737 0     0     $target = Perl6::Perldoc::To::Ansi::add_ansi($target, '34');
738 0           };
739            
740             # Link within this document...
741 0 0         if ($target =~ s{\A (?:doc:\s*)? [#] }{}xms ) {
742 0           $add_color->();
743 0 0         return defined $text ? qq{$text (see the $target section)}
744             : qq{the $target section}
745             }
746              
747             # Link to other documentation...
748 0 0         if ($target =~ s{\A doc: }{}xms) {
749 0           $add_color->();
750 0 0         return defined $text ? qq{$text (see the documentation for $target)}
751             : qq{the documentation for $target}
752             }
753              
754             # Link to manpage...
755 0 0         if ($target =~ s{\A man: }{}xms) {
756 0           $add_color->();
757 0 0         return defined $text ? qq{$text (see the $target manpage)}
758             : qq{the $target manpage}
759             }
760              
761             # Link back to definition in this document...
762 0 0         if ($target =~ s{\A (?:defn) : }{}xms) {
763 0           $add_color->();
764 0 0         return defined $text ? qq{$text (see the definition of $target)}
765             : $target
766             }
767              
768             # Link to an email address
769 0 0         if ($target =~ s{\A (?:mailto) : }{}xms) {
770 0           $add_color->();
771 0 0         return defined $text ? qq{$text ($target)}
772             : $target
773             }
774              
775             # Anything else...
776 0           $add_color->();
777 0 0         return defined $text ? qq{$text $target}
778             : $target;
779             }
780              
781             # Meta-formatter...
782             package Perl6::Perldoc::FormattingCode::M;
783             BEGIN {
784 1     1   22 $Perl6::Perldoc::FormattingCode::M::AUTHORITY = 'cpan:HINRIK';
785             }
786             BEGIN {
787 1     1   34 $Perl6::Perldoc::FormattingCode::M::VERSION = '0.11';
788             }
789              
790              
791             # Note formatter...
792             package Perl6::Perldoc::FormattingCode::N;
793             BEGIN {
794 1     1   26 $Perl6::Perldoc::FormattingCode::N::AUTHORITY = 'cpan:HINRIK';
795             }
796             BEGIN {
797 1     1   119 $Perl6::Perldoc::FormattingCode::N::VERSION = '0.11';
798             }
799              
800             sub to_ansi {
801 0     0     my $self = shift;
802 0           my $count = ++$_[0]{note_count};
803 0           my $marker = "[$count]";
804 0           $_[0]{notes} .= qq{$marker } . $self->SUPER::to_ansi(@_) . "\n";
805 0           return qq{$marker};
806             }
807              
808             # Placement link formatter...
809             package Perl6::Perldoc::FormattingCode::P;
810             BEGIN {
811 1     1   21 $Perl6::Perldoc::FormattingCode::P::AUTHORITY = 'cpan:HINRIK';
812             }
813             BEGIN {
814 1     1   246 $Perl6::Perldoc::FormattingCode::P::VERSION = '0.11';
815             }
816              
817             sub to_ansi {
818 0     0     my $self = shift;
819 0           my $target = $self->target();
820              
821             # Link within this document...
822 0 0         if ($target =~ s{\A (?:doc:\s*)? [#] }{}xms ) {
823 0           return qq{(See the "$target" section)};
824             }
825              
826             # Link to other documentation...
827 0 0         if ($target =~ s{\A doc: }{}xms) {
828 0           return qq{(See the documentation for $target)};
829             }
830              
831             # Link to manpage...
832 0 0         if ($target =~ s{\A man: }{}xms) {
833 0           return qq{(See the $target manpage)};
834             }
835              
836             # TOC insertion...
837 0 0         if ($target =~ s{\A toc: }{}xms) {
838 0           return Perl6::Perldoc::Root::_list_to_ansi([$self->content],@_);
839             }
840              
841             # Anything else...
842 0           $target =~ s{\A (?:defn) : }{}xms;
843 0           return qq{(See $target)};
844             }
845              
846             # Replacable item formatter...
847             package Perl6::Perldoc::FormattingCode::R;
848             BEGIN {
849 1     1   25 $Perl6::Perldoc::FormattingCode::R::AUTHORITY = 'cpan:HINRIK';
850             }
851             BEGIN {
852 1     1   75 $Perl6::Perldoc::FormattingCode::R::VERSION = '0.11';
853             }
854              
855             sub to_ansi {
856 0     0     my $self = shift;
857 0           return Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '32');
858             }
859              
860             # Space-preserving formatter...
861             package Perl6::Perldoc::FormattingCode::S;
862             BEGIN {
863 1     1   25 $Perl6::Perldoc::FormattingCode::S::AUTHORITY = 'cpan:HINRIK';
864             }
865             BEGIN {
866 1     1   62 $Perl6::Perldoc::FormattingCode::S::VERSION = '0.11';
867             }
868              
869             sub to_ansi {
870 0     0     my $self = shift;
871 0           return $self->SUPER::to_ansi(@_);
872             }
873              
874              
875             # Terminal output formatter...
876             package Perl6::Perldoc::FormattingCode::T;
877             BEGIN {
878 1     1   26 $Perl6::Perldoc::FormattingCode::T::AUTHORITY = 'cpan:HINRIK';
879             }
880             BEGIN {
881 1     1   85 $Perl6::Perldoc::FormattingCode::T::VERSION = '0.11';
882             }
883              
884             sub to_ansi {
885 0     0     my $self = shift;
886 0           return Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '36');
887             }
888              
889             # Unusual formatter...
890             package Perl6::Perldoc::FormattingCode::U;
891             BEGIN {
892 1     1   26 $Perl6::Perldoc::FormattingCode::U::AUTHORITY = 'cpan:HINRIK';
893             }
894             BEGIN {
895 1     1   70 $Perl6::Perldoc::FormattingCode::U::VERSION = '0.11';
896             }
897              
898             sub to_ansi {
899 0     0     my $self = shift;
900 0           return Perl6::Perldoc::To::Ansi::add_ansi($self->SUPER::to_ansi(@_), '4');
901             }
902              
903             # Verbatim formatter...
904             package Perl6::Perldoc::FormattingCode::V;
905             BEGIN {
906 1     1   23 $Perl6::Perldoc::FormattingCode::V::AUTHORITY = 'cpan:HINRIK';
907             }
908             BEGIN {
909 1     1   32 $Perl6::Perldoc::FormattingCode::V::VERSION = '0.11';
910             }
911              
912             # indeX formatter...
913             package Perl6::Perldoc::FormattingCode::X;
914             BEGIN {
915 1     1   23 $Perl6::Perldoc::FormattingCode::X::AUTHORITY = 'cpan:HINRIK';
916             }
917             BEGIN {
918 1     1   47 $Perl6::Perldoc::FormattingCode::X::VERSION = '0.11';
919             }
920              
921             sub to_ansi {
922 0     0     return q{};
923             }
924              
925             # Zero-width formatter...
926             package Perl6::Perldoc::FormattingCode::Z;
927             BEGIN {
928 1     1   21 $Perl6::Perldoc::FormattingCode::Z::AUTHORITY = 'cpan:HINRIK';
929             }
930             BEGIN {
931 1     1   97 $Perl6::Perldoc::FormattingCode::Z::VERSION = '0.11';
932             }
933              
934             sub to_ansi {
935 0     0     return q{};
936             }
937              
938              
939             # Standard =table block...
940             package Perl6::Perldoc::Block::table;
941              
942              
943             1; # Magic true value required at end of module
944              
945             =encoding utf8
946              
947             =head1 NAME
948              
949             Perl6::Perldoc::To::Ansi - ANSI-colored text renderer for Perl6::Perldoc
950              
951             =head1 SYNOPSIS
952              
953             use Perl6::Perldoc::Parser;
954             use Perl6::Perldoc::To::Ansi;
955              
956             # All Perl6::Perldoc::Parser DOM classes now have a to_ansi() method
957              
958             =head1 DESCRIPTION
959              
960             This module is almost identical to the Text renderer, except that many
961             constructs are highlighted with ANSI terminal codes. See
962             L for more information.
963              
964             =head1 AUTHOR
965              
966             Hinrik Örn Sigurðsson, L
967              
968             =head1 LICENCE AND COPYRIGHT
969              
970             Copyright (c) 2006, Damian Conway L. All rights reserved.
971              
972             Copyright (c) 2009, Hinrik Örn Sigurðsson L. All rights reserved.
973              
974             This module is free software; you can redistribute it and/or
975             modify it under the same terms as Perl itself. See L.
976              
977             =cut