File Coverage

blib/lib/Pod/Text/Termcap.pm
Criterion Covered Total %
statement 68 74 91.8
branch 4 10 40.0
condition 5 13 38.4
subroutine 14 15 93.3
pod 1 8 12.5
total 92 120 76.6


line stmt bran cond sub pod time code
1             # Pod::Text::Termcap -- Convert POD data to ASCII text with format escapes.
2             #
3             # This is a simple subclass of Pod::Text that overrides a few key methods to
4             # output the right termcap escape sequences for formatted text on the current
5             # terminal type.
6             #
7             # Copyright 1999, 2001, 2002, 2004, 2006, 2008, 2009, 2014, 2015
8             # Russ Allbery
9             #
10             # This program is free software; you may redistribute it and/or modify it
11             # under the same terms as Perl itself.
12              
13             ##############################################################################
14             # Modules and declarations
15             ##############################################################################
16              
17             package Pod::Text::Termcap;
18              
19 2     2   15402 use 5.006;
  2         5  
20 2     2   7 use strict;
  2         1  
  2         33  
21 2     2   5 use warnings;
  2         2  
  2         38  
22              
23 2     2   203 use Pod::Text ();
  2         3  
  2         32  
24 2     2   1070 use POSIX ();
  2         8785  
  2         43  
25 2     2   988 use Term::Cap;
  2         4178  
  2         62  
26              
27 2     2   9 use vars qw(@ISA $VERSION);
  2         2  
  2         1130  
28              
29             @ISA = qw(Pod::Text);
30              
31             $VERSION = '4.08';
32              
33             ##############################################################################
34             # Overrides
35             ##############################################################################
36              
37             # In the initialization method, grab our terminal characteristics as well as
38             # do all the stuff we normally do.
39             sub new {
40 2     2 1 743 my ($self, @args) = @_;
41 2         2 my ($ospeed, $term, $termios);
42 2         20 $self = $self->SUPER::new (@args);
43              
44             # $ENV{HOME} is usually not set on Windows. The default Term::Cap path
45             # may not work on Solaris.
46 2 50       9 unless (exists $ENV{TERMPATH}) {
47 0 0       0 my $home = exists $ENV{HOME} ? "$ENV{HOME}/.termcap:" : '';
48             $ENV{TERMPATH} =
49 0         0 "${home}/etc/termcap:/usr/share/misc/termcap:/usr/share/lib/termcap";
50             }
51              
52             # Fall back on a hard-coded terminal speed if POSIX::Termios isn't
53             # available (such as on VMS).
54 2         4 eval { $termios = POSIX::Termios->new };
  2         39  
55 2 50       10 if ($@) {
56 0         0 $ospeed = 9600;
57             } else {
58 2         17 $termios->getattr;
59 2   50     15 $ospeed = $termios->getospeed || 9600;
60             }
61              
62             # Fall back on the ANSI escape sequences if Term::Cap doesn't work.
63 2         3 eval { $term = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed } };
  2         22  
64 2   50     459 $$self{BOLD} = $$term{_md} || "\e[1m";
65 2   50     12 $$self{UNDL} = $$term{_us} || "\e[4m";
66 2   50     7 $$self{NORM} = $$term{_me} || "\e[m";
67              
68 2 50       7 unless (defined $$self{width}) {
69 2   0     9 $$self{opt_width} = $ENV{COLUMNS} || $$term{_co} || 80;
70 2         6 $$self{opt_width} -= 2;
71             }
72              
73 2         22 return $self;
74             }
75              
76             # Make level one headings bold.
77             sub cmd_head1 {
78 11     11 0 14 my ($self, $attrs, $text) = @_;
79 11         27 $text =~ s/\s+$//;
80 11         39 $self->SUPER::cmd_head1 ($attrs, "$$self{BOLD}$text$$self{NORM}");
81             }
82              
83             # Make level two headings bold.
84             sub cmd_head2 {
85 2     2 0 4 my ($self, $attrs, $text) = @_;
86 2         6 $text =~ s/\s+$//;
87 2         10 $self->SUPER::cmd_head2 ($attrs, "$$self{BOLD}$text$$self{NORM}");
88             }
89              
90             # Fix up B<> and I<>. Note that we intentionally don't do F<>.
91 12     12 0 11 sub cmd_b { my $self = shift; return "$$self{BOLD}$_[1]$$self{NORM}" }
  12         30  
92 16     16 0 19 sub cmd_i { my $self = shift; return "$$self{UNDL}$_[1]$$self{NORM}" }
  16         45  
93              
94             # Output any included code in bold.
95             sub output_code {
96 0     0 0 0 my ($self, $code) = @_;
97 0         0 $self->output ($$self{BOLD} . $code . $$self{NORM});
98             }
99              
100             # Strip all of the formatting from a provided string, returning the stripped
101             # version.
102             sub strip_format {
103 29     29 0 30 my ($self, $text) = @_;
104 29         83 $text =~ s/\Q$$self{BOLD}//g;
105 29         47 $text =~ s/\Q$$self{UNDL}//g;
106 29         44 $text =~ s/\Q$$self{NORM}//g;
107 29         48 return $text;
108             }
109              
110             # Override the wrapping code to ignore the special sequences.
111             sub wrap {
112 101     101 0 79 my $self = shift;
113 101         84 local $_ = shift;
114 101         79 my $output = '';
115 101         129 my $spaces = ' ' x $$self{MARGIN};
116 101         132 my $width = $$self{opt_width} - $$self{MARGIN};
117              
118             # $codes matches a single special sequence. $char matches any number of
119             # special sequences preceding a single character other than a newline.
120             # We have to do $shortchar and $longchar in variables because the
121             # construct ${char}{0,$width} didn't do the right thing until Perl 5.8.x.
122 101         196 my $codes = "(?:\Q$$self{BOLD}\E|\Q$$self{UNDL}\E|\Q$$self{NORM}\E)";
123 101         106 my $char = "(?:$codes*[^\\n])";
124 101         107 my $shortchar = $char . "{0,$width}";
125 101         97 my $longchar = $char . "{$width}";
126 101         199 while (length > $width) {
127 31 50 33     814 if (s/^($shortchar)\s+// || s/^($longchar)//) {
128 31         119 $output .= $spaces . $1 . "\n";
129             } else {
130 0         0 last;
131             }
132             }
133 101         133 $output .= $spaces . $_;
134 101         374 $output =~ s/\s+$/\n\n/;
135 101         276 return $output;
136             }
137              
138             ##############################################################################
139             # Module return value and documentation
140             ##############################################################################
141              
142             1;
143             __END__