--- loncom/xml/londefdef.pm 2007/01/22 11:28:08 1.353 +++ loncom/xml/londefdef.pm 2007/03/13 13:35:39 1.358 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Tags Default Definition Module # -# $Id: londefdef.pm,v 1.353 2007/01/22 11:28:08 foxr Exp $ +# $Id: londefdef.pm,v 1.358 2007/03/13 13:35:39 foxr Exp $ # # # Copyright Michigan State University Board of Trustees @@ -1227,11 +1227,10 @@ sub start_br { } if ($signal eq 1) { $currentstring .= ' \vskip 0 mm '; - } elsif ($$tagstack[-2] ne 'sub' && $$tagstack[-2] ne 'sup') { + } else { $currentstring .= '\strut \\\\ \strut '; - } else { # Honor break in simple - $currentstring .= '}} \strut \\\\ \strut \ensuremath{^{'; } + } return $currentstring; } @@ -1413,7 +1412,7 @@ sub start_sub { if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { - $currentstring .= '\ensuremath{_{'; + $currentstring .= '\raisebox{-\smallskipamount}{\scriptsize{'; } return $currentstring; } @@ -1436,7 +1435,7 @@ sub start_sup { if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { - $currentstring .= '\ensuremath{^{'; + $currentstring .= '\raisebox{\smallskipamount}{\scriptsize{'; } return $currentstring; } @@ -1926,7 +1925,7 @@ sub start_table { if ($#Apache::londefdef::table==0) { $textwidth=&recalc($env{'form.textwidth'}); #result is always in mm $textwidth=~/(\d+\.?\d*)/; - $textwidth=0.95*$1; #accounts "internal" LaTeX space for table frame + $textwidth=0.85*$1; #accounts "internal" LaTeX space for table frame } else { if ($Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]=~/\d/) { #the maximum width of nested table is determined by LATeX width of parent cell @@ -1994,12 +1993,6 @@ sub start_table { $Apache::londefdef::table[-1]{'minlen'}=[]; $Apache::londefdef::table[-1]{'content'}=[]; $Apache::londefdef::table[-1]{'align'}=[]; - if (&is_inside_of($tagstack, 'sup')) { - $currentstring .= '}} \\\\ \ensuremath{^{ '; - } - if (&is_inside_of($tagstack, 'sub')) { - $currentstring .= '}} \\\\ \ensuremath{_{ '; - } $currentstring.=' \keephidden{NEW TABLE ENTRY}'; @@ -2035,10 +2028,14 @@ sub end_table { $available_space=$available_space-$Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]; } } + #boundaries for contents columns my @min_len=();#columns can not be narrower my @max_len=();#maximum length of column - for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) { + my $avg_max; + my $avg_min; + my $counter_cols = $Apache::londefdef::table[-1]{'counter_columns'}; + for (my $jn=0;$jn<=$counter_cols; $jn++) { my ($localmin,$localmax)=(0,0); for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { if ($localmin<$Apache::londefdef::table[-1]{'minlen'}[$in][$jn]) { @@ -2050,8 +2047,28 @@ sub end_table { } push @min_len, $localmin; push @max_len, $localmax; + $avg_max = $localmax + $avg_max; + $avg_min = $localmin + $avg_min; } - for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) { + # Does not really matter what the average max/min are if there are no cols. + # and this prevents div 0 in that case. + + if ($counter_cols != 0) { + $avg_max = $avg_max/$counter_cols; + $avg_min = $avg_min/$counter_cols; + } + + + # I don't think the below is needed.. but just in case: + + if ($avg_min > $avg_max) { + my $temp = $avg_min; + $avg_min = $avg_max; + $avg_max = $temp; + } + + + for (my $jn=0;$jn<=$counter_cols;$jn++) { my $localmin=0,; for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { if ($localmin<$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn]) { @@ -2070,6 +2087,16 @@ sub end_table { $min_len[$jn]=0; $max_len[$jn]=0; } + # Spans seem to be really bothered by max/min = 0. So if we have one + # make it an average joe max/min. + + if ($max_len[$jn] == 0) { + $max_len[$jn] = $avg_max; + } + if ($min_len[$jn] == 0) { + $min_len[$jn] = $avg_min; + } + } #final adjustment of column width my @fwidth=@{$Apache::londefdef::table[-1]{'TeXlen'}[0]};#final width array @@ -2138,6 +2165,7 @@ sub end_table { $fwidth[$jn]=$max_len[$jn]; $acsessive=$acsessive+$adjust[$jn]-$max_len[$jn]; $adjust[$jn]=0; + } } if ($acsessive>0) { @@ -2192,12 +2220,23 @@ sub end_table { $Apache::londefdef::table[-1]{'content'}=\@cleaned_table; @fwidth=@cleaned_header; } + # At this time we must be sure the table does not overhang the total width + # this can happen due to our 'average width' adjustment. + # Total the column widths and see if they are larger than the avail width; + # If so scale them down in proportion to their percentage of total width. + + my $current_total_width = 0; + for (my $col = 0; $col < $#fwidth; $col++) { + $current_total_width = $current_total_width + $fwidth[$col]; + } + #construct header of the table my $header_of_table = '{'.$Apache::londefdef::table[-1]{'vvinc'}; for (my $in=0;$in<=$#fwidth;$in++) { $header_of_table.='p{'.$fwidth[$in].' mm}'.$Apache::londefdef::table[-1]{'vvinc'}; } $header_of_table .= '}'; + #fill the table for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { my $have_rowspan = 0; @@ -2208,17 +2247,18 @@ sub end_table { # single rowspan, columspan and combined row/colspans will # work correctly. LaTeX is delicate here. # RF. - + # Start a rowspan if necessary: - + + my $primary_col_width = $fwidth[$jn]; # Width of primary column. my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn]; my $colspan = $Apache::londefdef::table[-1]{'colspan'}[$in][$jn]; # # Do the appropriate magic if this has a colspan # - + + my $spanwidth = 0; if ($colspan > 1) { - my $spanwidth = 0; for (my $spancol = $jn; $spancol < $jn + $colspan; $spancol++) { $spanwidth += $fwidth[$spancol]; } @@ -2233,7 +2273,9 @@ sub end_table { else { $output .= "{|p{$spanwidth mm}|}{"; } - + + } else { + $spanwidth = $primary_col_width; # If no span width will be just colwidth } # Rowspan... if colspan is 1, and there's an alignment we'll need @@ -2253,13 +2295,17 @@ sub end_table { } } $have_rowspan++; - $output .= '\multirow{'.$rowspan.'}[0]{*}{'; + if ($multirow_aligned) { + $output .= '\multirow{'.$rowspan.'}[0]{*}{'; + } else { + $output .= '\multirow{'.$rowspan."}[0]{$spanwidth mm}{"; + } $Apache::londefdef::table[-1]{'content'}[$in][$jn] =~ s{^\s*\\par\s*}{}; $Apache::londefdef::table[-1]{'content'}[$in][$jn] =~ s{\s*\\vskip\s*0pt\s*$}{}; - + # # If we did not throw in a multicolumn to align, then add # an extra { @@ -2273,7 +2319,7 @@ sub end_table { if (($rowspan eq '^') || ($rowspan eq '_')) { $have_rowspan++; } - #-------------------------------------------------------------- + #-------------------------------------------------------------- # For right and center alignment of single cells. @@ -2518,9 +2564,11 @@ sub end_td_tex { my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); if (defined $TeXwidth) { - push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; - push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; - push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + for (my $c = 0; $c < $colspan; $c++) { + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + } } else { if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) { my $garbage_data=$data; @@ -2536,10 +2584,12 @@ sub end_td_tex { if ($fwidth<$current_length) {$fwidth=$current_length;} $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//; } - push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; - push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth; - push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; - push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + for (my $c = 0; $c < $colspan; $c++) { + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + } } elsif ($data=~/\\parbox\{\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*\s*\}/ or $data=~/\\epsfxsize\s*=\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*/) { my $garbage_data=$data; my $fwidth=0; @@ -2555,10 +2605,12 @@ sub end_td_tex { if ($fwidth<$1) {$fwidth=$1;} $garbage_data=~s/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//; } - push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; - push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth; - push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; - push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + for (my $c = 0; $c < $colspan; $c++) { + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + } $data=~s/\\\\\s*$//; } else { $data=~s/^\s+(\S.*)/$1/; @@ -2586,10 +2638,12 @@ sub end_td_tex { if ($min_length<$lengthword) {$min_length=$lengthword;} } } - push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; - push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; - push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length; - push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length; + for (my $c = 0; $c < $colspan; $c++) { + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length; + } } } # Substitute all of the tables nested in this cell in their appropriate places. @@ -2879,9 +2933,13 @@ sub start_img { $size=~s/,$/]/; $currentstring .= '\graphicspath{{'.$path.'}}' .'\includegraphics'.$size.'{'.$file.'} '; - $currentstring = &align_latex_image($align, $latex_rendering, - $currentstring, - $width_param, $height_param); + my $closure; + ($currentstring, $closure) = &align_latex_image($align, + $latex_rendering, + $currentstring, + $width_param, + $height_param); + $currentstring .= $closure; } else { &Apache::lonxml::debug("$src does not exist"); @@ -4360,11 +4418,15 @@ sub LATEX_length { # latex_rendering - rendering hint for latex. # image - The LaTeX needed to insert the image itsef. # width,height - dimensions of the image. +# Returns: +# The 1/2 wrapped image and the stuff required to close the +# wrappage. This allows e.g. randomlabel to insert more stuff +# into the closure. # sub align_latex_image { my ($align, $latex_rendering, $image, $width, $height) = @_; - my $currentstring; # The result. - + my $currentstring; # The 1/2 wrapped image. + my $closure; # The closure of the wrappage. # If there's an alignment specification we need to honor it here. # For the horizontal alignments, we will also honor the # value of the latex specfication. The default is parbox, @@ -4373,40 +4435,52 @@ sub align_latex_image { # Even though we set a default alignment value, the user # could have given us an illegal value. In that case we # just use the default alignment of bottom.. + $currentstring = "\n% figurewrapping \n"; if ($align eq "top") { - $currentstring = '\raisebox{-'.$height.'mm}{'.$image.'}'; + $currentstring .= '\raisebox{-'.$height.'mm}{'.$image; + $closure = '}'; } elsif (($align eq "center") || ($align eq "middle")) { # Being kind my $offset = $height/2; - $currentstring = '\raisebox{-'.$offset.'mm}{'.$image.'}'; + $currentstring .= '\raisebox{-'.$offset.'mm}{'.$image; + $closure = '}'; } elsif ($align eq "left") { if ($latex_rendering eq "parpic") { - $currentstring = '\parpic[l]{'.$image.'}'; + $currentstring .= '\parpic[l]{'.$image; + $closure = '}'; } elsif ($latex_rendering eq "parbox") { - $currentstring = '\begin{minipage}[l]{'.$width.'mm}' - .$image.'\end{minipage}'; + $currentstring .= '\begin{minipage}[l]{'.$width.'mm}' + .$image; + $closure = '\end{minipage}'; } elsif ($latex_rendering eq "wrapfigure" || $latex_rendering ne 'none') { # wrapfig render - $currentstring = + $currentstring .= '\begin{wrapfigure}{l}{'.$width.'mm}' - .'\scalebox{1.0}{'.$image.'}\end{wrapfigure}'; + .'\scalebox{1.0}{'.$image; + $closure = '}\end{wrapfigure}'; } } elsif ($align eq "right") { if ($latex_rendering eq "parpic") { - $currentstring = '\parpic[r]{'.$image.'}'; + $currentstring .= '\parpic[r]{'.$image; + $closure = '}'; } elsif ($latex_rendering eq "parbox") { - $currentstring = '\begin{minipage}[r]{'.$width.'mm}' - .$image.'\end{minipage}'; + $currentstring .= '\begin{minipage}[r]{'.$width.'mm}' + .$image; + $closure = '\end{minipage}'; } elsif ($latex_rendering eq "wrapfigure" || $latex_rendering ne 'none') { # wrapfig render - $currentstring = + $currentstring .= '\begin{wrapfigure}{r}{'.$width.'mm}' - .'\scalebox{1.0}{'.$image.'}\end{wrapfigure}'; + .'\scalebox{1.0}{'.$image; + $closure = '}\end{wrapfigure}'; } } else { # Bottom is also default. # $currentstring = '\raisebox{'.$height.'mm}{'.$image.'}'; - $currentstring = $image; + $currentstring .= "{$image"; + $closure = '}'; } - return $currentstring; + $currentstring .= "\n% end wrappage\n"; + $closure = "\n% Begin closure\n".$closure."\n% End closure\n"; + return ($currentstring, $closure); } # is_inside_of $tagstack $tag