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>