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

1.1       foxr        1: # The LearningOnline Network with CAPA
                      2: #  Generating TeX tables.
                      3: #
1.2     ! foxr        4: # $Id: lontable.pm,v 1.1 2008/11/24 11:56:53 foxr Exp $
1.1       foxr        5: # 
                      6: #
                      7: # Copyright Michigan State University Board of Trustees
                      8: #
                      9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                     10: #
                     11: # LON-CAPA is free software; you can redistribute it and/or modify
                     12: # it under the terms of the GNU General Public License as published by
                     13: # the Free Software Foundation; either version 2 of the License, or
                     14: # (at your option) any later version.
                     15: #
                     16: # LON-CAPA is distributed in the hope that it will be useful,
                     17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     19: # GNU General Public License for more details.
                     20: #
                     21: # You should have received a copy of the GNU General Public License
                     22: # along with LON-CAPA; if not, write to the Free Software
                     23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     24: #
                     25: # /home/httpd/html/adm/gpl.txt
                     26: #
                     27: # http://www.lon-capa.org/
                     28: ## Copyright for TtHfunc and TtMfunc by Ian Hutchinson. 
                     29: # TtHfunc and TtMfunc (the "Code") may be compiled and linked into 
                     30: # binary executable programs or libraries distributed by the 
                     31: # Michigan State University (the "Licensee"), but any binaries so 
                     32: # distributed are hereby licensed only for use in the context
                     33: # of a program or computational system for which the Licensee is the 
                     34: # primary author or distributor, and which performs substantial 
                     35: # additional tasks beyond the translation of (La)TeX into HTML.
                     36: # The C source of the Code may not be distributed by the Licensee
                     37: # to any other parties under any circumstances.
                     38: #
                     39: 
                     40: # This module is a support packkage that helps londefdef generate
                     41: # LaTeX tables using the LaTeX::Table package.  A prerequisite is that
                     42: # the print generator must have added the following to the LaTeX header:
                     43: #
                     44: #  \usepackage{xtab}
                     45: #  \usepackage{booktabs}
                     46: #  \usepackage{array}
                     47: #  \usepackage{colortbl}
                     48: #  \usepackage{xcolor}
                     49: #
                     50: #  These packages are installed in the packaged LaTeX distributions we know of as of
                     51: #  11/24/2008
                     52: #
                     53: 
                     54: 
                     55: 
                     56: package Apache::lontable;
                     57: use strict;
                     58: use LaTeX::Table;
                     59: 
                     60: 
                     61: =pod
                     62: 
                     63: =head1  lontable Table generation assistant for the LaTeX target
                     64: 
                     65: This module contains support software for generating tables in LaTeX output mode 
                     66: In this implementation, we use the LaTeX::Table package to do the actual final formatting.
                     67: Each table creates a new object.  Table objects can have global properties configured.
                     68: The main operations on a table object are:
                     69: 
                     70: =over 3
                     71: 
                     72: =item start_row  
                     73: 
                     74: Opens a new table row.
                     75: 
                     76: =item end_row
                     77: 
                     78: Closes a table row.
                     79: 
                     80: =item start_header
                     81: 
                     82: Starts a new row that has the header attribute (e.g. <th> tagged row).
                     83: header rows are ended with an end_row just like any ordinary row.
                     84: 
                     85: =item configure_row
                     86: 
                     87: Modifies a configuration item in the currently open row.
                     88: 
                     89: =item generate
                     90: 
                     91: Returns the generated table string.
                     92: 
                     93: =item configure
                     94: 
                     95: Configures a table's global configuration.
                     96: 
                     97: =back
                     98: 
                     99: =cut
                    100: 
                    101: =pod
                    102: 
                    103: =head2 new - create a new object.
                    104: 
                    105: Create a new table object.  Any of the raw table configuration items can be
                    106: modified by this.  These configuration items include:
                    107: 
                    108:   my $table = lontable::new(\%config_hash)
                    109: 
                    110: =over3
                    111: 
                    112: =item alignment
                    113: 
                    114: Table alignment.  Some table styles support this but not all.
                    115: 
                    116: =item tableborder
                    117: 
                    118: If true, a border is drawn around the table.
                    119: 
                    120: =item cellborder
                    121: 
                    122: If true, borders are drawn around the cells inside a table.
                    123: 
                    124: =item caption
                    125: 
                    126: The table caption text.
                    127: 
                    128: =item theme
                    129: 
                    130: The theme of the table to use.  Defaults to Zurich.  Themes we know about are:
                    131: NYC, NYC2, Zurich, Berlin, Dresden, Houston, Miami, plain, Paris.  Other themes can be added
                    132: to the LaTeX::Table package, and they will become supported automatically, as theme names are
                    133: not error checked.  Any use of a non-existent theme is reported by the LaTeX::Table package
                    134: when the table text is generated.
                    135: 
                    136: =back
                    137: 
                    138: =head3 Member data
                    139: 
                    140: The object hash has the following members:
                    141: 
                    142: =over 3
                    143: 
                    144: =item column_count 
                    145: 
                    146: Maintained internally, the number of colums in the widest row.
                    147: 
                    148: =item alignment
                    149: 
                    150: Table alignment (configurable) "left", "center", or "right".
                    151: 
                    152: =item outer_border
                    153: 
                    154: True if a border should be drawn around the entire table (configurable)
                    155: 
                    156: =item inner_borders
                    157: 
                    158: True if a border should be drawn around all cells (configurable).
                    159: 
                    160: =item caption
                    161: 
                    162: Table caption (configurable).
                    163: 
                    164: =item theme
                    165: 
                    166: Theme desired (configurable).
                    167: 
                    168: =item row_open 
                    169: 
                    170: True if a row is open and not yet closed.
                    171: 
                    172: =item rows
                    173: 
                    174: Array of row data. This is an array of hashes described below.
                    175: 
                    176: =back
                    177: 
                    178: =head3 Row data.
                    179: 
                    180: Each row of table data is an element of the rows hash array.  Hash elements are
                    181: 
                    182: =over 3
                    183: 
                    184: =item is_header
                    185: 
                    186: True if the user wants to format this row like a header.  This row will be used to generate
                    187: the table header.  All header rows will be gathered together into the table header.  If there
                    188: are multiple table headers interspersed with non table header data, this can lead to some 
                    189: surprises.
                    190: 
                    191: =item default_halign 
                    192: 
                    193: Default horizontal alignment for cells in this row.
                    194: 
                    195: =item default_valign
                    196: 
                    197: Default vertical alignment for cells in this row (may be ignored).
                    198: 
                    199: =item cells
                    200: 
                    201: Array of hashes where each element represents the data for a cell.
                    202: The contents of each element of this hash are described below:
                    203: 
                    204: =over 3
                    205: 
                    206: =item halign
                    207: 
                    208: If present, overrides the row default horizontal alignment.
                    209: 
                    210: =item valign
                    211: 
                    212: if present, override the row default vertical alignment.
                    213: 
                    214: =item rowspan
                    215: 
                    216: If present, indicates the number of rows this cell spans.
                    217: 
                    218: =item colspan
                    219: 
                    220: If present indicates the number of columns this cell spans.
                    221: Note that a cell can span both rows and columns.
                    222: 
                    223: =item contents
                    224: 
                    225: The contents of the cell.
                    226: 
                    227: =back
                    228: 
                    229: =back
                    230: 
                    231: =cut
                    232: 
                    233: sub new {
                    234:     my ($class, $configuration) = @_;
                    235: 
                    236:     #  Initialize the object member data with the default values
                    237:     #  then override with any stuff in $configuration.
                    238: 
                    239:     my $self = {
                    240: 	alignment      => "left",
                    241: 	outer_border   => 0,
1.2     ! foxr      242: 	inner_border  => 0,
1.1       foxr      243: 	caption        => "",
                    244: 	theme          => "Zurich",
                    245: 	column_count   => 0,
                    246: 	row_open       => 0,
                    247: 	rows           => [],
                    248:     };
                    249: 
                    250:     foreach my $key (keys %$configuration) {
                    251: 	$self->{$key} = $$configuration{$key};
                    252:     }
                    253: 
                    254:     bless($self, $class);
                    255: 
                    256:     return $self;
                    257: }
                    258: 
                    259: #-------------------------------------------------------------------------
                    260: #
                    261: #  Methods that get/set table global configuration.
1.2     ! foxr      262: #
        !           263: 
        !           264: =pod
        !           265: 
        !           266: =head2 Gets/set alignment.  
        !           267: 
        !           268: If the method is passed a new alignment value, that replaces the current one.
        !           269: Regardless, the current alignment is used:
        !           270: 
        !           271: =head3 Examples:
        !           272: 
        !           273:  my $align = $table->alignment(); # Return current alignment
        !           274:  $table->alignment("center");     # Attempt centered alignment.
        !           275: 
        !           276: =cut
        !           277: 
        !           278: sub alignment {
        !           279:     my ($self, $new_value) = @_;
        !           280: 
        !           281:     if (defined($new_value)) {
        !           282: 	$self->{alignment} = $new_value;
        !           283:     }
        !           284:     return $self->{alignment};
        !           285: }
        !           286: 
        !           287: =pod
        !           288: 
        !           289: =head2 table_border
        !           290: 
        !           291: Set or get the presence of an outer border in the table.
        !           292: If passed a parameter, that parameter replaces the current request
        !           293: for or not for an outer border. Regardless, the function returns
        !           294: the final value of the outer_border request.
        !           295: 
        !           296: =head3 Examples:
        !           297: 
        !           298:   $table->table_border(1);      # Request an outer border.
        !           299:   my $outer_requested = $table->table_border();
        !           300: 
        !           301: =cut
        !           302: 
        !           303: sub table_border {
        !           304:     my ($self, $new_value) = @_;
        !           305: 
        !           306:     if (defined($new_value)) {
        !           307: 	$self->{outer_border} = $new_value;
        !           308:     }
        !           309:     return $self->{outer_border};
        !           310: }
        !           311: 
        !           312: 
        !           313: =pod
        !           314: 
        !           315: =head2 cell_border
        !           316: 
        !           317: Set or get the presence of a request for cells to have borders
        !           318: drawn around them.  If a paramter is passed, it will be treated as
        !           319: a new value for the cell border configuration.  Regardless,the final
        !           320: value of that configuration parameter is returned.
        !           321: 
        !           322: =head3 Examples:
        !           323: 
        !           324:  my $cell_borders = $table->cell_border(); # ask if cell borders are requested.
        !           325:  $table->cell_border(1);	# Request cell borders.
        !           326: 
        !           327: =cut
        !           328: 
        !           329: sub cell_borders {
        !           330:     my ($self, $new_value) = @_;
        !           331: 
        !           332:     if (defined($new_value)) {
        !           333: 	$self->{inner_border} = $new_value;
        !           334:     }
        !           335:     reurn $self->{inner_border};
        !           336: }
        !           337: 
        !           338: =pod
        !           339: 
        !           340: =head2 caption
        !           341: 
        !           342: Gets and/or sets the caption string for the table.  The caption string appears to label
        !           343: the table.  If a parameter is supplied it will become the new caption string.k
        !           344: 
        !           345: =head3 Examples:
        !           346: 
        !           347: 
        !           348:   $my caption = $table->caption();
        !           349:   $table->caption("This is the new table caption");
        !           350: 
        !           351: =cut
        !           352: 
        !           353: sub caption {
        !           354:     my ($self, $new_value) = @_;
        !           355: 
        !           356:     if (defined($new_value)) {
        !           357: 	$self->catpion = $new_value;
        !           358:     }
        !           359: 
        !           360:     return $self->caption;
        !           361: }
        !           362: 
        !           363: =pod
        !           364: 
        !           365: =head2 theme
        !           366: 
        !           367: Gets and optionally sets the table theme.  The table theme describes how the
        !           368: table will be typset by the table package.  If a parameter is supplied it
        !           369: will be the new theme selection.
        !           370: 
        !           371: =head3 Examples:
1.1       foxr      372: 
1.2     ! foxr      373:   my $theme = $table->theme();
        !           374:   $table->theme("Dresden");
        !           375: 
        !           376: =cut
        !           377: 
        !           378: sub theme {
        !           379:     my ($self, $new_value) = @_;
        !           380: 
        !           381:     if (defined($new_value)) {
        !           382: 	$self->theme = $new_value;
        !           383:     }
        !           384:     return $self->theme;
        !           385: }
        !           386: 
        !           387: =pod
        !           388: 
        !           389: =head2 start_row
        !           390: 
        !           391: Begins a new row in the table.  If a row is already open, that row is
        !           392: closed off prior to starting the new row.  Rows can have the following attributes
        !           393: which are specified by an optional hash passed in to this function.
        !           394: 
        !           395: =over 3
        !           396: 
        !           397: =item default_halign
        !           398: 
        !           399: The default horizontal alignment of the row. This can be "left", "center", or "right"
        !           400: 
        !           401: =item default_valign
        !           402: 
        !           403: The default vertical alignment of the row.  This can be "top", "center", or "bottom"
        !           404: 
        !           405: =back
        !           406: 
        !           407: =head3 Examples:
        !           408: 
        !           409:   $table_start_row();                  # no attributes.
        !           410:   $table_start({default_halign => "center",
        !           411:                 default_valign => "bottom"}); # Create setting the attrbutes.
        !           412: 
        !           413: =cut
        !           414: 
        !           415: sub start_row {
        !           416:     my ($self, %config) = @_;
        !           417: 
        !           418:     if ($self->row_open) { 
        !           419: 	$self->end_row;
        !           420:     }
        !           421:     my $row_hash = {
        !           422: 	is_header      =>  0,
        !           423: 	default_halign => "left",
        !           424: 	default_valign => "top",
        !           425: 	cells          => []
        !           426:     };
        !           427: 
        !           428:     # Override the defaults if the config hash is present:
        !           429: 
        !           430:     if (defined(%config)) {
        !           431: 	foreach my $key  (keys %config) {
        !           432: 	    $row_hash->{$key} = $config{$key};
        !           433: 	}
        !           434:     }
        !           435:     
        !           436:     my $rows = $self->{rows};
        !           437:     push(@$rows, $row_hash);
        !           438: 
        !           439:     $self->row_open = 1;	# Row is now open and ready for business.
        !           440: }
        !           441: 
        !           442: =pod
        !           443: 
        !           444: =head2  end_row 
        !           445: 
        !           446: Closes off a row.  Once closed, cells cannot be added to this row again.
        !           447: 
        !           448: =head3 Examples:
        !           449: 
        !           450:    $table->close_row();
        !           451: 
        !           452: 
        !           453: =cut
        !           454: 
        !           455: sub close_row {
        !           456:     my ($self) = @_;
        !           457: 
        !           458:     if ($self->row_open) {
        !           459: 	
        !           460: 	# Mostly we need to determine if this row has the maximum
        !           461: 	# cell count of any row in existence in the table:
        !           462: 
        !           463: 	my $row        = $self->{rows}[-1];
        !           464: 	my $cells      = $row->{cells};
        !           465: 	my $cell_count = scalar(@$cells);
        !           466: 	if ($cell_count > $self->{column_count}) {
        !           467: 	    $self->{column_count} = $cell_count;
        !           468: 	}
        !           469: 
        !           470: 	$self->row_closed;
        !           471:     }
        !           472: }
        !           473: 
        !           474: =pod
        !           475: 
        !           476: =head2 start_header
        !           477: 
        !           478: Starts a row that is a header.  This is the same as start_row,but the is_header flag
        !           479: is set to true.
        !           480: 
        !           481: 
        !           482: =cut
        !           483: 
        !           484: sub start_header {
        !           485:     my ($self, %config) = @_;
        !           486: 
        !           487:     $self->start_row(%config);
        !           488:     $self->{rows}[-1]->is_header = 1;
        !           489: }
1.1       foxr      490: 
                    491: 
                    492: 
                    493: #   Mandatory initialization.
                    494: 
                    495: 1;
                    496: __END__

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