NAME
    Text::SpanningTable - ASCII tables with support for column spanning.

VERSION
    version 0.1

SYNOPSIS
            use Text::SpanningTable;

            # create a table object with four columns of varying widths
            my $t = Text::SpanningTable->new(10, 20, 15, 25);

            # enable auto-newline adding
            $t->newlines(1);
        
            # print a top border
            print $t->hr('top');
        
            # print a row (with header information)
            print $t->row('Column 1', 'Column 2', 'Column 3', 'Column 4');
        
            # print a double horizontal rule
            print $t->dhr; # also $t->hr('dhr');

            # print a row of data
            print $t->row('one', 'two', 'three', 'four');
        
            # print a horizontal rule
            print $t->hr;
        
            # print another row, with one column that spans all four columns
            print $t->row([4, 'Creedance Clearwater Revival']);
        
            # print a horizontal rule
            print $t->hr;
        
            # print a row with the first column normally and another column
            # spanning the remaining three columns
            print $t->row('normal', [3, 'spans three columns']);

            # finally, print the bottom border
            print $t->hr('bottom');

            # the output from all these commands is:
            .----------+------------------+-------------+-----------------------.
            | Column 1 | Column 2         | Column 3    | Column 4              |
            +==========+==================+=============+=======================+
            | one      | two              | three       | four                  |
            +----------+------------------+-------------+-----------------------+
            | Creedance Clearwater Revival                                      |
            +----------+------------------+-------------+-----------------------+
            | normal   | spans three columns                                    |
            '----------+------------------+-------------+-----------------------'

DESCRIPTION
    "Text::SpanningTable" provides a mechanism for creating simple ASCII
    tables, with support for column spanning. It is meant to be used with
    monospace fonts such as common in terminals, and thus is useful for
    logging purposes.

    This module is inspired by Text::SimpleTable and can generally produce
    the same output (except that "Text::SimpleTable" doesn't support column
    spanning), but with a few key differences:

    *   In "Text::SimpleTable", you build your table in the object and
        "draw()" it when you're done. In "Text::SpanningTable", you can
        print your table (or do whatever you want with the output) as it is
        being built. If you don't need to have your tables in "real-time",
        you can just save the output in a variable, but for convenience and
        compatibility with "Text::SimpleTable", this module provides a
        "draw()" method (which is actually an alias for the "output()"
        method) that returns the table's output.

    *   "Text::SimpleTable" takes care of the top and bottom borders of the
        table by itself. Due to "Text::SpanningTable"'s "real-time" nature,
        this functionality is not provided, and you have to take care of
        that yourself.

    *   "Text::SimpleTable" allows you to pass titles for a header column
        when creating the table object. This module doesn't have that
        functionality, you have to create header rows (or footer rows)
        yourself and how you see fit.

    *   "Text::SpanningTable" provides a second type of horizontal rules
        (called 'dhr' for 'double horizontal rule') that can be used for
        header and footer rows (or whatever you see fit).

    *   "Text::SpanningTable" provides an option to define a callback
        function that can be automatically invoked on the module's output
        when calling "row()", "hr()" or "dhr()".

    *   In "Text::SimpleTable", the widths you define for the columns are
        the widths of the data they can accommodate, i.e. without the
        borders and padding. In "Text::SpanningTable", the widths you define
        are WITH the borders and padding. If you are familiar with the CSS
        and the box model, then columns in "Text::SimpleTable" have
        "box-sizing" set to "content-box", while in "Text::SpanningTable"
        they have "box-sizing" set to "border-box". So take into account
        that the width of the column's data will be four characters less
        than defined.

    Like "Text::SimpleTable", the columns of the table will always be
    exactly the same width as defined, i.e. they will not stretch to
    accommodate the data passed to the rows. If a column's data is too big,
    it will be wrapped (with possible word-breaking using the '-'
    character), thus resulting in more lines of text.

METHODS
  new( [@column_widths] )
    Creates a new instance of "Text::SpanningTable" with columns of the
    provided widths. If you don't provide any column widths, the table will
    have one column with a width of 100 characters.

  newlines( [$boolean] )
    By default, newlines will NOT be added automatically to the output
    generated by this module (for example, when printing a horizontal rule,
    a newline character will not be added). Pass a boolean value to this
    method to enable/disable automatic newline creation. Returns the current
    value of this attribute (after changing it if a boolean value has been
    passed).

  exec( \&sub, [@args] )
    Define a callback function to be invoked whenever calling "row()",
    "hr()" or "dhr()". This function will receive, as arguments, the
    generated output, and whatever else you've passed to this function (note
    @args above).

  hr( ['top'|'middle'|'bottom'|'dhr'] )
    Generates a horizontal rule of a certain type. Unless a specific type is
    provided, 'middle' we be used. 'top' generates a top border for the
    table, 'bottom' generates a bottom border, and 'dhr' is the same as
    'middle', but generates a 'double horizontal rule' that is more
    pronounced and thus can be used for headers and footers.

    This method will always result in one line of text.

  dhr()
    Convenience method that simply calls "hr('dhr')".

  row( @column_data )
    Generates a new row of data. The array passed should contain the same
    number of columns defined in the instance object, or, if column spanning
    is used, the total amount of columns should be the same as defined.

    When a column doesn't span, simply pass a scalar. When it does span,
    pass an array-ref with two items, the first being the number of columns
    to span, and the second with the scalar data. Passing an array-ref with
    1 for the first item is the same as just passing the scalar data (as the
    column will simply span itself).

    So, for example, if the table has nine columns, the following is a valid
    value for @column_data:

            ( 'one', [2, 'two and three'], 'four', [5, 'five through nine'] )

    If a column's data will be longer than its width, the data will wrapped
    and broken, which results in the row being constructed from more than
    one lines of text. Thus, as oppose to the "hr()" method, this method has
    two options for a return value. In list context, it will return all the
    lines constructing the row (with or without newlines at the end of each
    string, see "newlines()" for more info). In scalar context, however, it
    will return the row as a string containing newline characters that
    separate the lines of text (once again, a trailing newline will be added
    to this string only if a true value was passed to "newlines()").

    If a callback function has be defined, it will not be invoked with the
    complete output of this row (i.e. with all the lines of text that has
    resulted), but instead will be called once per each line of text. This
    is what makes the callback function so useful, as it helps you cope with
    problems resulting from all the newline characters separating these
    lines.

  output()
  draw()
    Returns the entire output generated for the table up to the point of
    calling this method. It should be stressed that this method does not
    "finalize" the table by adding top and bottom borders or anything at
    all. Decoration is done "real-time" and if you don't add top and bottom
    borders yourself (with "hr('top')" and "hr('bottom')", respectively),
    this method will not do that for you. Returned output will or will not
    contain newlines as per the value defined with "newlines()".

    Both the above methods do the same, "draw()" is provided as an alias for
    compatibility with Text::SimpleTable.

AUTHOR
    Ido Perlmuter, "<ido at ido50.net>"

BUGS
    Please report any bugs or feature requests to "bug-text-spanningtable at
    rt.cpan.org", or through the web interface at
    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Text-SpanningTable>. I
    will be notified, and then you'll automatically be notified of progress
    on your bug as I make changes.

SUPPORT
    You can find documentation for this module with the perldoc command.

            perldoc Text::SpanningTable

    You can also look for information at:

    *   RT: CPAN's request tracker

        <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Text-SpanningTable>

    *   AnnoCPAN: Annotated CPAN documentation

        <http://annocpan.org/dist/Text-SpanningTable>

    *   CPAN Ratings

        <http://cpanratings.perl.org/d/Text-SpanningTable>

    *   Search CPAN

        <http://search.cpan.org/dist/Text-SpanningTable/>

ACKNOWLEDGEMENTS
    Sebastian Riedel and Marcus Ramberg, authors of Text::SimpleTable, which
    provided the inspiration of this module.

LICENSE AND COPYRIGHT
    Copyright 2010 Ido Perlmuter.

    This program is free software; you can redistribute it and/or modify it
    under the terms of either: the GNU General Public License as published
    by the Free Software Foundation; or the Artistic License.

    See http://dev.perl.org/licenses/ for more information.