.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.45) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "PDF::Builder::Content::Column_docs 3" .TH PDF::Builder::Content::Column_docs 3 2026-02-08 "perl v5.42.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME PDF::Builder::Content::Column_docs \-\- column text formatting system .SH "PDF::Builder::Content::Text/column and related routines" .IX Header "PDF::Builder::Content::Text/column and related routines" These routines form a sub\-library for support of complex columnar output with high level markup languages. Currently, a single rectangular layout may be defined on a page, to be filled by user\-defined content. Any content which could not be fit within the column confines is returned in an internal array format, and may be passed to the next \f(CWcolumn()\fR call to finish the formatting. .PP Future plans call for non\-rectangular columns to be definable, as well as flow from one column to another on a page, and column balancing. Other possible enhancements call for support of non\-Western writing systems (e.g., bidirectional text, using the HarfBuzz library), proper word\-splitting and paragraph shaping (possibly using the Knuth\-Plass algorithm), and additional markup languages. .SS column .IX Subsection "column" .Vb 1 \& ($rc, $next_y, $unused) = $text\->column($page, $text, $grfx, $markup, $txt, %opts) .Ve .Sp .RS 4 This method fills out a column of text on a page, returning any unused portion that could not be fit, and where it left off on the page. .Sp Tag names, CSS entries, markup type, etc. are case\-sensitive (usually lower\-case letters only). For example, you cannot give a
paragraph in
HTML or a \fBP\fR selector in CSS styling.
.Sp
\&\fR\f(CB$page\fR\fB\fR is the page context. Currently, its only use is for page annotations
for links (\*(Aqmd1\*(Aq []() and \*(Aqhtml\*(Aq ), so if you\*(Aqre not using those,
you may pass anything such as \f(CW\*(C`undef\*(C'\fR for \f(CW$page\fR if you wish.
.Sp
\&\fR\f(CB$text\fR\fB\fR is the text context, so that various font and text\-output operations
may be performed. It is often, but not necessarily always, the same as the
object containing the "column" method.
.Sp
\&\fR\f(CB$grfx\fR\fB\fR is the graphics (gfx) context. It may be a dummy (e.g., undef) if
\&\fIno\fR graphics are to be drawn, but graphical items such as the column outline
(\*(Aqoutline\*(Aq option) and horizontal rule (
in HTML markup) use it.
Currently, \fItext\-decoration\fR underline (default for links, \*(Aqmd1\*(Aq \f(CW\*(C`[]()\*(C'\fR and
\&\*(Aqhtml\*(Aq \f(CW\*(C`\*(C'\fR) or line\-through or overline use the text context, but
may in the future require a valid graphics context. Images (when implemented)
will require a graphics context.
.Sp
\&\fR\f(CB$markup\fR\fB\fR is information on what sort of \fImarkup\fR is being used to format
and lay out the column\*(Aqs text:
.IP \*(Aqpre\*(Aq 4
.IX Item "'pre'"
The input material has already been processed and is already in the desired
form. \f(CW$txt\fR is an array reference to the list of hashes. This \fImust\fR be used
when you are calling \f(CWcolumn()\fR a second (or later)
time to output material left over from the first call. It may also be used when
the caller application has already processed the text into the appropriate
format, and other markup isn\*(Aqt being used.
.IP \*(Aqnone\*(Aq 4
.IX Item "'none'"
If \fInone\fR is specified, there is no markup in use. At most, a blank line or
a new text array element specifies a new paragraph, and that\*(Aqs it. \f(CW$txt\fR may
be a single string, or an array (list) of strings.
.Sp
The input \fBtxt\fR is a list (anonymous array reference) of strings, each
containing one or more paragraphs. A single string may also be given. An empty
line between paragraphs may be used to separate the paragraphs. Paragraphs may
not span array elements.
.IP \*(Aqmd1\*(Aq 4
.IX Item "'md1'"
This specifies a certain flavor of Markdown compatible with Text::Markdown.
See the full description below.
.Sp
There are other flavors of Markdown, so other md\fIn\fR flavors \fImay\fR be defined
in the future, such as POD from Perl code.
.IP \*(Aqhtml\*(Aq 4
.IX Item "'html'"
This specifies that a large subset of HTML markup is used, along with some
attributes and CSS.
.Sp
Numeric entities (decimal nnn; and hexadecimal nnn;) are supported,
as well as named entities (— for example).
.Sp
The input \fBtxt\fR is a list (anonymous array reference) of strings, each
containing one or more paragraphs and other markup. A single string may also be
given. Per normal HTML practice, paragraph tags should be used to mark
paragraphs. \fINote that HTML::TreeBuilder is configured to automatically
mark top body\-level text with paragraph tags, in case you forget to do so,
although it is probably better to do it yourself, to maintain more control
over the processing.\fR
Separate array elements will first be glued together into a single string
before processing, permitting paragraphs to span array elements if desired.
.IP "Other input formats" 4
.IX Item "Other input formats"
There are other markup languages out there, such as HTML\-like Pango,
nroff\-like man page, Markdown\-like wikimedia, and Perl\*(Aqs POD, that
might be supported in the future (provided there are supported Perl libraries
for them). It is very unlikely that TeX or LaTeX will
ever be supported, as they both already have excellent PDF output.
.Sp
PDF::Builder currently only supports the markup languages described above.
If you want to use something else (e.g., Perl\*(Aqs POD, or \fIman\fR format, or even
MS Word or some other WYSIWYG format), you will need to find a converter
utility to convert it to a supported flavor of Markdown or HTML. Many such
converters already exist, so take a look (although you may well have to do some
cleanup before \f(CWcolumn()\fR accepts the resulting HTML as input).
.Sp
Perhaps in the future, PDF::Builder will directly support additional formats,
but no promises.
.RE
.RS 4
.Sp
\&\fR\f(CB$txt\fR\fB\fR is the input text: a string, an array reference to multiple strings,
or an array reference to hashes. See \f(CW$markup\fR for details.
.Sp
\&\fR\f(CB%opts\fR\fB\fR Options \-\- a number of these are, despite the name, mandatory.
.IP "\*(Aqrect\*(Aq => [x, y, width, height]" 4
.IX Item "'rect' => [x, y, width, height]"
This defines a column as a rectangular area of a given width and height (both
in points) on the current page. \fIIn the future, it is expected that more
elaborate non\-rectangular areas will be definable, but for now, a simple
rectangle is all that is permitted.\fR The column\*(Aqs upper left coordinate is
\&\f(CW\*(C`x, y\*(C'\fR.
.Sp
The top text baseline is assumed to be relative to the UL corner (based on the
determined line height), and the column outline
clips that baseline, as it does additional baselines down the page (interline
spacing is \f(CW\*(C`leading\*(C'\fR multiplied by the largest \f(CW\*(C`font_size\*(C'\fR or image height
needed on that line).
.Sp
\&\fICurrently, \*(Aqrect\*(Aq is required, as it is the only column shape supported.\fR
.IP "\*(Aqrelative\*(Aq => [ x, y, scale(s) ]" 4
.IX Item "'relative' => [ x, y, scale(s) ]"
\&\f(CW\*(Aqrelative\*(Aq\fR defaults to \f(CW\*(C`[ 0, 0, 1, 1 ]\*(C'\fR, and allows a column outline
(currently only \*(Aqrect\*(Aq) to be either absolute or relative. \f(CW\*(C`x\*(C'\fR and \f(CW\*(C`y\*(C'\fR are
added to each \f(CW\*(C`x,y\*(C'\fR coordinate pair, \fIafter\fR scaling. Scaling values:
.RS 4
.IP "(none) The scaling defaults to 1 in both x and y dimensions (no change)." 4
.IX Item "(none) The scaling defaults to 1 in both x and y dimensions (no change)."
.PD 0
.IP "scale (one value) The scaling in both the x (width) and y (height) dimensions uses this value." 4
.IX Item "scale (one value) The scaling in both the x (width) and y (height) dimensions uses this value."
.IP "scale_x, scale_y (two values) There are two separate scaling factors for the x dimension (width) and y dimension (height)." 4
.IX Item "scale_x, scale_y (two values) There are two separate scaling factors for the x dimension (width) and y dimension (height)."
.PD
.RE
.RS 4
.Sp
This permits a generically\-shaped outline to be defined, scaled (perhaps
not preserving the aspect ratio) and placed anywhere on the page. This could
save you from having to define similarly\-shaped columns from scratch multiple
times.
If you want to define a relative outline, the lower left corner (whether or
not it contains a point, and whether or not it\*(Aqs the first one listed) would
usually be \f(CW\*(C`0, 0\*(C'\fR, to have scaling work as expected. In other works, your
outline template should be in the lower left corner of the page.
.RE
.ie n .IP "\*(Aqstart_y\*(Aq => $start_y" 4
.el .IP "\*(Aqstart_y\*(Aq => \f(CW$start_y\fR" 4
.IX Item "'start_y' => $start_y"
If omitted, it is assumed that you want to start at the top of the defined
column (the maximum \f(CW\*(C`y\*(C'\fR value minus the maximum vertical extent of this line).
If used, the normal value is the \f(CW\*(C`next_y\*(C'\fR returned from the previous
\&\f(CWcolumn()\fR call. It is the deepest extent reached by the previous line (plus
leading), and is the top\-most point of the new first line of this \f(CWcolumn()\fR
call.
.Sp
Note that the \f(CW\*(C`x\*(C'\fR position will be determined by the column shape and size
(the left\-most point of the baseline), so there is no place to explicitly set
an \f(CW\*(C`x\*(C'\fR position to start at.
.ie n .IP "\*(Aqfont_size\*(Aq => $font_size" 4
.el .IP "\*(Aqfont_size\*(Aq => \f(CW$font_size\fR" 4
.IX Item "'font_size' => $font_size"
This is the starting font size (in points) to be used. Over the course of
the text, it may be modified by markup. The default is 12pt. It is in turn
overridden by any CSS or HTML font size\-settings.
.Sp
The starting font size may be set in a number of ways. It may be inherited from
a previous \f(CW\*(C`$text\->font(..., font\-size)\*(C'\fR statement; it may be set via the
\&\f(CW\*(C`font_size\*(C'\fR option (overriding any font method inheritance); it may default to
12pt (if neither explicit way is given). For HTML markup, it may of course be
modified by the \f(CW\*(C`font\*(C'\fR tag or by CSS styling \f(CW\*(C`font\-size\*(C'\fR. For Markdown, it
may be modified by CSS styling.
.ie n .IP "\*(Aqfont_info\*(Aq => $string" 4
.el .IP "\*(Aqfont_info\*(Aq => \f(CW$string\fR" 4
.IX Item "'font_info' => $string"
This permits the user to specify the starting font used in \f(CWcolumn()\fR (body
font\-family, font\-style, font\-weight, color). \f(CWcolumn()\fR will pick up any
font already
loaded (\f(CW\*(C`$text\->font($font, $size);\*(C'\fR, or using FontManager), and use that
as the "current" font. If no font has been loaded, and no other instructions
are given, the FontManager default (core Times\-Roman) will be used.
.Sp
The \f(CW\*(C`font_info\*(C'\fR option for \f(CWcolumn()\fR may be given to override either of the
two above methods. You may specify a \f(CW$string\fR of \fB\*(Aq\-fm\-\*(Aq\fR to instruct
\&\f(CWcolumn()\fR to use the FontManager "default" font (Times face core font).
Or, you may pick a font
face \fIknown\fR to FontManager (added by user code if not one of the 28 core
fonts), and optionally give it style and weight: \f(CW$string\fR of
\&\fB\*(Aqface:style:weight:color\*(Aq\fR. The style defaults to \*(Aqnormal\*(Aq (non\-italic), or
\&\*(Aqnormal\*(Aq or \*(Aq0\*(Aq may be given. For italics, use \*(Aqitalic\*(Aq or \*(Aq1\*(Aq. The weight
defaults to \*(Aqnormal\*(Aq (unbolded weight), or \*(Aqnormal\*(Aq or \*(Aq0\*(Aq may be given. For
bold (heavy) text, use \*(Aqbold\*(Aq or \*(Aq1\*(Aq. Finally, a color may be given.
.Sp
Finally, the \f(CW\*(C`style\*(C'\fR option for \f(CWcolumn()\fR may be given to override any of
the above settings, e.g., \fB\*(Aqstyle\*(Aq=>{ body { font\-family:... }\fR and set
the initial current font. Remember that, as with anything font\-related that
\&\f(CWcolumn()\fR does, the \*(Aqface\*(Aq (family) used must already be known to FontManager
(explicitly loaded with \f(CWadd_font()\fR if not one of the 28 core fonts).
Remember that the first 14 fonts are standard PDF, and the second 14 are
normally supplied with Windows (but not always with other operating systems).
.ie n .IP "\*(Aqmarker_width\*(Aq => $marker_width" 4
.el .IP "\*(Aqmarker_width\*(Aq => \f(CW$marker_width\fR" 4
.IX Item "'marker_width' => $marker_width"
.PD 0
.ie n .IP "\*(Aqmarker_gap\*(Aq => $marker_gap" 4
.el .IP "\*(Aqmarker_gap\*(Aq => \f(CW$marker_gap\fR" 4
.IX Item "'marker_gap' => $marker_gap"
.PD
This is the width of the gutter to the left of a list item, where (for the
first line of the item) the marker lives. The marker contains the symbol (for
bulleted/unordered lists) or formatted number and "before" and "after" text
(for numbered/ordered lists). Both have a single space (marker_gap = 1em)
before the item text starts. The number is a length, in points.
.Sp
The default is 1 em (1 times the font_size passed to \f(CWcolumn()\fR), and is not
adjusted for any changes of font_size in the markup, so that lists are indented
\&\fIconsistently\fR. This is usually fine for unordered (bulleted) lists and single
digit ordered (numbered) lists, although you may need to make it wider for
two or three digit numbered lists. An explicit value passed
in is also not changed \-\- the gutter width for the marker will be the same in
all lists (keeping them aligned). If you plan to have exceptionally long
markers, such as an ordered list of years in Roman numerals, e.g.,
\&\fB(MCMXCIX)\fR, you may want to make this gutter a bit wider.
.Sp
A value may be given for the marker_gap, which is the gap between the
(\f(CW$marker_width\fR wide) \fImarker\fR and the start of the list item\*(Aqs text.
The default is \f(CW$fs\fR points (1 em), set by the font_size in the markup.
.Sp
The \f(CW\*(C`list\-style\-position\*(C'\fR CSS property may be given as the standard \*(Aqoutside\*(Aq
(the default) or \*(Aqinside\*(Aq, or (extension to CSS) to indent the left side of
second, third, etc.