--- loncom/xml/londefdef.pm 2007/04/06 10:23:46 1.362 +++ loncom/xml/londefdef.pm 2008/12/11 23:57:04 1.396.2.1 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Tags Default Definition Module # -# $Id: londefdef.pm,v 1.362 2007/04/06 10:23:46 foxr Exp $ +# $Id: londefdef.pm,v 1.396.2.1 2008/12/11 23:57:04 raeburn Exp $ # # # Copyright Michigan State University Board of Trustees @@ -46,6 +46,7 @@ use Apache::File(); use Image::Magick; use Apache::lonmenu(); use Apache::lonmeta(); +use Apache::lonlocal; use Apache::Constants qw(:common); use File::Basename; use LONCAPA(); @@ -106,13 +107,13 @@ sub start_m { my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval); if ($eval eq 'on') { $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]); - #&Apache::lonxml::debug("M is evaulated to:$inside:"); + #&Apache::lonxml::debug("M is evaluated to:$inside:"); } my $tex = $inside; my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval); $currentstring = &Apache::lontexconvert::converted(\$inside,$display); if ($Apache::lontexconvert::errorstring) { - my $errormsg='
'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'occured while attempting to convert this TeX:
'; + my $errormsg=''.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'occurred while attempting to convert this TeX:'; $tex = &HTML::Entities::encode($tex,'<>&"'); my ($linenumber) = ($Apache::lontexconvert::errorstring =~ /Line (\d+)/); @@ -138,7 +139,7 @@ sub start_m { # detect simple math mode entry exits, and convert them # to use \ensuremath ... unless there's a \verb inside. if (! ($currentstring=~/\\verb/)) { - if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) { + if ($currentstring=~/^\s*\$[^\$].*\$\s*$/) { $currentstring=~s/^(\s*)\$/$1/; $currentstring=~s/\$(\s*)$/$1/; $currentstring='\ensuremath{'.$currentstring.'}'; @@ -200,14 +201,20 @@ sub start_html { '\usepackage[dvips]{graphicx}'. '\usepackage{wrapfig}'. '\usepackage{picins}'. + '\usepackage[T1]{fontenc}'."\n". + '\usepackage{lmodern}'."\n". + '\usepackage[postscript]{ucs}'."\n". + '\usepackage[utf8x]{inputenc}'."\n". + '\usepackage{pifont}' ."\n". + '\usepackage{latexsym}'."\n". '\usepackage{epsfig}'. '\usepackage{calc}'. '\usepackage{amsmath}'. '\usepackage{amssymb}'. '\usepackage{amsfonts}'. - '\usepackage{amsthm}'. - '\usepackage{amscd}'. - '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'. + '\usepackage{amsthm}'; + + $currentstring .= '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'. '\renewenvironment{theindex}{\begin{list}{}{{\vskip 1mm \noindent \large\textbf{Index}} \newline \setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.01in}\setlength{\itemsep}{0.1in}\setlength{\parsep}{-0.02in}\setlength{\belowdisplayskip}{0.01in}\setlength{\abovedisplayskip}{0.01in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.01in}}}{\end{list}}'; } return $currentstring; @@ -448,6 +455,16 @@ sub start_meta { if ((not defined $content) && (not defined $name)) { &Apache::lonxml::startredirection(); } + } elsif ($target eq 'edit') { + $currentstring .= &Apache::edit::tag_start($target,$token); + $currentstring .= &Apache::edit::text_arg('Name:','name',$token,30); + $currentstring .= &Apache::edit::text_arg('Content:','content',$token,70); + $currentstring .= &Apache::edit::end_row(); + } elsif ($target eq 'modified') { + my $constructtag = + &Apache::edit::get_new_args($token,$parstack,$safeeval, + 'name','content'); + if ($constructtag) { $currentstring = &Apache::edit::rebuild_tag($token); } } return $currentstring; } @@ -471,23 +488,38 @@ sub end_meta { return $currentstring; } +sub insert_meta { + return ' + '; +} + # accessrule sub start_accessrule { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; my $currentstring = ''; - my $eff=&Apache::lonxml::get_param - ('effect',$parstack,$safeeval,undef,1); - my $realm=&Apache::lonxml::get_param - ('realm',$parstack,$safeeval,undef,1); - my $role=&Apache::lonxml::get_param - ('role',$parstack,$safeeval,undef,1); - $realm=~s/\s+//g; - $realm=~s/\//\_/g; - $realm=~s/^\_//; - $realm=~s/\W/\;/g; - $role=~s/\s+//g; - $role=~s/\//\_/g; - $role=~s/\W/\;/g; + my $eff =&Apache::lonxml::get_param('effect',$parstack,$safeeval,undef,1); + my $realm=&Apache::lonxml::get_param('realm', $parstack,$safeeval,undef,1); + my $role =&Apache::lonxml::get_param('role', $parstack,$safeeval,undef,1); + my $type =&Apache::lonxml::get_param('type', $parstack,$safeeval,undef,1); + + my ($dom,$crs,$sec,$separator); + if ($type eq 'user') { + ($dom,$crs,$sec)=split(m{/},$realm); + $crs = &LONCAPA::clean_username($crs); + $separator = '/'; + } else { + ($dom,$crs,$sec)=split(/\_/,$realm); + $crs = &LONCAPA::clean_courseid($crs); + $separator = '_'; + } + $dom = &LONCAPA::clean_domain($dom); + + $sec =~s/\W//; + $realm = $dom; + if ($crs =~ /\S/) { $realm .= $separator.$crs; } + if ($sec =~ /\S/) { $realm .= $separator.$sec; } + $role=~s/\W//g; + if ($target eq 'web') { my $args=''; if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; } @@ -498,7 +530,7 @@ sub start_accessrule { } } if ($target eq 'meta') { - $currentstring=''.$eff.':'.$realm.':'.$role.' '; + $currentstring=''.$eff.':'.$realm.':'.$role.':'.$type.' '; } return $currentstring; } @@ -516,6 +548,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) = @_; @@ -530,21 +573,20 @@ 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}); if ($env{'request.state'} ne 'published') { $currentstring.=&Apache::lonmenu::constspaceform(); - $currentstring.=(<- - -
-EDITBUTTON + $currentstring.=&Apache::londefdef::edit_controls(); } $currentstring.=&Apache::lonxml::message_location(); } elsif ($target eq 'tex') { @@ -553,6 +595,20 @@ EDITBUTTON return $currentstring; } +sub edit_controls { + my $result .= ' + +
'; + return $result; +} + sub end_body { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off unclosed@@ -1228,9 +1284,7 @@ sub start_br { $signal = 1; } } - if ($signal eq 1) { - $currentstring .= ' \vskip 0 mm '; - } else { + if ($signal != 1) { $currentstring .= '\strut \\\\ \strut '; } @@ -1542,6 +1596,9 @@ sub start_div { } if ($target eq 'tex') { # 4 possible alignments: left, right, center, and -missing-. + # If inside a table row, we must let the table logic + # do the alignment, however. + # my $endstring = ''; @@ -1552,6 +1609,7 @@ sub start_div { $endstring = '\end{center}'; if (&is_inside_of($tagstack, "table")) { $currentstring = ¢er_correction().$currentstring; + $endstring .= ¢er_end_correction(); } } elsif ($align eq 'right') { @@ -1607,10 +1665,18 @@ sub end_a { &Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1); my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1); - if ($href =~ /\S/) { + my $uriprint = + &Apache::lonxml::get_param('uriprint',$parstack,$safeeval,undef,1); + my $anchorprint = + &Apache::lonxml::get_param('anchorprint',$parstack,$safeeval,undef,1); + if (($href =~ /\S/) && ($uriprint=~/^on|uriprint|yes|1$/i)) { $href =~ s/([^\\])%/$1\\\%/g; - $currentstring .= ' ({\tt URI:'.&Apache::lonxml::latex_special_symbols($href).'})'; - } elsif ($name =~ /\S/) { + # 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/) && ($anchorprint=~/^on|anchorprint|yes|1$/i)) { $currentstring .= ' ({\tt Anchor:'.&Apache::lonxml::latex_special_symbols($name).'})'; } else { $currentstring.=''; @@ -1953,6 +2019,7 @@ sub start_table { if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { + &disable_para(); # Can't have paras in a table. push(@Apache::londefdef::table, {}); $Apache::londefdef::table[-1]{'row_number'} = -1; #maximum table's width (default coincides with text line length) @@ -1985,21 +2052,14 @@ sub start_table { } else { $TeXwidth = $textwidth; } - } else { - $Apache::londefdef::table[-1]{'forcedtablewidth'} = 1; - } - # This stuff looks a bit hokey.. - # Percentage width is actually given as an absolute width.. - # but it appears that unless the 'percent' flag is set, - # The table is just allowed to go to its natural width - # for now let's always claim 'percent' is set.. - # + } + # 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 { - $Apache::londefdef::table[-1]{'percent'} = 1; # kludge until we get the intent. $Apache::londefdef::table[-1]{'width'}=$TeXwidth; } # In the end, however the table width cannot be wider than $textwidth... @@ -2046,11 +2106,16 @@ sub end_table { if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { + my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval); my $inmemory = ''; my $output = ''; my $WARNING=''; #width of columns from TeXwidth attributes + # Protect against unbalanced tag. + + if (scalar(@Apache::londefdef::table) > 0) { + for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) { if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]<$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]) { @@ -2142,11 +2207,11 @@ sub end_table { my @fwidth=@{$Apache::londefdef::table[-1]{'TeXlen'}[0]};#final width array my @adjust=(); #step 1. adjustment by maximum value - my $space_neeeded=0; + my $space_needed=0; for (my $jn=0;$jn<=$#max_len;$jn++) { - $space_neeeded=$space_neeeded+$max_len[$jn]; + $space_needed=$space_needed+$max_len[$jn]; } - if ($space_neeeded<=$available_space) { + if ($space_needed<=$available_space) { for (my $jn=0;$jn<=$#max_len;$jn++) { if ($fwidth[$jn]==0) { @@ -2155,11 +2220,11 @@ sub end_table { } } else { #step 2. adjustment by minimum value (estimation) - $space_neeeded=0; + $space_needed=0; for (my $jn=0;$jn<=$#min_len;$jn++) { - $space_neeeded+=$min_len[$jn]; + $space_needed+=$min_len[$jn]; } - if ($space_neeeded>$available_space) { + if ($space_needed>$available_space) { $WARNING=' \textbf{NOT ENOUGH SPACE FOR TABLE} '; for (my $jn=0;$jn<=$#max_len;$jn++) { if ($fwidth[$jn]==0) { @@ -2176,7 +2241,7 @@ sub end_table { } } if ($how_many_to_scale>0) { - my $space_to_adjust=($space_neeeded-$available_space)/$how_many_to_scale; + my $space_to_adjust=($space_needed-$available_space)/$how_many_to_scale; foreach my $jn (@to_scale) { for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/; @@ -2198,7 +2263,7 @@ sub end_table { } } else { #step 3. adjustment over minimal + corrections - my $enlarge_coef=$available_space/$space_neeeded; + my $enlarge_coef=$available_space/$space_needed; my $acsessive=0; for (my $jn=0;$jn<=$#min_len;$jn++) { $adjust[$jn]=$min_len[$jn]*$enlarge_coef; @@ -2231,16 +2296,19 @@ 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]; + } + if ($current == 0) { + $current = $Apache::londefdef::table[-1]{'width'}; + } + 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); @@ -2290,6 +2358,10 @@ sub end_table { # Do the appropriate magic if this has a colspan # + my $border_char = ""; + if ($border) { + $border_char = "|"; + } my $spanwidth = 0; if ($colspan > 1) { for (my $spancol = $jn; $spancol < $jn + $colspan; $spancol++) { @@ -2299,12 +2371,12 @@ sub end_table { $colspan ."}"; if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { - $output .= '{|c|}{'; + $output .= '{'.$border_char.'c'.$border_char.'}{'; } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { - $output .= '{|r|}{'; + $output .= '{'.$border_char.'r'.$border_char.'}{'; } else { - $output .= "{|p{$spanwidth mm}|}{"; + $output .= '{'.$border_char."p{$spanwidth mm}".$border_char.'}{'; } } else { @@ -2320,10 +2392,10 @@ sub end_table { if ($rowspan > 1) { if ($colspan == 1) { if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { - $output .= '\multicolumn{1}{|c|}{'; + $output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{'; $multirow_aligned = 1; } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { - $output .= '\multicolumn{1}{|r|}{'; + $output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{'; $multirow_aligned = 1; } } @@ -2360,9 +2432,9 @@ sub end_table { # if ($colspan == 1 && $rowspan == 1) { if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { - $output .= '\multicolumn{1}{|c|}{'; + $output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{'; } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { - $output .= '\multicolumn{1}{|r|}{'; + $output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{'; } } @@ -2446,6 +2518,8 @@ sub end_table { pop @Apache::londefdef::table; undef @Apache::londefdef::table; } + } + &enable_para(); } return $currentstring; } @@ -2945,7 +3019,7 @@ sub start_img { # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src"); - #if original gif/jpg/png file exist do following: + #if original bmp/gif/jpg/png file exist do following: my $origsrc=$src; my ($path,$file) = &get_eps_image($src); # &Apache::lonnet::logthis("Image source: $src result: $path $file"); @@ -2989,9 +3063,10 @@ sub start_img { # And here's where the semi-quote breaks down: allow the user # to edit the beast as well by rendering the problem for edit: } elsif ($target eq 'edit') { + my $only = join(',',&Apache::loncommon::filecategorytypes('Pictures')); $currentstring .=&Apache::edit::tag_start($target,$token); $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70). - &Apache::edit::browse('src',undef,'alt').' '. + &Apache::edit::browse('src',undef,'alt',$only).' '. &Apache::edit::search('src',undef,'alt').'
'; $currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'
'; $currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5); @@ -3010,11 +3085,14 @@ sub start_img { my $width= &Apache::lonxml::get_param('width',$parstack,$safeeval); my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval); - - $currentstring .= '[2]{'src'}=~/\$/) { + $currentstring.='Variable image source'; + } else { + $currentstring .= '[2]{'src'},$token->[2]{'width'},$token->[2]{'height'}); @@ -4342,8 +4420,8 @@ sub get_eps_image { &Apache::lonnet::repcopy($orig_src); # Failure is not completely fatal. } &Apache::lonxml::debug("get_eps_image: Original image: $orig_src"); - my ($spath, $sname, $sext) = &fileparse($src, qr/\.(gif|png|jpg|jpeg)/i); - $src=~s/\.(gif|png|jpg|jpeg)$/\.eps/i; + my ($spath, $sname, $sext) = &fileparse($src, qr/\.(bmp|gif|png|jpg|jpeg)/i); + $src=~s/\.(bmp|gif|png|jpg|jpeg)$/\.eps/i; $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src); &Apache::lonxml::debug("Filelocation gives: $src"); if (! -e $src) { @@ -4404,7 +4482,7 @@ sub eps_generation { my $temp_file = Apache::File->new('>>'.$filename); print $temp_file "$src\n"; my $newsrc = $src; - $newsrc =~ s/(\.gif|\.jpg|\.jpeg)$/\.eps/i; + $newsrc =~ s/(\.bmp|\.gif|\.jpg|\.jpeg)$/\.eps/i; $newsrc=~s{/home/httpd/html/res}{}; $newsrc=~s{/home/($LONCAPA::username_re)/public_html/}{/$1/}; $newsrc=~s{/\./}{/}; @@ -4494,6 +4572,12 @@ sub align_latex_image { my ($align, $latex_rendering, $image, $width, $height) = @_; my $currentstring; # The 1/2 wrapped image. my $closure; # The closure of the wrappage. + + # if it's none just return it back + if ($latex_rendering eq 'none') { + return ($image,''); + } + # 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,