Annotation of loncom/xml/lonlatextable.pm, revision 1.2

1.1       foxr        1: #  Generating TeX tables.
                      2: #
1.2     ! foxr        3: # $Id: lonlatextable.pm,v 1.1 2010/08/18 12:04:31 foxr Exp $
1.1       foxr        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: 
1.2     ! foxr      143: =item Lines with one cell that is empty.
1.1       foxr      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) = @_;
1.2     ! foxr      225:     my $result = '\begin{tabular}{';
1.1       foxr      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: {
1.2     ! foxr      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;
1.1       foxr      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>