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