[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--