xref: /openbsd-src/gnu/usr.bin/perl/cpan/podlators/lib/Pod/Text/Overstrike.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
1b46d8ef2Safresh1# Convert POD data to formatted overstrike text
2b39c5158Smillert#
3b39c5158Smillert# This was written because the output from:
4b39c5158Smillert#
5b39c5158Smillert#     pod2text Text.pm > plain.txt; less plain.txt
6b39c5158Smillert#
7b39c5158Smillert# is not as rich as the output from
8b39c5158Smillert#
9b39c5158Smillert#     pod2man Text.pm | nroff -man > fancy.txt; less fancy.txt
10b39c5158Smillert#
11b39c5158Smillert# and because both Pod::Text::Color and Pod::Text::Termcap are not device
12b39c5158Smillert# independent.
1391f110e0Safresh1#
14b46d8ef2Safresh1# SPDX-License-Identifier: GPL-1.0-or-later OR Artistic-1.0-Perl
15b39c5158Smillert
16b39c5158Smillert##############################################################################
17b39c5158Smillert# Modules and declarations
18b39c5158Smillert##############################################################################
19b39c5158Smillert
20b39c5158Smillertpackage Pod::Text::Overstrike;
21b39c5158Smillert
22e0680481Safresh1use 5.010;
23b8851fccSafresh1use strict;
24b8851fccSafresh1use warnings;
25b8851fccSafresh1
26b39c5158Smillertuse Pod::Text ();
27b39c5158Smillert
28e0680481Safresh1our @ISA = qw(Pod::Text);
29*3d61058aSafresh1our $VERSION = '5.01_02';
30*3d61058aSafresh1$VERSION =~ tr/_//d;
31b39c5158Smillert
32b39c5158Smillert##############################################################################
33b39c5158Smillert# Overrides
34b39c5158Smillert##############################################################################
35b39c5158Smillert
369f11ffb7Safresh1# Make level one headings bold, overriding any existing formatting.
37b39c5158Smillertsub cmd_head1 {
38b39c5158Smillert    my ($self, $attrs, $text) = @_;
39b39c5158Smillert    $text =~ s/\s+$//;
40b39c5158Smillert    $text = $self->strip_format ($text);
41b39c5158Smillert    $text =~ s/(.)/$1\b$1/g;
42b39c5158Smillert    return $self->SUPER::cmd_head1 ($attrs, $text);
43b39c5158Smillert}
44b39c5158Smillert
45b39c5158Smillert# Make level two headings bold, overriding any existing formatting.
46b39c5158Smillertsub cmd_head2 {
47b39c5158Smillert    my ($self, $attrs, $text) = @_;
48b39c5158Smillert    $text =~ s/\s+$//;
49b39c5158Smillert    $text = $self->strip_format ($text);
50b39c5158Smillert    $text =~ s/(.)/$1\b$1/g;
51b39c5158Smillert    return $self->SUPER::cmd_head2 ($attrs, $text);
52b39c5158Smillert}
53b39c5158Smillert
54b39c5158Smillert# Make level three headings underscored, overriding any existing formatting.
55b39c5158Smillertsub cmd_head3 {
56b39c5158Smillert    my ($self, $attrs, $text) = @_;
57b39c5158Smillert    $text =~ s/\s+$//;
58b39c5158Smillert    $text = $self->strip_format ($text);
59b39c5158Smillert    $text =~ s/(.)/_\b$1/g;
60b39c5158Smillert    return $self->SUPER::cmd_head3 ($attrs, $text);
61b39c5158Smillert}
62b39c5158Smillert
63b39c5158Smillert# Level four headings look like level three headings.
64b39c5158Smillertsub cmd_head4 {
65b39c5158Smillert    my ($self, $attrs, $text) = @_;
66b39c5158Smillert    $text =~ s/\s+$//;
67b39c5158Smillert    $text = $self->strip_format ($text);
68b39c5158Smillert    $text =~ s/(.)/_\b$1/g;
69b39c5158Smillert    return $self->SUPER::cmd_head4 ($attrs, $text);
70b39c5158Smillert}
71b39c5158Smillert
72b39c5158Smillert# The common code for handling all headers.  We have to override to avoid
73b39c5158Smillert# interpolating twice and because we don't want to honor alt.
74b39c5158Smillertsub heading {
75b39c5158Smillert    my ($self, $text, $indent, $marker) = @_;
76b39c5158Smillert    $self->item ("\n\n") if defined $$self{ITEM};
77b39c5158Smillert    $text .= "\n" if $$self{opt_loose};
78b39c5158Smillert    my $margin = ' ' x ($$self{opt_margin} + $indent);
79b39c5158Smillert    $self->output ($margin . $text . "\n");
80b39c5158Smillert    return '';
81b39c5158Smillert}
82b39c5158Smillert
83b39c5158Smillert# Fix the various formatting codes.
84b39c5158Smillertsub cmd_b { local $_ = $_[0]->strip_format ($_[2]); s/(.)/$1\b$1/g; $_ }
85b39c5158Smillertsub cmd_f { local $_ = $_[0]->strip_format ($_[2]); s/(.)/_\b$1/g; $_ }
86b39c5158Smillertsub cmd_i { local $_ = $_[0]->strip_format ($_[2]); s/(.)/_\b$1/g; $_ }
87b39c5158Smillert
88b39c5158Smillert# Output any included code in bold.
89b39c5158Smillertsub output_code {
90b39c5158Smillert    my ($self, $code) = @_;
91b39c5158Smillert    $code =~ s/(.)/$1\b$1/g;
92b39c5158Smillert    $self->output ($code);
93b39c5158Smillert}
94b39c5158Smillert
95b39c5158Smillert# Strip all of the formatting from a provided string, returning the stripped
96b39c5158Smillert# version.
97b39c5158Smillertsub strip_format {
98b39c5158Smillert    my ($self, $text) = @_;
99b39c5158Smillert    $text =~ s/(.)[\b]\1/$1/g;
100b39c5158Smillert    $text =~ s/_[\b]//g;
101b39c5158Smillert    return $text;
102b39c5158Smillert}
103b39c5158Smillert
104b39c5158Smillert# We unfortunately have to override the wrapping code here, since the normal
105b39c5158Smillert# wrapping code gets really confused by all the backspaces.
106b39c5158Smillertsub wrap {
107b39c5158Smillert    my $self = shift;
108b39c5158Smillert    local $_ = shift;
109b39c5158Smillert    my $output = '';
110b39c5158Smillert    my $spaces = ' ' x $$self{MARGIN};
111b39c5158Smillert    my $width = $$self{opt_width} - $$self{MARGIN};
112b39c5158Smillert    while (length > $width) {
113b39c5158Smillert        # This regex represents a single character, that's possibly underlined
114b39c5158Smillert        # or in bold (in which case, it's three characters; the character, a
115b39c5158Smillert        # backspace, and a character).  Use [^\n] rather than . to protect
116b39c5158Smillert        # against odd settings of $*.
117b39c5158Smillert        my $char = '(?:[^\n][\b])?[^\n]';
118b39c5158Smillert        if (s/^((?>$char){0,$width})(?:\Z|\s+)//) {
119b39c5158Smillert            $output .= $spaces . $1 . "\n";
120b39c5158Smillert        } else {
121b39c5158Smillert            last;
122b39c5158Smillert        }
123b39c5158Smillert    }
124b39c5158Smillert    $output .= $spaces . $_;
125b39c5158Smillert    $output =~ s/\s+$/\n\n/;
126b39c5158Smillert    return $output;
127b39c5158Smillert}
128b39c5158Smillert
129b39c5158Smillert##############################################################################
130b39c5158Smillert# Module return value and documentation
131b39c5158Smillert##############################################################################
132b39c5158Smillert
133b39c5158Smillert1;
134b39c5158Smillert__END__
135b39c5158Smillert
136b46d8ef2Safresh1=for stopwords
137b46d8ef2Safresh1overstrike overstruck Overstruck Allbery terminal's
138b46d8ef2Safresh1
139b39c5158Smillert=head1 NAME
140b39c5158Smillert
141b39c5158SmillertPod::Text::Overstrike - Convert POD data to formatted overstrike text
142b39c5158Smillert
143b39c5158Smillert=head1 SYNOPSIS
144b39c5158Smillert
145b39c5158Smillert    use Pod::Text::Overstrike;
146b39c5158Smillert    my $parser = Pod::Text::Overstrike->new (sentence => 0, width => 78);
147b39c5158Smillert
148b39c5158Smillert    # Read POD from STDIN and write to STDOUT.
149b39c5158Smillert    $parser->parse_from_filehandle;
150b39c5158Smillert
151b39c5158Smillert    # Read POD from file.pod and write to file.txt.
152b39c5158Smillert    $parser->parse_from_file ('file.pod', 'file.txt');
153b39c5158Smillert
154b39c5158Smillert=head1 DESCRIPTION
155b39c5158Smillert
156b39c5158SmillertPod::Text::Overstrike is a simple subclass of Pod::Text that highlights
157b39c5158Smillertoutput text using overstrike sequences, in a manner similar to nroff.
158b39c5158SmillertCharacters in bold text are overstruck (character, backspace, character)
159b39c5158Smillertand characters in underlined text are converted to overstruck underscores
160b39c5158Smillert(underscore, backspace, character).  This format was originally designed
161b39c5158Smillertfor hard-copy terminals and/or line printers, yet is readable on soft-copy
162b39c5158Smillert(CRT) terminals.
163b39c5158Smillert
164b39c5158SmillertOverstruck text is best viewed by page-at-a-time programs that take
165b39c5158Smillertadvantage of the terminal's B<stand-out> and I<underline> capabilities, such
166b39c5158Smillertas the less program on Unix.
167b39c5158Smillert
168b39c5158SmillertApart from the overstrike, it in all ways functions like Pod::Text.  See
169b39c5158SmillertL<Pod::Text> for details and available options.
170b39c5158Smillert
171b39c5158Smillert=head1 BUGS
172b39c5158Smillert
173b39c5158SmillertCurrently, the outermost formatting instruction wins, so for example
174b39c5158Smillertunderlined text inside a region of bold text is displayed as simply bold.
175b39c5158SmillertThere may be some better approach possible.
176b39c5158Smillert
177e0680481Safresh1=head1 COMPATIBILITY
178e0680481Safresh1
179e0680481Safresh1Pod::Text::Overstrike 1.01 (based on L<Pod::Parser>) was the first version of
180e0680481Safresh1this module included with Perl, in Perl 5.6.1.
181e0680481Safresh1
182e0680481Safresh1The current API based on L<Pod::Simple> was added in Pod::Text::Overstrike
183e0680481Safresh12.00, included in Perl 5.9.3.
184e0680481Safresh1
185e0680481Safresh1Several problems with wrapping and line length were fixed as recently as
186e0680481Safresh1Pod::Text::Overstrike 2.04, included in Perl 5.11.5.
187e0680481Safresh1
188e0680481Safresh1This module inherits its API and most behavior from Pod::Text, so the details
189e0680481Safresh1in L<Pod::Text/COMPATIBILITY> also apply.  Pod::Text and Pod::Text::Overstrike
190e0680481Safresh1have had the same module version since 4.00, included in Perl 5.23.7.  (They
191e0680481Safresh1unfortunately diverge in confusing ways prior to that.)
192e0680481Safresh1
193b46d8ef2Safresh1=head1 AUTHOR
194b46d8ef2Safresh1
195b46d8ef2Safresh1Originally written by Joe Smith <Joe.Smith@inwap.com>, using the framework
196b46d8ef2Safresh1created by Russ Allbery <rra@cpan.org>.  Subsequently updated by Russ Allbery.
197b46d8ef2Safresh1
198b46d8ef2Safresh1=head1 COPYRIGHT AND LICENSE
199b46d8ef2Safresh1
200b46d8ef2Safresh1Copyright 2000 by Joe Smith <Joe.Smith@inwap.com>
201b46d8ef2Safresh1
202e0680481Safresh1Copyright 2001, 2004, 2008, 2014, 2018-2019, 2022 by Russ Allbery <rra@cpan.org>
203b46d8ef2Safresh1
204b46d8ef2Safresh1This program is free software; you may redistribute it and/or modify it
205b46d8ef2Safresh1under the same terms as Perl itself.
206b46d8ef2Safresh1
207b39c5158Smillert=head1 SEE ALSO
208b39c5158Smillert
209b39c5158SmillertL<Pod::Text>, L<Pod::Simple>
210b39c5158Smillert
211b39c5158SmillertThe current version of this module is always available from its web site at
212b46d8ef2Safresh1L<https://www.eyrie.org/~eagle/software/podlators/>.  It is also part of the
213b39c5158SmillertPerl core distribution as of 5.6.0.
214b39c5158Smillert
215b39c5158Smillert=cut
216b46d8ef2Safresh1
217b46d8ef2Safresh1# Local Variables:
218b46d8ef2Safresh1# copyright-at-end-flag: t
219b46d8ef2Safresh1# End:
220