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 ago) by foxr
Branches: MAIN
CVS tags: version_2_12_X, version_2_11_X, 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.

    1: #  Generating TeX tables.
    2: #
    3: # $Id: lonlatextable.pm,v 1.4 2011/04/13 10:44:26 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: Calling this multiple times will continue to append cell data.
  150: 
  151: =head3 Example
  152: 
  153:     $table->set_data([ ['Gnu', '92.52'], [], ['Emu', '33.33'] ]);
  154: 
  155: Produces
  156:     +--------------+--------------+
  157:     |   Gnu        | 92.52        |
  158:     +--------------+--------------+ (due to the empty row).
  159:     |   Emu        | 33.33        |
  160:     +--------------+--------------+
  161: 
  162: 
  163: =cut
  164: 
  165: sub set_data {
  166:     my ($self, $data) = @_;
  167:     my $current_data = $self->{'data'};
  168:     push (@$current_data, @$data);
  169:     $self->{'data'} = $current_data;
  170: 
  171: 
  172: }
  173: 
  174: =pod
  175: 
  176: =head2 Column  definitions.
  177: 
  178: The hash value 'coldef' can overide the column definitions computed by default for the table.
  179: 
  180: =head3 Example
  181: 
  182:     $table->{'coldef'} = 'lrcr';
  183: 
  184: Produces table header output of:
  185: 
  186:     \begin{tabular}{lrcr}
  187: 
  188: The default is to produce a set of left aligned columns.  The number of columns produced
  189: will be determined by the size of the longest row.
  190: 
  191: =cut
  192: 
  193: =pod
  194: 
  195: =head2   $table->generate_string()
  196: 
  197: Generates the LaTeX for the table as a string that is returned to the caller.
  198: 
  199: =head3 Example
  200: 
  201:     $latex = $table->generate_string();
  202: 
  203: =cut
  204: 
  205: sub generate_string {
  206: 
  207:     my ($self) = @_;
  208:     my $result;
  209: 
  210:     $result  = $self->table_header();
  211:     $result .= $self->table_body();
  212:     $result .= $self->table_trailer();
  213: 
  214: 
  215: 
  216:     return $result;
  217: }
  218:  
  219: 
  220: ###################################################################################
  221: #
  222: #  Private methods:
  223: #
  224: 
  225: #  generate the table header.
  226: #  If coldef is an empty string, the default column definition is computed instead.
  227: #
  228: sub table_header()
  229: {
  230:     my ($self) = @_;
  231:     my $result = '\begin{tabular}{';
  232:     my $coldef = $self->{'coldef'};
  233: 
  234:     if ($coldef eq '') {
  235: 	my @rows   = @$self->{'data'};
  236: 	my $longest = 0;
  237: 	foreach my $row (@rows) {
  238: 	    my $length = scalar @{$row};
  239: 	    if ($length > $longest) {
  240: 		$longest = $length;
  241: 	    }
  242:         } 
  243: 	# $longest cells all left aligned.
  244: 	# There's got to be a better way than this in perl?
  245: 
  246: 	for (my $i =0; $i < $longest; $i++) {
  247: 	    $coldef .= 'l';
  248: 	}
  249:     }
  250:     
  251:     $result .= $coldef . '}';
  252:     $result .= "\n";
  253: 
  254:     return $result;
  255: }
  256: #
  257: #   Generate the table body
  258: #
  259: sub table_body()
  260: {
  261:     my ($self) = @_;
  262:     my $result = '';
  263:     foreach my $row (@{$self->{'data'}}) {
  264: 	#
  265: 	# If a row has only a single cell we need to deal with the two special cases
  266: 	# Pass LaTeX uninterpreted or \hline.
  267: 	#
  268: 	if ((scalar @{$row}) == 1) {
  269: 	    my $cell = $row->[0];
  270: 	    if ($cell eq '') {
  271: 		$result .= '\hline' . "\n";
  272: 	    } elsif (substr($cell, 0, 1) eq "\\") {
  273: 		$result .= $cell . "\n";
  274: 	    } else {
  275: 		# could just be a table with one col...
  276: 
  277: 		$result .= $cell . ' \\\\ ' ."\n";
  278: 	    }
  279: 	} else {
  280: 	    my $line = '';
  281: 	    foreach my $cell (@{$row}) {
  282: 		$line .= $cell . ' & ';
  283: 	    }
  284: 	    #  Replace the last ' & ' with \\ and a line terminator..
  285: 	    #  and append the line to the result.
  286: 
  287: 	    $line =~ s/ & $/ \\\\\n/;
  288: 	    $result .= $line;
  289: 	}
  290:     }
  291:     return $result;
  292: }
  293: 
  294: #
  295: #  Generate the table trailer
  296: #
  297: sub table_trailer {
  298:     my ($self) = @_;
  299: 
  300:     my $result = '\end{tabular}' . "\n";
  301:     if ($self->{'caption'} ne '') {
  302: 	$result .= '\caption{' . $self->{'caption'} . '}' . "\n";
  303:     }
  304:     return $result;
  305: }
  306: 
  307: 
  308: 
  309: 1;
  310: __END__

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