summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <rra@cpan.org>2021-09-06 13:05:56 -0700
committerRuss Allbery <rra@cpan.org>2021-09-06 13:05:56 -0700
commitb065139205368d44a65893d72f008e559e6f5b89 (patch)
treef1035e66fa78563ab3dc0be8cf7cfe4deef1ead5
parent7ecfe37c52b2de3805dc8f8eacd95ea808725d18 (diff)
Refactor App::DocKnot::Spin output method
Move $SPACE into module state and rewrite the output method as _output using my current Perl coding style.
-rwxr-xr-xlib/App/DocKnot/Spin.pm60
-rw-r--r--t/data/perl.conf6
2 files changed, 46 insertions, 20 deletions
diff --git a/lib/App/DocKnot/Spin.pm b/lib/App/DocKnot/Spin.pm
index b51da48..8c38f35 100755
--- a/lib/App/DocKnot/Spin.pm
+++ b/lib/App/DocKnot/Spin.pm
@@ -41,29 +41,53 @@ use strict;
use subs qw(expand parse parse_context);
use warnings;
use vars qw(%DEPEND $DOCID $FILE @FILES $FULLPATH $ID $OUTPUT
- %OUTPUT $REPO @RSS %SITEDESCS %SITELINKS @SITEMAP $SOURCE $SPACE
+ %OUTPUT $REPO @RSS %SITEDESCS %SITELINKS @SITEMAP $SOURCE
@STATE $STYLES %VERSIONS %commands %macros %strings);
##############################################################################
# Output
##############################################################################
-# Sends something to the output file. Pull out any trailing space and stash
-# it temporarily, and put any trailing space that we'd previously stashed into
-# the output string after any close tags. This gets spacing working properly
-# around boundaries.
-sub output {
+# Sends something to the output file with special handling of whitespace for
+# more readable HTML output.
+#
+# @output - Strings to output.
+sub _output {
my ($self, @output) = @_;
- local $_ = join ('', @output);
- if ($SPACE) {
- my ($close, $body) = m%^(\s*(?:</(?!body)[^>]+>\s*)*)(.*)%s;
- $close .= $SPACE;
+ my $output = join(q{}, @output);
+
+ # If we have saved whitespace, separate any closing tags at the start of
+ # the output from the rest of the output and insert that saved space
+ # between those closing tags and the rest of the output.
+ #
+ # The effect of this is to move whitespace between element bodies and
+ # their closing tags to outside of the closing tags, which makes the HTML
+ # much more readable.
+ if ($self->{space}) {
+ my ($close, $body) = $output =~ m{
+ \A
+ (\s*
+ (?: </(?!body)[^>]+> \s* )*
+ )
+ (.*)
+ }xms;
+ $close .= $self->{space};
+
+ # Collapse multiple whitespace-only lines into a single blank line.
$close =~ s/\n\s*\n\s*\n/\n\n/g;
- $_ = $close . $body;
- $SPACE = '';
+
+ # Replace the output with added whitespace and clear saved whitespace.
+ $output = $close . $body;
+ $self->{space} = q{};
}
- if (s/\n(\s+)\z/\n/) { $SPACE = $1 }
- print OUT $_;
+
+ # Remove and save any trailing whitespace.
+ if ($output =~ s{ \n (\s+) \z }{\n}xms) {
+ $self->{space} = $1;
+ }
+
+ # Send the results to the output file.
+ print OUT $output;
}
##############################################################################
@@ -1155,7 +1179,9 @@ sub spin {
my $fh = FileHandle->new ("< $thread")
or die "$0: cannot open $thread: $!\n";
@FILES = ([$fh, $thread]);
- $SPACE = '';
+
+ # Initialize object state for a new document.
+ $self->{space} = q{};
# Parse the thread file a paragraph at a time (but pick up macro contents
# that are continued across paragraphs. We maintain the stack of files
@@ -1183,13 +1209,13 @@ sub spin {
}
my $result = $self->parse($self->escape($_), 1);
$result =~ s/^(?:\s*\n)+//;
- $self->output($result) unless ($result =~ /^\s*$/);
+ $self->_output($result) unless ($result =~ /^\s*$/);
($fh, $FILE) = @{ $FILES[0] };
}
close $fh;
shift @FILES;
}
- print OUT $self->border_clear(), $SPACE;
+ print OUT $self->border_clear(), $self->{space};
close OUT;
undef %macros;
undef %strings;
diff --git a/t/data/perl.conf b/t/data/perl.conf
index b661de6..6a57059 100644
--- a/t/data/perl.conf
+++ b/t/data/perl.conf
@@ -24,10 +24,10 @@ $MINIMUM_VERSION = '5.024';
qr{ ^ do_ .* }xms,
qr{ ^ (?: block | border_ .* | delete_files | enclose | escape ) \z }xms,
qr{ ^ (?: footer | format_string | heading | inline | macro ) \z }xms,
- qr{ ^ (?: new | output | paragraph | placement | process_file ) \z }xms,
- qr{ ^ (?: read_ .* | relative | run_converter | sign | sitelinks ) \z }xms,
+ qr{ ^ (?: new | paragraph | placement | process_file ) \z }xms,
+ qr{ ^ (?: read_ .* | relative | run_converter | sitelinks ) \z }xms,
qr{ ^ (?: spin | spin_command | split_paragraphs ) \z }xms,
- qr{ ^ (?: border | extract | time_to_seconds | unescape ) \z }xms,
+ qr{ ^ (?: border | extract | time_to_seconds ) \z }xms,
);
# File must end with this line.