--- loncom/xml/londefdef.pm 2007/02/01 10:49:27 1.354 +++ loncom/xml/londefdef.pm 2007/06/05 22:37:58 1.366 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Tags Default Definition Module # -# $Id: londefdef.pm,v 1.354 2007/02/01 10:49:27 foxr Exp $ +# $Id: londefdef.pm,v 1.366 2007/06/05 22:37:58 albertel Exp $ # # # Copyright Michigan State University Board of Trustees @@ -128,6 +128,7 @@ sub start_m { #&Apache::lonxml::debug("M is ends with:$currentstring:"); $Apache::lonxml::post_evaluate=0; } elsif ($target eq 'tex') { + $currentstring = $inside; my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval); if ($eval eq 'on') { @@ -135,11 +136,13 @@ sub start_m { } if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';} # detect simple math mode entry exits, and convert them - # to use \ensuremath - if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) { - $currentstring=~s/^(\s*)\$/$1/; - $currentstring=~s/\$(\s*)$/$1/; - $currentstring='\ensuremath{'.$currentstring.'}'; + # to use \ensuremath ... unless there's a \verb inside. + if (! ($currentstring=~/\\verb/)) { + if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) { + $currentstring=~s/^(\s*)\$/$1/; + $currentstring=~s/\$(\s*)$/$1/; + $currentstring='\ensuremath{'.$currentstring.'}'; + } } $Apache::lonxml::post_evaluate=0; } @@ -513,6 +516,17 @@ sub end_accessrule { return $currentstring; } +sub generate_css_links { + my $links; + my $css_href = &Apache::lonnet::EXT('resource.0.cssfile'); + if ($css_href =~ /\S/) { + &Apache::lonxml::extlink($css_href); + $links .= + ''; + } + return $links; +} + #-- tag (end tag required) sub start_body { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; @@ -527,9 +541,13 @@ sub start_body { if (&is_inside_of($tagstack, "head")) { &end_head(@_); } + + my $extra_head = &generate_css_links(); + $currentstring = &Apache::loncommon::start_page($Apache::londefdef::title, - $Apache::londefdef::head, + $Apache::londefdef::head + .$extra_head, {'add_entries' => $token->[2], 'no_title' => 1, 'force_register' => 1}); @@ -1227,11 +1245,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 +1430,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 +1453,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; } @@ -1459,6 +1476,27 @@ sub start_hr { if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { + + #
can't be inside of thank you LaTeX. + # + my $restart_sub = 0; + my $restart_sup = 0; + + # Since and are simple tags it's ok to turn off/on + # using the start_ stop_ functions.. those tags only care about + # $target. + + if (&is_inside_of($tagstack, "sub")) { + $restart_sub = 1; + $currentstring .= &end_sub($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + if (&is_inside_of($tagstack, "sup")) { + $restart_sup = 1; + $currentstring .= &end_sup($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + my $LaTeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); if (defined $LaTeXwidth) { if ($LaTeXwidth=~/^%/) { @@ -1479,6 +1517,16 @@ sub start_hr { } $currentstring .= ' \vskip 0 mm \noindent\makebox['.$LaTeXwidth.']{'.$pre.'\makebox['. $LaTeXwidth.'][b]{\hrulefill}'.$post.'}\vskip 0 mm '; + # Turn stuff back on that we can't be inside of. + + if ($restart_sub) { + $currentstring .= &start_sub($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + if ($restart_sup) { + $currentstring .= &start_sup($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } } return $currentstring; } @@ -1576,7 +1624,11 @@ sub end_a { &Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1); if ($href =~ /\S/) { $href =~ s/([^\\])%/$1\\\%/g; - $currentstring .= ' ({\tt URI:'.&Apache::lonxml::latex_special_symbols($href).'})'; + # Substitute special symbols... and allow line breaks at each / + # + $href = &Apache::lonxml::latex_special_symbols($href); + $href =~ s/\//\/\\-/g; # Map / to /\- to allow hyphenation. + $currentstring .= ' ({\tt URI:'.$href.'})'; } elsif ($name =~ /\S/) { $currentstring .= ' ({\tt Anchor:'.&Apache::lonxml::latex_special_symbols($name).'})'; } else { @@ -1926,7 +1978,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 @@ -1952,11 +2004,11 @@ sub start_table { } else { $TeXwidth = $textwidth; } - } else { - $Apache::londefdef::table[-1]{'forcedtablewidth'} = 1; } + # if the width is specified as a % it is converted to an absolute width. + # otherwise.. just plugged right in the hash + if ($TeXwidth=~/%/) { - $Apache::londefdef::table[-1]{'percent'}=1; $TeXwidth=~/(\d+)/; $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100; } else { @@ -1967,7 +2019,6 @@ sub start_table { if ($Apache::londefdef::table[-1]{'width'} > $textwidth) { $Apache::londefdef::table[-1]{'width'} = $textwidth; } - #table's border my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval); my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0); @@ -1994,12 +2045,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 +2080,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 +2099,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 +2139,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 @@ -2080,6 +2159,7 @@ sub end_table { $space_neeeded=$space_neeeded+$max_len[$jn]; } if ($space_neeeded<=$available_space) { + for (my $jn=0;$jn<=$#max_len;$jn++) { if ($fwidth[$jn]==0) { $fwidth[$jn]=$max_len[$jn]; @@ -2138,6 +2218,7 @@ sub end_table { $fwidth[$jn]=$max_len[$jn]; $acsessive=$acsessive+$adjust[$jn]-$max_len[$jn]; $adjust[$jn]=0; + } } if ($acsessive>0) { @@ -2162,16 +2243,16 @@ sub end_table { } } } - #use all available width if it is defined in % or as TeXwidth - if (($Apache::londefdef::table[-1]{'percent'}==1) || ($Apache::londefdef::table[-1]{'forcetablewidth'}==1)) { - my $current=0; - for (my $i=0;$i<=$#fwidth;$i++) { - $current+=$fwidth[$i]; - } - my $coef=$Apache::londefdef::table[-1]{'width'}/$current; - for (my $i=0;$i<=$#fwidth;$i++) { - $fwidth[$i]*=$coef; - } + # use all available width or specified width as if not specified, + # the specified width gets defaulted to the available width. + + my $current=0; + for (my $i=0;$i<=$#fwidth;$i++) { + $current+=$fwidth[$i]; + } + my $coef=$Apache::londefdef::table[-1]{'width'}/$current; + for (my $i=0;$i<=$#fwidth;$i++) { + $fwidth[$i]*=$coef; } #removing of empty columns if allowed my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0); @@ -2192,12 +2273,15 @@ sub end_table { $Apache::londefdef::table[-1]{'content'}=\@cleaned_table; @fwidth=@cleaned_header; } + + #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 +2292,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 +2318,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 +2340,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 +2364,7 @@ sub end_table { if (($rowspan eq '^') || ($rowspan eq '_')) { $have_rowspan++; } - #-------------------------------------------------------------- + #-------------------------------------------------------------- # For right and center alignment of single cells. @@ -2518,9 +2609,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 +2629,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 +2650,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 +2683,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. @@ -3010,6 +3109,29 @@ sub start_applet { $currentstring='[APPLET: '.$alttag.']'; } } elsif ($target eq 'tex') { + # Turn off some stuff we can't be inside thank you LaTeX + + + my $restart_sub = 0; + my $restart_sup = 0; + + # Since and are simple tags it's ok to turn off/on + # using the start_ stop_ functions.. those tags only care about + # $target. + + if (&is_inside_of($tagstack, "sub")) { + $restart_sub = 1; + $currentstring .= &end_sub($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + if (&is_inside_of($tagstack, "sup")) { + $restart_sup = 1; + $currentstring .= &end_sup($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + + # Now process the applet; just replace it with its alt attribute. + my $alttag= &Apache::lonxml::get_param('alt',$parstack, $safeeval,undef,1); unless ($alttag) { @@ -3020,6 +3142,17 @@ sub start_applet { } $currentstring.='\begin{center} \fbox{Java Applet: '.$alttag. '.}\end{center}'; + + # Turn stuff back on that we can't be inside of. + + if ($restart_sub) { + $currentstring .= &start_sub($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + if ($restart_sup) { + $currentstring .= &start_sup($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } } return $currentstring; }