Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

Exegesis 7
by Damian Conway | Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13

Editor's note: this document is out of date and remains here for historic interest. See Synopsis 7 for the current design information.

And now at length they overflow their banks.

It's not uncommon for a report to need a series of data fields in one column and then a second column with only single field, perhaps containing a summary or discussion of the other data. For example, we might want to produce recipes of the form:


    =================[  Hecate's Broth of Ambition  ]=================
                                                                      
      Preparation time:             Method:                           
         66.6 minutes                  Remove the legs from the       
                                       lizard, the wings from the     
      Serves:                          owlet, and the tongue of the   
         2 doomed souls                adder. Set them aside.         
                                       Refrigerate the remains (they  
      Ingredients:                     can be used to make a lovely   
         2 snakes (1 fenny, 1          white-meat stock). Drain the   
         adder)                        newts' eyes if using pickled.  
         2 lizards (1 legless,         Wrap the toad toes in the      
         1 regular)                    bat's wool and immerse in half 
         3 eyes of newt (fresh         a pint of vegan stock in       
         or pickled)                   bottom of a preheated          
         2 toad toes (canned           cauldron. (If you can't get a  
         are fine)                     fresh vegan for the stock, a   
         2 cups of bat's wool          cup of boiling water poured    
         1 dog tongue                  over a vegetarian holding a    
         1 common or spotted           sprouted onion will do). Toss  
         owlet                         in the fenny snake, then the   
                                       legless lizard. Puree the      
                                       tongues together and fold      
                                       gradually into the mixture,    
                                       stirring widdershins at all   
                                       times.  Allow to bubble for 45 
                                       minutes then decant into two   
                                       tarnished copper chalices.         
                                       Garnish each with an owlet     
                                       wing, and serve immediately.

There are several ways to achieve that effect. The most obvious is to format each column separately and then lay them out side-by-side with a pair of verbatim fields:


    my $prep = form 'Preparation time:        ',
                    '   {<<<<<<<<<<<<<<<<<<<<}', $prep_time,
                    '                         ',
                    'Serves:                  ',
                    '   {<<<<<<<<<<<<<<<<<<<<}', $serves,
                    '                         ',
                    'Ingredients:             ',
                    '   {[[[[[[[[[[[[[[[[[[[[}', $ingredients;

    my $make = form 'Method:                          ',
                    '   {[[[[[[[[[[[[[[[[[[[[[[[[[[[[}',
                        $method;

    print form 
        '=================[ {||||||||||||||||||||||||||} ]=================',
                                      $recipe,
        '                                                                  ',
        '  {"""""""""""""""""""""""}     {"""""""""""""""""""""""""""""""} ',
           $prep,                        $make;

We could even chain the calls to form to eliminate the interim variables:


    print form 
        '=================[ {||||||||||||||||||||||||||} ]=================',
                                      $recipe,
        '                                                                  ',
        '  {"""""""""""""""""""""""}     {"""""""""""""""""""""""""""""""} ',
           form('Preparation time:        ',
                '   {<<<<<<<<<<<<<<<<<<<<}', $prep_time,
                '                         ',
                'Serves:                  ',
                '   {<<<<<<<<<<<<<<<<<<<<}', $serves
                '                         ',
                'Ingredients:             ',
                '   {[[[[[[[[[[[[[[[[[[[[}', $ingredients,
               ),
           form('Method:                          ',
                '   {[[[[[[[[[[[[[[[[[[[[[[[[[[[[}',
                    $method,
               );

While it's impressive to be able to do that kind of nested formatting (and highly useful in extreme formatting scenarios), it's also far too ungainly for regular use. A cleaner, more maintainable solution is use a single format and just build the method column up piecemeal, like so:


    print form 
        '=================[ {||||||||||||||||||||||||||} ]=================',
                                      $recipe,
        '                                                                  ',
        'Preparation time:               Method:                           ',
        '   {<<<<<<<<<<<<<<<<<<<<}          {<<<<<<<<<<<<<<<<<<<<<<<<<<<…} ',
            $prep_time,                     $method,
        '                                   {…<<<<<<<<<<<<<<<<<<<<<<<<<<…} ',
                                            $method,
        'Serves:                            {…<<<<<<<<<<<<<<<<<<<<<<<<<<…} ',
                                            $method,
        '   {<<<<<<<<<<<<<<<<<<<<}          {…<<<<<<<<<<<<<<<<<<<<<<<<<<…} ',
            $serves,                        $method,
        '                                   {…<<<<<<<<<<<<<<<<<<<<<<<<<<…} ',
                                            $method,
        'Ingredients:                       {…<<<<<<<<<<<<<<<<<<<<<<<<<<…} ',
                                            $method,
        '   {[[[[[[[[[[[[[[[[[[[[}          {…[[[[[[[[[[[[[[[[[[[[[[[[[[[} ',
            $ingredients,                   $method;

That produces exactly the same result as the previous versions, because each follow-on {…<<<<<<<…} field in the "Method" column grabs one extra line from $method, and then the final follow-on {…[[[[[[…} field grabs as many more as are required to lay out the rest of the contents of the variable. The only down-side is that the resulting code is still downright ugly. With all those tedious repetitions of the same variable, there's far too much $method in our madness.

Having a series of follow-on fields like this – vertically continuing a single column across subsequent format lines – is so common that form provides a special shortcut: the {VVVVVVVVV} overflow field.

An overflow field automagically duplicates the field specification immediately above it. The important point being that, because that duplication includes copying the preceding field's data source, overflow fields don't require a separate data source of their own.

Using overflow fields, we could rewrite our quotation generator like this:


    print form 
        '=================[ {||||||||||||||||||||||||||} ]=================',
                                      $recipe,
        '                                                                  ',
        'Preparation time:               Method:                           ',
        '   {<<<<<<<<<<<<<<<<<<<<}          {<<<<<<<<<<<<<<<<<<<<<<<<<<<<} ',
            $prep_time,                     $method,
        '                                   {VVVVVVVVVVVVVVVVVVVVVVVVVVVV} ',
        'Serves:                            {VVVVVVVVVVVVVVVVVVVVVVVVVVVV} ',
        '   {<<<<<<<<<<<<<<<<<<<<}          {VVVVVVVVVVVVVVVVVVVVVVVVVVVV} ',
            $serves,                        
        '                                   {VVVVVVVVVVVVVVVVVVVVVVVVVVVV} ',
        'Ingredients:                       {VVVVVVVVVVVVVVVVVVVVVVVVVVVV} ',
        '   {[[[[[[[[[[[[[[[[[[[[}          {VVVVVVVVVVVVVVVVVVVVVVVVVVVV} ',
            $ingredients,
        '                                   {VVVVVVVVVVVVVVVVVVVVVVVVVVVV} ';

Which would once again produce the recipe shown earlier.

Note that the overflow fields interact equally well in formats with single-line and block fields. That's because block overflow fields have one other special feature: they're non-greedy. Unless we specify otherwise, all types of block fields will consume their entire data source. For example, if we wrote:


    print form :layout«across»,
         '{<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>…}',
                                  $speech,
         '{…<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>…}',
                                  $speech,
         '{…[[[[[]]]]]…}   {="""""""""""""""""""=}   {…[[[[[]]]]]]…}',
             $speech,             $advert,              $speech,
         '{…[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]}',
                                  $speech;

we'd get:


    Now is the winter of our discontent / Made glorious summer
    by this sun of York; / And all the clouds that lour'd upon
    our house / In                             the deep  bosom
    of  the  ocean                             buried.  /  Now
    are our  brows                             bound      with
    victorious                                 wreaths; /  Our
    bruised   arms                             hung   up   for
    monuments;   /                             Our       stern
    alarums          +---------------------+   changed      to
    merry            |                     |   meetings, / Our
    dreadful         | Eat at Mrs Miggins! |   marches      to
    delightful       |                     |   measures. Grim-
    visaged    war   +---------------------+   hath   smooth'd
    his   wrinkled                             front;  /   And
    now,   instead                             of     mounting
    barded  steeds                             / To fright the
    souls       of                             fearful        
    adversaries, /                             He       capers
    nimbly  in   a                             lady's chamber.

That's because the two {…[[[[[]]]]]…} block fields on either side of the verbatim advertisement field will eat all the data in $speech, leaving nothing for the final format. Then the advertisement will be centred on the two resulting columns of text.

But, block overflow fields are different. They only take as many lines as are required to fill the lines generated by the non-overflow fields in their format. So, if we changed our code to use overflows:


    print form :layout«across»
         '{<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}', $speech,
         '{VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}',
         '{VVVVVVVVVVVV}   {="""""""""""""""""""=}   {VVVVVVVVVVVVV}', $advert,
         '{VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}';

we get both a cleaner specification and a more elegant result:


    Now is the winter of our discontent / Made glorious summer
    by this sun of York; / And all the clouds that lour'd upon
    our house / In                             the deep  bosom
    of  the  ocean   +---------------------+   buried.  /  Now
    are our  brows   |                     |   bound      with
    victorious       | Eat at Mrs Miggins! |   wreaths; /  Our
    bruised   arms   |                     |   hung   up   for
    monuments;   /   +---------------------+   Our       stern
    alarums                                    changed      to
    merry meetings,  /  Our  dreadful  marches  to  delightful
    measures. Grim-visaged  war  hath  smooth'd  his  wrinkled
    front; / And now, instead of mounting barded steeds  /  To
    fright the souls  of  fearful  adversaries,  /  He  capers
    nimbly in a lady's chamber.

Notice that, in the third format line of the previous example, the two overflow fields on either side of the advertisement are each overflowing from the single field that's above both of them. This kind of multiple overflow is fine, but it does require that we specify how the various fields overflow (i.e. as two separate columns of text, or – as in this case – as a single, broken column across the page). That's the purpose of the :layout«across» option on the first line. This option is explained in detail below.

The {VVVVVVVV} fields only consumed as much data from $speech as was required to sandwich the output lines created by the verbatim advertisement. This feature is important, because it means we can lay out a series of block fields in one column and a single overflowed field in another column without introducing ugly gaps. For example, because the {VVVVVVVVV} fields in:


    print form
        "Name:                                                  ",
        "  {[[[[[[[[[[[[}                                       ", $name,
        "                  Biography:                           ",
        "Status:             {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<}", $bio,
        "  {[[[[[[[[[[[[}    {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}", $status,
        "                    {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}", 
        "Comments:           {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}",
        "  {[[[[[[[[[[[}     {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}", $comments;

only consume as much of the overflowing $bio field as necessary, the result is something like:


    Name:                                                  
      William                                             
      Shakespeare                                         
                      Biography:                          
    Status:             William Shakespeare was born on    
      Deceased (1564    April 23, 1564 in Strathford-upon- 
      -1616)            Avon, England; he was third of     
                        eight children from Father John    
    Comments:           Shakespeare and Mother Mary Arden. 
      Theories          Shakespeare began his education at 
      abound as to      the age of seven when he probably  
      the true          attended the Strathford grammar    
      author of his     school. The school provided        
      plays. The        Shakespeare with his formal        
      prime             education. The students chiefly    
      alternative       studied Latin rhetoric, logic, and 
      candidates        literature. His knowledge and      
      being Sir         imagination may have come from his 
      Francis           reading of ancient authors and     
      Bacon,            poetry. In November 1582,          
      Christopher       Shakespeare received a license to  
      Marlowe, or       marry Anne Hathaway. At the time of
      Edward de         their marriage, Shakespeare was 18 
      Vere              years old and Anne was 26. They had
                        three children, the oldest Susanna,
                        and twins- a boy, Hamneth, and a   
                        girl, Judith. Before his death on    
                        April 23 1616, William Shakespeare 
                        had written thirty-seven plays. He 
                        is generally considered the        
                        greatest playwright the world has  
                        ever known and has always been the 
                        world's most popular author.

If {VVVVVVVVVVV} fields ate their entire data – the way {[[[[[[[[[} or {IIIIIIIIII} fields do – then the output would be much less satisfactory. The first block overflow field for $bio would have to consume the entire biography, before the comments field was even reached. So our output would be something like:


    Name:                                                                
      William                                                
      Shakespeare                                            
                      Biography:                          
    Status:             William Shakespeare was born on    
      Deceased (1564    April 23, 1564 in Strathford-upon- 
      -1616)            Avon, England; he was third of     
                        eight children from Father John    
                        Shakespeare and Mother Mary Arden. 
                        Shakespeare began his education at 
                        the age of seven when he probably  
                        attended the Strathford grammar    
                        school. The school provided        
                        Shakespeare with his formal        
                        education. The students chiefly    
                        studied Latin rhetoric, logic, and 
                        literature. His knowledge and      
                        imagination may have come from his 
                        reading of ancient authors and     
                        poetry. In November 1582,          
                        Shakespeare received a license to  
                        marry Anne Hathaway. At the time of
                        their marriage, Shakespeare was 18 
                        years old and Anne was 26. They had
                        three children, the oldest Susanna,
                        and twins- a boy, Hamneth, and a   
                        girl, Judith. Before his death on  
                        April 23 1616, William Shakespeare 
                        had written thirty-seven plays. He 
                        is generally considered the        
                        greatest playwright the world has  
                        ever known and has always been the 
                        world's most popular author.       
                                                   
    Comments:                                               
      Theories                                               
      abound as to                                           
      the true                                               
      author of his                                          
      plays. The                                             
      prime                                                  
      alternative                                            
      candidates                                             
      being Sir                                              
      Francis                                                
      Bacon,                                                 
      Christopher                                            
      Marlowe, or                                            
      Edward de                                              
      Vere

Which is precisely why {VVVVVVVVVVV} fields don't work that way.

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13

Next Pagearrow