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