NAME
Text::PageLayout - Distribute paragraphs onto pages, with headers and footers.
SYNOPSIS
use 5.010;
use Text::PageLayout;
my @paragraphs = ("a\nb\nc\nd\n") x 6,
# simple example
my $layout = Text::PageLayout->new(
page_size => 20, # number of lines per page
header => "head\n",
footer => "foot\n",
paragraphs => \@paragraphs, # REQUIRED
);
for my $p ( $layout->pages ) {
say "Page No. ", $p->page_number;
say $p;
}
# more complex example:
sub header {
my %param = @_;
if ($param{page_number} == 1) {
return "header for first page\n";
}
return "== page %d of %d == \n";
}
sub process_template {
my %param = @_;
my $t = $param{template};
if ($t =~ /%/) {
return sprintf $t, $param{page_number}, $param{total_pages};
}
else {
return $t;
}
}
sub split_paragraph {
my %param = @_;
my ($first, $rest) = split /\n\n/, $param{paragraph}, 2;
return ("$first\n", $rest);
}
$layout = Text::PageLayout->new(
page_size => 42,
tolerance => 2,
paragraphs => [ ... ],
separator => "\n\n",
footer => "\nCopyright (C) 2014 by M. Lenz\n",
header => \&header,
process_template => \&process_template,
split_paragraph => \&split_paragraph,
);
DESCRIPTION
Text::PageLayout breaks up a list of paragraphs into pages. It supports headers and footers, possibly varying by page number.
It operates under the assumption that all text blocks that are passed to (header, footer, paragraphs, separator) are either the empty string, or terminated by a newline. It also assumes that all those text blocks are properly line-wrapped already.
The header and footer can either be strings, or subroutines that will be called, and must return the string that is then used as a header or a footer. In both cases, the string that is used as header or footer can be post-processed with a custom callback process_template
.
The layout of a result page is always the header first, then as many paragraphs as fit on the page, separated by separator
, followed by as many blank lines as necessary to fill the page (if fillup_pages
is set, which it is by default), followed by the footer.
If the naive layouting algorithm (take as many paragraphs as fit) leaves more than tolerance
empty fill lines, the split_paragraph
callback is called, which can attempt to split the paragraph into small chunks, which are nicer to format.
ATTRIBUTES
Attributes should be set in the constructor (Text::PageLayout->new
), but most of them can also be set later on, for example the page_size
attribute with $layout->page_size(42)
.
Note that all callbacks receive named arguments, i.e. are called like this:
$callback->(
page_number => 1,
total_pages => 2,
);
Callbacks must accept additional named arguments (future versions of this module might pass more arguments).
page_size
Max. number of lines on a result page.
Default: 67
tolerance
Number of empty lines to accept on a page before attempting to split paragraphs.
Default: 6 (subject to change)
paragraphs
An array reference of paragraphs (newline-terminated strings) that is to be split up in pages.
This attribute is required.
header
A string that is used as a per-page header (or header template, if process_template
is set), or a callback that returns the header.
If used as a callback, it receives page_number
as a named argument.
Default: empty string.
footer
A string that is used as a per-page footer (or footer template, if process_template
is set), or a callback that returns the footer.
If used as a callback, it receives page_number
as a named argument.
Default: empty string.
fillup_pages
If set to a true value, pages are filled up to their maximum length by adding newlines before the footer.
Default: 1.
separator
A string that is used to separate multiple paragraphs on the same page.
Default: "\n" (newline)
split_paragraph
A callback that can split a paragraph into smaller chunks to create nicer layouts. If paragraphs exist that exceed the number of free lines on a page that only contains header or footer, this callback must split such a paragraph into smaller chunks, the first of which must fit on a page.
The return value must be a list of paragraphs.
It receives the arguments paragraph
, max_lines
and page_number
. max_lines
is the maximal number of lines that fit on the current page.
The default split_paragraph
simply splits off the first max_lines
as a sparate chunk, without any consideration for its content.
process_template
A callback that turns a header or footer template into the actual header or footer. It receives the named arguments template
, element
(which can be header
or footer
), page_number
and total_pages
.
It must return a string with the same number of lines as the template
.
The default template callback simply returns the template.
METHODS
new
Creates a new Text::PageLayout
object. Expects attributes as named arguments, with paragraphs
being the only required attribute.
pages
Returns a list of Text::PageLayout::Page
objects (which you can use like strings, if you want to).
AUTHOR
Moritz Lenz, <moritz at faui2k3.org>
BUGS
Please report any bugs or feature requests to bug-text-pagelayout at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Text-PageLayout. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Text::PageLayout
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
ACKNOWLEDGEMENTS
Thanks to noris network AG for letting the author develop and open-source this module.
LICENSE AND COPYRIGHT
Copyright 2014 Moritz Lenz. Written for noris network AG.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
DEVELOPMENT
Development happens at github, see https://github.com/moritz/perl5-Text-Layout. Pull requests welcome!