[LON-CAPA-cvs] cvs: loncom /xml lontable.pm lontable.test

foxr foxr@source.lon-capa.org
Tue, 23 Dec 2008 11:49:33 -0000


This is a MIME encoded message

--foxr1230032973
Content-Type: text/plain

foxr		Tue Dec 23 11:49:33 2008 EDT

  Modified files:              
    /loncom/xml	lontable.pm lontable.test 
  Log:
  Starting to get an idea of how to control what LaTeX::Table generates
  so we can format the table the way the XML/Html will request it.l
  
  
--foxr1230032973
Content-Type: text/plain
Content-Disposition: attachment; filename="foxr-20081223114933.txt"

Index: loncom/xml/lontable.pm
diff -u loncom/xml/lontable.pm:1.5 loncom/xml/lontable.pm:1.6
--- loncom/xml/lontable.pm:1.5	Tue Dec  9 11:50:08 2008
+++ loncom/xml/lontable.pm	Tue Dec 23 11:49:32 2008
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 #  Generating TeX tables.
 #
-# $Id: lontable.pm,v 1.5 2008/12/09 11:50:08 foxr Exp $
+# $Id: lontable.pm,v 1.6 2008/12/23 11:49:32 foxr Exp $
 # 
 #
 # Copyright Michigan State University Board of Trustees
@@ -164,6 +164,11 @@
 
 Theme desired (configurable).
 
+=item width
+
+If defined, the width of the table (should be supplied
+in fraction of column width e.g. .75 for 75%.
+
 =item row_open 
 
 True if a row is open and not yet closed.
@@ -189,6 +194,11 @@
 
 Default vertical alignment for cells in this row (may be ignored).
 
+=item cell_width
+ 
+The width of the row in cells.  This is the sum of the column spans 
+of the cells in the row.
+
 =item cells
 
 Array of hashes where each element represents the data for a cell.
@@ -218,6 +228,10 @@
 If present indicates the number of columns this cell spans.
 Note that a cell can span both rows and columns.
 
+=item start_col
+
+The starting column of the cell in the table grid.
+
 =item contents
 
 The contents of the cell.
@@ -420,6 +434,7 @@
     my $row_hash = {
 	default_halign => "left",
 	default_valign => "top",
+	cell_width     =>  0,
 	cells          => []
     };
 
@@ -459,19 +474,11 @@
 	# Mostly we need to determine if this row has the maximum
 	# cell count of any row in existence in the table:
 
-	my $row        = $self->{'rows'}[-1];
+	my $row        = $self->{'rows'}->[-1];
 	my $cells      = $row->{'cells'};
-	my $raw_cell_count = scalar(@$cells);
 
-	# Need to iterate through the columns as 
-	# colspans affect the count:
-	#
-	my $cell_count = 0;
-	for (my $i =0; $i < $raw_cell_count; $i++) {
-	    $cell_count = $cell_count + $cells->[$i]->{'colspan'};
-	}
-	if ($cell_count > $self->{'column_count'}) {
-	    $self->{'column_count'} = $cell_count;
+	if ($row->{'cell_width'} > $self->{'column_count'}) {
+	    $self->{'column_count'} = $row->{'cell_width'};
 	}
 
 	$self->{'row_open'} = 0;;
@@ -572,44 +579,55 @@
     if (!$self->{'row_open'}) {
 	$self->start_row();
     }
-
-    my $current_row   = $self->{'rows'}->[-1];
+    my $rows          = $self->{'rows'};
+    my $current_row   = $rows->[-1];
     my $current_cells = $current_row->{'cells'}; 
+    my $last_coord    = $current_row->{'cell_width'};
 
-    # The way we handle row spans is to insert additional
-    # blank cells as needed to reach this column.  Each
-    # cell that is inserted is empty, but has a row span decreased by one
-    # from the row above.  Column spans are propagated down from the row above
-    # and handled when the table's LaTeX is generated.
-    # There must be at least two rows in the row table to need to do this:
+    #  We have to worry about row spans if there is a prior row:
 
-    my $rows = $self->{'rows'};
-    my $row_count = scalar(@$rows);
-    if ($row_count > 1) {
-	my $prior_row      = $rows->[-2];
-	my $cells          = $current_row->{'cells'};
-	my $prior_cells    = $prior_row->{'cells'};
-	my $curr_colcount  = scalar(@$cells);
-	
-	my $prior_colcount = scalar(@$prior_cells);
+    if (scalar(@$rows) > 1) {
 
-	while (($curr_colcount < $prior_colcount) &&
-	       $prior_cells->[$curr_colcount]->{'rowspan'} > 1) {
-	    my %cell;
-	    my $prior_cell = $prior_cells->[$curr_colcount];
-	    %cell = %$prior_cell;
-	    $cell{'rowspan'}--;
-	    $cell{'contents'} = "";
-	    push(@$current_cells, \%cell);
-	    $curr_colcount += $prior_cells->[$curr_colcount]->{'colspan'}; # could be a colspan too.
+	my $last_row = $rows->[-2];
+	if ($last_coord < $last_row->{'cell_width'}) {
+	    my $prior_coord       = 0;
+	    my $prior_cell_index  = 0;
+	    while ($prior_coord <= $last_coord) {
+		
+		# Pull a cell down if it's coord matches our start coord
+		# And there's a row span > 1.
+		# Having done so, we adjust our $last_coord to match the
+		# end point of the pulled down cell.
+
+		my $prior_cell = $last_row->{'cells'}->[$prior_cell_index];
+		if (($prior_cell->{'start_col'} == $last_coord) &&
+		    ($prior_cell->{'rowspan'}  > 1)) {
+		    
+		    #  Need to drop the cell down
+
+		    my %dropped_down_cell = %$prior_cell;
+		    $dropped_down_cell{'rowspan'}--;
+		    $dropped_down_cell{'contents'} = '';
+
+		    push(@$current_cells, \%dropped_down_cell);
+		    $last_coord += $dropped_down_cell{'colspan'};
+		    $current_row->{'cell_width'} = $last_coord;
+		    
+		}
+		$prior_coord += $prior_cell->{'colspan'};
+		$prior_cell_index++;
+	    }
 	}
+
     }
+
     #
     # Now we're ready to build up our cell:
 
     my $cell = {
 	rowspan    => 1,
 	colspan    => 1,
+	start_col  => $last_coord,
 	contents   => $text
     };
     
@@ -618,9 +636,90 @@
 	    $cell->{$key} = $config->{$key};
 	}
     }
+    $current_row->{'cell_width'} += $cell->{'colspan'};
+
     push(@$current_cells, $cell);
 }
 
+=pod
+
+=head2 generate
+
+Call this when the structures for the table have been built.
+This will generate and return the table object that can be used
+to generate the table.  Returning the table object allows for
+a certain amount of testing to be done on the generated table.
+The caller can then ask the table object to generate LaTeX.
+
+=cut
+sub generate {
+    my ($this) = @_;
+
+    my $table = LaTeX::Table->new();
+
+    # Build up the data:
+
+    my @data;
+    my $rows      = $this->{'rows'};
+    my $row_count = scalar(@$rows);
+    my $inner_border = $this->{'inner_border'};
+    my $outer_border = $this->{'outer_border'};
+    my $column_count = $this->{'column_count'};
+
+    for (my $row = 0; $row < $row_count; $row++) {
+	my @row;
+	my $cells      = $rows->[$row]->{'cells'};
+	my $cell_count = scalar(@$cells);
+	my $startcol   = 1;
+	my @underlines;		# Array of \cline cells if cellborder on.
+
+	for (my $cell  = 0; $cell < $cell_count; $cell++) {
+	    my $contents = $cells->[$cell]->{'contents'};
+	    my $cspan    = $cells->[$cell]->{'colspan'};
+	    my $nextcol  = $startcol + $cspan;
+	    if ($cspan > 1) {
+		$contents = '\multicolumn{'.$cspan.'}{|l|}{'.$contents.'}';
+	    }
+	    if ($inner_border && ($cells->[$cell]->{'rowspan'} == 1)) {
+		my $lastcol = $nextcol -1;
+		push(@underlines, "\\cline{$startcol-$lastcol}");
+	    }
+	    $startcol = $nextcol;
+	    # Rowspans should take care of themselves.
+	    
+
+	    push(@row, $contents);
+
+	}
+	push(@data, \@row);
+	if ($inner_border) {
+	    for (my $i =0; $i < scalar(@underlines); $i++) {
+		push(@data, [$underlines[$i]]);
+	    }
+	}
+
+    }
+    $table->set_data(\@data);
+    
+    my $coldef = "";
+    if ($outer_border || $inner_border) {
+	$coldef .= '|';
+    }
+    for (my $i =0; $i < $column_count; $i++) {
+	$coldef .= 'l';
+	if ($inner_border || 
+	    ($outer_border && ($i == $column_count-1))) {
+	    $coldef .= '|';
+	}
+    }
+    $table->{'coldef'} = $coldef;
+
+    # Return the table:
+
+    return $table;
+
+}
+#----------------------------------------------------------------------------
 # The following methods allow for testability.
 
 
Index: loncom/xml/lontable.test
diff -u loncom/xml/lontable.test:1.2 loncom/xml/lontable.test:1.3
--- loncom/xml/lontable.test:1.2	Tue Dec  9 11:50:08 2008
+++ loncom/xml/lontable.test	Tue Dec 23 11:49:32 2008
@@ -3,7 +3,7 @@
 # The LearningOnline Network with CAPA
 #  Generating TeX tables.
 #
-# $Id: lontable.test,v 1.2 2008/12/09 11:50:08 foxr Exp $
+# $Id: lontable.test,v 1.3 2008/12/23 11:49:32 foxr Exp $
 # 
 #
 # Copyright Michigan State University Board of Trustees
@@ -219,7 +219,7 @@
 #  +----------+---------+----+-----------+---------+
 
 
-$testobject = new Apache::lontable();
+$testobject = new Apache::lontable({theme => "Dresden"});
 
 $testobject->start_row();
 $testobject->add_cell('2 cols 3 rows', {rowspan => 3, colspan => 2});
@@ -264,6 +264,7 @@
 
 $row   = $testobject->get_row(1);
 $cells = $row->{'cells'};
+
 ok(scalar(@$cells) == 3,  ' 3 cell hashes in row 1');
 ok($cells->[0]->{'rowspan'} == 2, '2,1 rowspan carried from above');
 ok($cells->[0]->{'colspan'} == 2, '2,1 colspan carried from above');
@@ -305,6 +306,7 @@
 
 ok($cells->[1]->{'rowspan'} == 1, '4,2 rowspan');
 ok($cells->[1]->{'colspan'} == 1, '4,2 colspan');
+my $contents = $cells->[1]->{'contents'};
 ok($cells->[1]->{'contents'} eq 'ordinary cell', '4,2, contents');
 
 ok($cells->[2]->{'rowspan'} == 1, "4,3 rowspan carried down");
@@ -312,5 +314,14 @@
 ok($cells->[2]->{'contents'} eq '', '4,3 contents empty');
 
 ok($cells->[3]->{'rowspan'} == 1, "4,4 rowspan");
-ok($cells->[3]->{'colspan'} == 2, '4,4 colspan');
+ok($cells->[3]->{'colspan'} == 1, '4,4 colspan');
 ok($cells->[3]->{'contents'} eq 'ordinary cell', '4,4 contents');
+
+
+
+my $table = $testobject->generate();
+$table->set_filename('table.tex');
+$table->generate();
+
+
+

--foxr1230032973--