Formats
CHAPTER 18: FORMATS
Formats
- A format is a template for a report
- The format defines the column labels and fixed part of the
report as well as the variable part of the report
- Formats can also define the headers for each page of the report
- Unfortunately, Perl does not support footers in formats. You
have to do your own processing to add footers to each page of
the report.
- Formats have their own namespace
- Format definitions can be placed anywhere in the Perl program,
but can NOT be nested
Why Use Formats?
- More efficient than a bunch of printf's
- Built-in page header processing
- Built-in filled text blocks
Defining A Format
- format format_name =
FORMATLIST
.
- Note that the format definition ends with a line containing a
period by itself. The period MUST be the first character on
the line.
- The FORMATLIST consists of a sequence of picture lines (also
called field lines)
- A picture line can have picture fields (also called field
holders) which define places where variable text will be
substituted
- If a picture line has picture fields, it is followed by a
value line that defines the scalar values to be used for the
fields
- The values on the value line are separated by commas
Basic Picture Fields
- The basic types of picture fields are:
@<<<< Left-justified field
@>>>> Right-justified field
@|||| Center-justified field
@#.## Numeric field
- The field width is specified by the number of <'s, >'s, |'s or
#'s (including the @)
- For a numeric field, the number of #'s to the right of the
decimal point in the definition specifies the number of places
to the right of the decimal place in the output
- The pad character is space
- If the value is too large for the field width, the value is
truncated
- If the value contains a newline, output is stopped at the first
newline encountered. (But see Multiline Fields below.)
Format Example
- Ex.
format GRADE_REPORT =
**************************************************
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$name
@<< @<< @###.###
$test1, $test2, ($test1 + $test2) /2
Final Grade: @<<
$grade
**************************************************
.
- Note that whitespace in the value line is ignored, but
whitespace in the picture line is preserved!
- Note that expressions can be used in a value line. (But the
value line must be just ONE line, so all expressions and values
must be specified on one line.)
Invoking A Format
- A format is invoked using the write function
- write (FILEHANDLE)
write
- Writes a formatted record to the specified filehandle
- Each filehandle has an associated format. By default, the name
of this format is same as the name of the filehandle. The
format of the currently selected filehandle (the current default
filehandle, CDF) can be set by assigning a format name to the
special $~ variable.
- If FILEHANDLE is not specified, the CDF is used
- FILEHANDLE can be a scalar expression
- Ex.
# Use the format definition for GRADE_REPORT given above.
open (IN, "<course.info"); # Open the input file
open (OUT ">grades.dat"); # Open the report file
$oldcdf = select (OUT);
$~ = "GRADE_REPORT"; # Specify FORMAT name for
# OUT
select ($oldcdf);
while (<IN>)
{
chop;
($name, $test1, $test2, $grade) = split(/:/);
# Split up the colon-
# separated fields of
# the input file
write (OUT); # Write a report record
}
Note that the variable names used here are the same as
used in the format definition. This need not be the case.
- Ex.
We could also have done the previous example as follows:
open (IN, "<course.info"); # Open the input file
open (GRADE_REPORT, ">grades.dat"); # Open the report file
while (<IN>)
{
chop;
($name, $test1, $test2, $grade) = split(/:/);
write (GRADE_REPORT);
}
By default, the format name of a filehandle is the same as
the filehandle name, so initially the format name for the
GRADE_REPORT filehandle is "GRADE_REPORT".
Multiline Fields
- The special @* picture field is used to output multiple lines
of data from one scalar value
- If used, it should appear on a picture line by itself
- Ex.
format STDOUT =
**************************************************
@*
$multiline_text
**************************************************
.
$multiline_text = `who`; # Get some multiline data
write; # Output the data using the
# CDF (assumed to be STDOUT)
# and the format STDOUT
Filled Fields
- There are also picture fields that allow the creation of
filled text blocks:
^<<<< Left-justified text blocks
^>>>> Right-justified text blocks
^|||| Center-justified text blocks
- The value used with a filled field must be a scalar variable
or an array element containing a string scalar. This is
because Perl will modify the value of this variable while
filling the field.
- To create the filled text block, Perl breaks the value into
words, puts as much text as possible into the first line of
the text block, outputs this line, and then removes this data
from the variable so that it can be used for the next line of
the filled text block
- So to create the filled text block, a sequence of picture fields
on successive picture lines is used
- The word-break characters default to space, newline and hyphen.
These can be changed by setting the special $: variable.
- Ex.
format STDOUT =
**************************************************
Right-justified text block: ^>>>>>>>>>>>>>>>>>>>
$multiline_text
^>>>>>>>>>>>>>>>>>>>
$multiline_text
^>>>>>>>>>>>>>>>>>>>
$multiline_text
**************************************************
.
$multiline_text = `cat sample.dat`; # Get some multiline data
write; # Output the report
Note that this example creates at most three lines of filled
text in a rectangle 20 characters wide on the right side of
the output.
Blank Line Suppression
- To suppress the output of a blank line, put a tilde (~) anywhere
in the picture line where a space would have been output
- The tilde is translated to a blank on output
- Blank line suppression is useful in filled fields. In the
filled field example above, if the filled text is less than
three lines, blank lines are output. These can be suppressed
with the tilde indicator.
- Ex.
format STDOUT =
**************************************************
Right-justified text block: ^>>>>>>>>>>>>>>>>>>>
$multiline_text
~ ^>>>>>>>>>>>>>>>>>>>
$multiline_text
~ ^>>>>>>>>>>>>>>>>>>>
$multiline_text
**************************************************
.
Repeated Picture Lines
- To repeat the output of picture line until a blank line would
be output, put two consecutive tildes anywhere in the picture
line where two spaces would have been output
- The tildes are translated to blanks on output
- Repeated picture lines are also very useful with filled fields.
In the filled field example above, if the filled text is more
than three lines, the text is truncated and lost.
- Ex.
format STDOUT =
**************************************************
Right-justified text block: ^>>>>>>>>>>>>>>>>>>>
$multiline_text
~~ ^>>>>>>>>>>>>>>>>>>>
$multiline_text
**************************************************
.
This is the usual way that filled text blocks are done in a
format definition.
Top-Of-Page Formats
- The Top-Of-Page (TOP) format is output whenever a new page is
started
- A new page is started before the first output record and whenever
there is insufficient space on the current page to output the
next record
- The page output delimiter is a formfeed
- The default number of lines per pages is 60
- Each filehandle has an associated TOP format. By default, the
name of this TOP format is same as the name of the filehandle,
but with "_TOP" appended. Thus, the TOP format for STDOUT is
STDOUT_TOP. The TOP format of the currently selected filehandle
(the current default filehandle, CDF) can be set by assigning a
format name to the special $^ variable.
- Each filehandle also keeps tracks of the current page number in
the special $% variable
- Ex.
format STDOUT_TOP =
Page Number: @<<
$%
.
Changing Format Defaults
- EACH filehandle maintains the following values:
Format Name (Default: Name of filehandle)
TOP Format Name (Default: Name of filehandle with "_TOP"
appended)
Page Length (Default: 60 lines)
Current Page Number (Initially, 0)
Number Of Lines Left On The Page
- To change any of these for a given filehandle you must first
make that filehandle by the current default filehandle (CDF)
using the select function and then set the appropriate special
variable as follows:
$~ Format Name
$^ TOP Format Name
$= Page Length
$% Current Page Number
$- Number Of Lines Left On The Page
- If the page length is changed, its new value will not be used
until a new page is started
- When the $- variable becomes 0, a new page is started
- Ex.
$oldcdf = select (GRADE_REPORT);
$= = 40; # Change to 40 lines per page
$~ = "GRADES"; # Change format to "GRADES"
$^ = "TOP"; # Change TOP format to "TOP"
Mixing Print (Or Printf) With Write
- Whenever you output data to a filehandle using the write function
(and thus using the filehandle's format), Perl keeps track of the
current page number and line number within that page
- If you also output data to the filehandle using the print or
printf functions, Perl does NOT update the internal line or page
counts
- So if you want to mix these two types of output, you must update
$- and $% yourself whenever you output via print() or printf()
Bob Tarr
University of Maryland, Baltimore County
tarr@umbc.edu