SPUG: modules for building strings top down

Showell30 at aol.com Showell30 at aol.com
Tue Sep 26 08:55:50 CDT 2000


# Hello.
#
# I want a more generic interface for assembling 
# text than, say, HTML::Entities provides me.  I want 
# to build up strings in a top-down fashion, so that I can
# hook in parts of the string later, with an 
# object-oriented interface.  I created an object 
# class called "topdown" that has two functions:
#
#   hook - allows you to hook in a string, array of 
#          strings, or other topdown into your string
#   expanded - returns expanded string (recursing tree)
#
# I am interested in alternative solutions to this.  Thanks. 
# I suppose the best thing would be to discover that there's
# already a module out there that does what my "topdown" does,
# only more robustly.

# Design the big page layout first
my $page = new topdown(<<PAGE);
TITLEBAR
<table width=100%>
<tr><td width=30%>TOC</td><td>MAIN</td></tr>
<table>
PAGE

# Design a blue title bar at the top.
$titlebar = new topdown(<<TITLEBAR);
<table width=100% bgcolor="BGCOLOR">
<tr><td><center>TITLE<center></td></tr>
</table>
TITLEBAR
$page->hook("TITLEBAR",$titlebar);
$titlebar->hook("BGCOLOR","blue");
$titlebar->hook("FGCOLOR","white");
$titlebar->hook("TITLE","Sample Use of Topdown Class");

# Design the table of contents next
$toc = new topdown(<<TOC);
<h4>Table of Contents</h4>
CHAPTERS

TOC
$page->hook("TOC",$toc);

# Lay out the specific chapters
$toc->hook("CHAPTERS", [
    chapter("Perl Quirks"),
    chapter("Why I Wrote This")]);

sub chapter {return "  $_[0]\n";}

#
$page->hook("MAIN",<<MAIN);
This is the main section of my web page.
MAIN

print $page->expanded();

package topdown;

sub new
{
    my $class = shift;
    my $data  = shift;
    my $self  = bless {_data => $data }, $class;
}

sub hook
{
    my $self = shift;
    my $hook = shift;
    my $data = shift;

    $self->{'_hooks'}{$hook} = $data;
    return "";
}

sub expanded
{
    # This is a deeply flawed implementation --
    # it will break down if children nodes have the keywords in them.
    my $self = shift;
    my $exp   = $self->{'_data'};
    my $hooks = $self->{'_hooks'};

    foreach $hook (sort keys %{$hooks})
    {
        my $data = $hooks->{$hook};
        if ((ref $data) eq "topdown")
        {
            $data = $data->expanded(); 
            $exp =~s/$hook/$data/gm
        }
        elsif (ref $data eq "ARRAY")
        {       
            # oversimplified for now, just accept strings   
            my $text;
            foreach $elem (@$data)
            {
                $text .= $elem;
            }
            $exp =~s/$hook/$text/gm
        }
        else
        {
            $exp =~s/$hook/$data/gm
        }
    }

    return $exp;
}   

1;
    



 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
  Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/





More information about the spug-list mailing list