File:  [LON-CAPA] / loncom / xml / lonlatextable.pm
Revision 1.2: download - view: text, annotated - select for diffs
Fri Aug 27 09:42:48 2010 UTC (13 years, 8 months ago) by foxr
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_1, version_2_10_0_RC2, version_2_10_0, HEAD
BZ 6331 - Replace LaTeX::Table usage with lonlatextable which is a simple
subset that is ok in safe space.

    1: #  Generating TeX tables.
    2: #
    3: # $Id: lonlatextable.pm,v 1.2 2010/08/27 09:42:48 foxr Exp $
    4: # 
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: ## Copyright for TtHfunc and TtMfunc by Ian Hutchinson. 
   28: # TtHfunc and TtMfunc (the "Code") may be compiled and linked into 
   29: # binary executable programs or libraries distributed by the 
   30: # Michigan State University (the "Licensee"), but any binaries so 
   31: # distributed are hereby licensed only for use in the context
   32: # of a program or computational system for which the Licensee is the 
   33: # primary author or distributor, and which performs substantial 
   34: # additional tasks beyond the translation of (La)TeX into HTML.
   35: # The C source of the Code may not be distributed by the Licensee
   36: # to any other parties under any circumstances.
   37: #
   38: 
   39: # This module is a support packkage that helps londefdef generate
   40: # LaTeX tables using the LaTeX::Table package.  A prerequisite is that
   41: # the print generator must have added the following to the LaTeX 
   42: #
   43: #  \usepackage{xtab}
   44: #  \usepackage{booktabs}
   45: #  \usepackage{array}
   46: #  \usepackage{colortbl}
   47: #  \usepackage{xcolor}
   48: #
   49: #  These packages are installed in the packaged LaTeX distributions we know of as of
   50: #  11/24/2008
   51: #
   52: 
   53: 
   54: # 
   55: #  This module provides a sub-set substitute for LaTeX::table 
   56: #  which is a great module but unfortunately not usable in safe space
   57: #  
   58: 
   59: 
   60: =pod
   61: 
   62: =head1  NAME
   63: 
   64: Apache:lonltextable
   65: 
   66: =head1 SYNOPSIS
   67: 
   68:     use Apache::lonlatextable;
   69: 
   70:     $table = Apache::lonlatextable->new();
   71:     $table->set_caption("some text");
   72:     $table->set_data(cell_descriptions);
   73:     $table->{'coldef'} = column_definitions;
   74:     $table->generate_string();
   75: 
   76: =head1 DETAILS
   77: 
   78: =cut
   79: 
   80: package Apache::lonlatextable;
   81: use strict;
   82: 
   83: =pod
   84: 
   85: =head2 new
   86: 
   87: Creates a new instance of a lonlatextable.  The returned value should be used on the left side of the
   88: -> for further calls to object methods
   89: 
   90: =head3 Example:
   91:    
   92:     my $latexTable = &Apache::lonlatextable->new();
   93: 
   94: =cut
   95: 
   96: 
   97: sub new {
   98:     my ($class) = @_;
   99: 
  100:     my $self = {
  101: 	caption           => '',
  102: 	data              => [],
  103: 	coldef            =>  '',
  104: 	
  105:     };
  106:     bless($self, $class);
  107:     return $self;
  108: }
  109: 
  110: =pod
  111: 
  112: =head2 set_caption(some_text)
  113: 
  114: Set the table caption value.  If this string is empty, the table will be generated without a caption.
  115: some_text will be the  new table caption value.
  116: 
  117: =head3 Example:
  118: 
  119:     $table = Apache::lonlatextable->new();
  120:     $table->set_caption("Some very interesting table");
  121: 
  122: =cut
  123: 
  124: sub set_caption {
  125:     my ($self, $caption) = @_;
  126:     $self->{'caption'} = $caption;
  127: }
  128: 
  129: =pod
  130: 
  131: =head2 set_data(cell_descriptions)
  132: 
  133: Sets the table cell data.  Table data in its simplest is an aray of arrays.  Each outer 
  134: array element is a table row. However:
  135:   
  136: =over 3
  137: 
  138: =item Single column rows sarting with \
  139: 
  140: These are treated as LaTeX/TeX commands and, when the table is generated, 
  141: passed without interpretation.
  142: 
  143: =item Lines with one cell that is empty.
  144: 
  145: These produce a horizontal rule that spans the width of the table.
  146: 
  147: =back
  148: 
  149: =head3 Example
  150: 
  151:     $table->set_data([ ['Gnu', '92.52'], [], ['Emu', '33.33'] ]);
  152: 
  153: Produces
  154:     +--------------+--------------+
  155:     |   Gnu        | 92.52        |
  156:     +--------------+--------------+ (due to the empty row).
  157:     |   Emu        | 33.33        |
  158:     +--------------+--------------+
  159: 
  160: =cut
  161: 
  162: sub set_data {
  163:     my ($self, $data) = @_;
  164:     $self->{'data'}  = $data;
  165: 
  166: }
  167: 
  168: =pod
  169: 
  170: =head2 Column  definitions.
  171: 
  172: The hash value 'coldef' can overide the column definitions computed by default for the table.
  173: 
  174: =head3 Example
  175: 
  176:     $table->{'coldef'} = 'lrcr';
  177: 
  178: Produces table header output of:
  179: 
  180:     \begin{tabular}{lrcr}
  181: 
  182: The default is to produce a set of left aligned columns.  The number of columns produced
  183: will be determined by the size of the longest row.
  184: 
  185: =cut
  186: 
  187: =pod
  188: 
  189: =head2   $table->generate_string()
  190: 
  191: Generates the LaTeX for the table as a string that is returned to the caller.
  192: 
  193: =head3 Example
  194: 
  195:     $latex = $table->generate_string();
  196: 
  197: =cut
  198: 
  199: sub generate_string {
  200: 
  201:     my ($self) = @_;
  202:     my $result;
  203: 
  204:     $result  = $self->table_header();
  205:     $result .= $self->table_body();
  206:     $result .= $self->table_trailer();
  207: 
  208: 
  209: 
  210:     return $result;
  211: }
  212:  
  213: 
  214: ###################################################################################
  215: #
  216: #  Private methods:
  217: #
  218: 
  219: #  generate the table header.
  220: #  If coldef is an empty string, the default column definition is computed instead.
  221: #
  222: sub table_header()
  223: {
  224:     my ($self) = @_;
  225:     my $result = '\begin{tabular}{';
  226:     my $coldef = $self->{'coldef'};
  227: 
  228:     if ($coldef eq '') {
  229: 	my @rows   = @$self->{'data'};
  230: 	my $longest = 0;
  231: 	foreach my $row (@rows) {
  232: 	    my $length = scalar @{$row};
  233: 	    if ($length > $longest) {
  234: 		$longest = $length;
  235: 	    }
  236:         } 
  237: 	# $longest cells all left aligned.
  238: 	# There's got to be a better way than this in perl?
  239: 
  240: 	for (my $i =0; $i < $longest; $i++) {
  241: 	    $coldef .= 'l';
  242: 	}
  243:     }
  244:     
  245:     $result .= $coldef . '}';
  246:     $result .= "\n";
  247: 
  248:     return $result;
  249: }
  250: #
  251: #   Generate the table body
  252: #
  253: sub table_body()
  254: {
  255:     my ($self) = @_;
  256:     my $result = '';
  257:     foreach my $row (@{$self->{'data'}}) {
  258: 	#
  259: 	# If a row has only a single cell we need to deal with the two special cases
  260: 	# Pass LaTeX uninterpreted or \hline.
  261: 	#
  262: 	if ((scalar @{$row}) == 1) {
  263: 	    my $cell = $row->[0];
  264: 	    if ($cell eq '') {
  265: 		$result .= '\hline' . "\n";
  266: 	    } elsif (substr($cell, 0, 1) eq "\\") {
  267: 		$result .= $cell . "\n";
  268: 	    } else {
  269: 		# could just be a table with one col...
  270: 
  271: 		$result .= $cell . ' \\\\ ' ."\n";
  272: 	    }
  273: 	} else {
  274: 	    my $line = '';
  275: 	    foreach my $cell (@{$row}) {
  276: 		$line .= $cell . ' & ';
  277: 	    }
  278: 	    #  Replace the last ' & ' with \\ and a line terminator..
  279: 	    #  and append the line to the result.
  280: 
  281: 	    $line =~ s/ & $/ \\\\\n/;
  282: 	    $result .= $line;
  283: 	}
  284:     }
  285:     return $result;
  286: }
  287: 
  288: #
  289: #  Generate the table trailer
  290: #
  291: sub table_trailer {
  292:     my ($self) = @_;
  293: 
  294:     my $result = '\end{tabular}' . "\n";
  295:     if ($self->{'caption'} ne '') {
  296: 	$result .= '\caption{' . $self->{'caption'} . '}' . "\n";
  297:     }
  298:     return $result;
  299: }
  300: 
  301: 
  302: 
  303: 1;
  304: __END__

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