# 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__