| 1 | #!/usr/local/bin/webwork-perl |
|
|
| 2 | ########### |
1 | ########### |
| 3 | #use Carp; |
2 | #use Carp; |
| 4 | |
3 | |
| 5 | =head1 NAME |
4 | =head1 NAME |
| 6 | |
5 | |
| … | |
… | |
| 144 | an individual problem with optional arguments such as left=>"|", or |
143 | an individual problem with optional arguments such as left=>"|", or |
| 145 | right=>"]". |
144 | right=>"]". |
| 146 | |
145 | |
| 147 | You can specify an optional argument of 'top_labels'=> ['a', 'b', 'c']. |
146 | You can specify an optional argument of 'top_labels'=> ['a', 'b', 'c']. |
| 148 | These are placed above the columns of the matrix (as is typical for |
147 | These are placed above the columns of the matrix (as is typical for |
| 149 | linear programming tableaux, for example. The entries will be typeset |
148 | linear programming tableau, for example). The entries will be typeset |
| 150 | in math mode. |
149 | in math mode. |
| 151 | |
150 | |
| 152 | Top labels require a bit of care. For image modes, they look better |
151 | Top labels require a bit of care. For image modes, they look better |
| 153 | with display_matrix_mm where it is all one big image, but they work with |
152 | with display_matrix_mm where it is all one big image, but they work with |
| 154 | display_matrix. With tth, you pretty much have to use display_matrix |
153 | display_matrix. With tth, you pretty much have to use display_matrix |
| … | |
… | |
| 179 | 'force_tex' => 0, |
178 | 'force_tex' => 0, |
| 180 | 'left' => substr($styleParams,0,1), |
179 | 'left' => substr($styleParams,0,1), |
| 181 | 'right' => substr($styleParams,2,1), |
180 | 'right' => substr($styleParams,2,1), |
| 182 | 'midrule' => substr($styleParams,1,1), |
181 | 'midrule' => substr($styleParams,1,1), |
| 183 | 'top_labels' => 0, |
182 | 'top_labels' => 0, |
| 184 | 'box'=>0, # pair location of boxed element |
183 | 'box'=>[-1,-1], # pair location of boxed element |
| 185 | 'allow_unknown_options'=> 1); |
184 | 'allow_unknown_options'=> 1, |
|
|
185 | 'num_format' => "%.0f", |
|
|
186 | ); |
| 186 | |
187 | |
| 187 | my ($numRows, $numCols, @myRows); |
188 | my ($numRows, $numCols, @myRows); |
| 188 | |
189 | |
| 189 | if (ref($ra_matrix) eq 'Matrix' ) { |
190 | if (ref($ra_matrix) eq 'Matrix' ) { |
| 190 | ($numRows, $numCols) = $ra_matrix->dim(); |
191 | ($numRows, $numCols) = $ra_matrix->dim(); |
| … | |
… | |
| 207 | $numCols= scalar(@arow); #number of columns in table |
208 | $numCols= scalar(@arow); #number of columns in table |
| 208 | last; |
209 | last; |
| 209 | } |
210 | } |
| 210 | } |
211 | } |
| 211 | } |
212 | } |
| 212 | my ($boxrow,$boxcol) = (-1,-1); #default to impossible values so nothing is boxed |
|
|
| 213 | if($opts{'box'}) { |
|
|
| 214 | $boxrow = $opts{'box'}->[0]; |
|
|
| 215 | $boxcol = $opts{'box'}->[1]; |
|
|
| 216 | } |
|
|
| 217 | |
|
|
| 218 | |
213 | |
| 219 | my $out; |
214 | my $out; |
| 220 | my $j; |
215 | my $j; |
| 221 | my $alignString=''; # alignment as a string for dvi/pdf |
216 | my $alignString=''; # alignment as a string for dvi/pdf |
| 222 | my $alignList; # alignment as a list |
217 | my $alignList; # alignment as a list |
| … | |
… | |
| 240 | $opts{'top_labels'} = 0; |
235 | $opts{'top_labels'} = 0; |
| 241 | } |
236 | } |
| 242 | |
237 | |
| 243 | $out .= dm_begin_matrix($alignString, %opts); |
238 | $out .= dm_begin_matrix($alignString, %opts); |
| 244 | # column labels for linear programming |
239 | # column labels for linear programming |
| 245 | $out .= dm_special_tops(%opts) if ($opts{'top_labels'}); |
240 | $out .= dm_special_tops(%opts, 'alignList'=>$alignList) if ($opts{'top_labels'}); |
| 246 | $out .= dm_mat_left($numRows, %opts); |
241 | $out .= dm_mat_left($numRows, %opts); |
|
|
242 | my $cnt = 1; # we count rows in in case an element is boxed |
| 247 | # vertical lines put in with first row |
243 | # vertical lines put in with first row |
| 248 | $j = shift @myRows; |
244 | $j = shift @myRows; |
| 249 | $out .= dm_mat_row($j, $alignList, %opts, 'isfirst'=>$numRows); |
245 | $out .= dm_mat_row($j, $alignList, %opts, 'isfirst'=>$numRows, |
|
|
246 | 'cnt' => $cnt); |
|
|
247 | $cnt++ unless ($j eq 'hline'); |
| 250 | $out .= dm_mat_right($numRows, %opts); |
248 | $out .= dm_mat_right($numRows, %opts); |
| 251 | for $j (@myRows) { |
249 | for $j (@myRows) { |
| 252 | $out .= dm_mat_row($j, $alignList, %opts, 'isfirst'=>0); |
250 | $out .= dm_mat_row($j, $alignList, %opts, 'isfirst'=>0, |
|
|
251 | 'cnt' => $cnt); |
|
|
252 | $cnt++ unless ($j eq 'hline'); |
| 253 | } |
253 | } |
| 254 | $out .= dm_end_matrix(%opts); |
254 | $out .= dm_end_matrix(%opts); |
| 255 | $out; |
255 | $out; |
| 256 | } |
256 | } |
| 257 | |
257 | |
| … | |
… | |
| 288 | } |
288 | } |
| 289 | |
289 | |
| 290 | sub dm_special_tops { |
290 | sub dm_special_tops { |
| 291 | my %opts = @_; |
291 | my %opts = @_; |
| 292 | my @top_labels = @{$opts{'top_labels'}}; |
292 | my @top_labels = @{$opts{'top_labels'}}; |
| 293 | my $ncols = scalar(@top_labels); |
|
|
| 294 | my $out = ''; |
293 | my $out = ''; |
|
|
294 | my @alignList = @{$opts{'alignList'}}; |
| 295 | my $j; |
295 | my ($j, $k); |
| 296 | my ($brh, $erh) = ("",""); # Start and end raw html |
296 | my ($brh, $erh) = ("",""); # Start and end raw html |
| 297 | if($main::displayMode eq 'Latex2HTML') { |
297 | if($main::displayMode eq 'Latex2HTML') { |
| 298 | $brh = "\\begin{rawhtml}"; |
298 | $brh = "\\begin{rawhtml}"; |
| 299 | $erh = "\\end{rawhtml}"; |
299 | $erh = "\\end{rawhtml}"; |
| 300 | } |
300 | } |
| … | |
… | |
| 310 | or $main::displayMode eq 'HTML_dpng' |
310 | or $main::displayMode eq 'HTML_dpng' |
| 311 | or $main::displayMode eq 'HTML_img' |
311 | or $main::displayMode eq 'HTML_img' |
| 312 | or $main::displayMode eq 'Latex2HTML') { |
312 | or $main::displayMode eq 'Latex2HTML') { |
| 313 | $out .= "$brh<tr><td>$erh"; # Skip a column for the left brace |
313 | $out .= "$brh<tr><td>$erh"; # Skip a column for the left brace |
| 314 | for $j (@top_labels) { |
314 | for $j (@top_labels) { |
|
|
315 | $k = shift @alignList; |
|
|
316 | while(defined($k) and ($k !~ /[lrc]/)) { |
|
|
317 | $out .= "$brh<td></td>$erh"; |
|
|
318 | $k = shift @alignList; |
|
|
319 | } |
| 315 | $out .= "$brh<td>$erh". ' \('.$j.'\)'."$brh</td>$erh"; |
320 | $out .= "$brh<td align=\"center\">$erh". ' \('.$j.'\)'."$brh</td>$erh"; |
| 316 | } |
321 | } |
|
|
322 | $out .= "<td></td>"; |
| 317 | } else { |
323 | } else { |
| 318 | $out = "Error: dm_begin_matrix: Unknown displayMode: $main::displayMode.\n"; |
324 | $out = "Error: dm_begin_matrix: Unknown displayMode: $main::displayMode.\n"; |
| 319 | } |
325 | } |
| 320 | return $out; |
326 | return $out; |
| 321 | } |
327 | } |
| … | |
… | |
| 386 | my %opts = @_; |
392 | my %opts = @_; |
| 387 | |
393 | |
| 388 | my $out = ""; |
394 | my $out = ""; |
| 389 | if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) { |
395 | if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) { |
| 390 | $out .= "\\end{array}\\right$opts{right}"; |
396 | $out .= "\\end{array}\\right$opts{right}"; |
| 391 | $out .= $opts{'force_tex'} ? '' : "\\) "; |
|
|
| 392 | if($opts{'top_labels'}) { |
397 | if($opts{'top_labels'}) { |
| 393 | $out .= '}} \dimen3=\ht3 \advance\dimen3 by 3ex \ht3=\dimen3'."\n". |
398 | $out .= '}} \dimen3=\ht3 \advance\dimen3 by 3ex \ht3=\dimen3'."\n". |
| 394 | '\box3\endgroup'; |
399 | '\box3\endgroup'; |
| 395 | } |
400 | } |
|
|
401 | $out .= $opts{'force_tex'} ? '' : "\\) "; |
| 396 | } |
402 | } |
| 397 | elsif ($main::displayMode eq 'Latex2HTML') { |
403 | elsif ($main::displayMode eq 'Latex2HTML') { |
| 398 | $out .= "\n\\begin{rawhtml} </TABLE >\n\\end{rawhtml}"; |
404 | $out .= "\n\\begin{rawhtml} </TABLE >\n\\end{rawhtml}"; |
| 399 | } |
405 | } |
| 400 | elsif ($main::displayMode eq 'HTML' or $main::displayMode eq 'HTML_tth' |
406 | elsif ($main::displayMode eq 'HTML' or $main::displayMode eq 'HTML_tth' |
| … | |
… | |
| 488 | |
494 | |
| 489 | my @elements = @{$elements}; |
495 | my @elements = @{$elements}; |
| 490 | my $out = ""; |
496 | my $out = ""; |
| 491 | my ($brh, $erh) = ("",""); # Start and end raw html |
497 | my ($brh, $erh) = ("",""); # Start and end raw html |
| 492 | my $element; |
498 | my $element; |
|
|
499 | my $colcount=0; |
| 493 | if($main::displayMode eq 'Latex2HTML') { |
500 | if($main::displayMode eq 'Latex2HTML') { |
| 494 | $brh = "\\begin{rawhtml}"; |
501 | $brh = "\\begin{rawhtml}"; |
| 495 | $erh = "\\end{rawhtml}"; |
502 | $erh = "\\end{rawhtml}"; |
| 496 | } |
503 | } |
| 497 | if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) { |
504 | if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) { |
| 498 | while (@elements) { |
505 | while (@elements) { |
|
|
506 | $colcount++; |
|
|
507 | $out .= '\fbox{' if ($colcount == $opts{'box'}->[1] and $opts{'cnt'} == $opts{'box'}->[0]); |
| 499 | $element= shift(@elements); |
508 | $element= shift(@elements); |
| 500 | if(ref($element) eq 'Fraction') { |
509 | if(ref($element) eq 'Fraction') { |
| 501 | $element= $element->print_inline(); |
510 | $element= $element->print_inline(); |
| 502 | } |
511 | } |
|
|
512 | $out .= '\\mbox{'."$element".'}'; |
|
|
513 | $out .= '}' if ($colcount == $opts{'box'}->[1] and $opts{'cnt'} == $opts{'box'}->[0]); |
| 503 | $out .= "$element &"; |
514 | $out .= " &"; |
| 504 | } |
515 | } |
| 505 | chop($out); # remove last & |
516 | chop($out); # remove last & |
| 506 | $out .= "\\cr \n"; |
517 | $out .= "\\cr \n"; |
| 507 | # carriage returns must be added manually for tex |
518 | # carriage returns must be added manually for tex |
| 508 | } elsif ($main::displayMode eq 'HTML' or $main::displayMode eq 'HTML_tth' |
519 | } elsif ($main::displayMode eq 'HTML' or $main::displayMode eq 'HTML_tth' |
| … | |
… | |
| 528 | } |
539 | } |
| 529 | } else { |
540 | } else { |
| 530 | if($myalign eq "c") { $myalign = "center";} |
541 | if($myalign eq "c") { $myalign = "center";} |
| 531 | if($myalign eq "l") { $myalign = "left";} |
542 | if($myalign eq "l") { $myalign = "left";} |
| 532 | if($myalign eq "r") { $myalign = "right";} |
543 | if($myalign eq "r") { $myalign = "right";} |
|
|
544 | $colcount++; |
|
|
545 | $out .= '\fbox{' if ($colcount == $opts{'box'}->[1] and $opts{'cnt'} == $opts{'box'}->[0]); |
| 533 | $element= shift(@elements); |
546 | $element= shift(@elements); |
| 534 | if (ref($element) eq 'Fraction') { |
547 | if (ref($element) eq 'Fraction') { |
| 535 | $element= $element->print_inline(); |
548 | $element= $element->print_inline(); |
| 536 | } |
549 | #}elsif( $element =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/ and $element != sprintf($opts{'num_format'},$element) and $element - sprintf($opts{'num_format'},$element) < $main::functZeroLevelTolDefault){ |
|
|
550 | # $element = sprintf($opts{'num_format'},$element); |
|
|
551 | # $element = 0 if abs($element) < $main::functZeroLevelTolDefault; |
|
|
552 | } |
| 537 | $out .= "$brh<TD nowrap=\"nowrap\" align=\"$myalign\">$erh" . |
553 | $out .= "$brh<TD nowrap=\"nowrap\" align=\"$myalign\">$erh"; |
| 538 | $element . "$brh</TD>$erh"; |
554 | $out .= '<table border="1"><tr><td>' if ($colcount == $opts{'box'}->[1] and $opts{'cnt'} == $opts{'box'}->[0]); |
|
|
555 | $out .= $element; |
|
|
556 | $out .= '</td></tr></table>' if ($colcount == $opts{'box'}->[1] and $opts{'cnt'} == $opts{'box'}->[0]); |
|
|
557 | $out .= "$brh</TD>$erh"; |
| 539 | } |
558 | } |
| 540 | } |
559 | } |
| 541 | if(not $opts{'isfirst'}) {$out .="$brh</TR>$erh\n";} |
560 | if(not $opts{'isfirst'}) {$out .="$brh</TR>$erh\n";} |
| 542 | } |
561 | } |
| 543 | else { |
562 | else { |