File:  [LON-CAPA] / loncom / xml / lonlatextable.pm
Revision 1.4: download - view: text, annotated - select for diffs
Wed Apr 13 10:44:26 2011 UTC (13 years, 7 months ago) by foxr
Branches: MAIN
CVS tags: version_2_12_X, version_2_11_X, version_2_11_5_msu, version_2_11_5, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, HEAD, BZ4492-merge, BZ4492-feature_horizontal_radioresponse
BZ6317 - Support (W/O debug spew) rules="groups" for tables with
row groups (tbody, thead, tfoot)...also get those sections out in the
right order.

#  Generating TeX tables.
#
# $Id: lonlatextable.pm,v 1.4 2011/04/13 10:44:26 foxr Exp $
# 
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
## Copyright for TtHfunc and TtMfunc by Ian Hutchinson. 
# TtHfunc and TtMfunc (the "Code") may be compiled and linked into 
# binary executable programs or libraries distributed by the 
# Michigan State University (the "Licensee"), but any binaries so 
# distributed are hereby licensed only for use in the context
# of a program or computational system for which the Licensee is the 
# primary author or distributor, and which performs substantial 
# additional tasks beyond the translation of (La)TeX into HTML.
# The C source of the Code may not be distributed by the Licensee
# to any other parties under any circumstances.
#

# This module is a support packkage that helps londefdef generate
# LaTeX tables using the LaTeX::Table package.  A prerequisite is that
# the print generator must have added the following to the LaTeX 
#
#  \usepackage{xtab}
#  \usepackage{booktabs}
#  \usepackage{array}
#  \usepackage{colortbl}
#  \usepackage{xcolor}
#
#  These packages are installed in the packaged LaTeX distributions we know of as of
#  11/24/2008
#


# 
#  This module provides a sub-set substitute for LaTeX::table 
#  which is a great module but unfortunately not usable in safe space
#  


=pod

=head1  NAME

Apache:lonltextable

=head1 SYNOPSIS

    use Apache::lonlatextable;

    $table = Apache::lonlatextable->new();
    $table->set_caption("some text");
    $table->set_data(cell_descriptions);
    $table->{'coldef'} = column_definitions;
    $table->generate_string();

=head1 DETAILS

=cut

package Apache::lonlatextable;
use strict;

=pod

=head2 new

Creates a new instance of a lonlatextable.  The returned value should be used on the left side of the
-> for further calls to object methods

=head3 Example:
   
    my $latexTable = &Apache::lonlatextable->new();

=cut


sub new {
    my ($class) = @_;

    my $self = {
	caption           => '',
	data              => [],
	coldef            =>  '',
	
    };
    bless($self, $class);
    return $self;
}

=pod

=head2 set_caption(some_text)

Set the table caption value.  If this string is empty, the table will be generated without a caption.
some_text will be the  new table caption value.

=head3 Example:

    $table = Apache::lonlatextable->new();
    $table->set_caption("Some very interesting table");

=cut

sub set_caption {
    my ($self, $caption) = @_;
    $self->{'caption'} = $caption;
}

=pod

=head2 set_data(cell_descriptions)

Sets the table cell data.  Table data in its simplest is an aray of arrays.  Each outer 
array element is a table row. However:
  
=over 3

=item Single column rows sarting with \

These are treated as LaTeX/TeX commands and, when the table is generated, 
passed without interpretation.

=item Lines with one cell that is empty.

These produce a horizontal rule that spans the width of the table.

=back

Calling this multiple times will continue to append cell data.

=head3 Example

    $table->set_data([ ['Gnu', '92.52'], [], ['Emu', '33.33'] ]);

Produces
    +--------------+--------------+
    |   Gnu        | 92.52        |
    +--------------+--------------+ (due to the empty row).
    |   Emu        | 33.33        |
    +--------------+--------------+


=cut

sub set_data {
    my ($self, $data) = @_;
    my $current_data = $self->{'data'};
    push (@$current_data, @$data);
    $self->{'data'} = $current_data;


}

=pod

=head2 Column  definitions.

The hash value 'coldef' can overide the column definitions computed by default for the table.

=head3 Example

    $table->{'coldef'} = 'lrcr';

Produces table header output of:

    \begin{tabular}{lrcr}

The default is to produce a set of left aligned columns.  The number of columns produced
will be determined by the size of the longest row.

=cut

=pod

=head2   $table->generate_string()

Generates the LaTeX for the table as a string that is returned to the caller.

=head3 Example

    $latex = $table->generate_string();

=cut

sub generate_string {

    my ($self) = @_;
    my $result;

    $result  = $self->table_header();
    $result .= $self->table_body();
    $result .= $self->table_trailer();



    return $result;
}
 

###################################################################################
#
#  Private methods:
#

#  generate the table header.
#  If coldef is an empty string, the default column definition is computed instead.
#
sub table_header()
{
    my ($self) = @_;
    my $result = '\begin{tabular}{';
    my $coldef = $self->{'coldef'};

    if ($coldef eq '') {
	my @rows   = @$self->{'data'};
	my $longest = 0;
	foreach my $row (@rows) {
	    my $length = scalar @{$row};
	    if ($length > $longest) {
		$longest = $length;
	    }
        } 
	# $longest cells all left aligned.
	# There's got to be a better way than this in perl?

	for (my $i =0; $i < $longest; $i++) {
	    $coldef .= 'l';
	}
    }
    
    $result .= $coldef . '}';
    $result .= "\n";

    return $result;
}
#
#   Generate the table body
#
sub table_body()
{
    my ($self) = @_;
    my $result = '';
    foreach my $row (@{$self->{'data'}}) {
	#
	# If a row has only a single cell we need to deal with the two special cases
	# Pass LaTeX uninterpreted or \hline.
	#
	if ((scalar @{$row}) == 1) {
	    my $cell = $row->[0];
	    if ($cell eq '') {
		$result .= '\hline' . "\n";
	    } elsif (substr($cell, 0, 1) eq "\\") {
		$result .= $cell . "\n";
	    } else {
		# could just be a table with one col...

		$result .= $cell . ' \\\\ ' ."\n";
	    }
	} else {
	    my $line = '';
	    foreach my $cell (@{$row}) {
		$line .= $cell . ' & ';
	    }
	    #  Replace the last ' & ' with \\ and a line terminator..
	    #  and append the line to the result.

	    $line =~ s/ & $/ \\\\\n/;
	    $result .= $line;
	}
    }
    return $result;
}

#
#  Generate the table trailer
#
sub table_trailer {
    my ($self) = @_;

    my $result = '\end{tabular}' . "\n";
    if ($self->{'caption'} ne '') {
	$result .= '\caption{' . $self->{'caption'} . '}' . "\n";
    }
    return $result;
}



1;
__END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>