--- loncom/xml/londefdef.pm 2005/09/19 10:59:08 1.286 +++ loncom/xml/londefdef.pm 2008/10/15 09:25:42 1.394 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Tags Default Definition Module # -# $Id: londefdef.pm,v 1.286 2005/09/19 10:59:08 foxr Exp $ +# $Id: londefdef.pm,v 1.394 2008/10/15 09:25:42 bisitz Exp $ # # # Copyright Michigan State University Board of Trustees @@ -46,8 +46,11 @@ 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(); +# use Data::Dumper; BEGIN { @@ -55,6 +58,20 @@ BEGIN { } +# +# Dumps all elements of the table structure. +# Need this 'cause evidently when given an array, Data::Dumper only seems +# to dump element 0. +# +#sub debug_dump_table { +# my $lastrow = $#Apache::londefdef::table; +# &Apache::lonnet::logthis("Dumping table: Last row index: $lastrow"); +# my $row; +# for ($row =0; $row <= $lastrow; $row++ ) { +# my $text = Dumper($Apache::londefdef::table[$row]); +# &Apache::lonnet::logthis("table [ $row ]".$text); +# } +#} sub initialize_londefdef { $Apache::londefdef::TD_redirection=0; @Apache::londefdef::table = (); @@ -64,6 +81,8 @@ sub initialize_londefdef { @Apache::londefdef::DT=(0); @Apache::londefdef::seenDT=(0); $Apache::londefdef::list_index=0; + undef($Apache::londefdef::head); + undef($Apache::londefdef::title); } #======================= TAG SUBROUTINES ===================== @@ -88,18 +107,29 @@ 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) { - &Apache::lonxml::warning("tth error: ". - $Apache::lontexconvert::errorstring); + 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+)/);
+	    if (defined($linenumber)) {
+		my @tex=split("\n",$tex);
+		$tex[$linenumber]=''.
+		    $tex[$linenumber].'';
+		$tex=join("\n",@tex);
+	    }
+	    &Apache::lonxml::warning($errormsg.$tex.'
'); $Apache::lontexconvert::errorstring=''; } #&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') { @@ -107,11 +137,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/^\$//; - $currentstring=~s/\$$//; - $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; } @@ -128,10 +160,11 @@ sub end_m { } sub start_tthoption { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; my $result; - if ($target eq 'web') { - my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser); + if ($target eq 'web' || $target eq 'webgrade') { + my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser, + $style); $inside=~s/^\s*//; if ($env{'browser.mathml'}) { &tth::ttmoptions($inside); @@ -152,30 +185,43 @@ sub end_tthoption { sub start_html { my ($target,$token) = @_; my $currentstring = ''; - my $options=$env{'course.'.$env{'request.course.id'}.'.tthoptions'}; - &Apache::lontexconvert::init_tth(); if ($target eq 'web' || $target eq 'edit' || $target eq 'webgrade' ) { - $currentstring = &Apache::lonxml::xmlbegin(); + # start_body() takes care of emitting the } elsif ($target eq 'tex') { - $currentstring .= '\documentclass[letterpaper]{article}'; + $currentstring .= + '\documentclass[letterpaper,twoside]{article}\raggedbottom'; if (($env{'form.latex_type'}=~'batchmode') || (!$env{'request.role.adv'})) {$currentstring .='\batchmode';} $currentstring .= '\newcommand{\keephidden}[1]{}'. '\renewcommand{\deg}{$^{\circ}$}'. + '\usepackage{multirow}'. '\usepackage{longtable}'. '\usepackage{textcomp}'. '\usepackage{makeidx}'. '\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{amscd}'; + + if($env{'form.pdfFormFields'} eq 'yes') { + $currentstring .= '\usepackage{hyperref}'. + '\usepackage{eforms}'. + '\usepackage{tabularx}'; + } + + $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; @@ -184,8 +230,8 @@ sub start_html { sub end_html { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { - $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + # end_body takes care of the } return $currentstring; } @@ -194,8 +240,8 @@ sub end_html { sub start_head { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4].&Apache::lonxml::fontsettings(); + if ($target eq 'web' || $target eq 'webgrade') { + &Apache::lonxml::startredirection(); } return $currentstring; } @@ -203,9 +249,12 @@ sub start_head { sub end_head { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web' && $env{'request.state'} eq 'published') { - $currentstring = &Apache::lonmenu::registerurl(undef,$target). - $token->[2]; + if (($target eq 'web' && $env{'request.state'} eq 'published') || + ($target eq 'webgrade' && $env{'request.state'} eq 'published')) { + # in case there is a but no + if ($Apache::lonxml::redirection) { + $Apache::londefdef::head = &Apache::lonxml::endredirection(); + } } return $currentstring; } @@ -214,7 +263,7 @@ sub end_head { sub start_map { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -223,7 +272,7 @@ sub start_map { sub end_map { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -233,7 +282,7 @@ sub end_map { sub start_select { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $Apache::londefdef::select=0; @@ -244,7 +293,7 @@ sub start_select { sub end_select { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -254,7 +303,7 @@ sub end_select { sub start_option { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $Apache::londefdef::select++; @@ -270,7 +319,7 @@ sub start_option { sub end_option { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring='}'; @@ -282,7 +331,7 @@ sub end_option { sub start_input { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -291,7 +340,7 @@ sub start_input { sub end_input { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -301,7 +350,7 @@ sub end_input { sub start_textarea { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -310,7 +359,7 @@ sub start_textarea { sub end_textarea { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -320,7 +369,7 @@ sub end_textarea { sub start_form { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -329,7 +378,7 @@ sub start_form { sub end_form { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -337,10 +386,11 @@ sub end_form { #-- tag (end tag required) sub start_title { - my ($target,$token) = @_; + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; + if ($target eq 'web' || $target eq 'webgrade') { + $Apache::londefdef::title = + &Apache::lonxml::get_all_text('/title',$parser,$style); } elsif ($target eq 'tex') { $currentstring .= '\keephidden{Title of the document: ' } @@ -354,8 +404,8 @@ sub start_title { sub end_title { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; + if ($target eq 'web' || $target eq 'webgrade') { + # start_title takes care of swallowing the title } elsif ($target eq 'tex') { $currentstring .= '}'; } @@ -368,13 +418,13 @@ sub end_title { #-- <meta> tag (end tag forbidden) sub start_meta { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { my $args=''; if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; } if ($args eq '') { - &Apache::lonxml::get_all_text("/meta",$parser); + &Apache::lonxml::get_all_text("/meta",$parser,$style); } else { $currentstring = $token->[4]; } @@ -412,6 +462,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; } @@ -419,7 +479,7 @@ sub start_meta { sub end_meta { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { my $args=''; if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; } if ($args ne '') { @@ -435,34 +495,49 @@ sub end_meta { return $currentstring; } +sub insert_meta { + return ' + <meta />'; +} + # accessrule sub start_accessrule { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + 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]; } if ($args eq '') { - &Apache::lonxml::get_all_text("/accessrule",$parser); + &Apache::lonxml::get_all_text("/accessrule",$parser,$style); } else { $currentstring = $token->[4]; } } if ($target eq 'meta') { - $currentstring='<rule>'.$eff.':'.$realm.':'.$role.'</rule>'; + $currentstring='<rule>'.$eff.':'.$realm.':'.$role.':'.$type.'</rule>'; } return $currentstring; } @@ -480,84 +555,45 @@ 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 .= + '<link rel="stylesheet" type="text/css" href="'.$css_href.'" />'; + } + return $links; +} + #-- <body> tag (end tag required) sub start_body { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { if ($Apache::lonhomework::parsing_a_problem) { &Apache::lonxml::warning("<body> tag found inside of <problem> tag this can cause problems."); return ''; } - if (!$Apache::lonxml::registered && - $env{'request.state'} eq 'published') { - $currentstring.='<head>'. - &Apache::lonmenu::registerurl(undef,$target).'</head>'; - } -# Accessibility - if ($env{'browser.imagesuppress'} eq 'on') { - delete($token->[2]->{'background'}); - } - if ($env{'browser.fontenhance'} eq 'on') { - my $style=''; - foreach my $key (keys(%{$token->[2]})) { - if ($key =~ /^style$/i) { - $style.=$token->[2]->{$key}.';'; - delete($token->[2]->{$key}); - } - } - $token->[2]->{'style'}=$style.'; font-size: x-large;'; - } - if ($env{'browser.blackwhite'} eq 'on') { - delete($token->[2]->{'font'}); - delete($token->[2]->{'link'}); - delete($token->[2]->{'alink'}); - delete($token->[2]->{'vlink'}); - delete($token->[2]->{'bgcolor'}); - delete($token->[2]->{'background'}); - } -# Overload loads - my $onLoad=''; - foreach my $key (keys(%{$token->[2]})) { - if ($key =~ /^onload$/i) { - $onLoad.=$token->[2]->{$key}.';'; - delete($token->[2]->{$key}); - } - } - $token->[2]->{'onload'}=&Apache::lonmenu::loadevents().';'.$onLoad; - my $onUnload=''; - foreach my $key (keys(%{$token->[2]})) { - if ($key =~ /^onunload$/i) { - $onUnload.=$token->[2]->{$key}.';'; - delete($token->[2]->{$key}); - } - } - $token->[2]->{'onunload'}=&Apache::lonmenu::unloadevents(). - ';'.$onUnload; - $currentstring .= '<'.$token->[1]; - foreach (keys %{$token->[2]}) { - $currentstring.=' '.$_.'="'.$token->[2]->{$_}.'"'; - } - $currentstring.='>'; - &Apache::lontexconvert::jsMath_reset(); - if ($env{'environment.texengine'} eq 'jsMath') { - $currentstring.=&Apache::lontexconvert::jsMath_header(); + 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 + .$extra_head, + {'add_entries' => $token->[2], + 'no_title' => 1, + 'force_register' => 1}); + if ($env{'request.state'} ne 'published') { - if ($env{'environment.remote'} eq 'off') { - $currentstring.= - &Apache::lonmenu::constspaceform(). - &Apache::lonmenu::menubuttons(1,'web',1); - } - $currentstring.=(<<EDITBUTTON); -<form method="post"> -<input type="submit" name="editmode" accesskey="e" value="Edit" /> -</form> -EDITBUTTON - } else { - $currentstring.=&Apache::lonmenu::menubuttons(undef,$target,1); + $currentstring.=&Apache::lonmenu::constspaceform(); + $currentstring.=&Apache::londefdef::edit_controls(); } $currentstring.=&Apache::lonxml::message_location(); } elsif ($target eq 'tex') { @@ -566,36 +602,63 @@ EDITBUTTON return $currentstring; } +sub edit_controls { + my $result .= ' +<form method="post"> +<div class="LC_edit_problem_header"> +<div class="LC_edit_problem_header_row1">'. +&Apache::lonxml::renderingoptions().' +<input type="submit" name="changeproblemmode" value="'.&mt('Change View').'" /> +</div> +<div class="LC_edit_problem_header_edit_row"><input type="submit" name="editmode" accesskey="e" value="'.&mt('Edit').'" /></div></div> +</form> +<br />'; + return $result; +} + sub end_body { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off unclosed <p> - if ($target eq 'web') { - $currentstring .= &Apache::lonxml::xmlend($target,$parser); + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= &Apache::loncommon::end_page({'discussion' => 1}); } elsif ($target eq 'tex') { $currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}'; } return $currentstring; } +# \begin{center} causes a new paragprah spacing that looks odd inside +# of a table cell. Same at the end of a \center but with a slightly +# larger space .. hence center_correction and center_end_correction. +# +sub center_correction { return '\vspace*{-6 mm}'; } +sub center_end_correction { return '\vspace*{-7 mm}'; } + #-- <center> tag (end tag required) sub start_center { - my ($target,$token) = @_; + my ($target,$token,$tagstack) = @_; my $currentstring = &end_p(); # Close off any prior para. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { + if (&is_inside_of($tagstack, "table")) { + $currentstring .= ¢er_correction(); + } $currentstring .= '\begin{center}'; } return $currentstring; } sub end_center { - my ($target,$token) = @_; + my ($target,$token,$tagstack) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring = '\end{center}'; + if (&is_inside_of($tagstack, "table")) { + $currentstring .= ¢er_end_correction(); + } } return $currentstring; } @@ -605,7 +668,7 @@ sub end_center { sub start_b { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { &disable_para(); @@ -617,7 +680,7 @@ sub start_b { sub end_b { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { &enable_para(); @@ -631,7 +694,7 @@ sub end_b { sub start_strong { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { &disable_para(); @@ -643,7 +706,7 @@ sub start_strong { sub end_strong { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { &enable_para(); @@ -656,7 +719,7 @@ sub end_strong { sub start_h1 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off any prior para. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { my $pre; @@ -681,7 +744,7 @@ sub start_h1 { sub end_h1 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { my $post='\vskip 0 mm '; @@ -705,7 +768,7 @@ sub end_h1 { sub start_h2 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off any prior para. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { my $pre; @@ -727,7 +790,7 @@ sub start_h2 { sub end_h2 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { my $post='\vskip 0 mm '; @@ -748,7 +811,7 @@ sub end_h2 { sub start_h3 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off any prior para. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { my $pre; @@ -770,7 +833,7 @@ sub start_h3 { sub end_h3 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { my $post='\vskip 0 mm '; @@ -791,7 +854,7 @@ sub end_h3 { sub start_h4 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off any prior para. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { my $pre; @@ -813,7 +876,7 @@ sub start_h4 { sub end_h4 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { my $post='\vskip 0 mm '; @@ -834,7 +897,7 @@ sub end_h4 { sub start_h5 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off any prior paras. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { my $pre; @@ -856,7 +919,7 @@ sub start_h5 { sub end_h5 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { my $post='\vskip 0 mm '; @@ -877,7 +940,7 @@ sub end_h5 { sub start_h6 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off any prior paras. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { my $pre; @@ -899,7 +962,7 @@ sub start_h6 { sub end_h6 { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { my $post='\vskip 0 mm '; @@ -920,7 +983,7 @@ sub end_h6 { sub start_cite { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\textit{'; @@ -931,7 +994,7 @@ sub start_cite { sub end_cite { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -943,7 +1006,7 @@ sub end_cite { sub start_i { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\textit{'; @@ -954,7 +1017,7 @@ sub start_i { sub end_i { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -966,7 +1029,7 @@ sub end_i { sub start_address { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\textit{'; @@ -977,7 +1040,7 @@ sub start_address { sub end_address { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -989,7 +1052,7 @@ sub end_address { sub start_dfn { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\textit{'; @@ -1000,7 +1063,7 @@ sub start_dfn { sub end_dfn { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -1012,7 +1075,7 @@ sub end_dfn { sub start_tt { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\texttt{'; @@ -1023,7 +1086,7 @@ sub start_tt { sub end_tt { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -1035,7 +1098,7 @@ sub end_tt { sub start_kbd { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\texttt{'; @@ -1046,7 +1109,7 @@ sub start_kbd { sub end_kbd { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -1058,7 +1121,7 @@ sub end_kbd { sub start_code { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\texttt{'; @@ -1069,7 +1132,7 @@ sub start_code { sub end_code { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -1081,7 +1144,7 @@ sub end_code { sub start_em { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\emph{'; @@ -1092,7 +1155,7 @@ sub start_em { sub end_em { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -1104,7 +1167,7 @@ sub end_em { sub start_q { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\emph{'; @@ -1115,7 +1178,7 @@ sub start_q { sub end_q { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -1154,27 +1217,37 @@ sub enable_para { sub start_p { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= &end_p(); # close off prior para if in progress. $currentstring .= $token->[4]; if (! ($currentstring =~ /\//)) { $closing_string = '</p>'; # Deal correctly with <p /> e.g. } } elsif ($target eq 'tex' && !$para_disabled) { + $currentstring .= &end_p(); # close off prior para if in progress. my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); if ($align eq 'center') { - $currentstring .='\begin{center}\par'; + $currentstring .='\begin{center}\par '; $closing_string = '\end{center}'; + if (&is_inside_of($tagstack, "table")) { + $currentstring = ¢er_correction().$currentstring; + } } elsif ($align eq 'right') { - $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{'; - $closing_string= '}}'; + $currentstring.="\n".'{\flushright '; +# $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{'; + $closing_string= "}\n"; } elsif ($align eq 'left') { - $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{\rlap{'; - $closing_string = '}\hfill}'; + $currentstring.= "\n".'{\flushleft '; +# $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{{'; + $closing_string = "}\n"; } else { $currentstring.='\par '; - $closing_string = '\strut\\\\\strut '; + if (&is_inside_of($tagstack, 'table')) { + $closing_string = '\vskip 0pt'; # Seems to be consistent with <p> in tables. + } else { + $closing_string = '\strut\\\\\strut '; + } } } @@ -1201,24 +1274,27 @@ sub end_p { sub start_br { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { my @tempo=@$tagstack; my $signal=0; + # Not going to factor this to is_inside_of since that would require + # multiple stack traversals. + # for (my $i=$#tempo;$i>=0;$i--) { if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') || - ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul') || - ($tempo[$i] eq 'td') || ($tempo[$i] eq 'th')) { + ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul')) { $signal=1; - last; + } + if (($tempo[$i] eq 'td') || ($tempo[$i] eq 'th')) { + $signal = 1; } } - if ($signal) { - $currentstring .= ' \vskip 0 mm '; - } elsif ($$tagstack[-2] ne 'sub' && $$tagstack[-2] ne 'sup') { + if ($signal != 1) { $currentstring .= '\strut \\\\ \strut '; } + } return $currentstring; } @@ -1226,7 +1302,7 @@ sub start_br { sub end_br { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } return $currentstring; @@ -1236,7 +1312,7 @@ sub end_br { sub start_big { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '{\large '; @@ -1247,7 +1323,7 @@ sub start_big { sub end_big { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -1259,7 +1335,7 @@ sub end_big { sub start_small { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '{\footnotesize '; @@ -1270,7 +1346,7 @@ sub start_small { sub end_small { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}'; @@ -1282,7 +1358,7 @@ sub end_small { sub start_basefont { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval); @@ -1296,7 +1372,7 @@ sub start_basefont { sub end_basefont { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval); @@ -1311,7 +1387,7 @@ sub end_basefont { sub start_font { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval); if ($face!~/symbol/i) { if (($env{'browser.fontenhance'} eq 'on') || @@ -1330,7 +1406,7 @@ sub start_font { sub end_font { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval); @@ -1345,7 +1421,7 @@ sub end_font { sub start_strike { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { &Apache::lonxml::startredirection(); @@ -1356,7 +1432,7 @@ sub start_strike { sub end_strike { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring=&Apache::lonxml::endredirection(); @@ -1371,7 +1447,7 @@ sub end_strike { sub start_s { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { &Apache::lonxml::startredirection(); @@ -1382,7 +1458,7 @@ sub start_s { sub end_s { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring=&Apache::lonxml::endredirection(); @@ -1397,10 +1473,10 @@ sub end_s { sub start_sub { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { - $currentstring .= '\ensuremath{_{'; + $currentstring .= '\raisebox{-\smallskipamount}{\scriptsize{'; } return $currentstring; } @@ -1408,7 +1484,7 @@ sub start_sub { sub end_sub { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}}'; @@ -1420,10 +1496,10 @@ sub end_sub { sub start_sup { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { - $currentstring .= '\ensuremath{^{'; + $currentstring .= '\raisebox{\smallskipamount}{\scriptsize{'; } return $currentstring; } @@ -1431,7 +1507,7 @@ sub start_sup { sub end_sup { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '}}'; @@ -1443,9 +1519,30 @@ sub end_sup { sub start_hr { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # End enclosing para. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { + + # <hr /> can't be inside of <sup><sub> thank you LaTeX. + # + my $restart_sub = 0; + my $restart_sup = 0; + + # Since <sub> and <sup> 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=~/^%/) { @@ -1466,6 +1563,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; } @@ -1473,7 +1580,7 @@ sub start_hr { sub end_hr { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } return $currentstring; @@ -1491,11 +1598,14 @@ sub end_hr { sub start_div { my ($target,$token, $tagstack, $parstack, $parser, $safeeval) = @_; my $currentstring = &end_p(); # Close enclosing para. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } 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 = ''; @@ -1504,6 +1614,10 @@ sub start_div { if ($align eq 'center') { $currentstring .= '\begin{center}'; $endstring = '\end{center}'; + if (&is_inside_of($tagstack, "table")) { + $currentstring = ¢er_correction().$currentstring; + $endstring .= ¢er_end_correction(); + } } elsif ($align eq 'right') { $currentstring .= '\begin{flushright}'; @@ -1524,7 +1638,7 @@ sub start_div { sub end_div { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } if ($target eq 'tex') { @@ -1539,21 +1653,10 @@ sub end_div { sub start_a { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval, undef,1); $currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href}); - } elsif ($target eq 'tex') { - my $a=&Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1); - my $b=&Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1); - if ($a=~/\S/) { - $a=~s/([^\\])%/$1\\\%/g; - $currentstring .= '\ref{URI: '.$a.'}'; - } elsif ($b=~/\S/) { - $currentstring .= '\ref{Anchor: '.$b.'}'; - } else { - $currentstring.=''; - } } return $currentstring; } @@ -1561,9 +1664,31 @@ sub start_a { sub end_a { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } + if ($target eq 'tex') { + my $href = + &Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1); + my $name = + &Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1); + 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; + # 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.=''; + } + } return $currentstring; } @@ -1571,7 +1696,7 @@ sub end_a { sub start_li { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0); @@ -1602,7 +1727,7 @@ sub start_li { sub end_li { my ($target,$token) = @_; my $currentstring = &end_p(); # In case there's a <p> in the <li> - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } return $currentstring; @@ -1612,7 +1737,7 @@ sub end_li { sub start_u { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { &Apache::lonxml::startredirection(); @@ -1623,7 +1748,7 @@ sub start_u { sub end_u { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring=&Apache::lonxml::endredirection(); @@ -1638,7 +1763,7 @@ sub end_u { sub start_ul { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close off enclosing list. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { my $TeXtype=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0); @@ -1667,7 +1792,7 @@ sub start_ul { sub end_ul { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring = '\end{itemize} \renewcommand{\labelitemi}{$\bullet$}'. @@ -1682,7 +1807,7 @@ sub end_ul { sub start_menu { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $currentstring = " \\begin{itemize} "; @@ -1693,7 +1818,7 @@ sub start_menu { sub end_menu { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring = " \\end{itemize}"; @@ -1705,7 +1830,7 @@ sub end_menu { sub start_dir { my ($target,$token) = @_; my $currentstring = &end_p(); # In case there's a <p> prior to the list. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= " \\begin{itemize} "; @@ -1716,7 +1841,7 @@ sub start_dir { sub end_dir { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring = " \\end{itemize}"; @@ -1728,7 +1853,7 @@ sub end_dir { sub start_ol { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # In case there's a <p> prior to the list. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $Apache::londefdef::list_index=0; @@ -1767,7 +1892,7 @@ sub start_ol { sub end_ol { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring = '\end{enumerate}\renewcommand{\labelenumi}{\arabic{enumi}.}'. @@ -1782,7 +1907,7 @@ sub end_ol { sub start_dl { my ($target,$token) = @_; my $currentstring = &end_p(); # In case there's a <p> unclosed prior to the list. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\begin{description}'; @@ -1798,7 +1923,7 @@ sub start_dl { sub end_dl { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { if ($Apache::londefdef::DT[-1]) { &end_dt(@_); } @@ -1820,7 +1945,7 @@ sub end_dl { sub start_dt { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring=''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { if ($Apache::londefdef::DT[-1]) { &end_dt(@_); } @@ -1835,7 +1960,7 @@ sub start_dt { sub end_dt { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { if ($Apache::londefdef::DT[-1]) { @@ -1858,7 +1983,7 @@ sub item_cleanup { sub start_dd { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { if ($Apache::londefdef::DT[-1]) { &end_dt(@_); } @@ -1877,7 +2002,7 @@ sub start_dd { sub end_dd { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $Apache::londefdef::description[-1]->[-1].= @@ -1898,17 +2023,16 @@ sub start_table { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $textwidth = ''; my $currentstring = &end_p(); - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { - my $aa = {}; - push @Apache::londefdef::table, $aa; + push(@Apache::londefdef::table, {}); $Apache::londefdef::table[-1]{'row_number'} = -1; #maximum table's width (default coincides with text line length) 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 @@ -1921,24 +2045,34 @@ sub start_table { } } } + + # width either comes forced from the TeXwidth or the width parameters. + # in either case it can be a percentage or absolute width. + # in the width case we ignore absolute width my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); - if (not defined $TeXwidth) { - my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,$safeeval,undef,1); - if ($htmlwidth=~/%/) { - $Apache::londefdef::table[-1]{'percent'}=1; - $htmlwidth=~/(\d+)/; - $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;; - } else { - $Apache::londefdef::table[-1]{'width'}=$textwidth; + if (!defined($TeXwidth)) { + my $htmlwidth = &Apache::lonxml::get_param('width',$parstack, + $safeeval,undef,1); + if ($htmlwidth =~ /%/) { + $TeXwidth = $htmlwidth; + } else { + $TeXwidth = $textwidth; } - } elsif ($TeXwidth=~/%/) { - $Apache::londefdef::table[-1]{'percent'}=1; + } + # if the width is specified as a % it is converted to an absolute width. + # otherwise.. just plugged right in the hash + + if ($TeXwidth=~/%/) { $TeXwidth=~/(\d+)/; $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100; } else { - $Apache::londefdef::table[-1]{'forcetablewidth'}=1; $Apache::londefdef::table[-1]{'width'}=$TeXwidth; - } + } + # In the end, however the table width cannot be wider than $textwidth... + + 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); @@ -1965,21 +2099,29 @@ sub start_table { $Apache::londefdef::table[-1]{'minlen'}=[]; $Apache::londefdef::table[-1]{'content'}=[]; $Apache::londefdef::table[-1]{'align'}=[]; - $currentstring.='\keephidden{NEW TABLE ENTRY}'; - } + $currentstring.=' \keephidden{NEW TABLE ENTRY}'; + + + } return $currentstring; } sub end_table { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + 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 </table> 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]) { @@ -1997,10 +2139,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]) { @@ -2012,8 +2158,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]) { @@ -2032,16 +2198,27 @@ 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 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) { $fwidth[$jn]=$max_len[$jn]; @@ -2049,11 +2226,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) { @@ -2070,7 +2247,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)*)/; @@ -2092,7 +2269,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; @@ -2100,6 +2277,7 @@ sub end_table { $fwidth[$jn]=$max_len[$jn]; $acsessive=$acsessive+$adjust[$jn]-$max_len[$jn]; $adjust[$jn]=0; + } } if ($acsessive>0) { @@ -2124,16 +2302,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); @@ -2154,35 +2335,188 @@ 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; for (my $jn=0;$jn<=$#fwidth;$jn++) { - if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { - $output.='\vspace*{-6 mm}\begin{center}'; - } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { - $output.=' \hfill \llap{' + + #----------------------------------------------------------- + # I think this order of doing things will ensure that + # 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 $border_char = ""; + if ($border) { + $border_char = "|"; } + my $spanwidth = 0; + if ($colspan > 1) { + for (my $spancol = $jn; $spancol < $jn + $colspan; $spancol++) { + $spanwidth += $fwidth[$spancol]; + } + $output .= '\multicolumn{'. + $colspan + ."}"; + if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { + $output .= '{'.$border_char.'c'.$border_char.'}{'; + } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { + $output .= '{'.$border_char.'r'.$border_char.'}{'; + } + else { + $output .= '{'.$border_char."p{$spanwidth mm}".$border_char.'}{'; + } + + } 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 + # to kick in a multicolumn in order to get the alignment spec. + # this must precede the multirow or LaTex gets quite upset. + # Naturally if colspan > 1 we've already done that above ^ + # + my $multirow_aligned = 0; + if ($rowspan > 1) { + if ($colspan == 1) { + if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq '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}{'.$border_char.'r'.$border_char.'}{'; + $multirow_aligned = 1; + } + } + $have_rowspan++; + 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 { + # so we close correctly without having to keep additional state + # around + # + if (!$multirow_aligned) { + $output .= '{'; + } + } + if (($rowspan eq '^') || ($rowspan eq '_')) { + $have_rowspan++; + } + #-------------------------------------------------------------- + + + # For right and center alignment of single cells. + # we are going to use a multicolumn with a span of 1 to specify alignment. + # + if ($colspan == 1 && $rowspan == 1) { + if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { + $output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{'; + } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { + $output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{'; + } + } + $output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn]; - if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { - $output.='\end{center}\vspace*{-6 mm}'; - } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { - $output.='} '; + + if (($colspan == 1 && $rowspan == 1) && + (($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') || + ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r'))) { + $output .= '}'; + } + + # Close off any open multirow: + + if ($rowspan > 1) { + $output .= '}}'; + } + # Close off the colspan... + # + if ($colspan > 1) { + $output .= '}'; + $jn += $colspan-1; # Adjust for number of rows really left. } if ($jn!=$#fwidth) {$output.=' '.$Apache::londefdef::table[-1]{'vinc'};} } - $output.=' \\\\ '.$Apache::londefdef::table[-1]{'hinc'}.' '; + # If have_rowspan > 0, and borders are on, then + # we need to do more than put an \hline at the bottom of row. + # we need to do the appropriate \cline to ensure that + # the spanned rows don't have \hlines through them. + + if (($Apache::londefdef::table[-1]{'hinc'} =~ /\\hline/) && $have_rowspan) { + $output .= ' \\\\ '; + for (my $jn=0; $jn<=$#fwidth;$jn++) { + my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn]; + if ($rowspan ne "^") { + if (($rowspan <= 1) || ($rowspan eq '_')) { + my $column = $jn+1; + $output .= '\cline{'.$column.'-'.$column.'} '; + } + } + } + + } else { + $output.=' \\\\ '.$Apache::londefdef::table[-1]{'hinc'}.' '; + } } # Note that \newline destroys alignment env's produced by e.g. <div> # $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut\newline\strut '; $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut'.'\\\\'."\n".'\strut '; if ($#Apache::londefdef::table > 0) { my $inmemory = $Apache::londefdef::table[-1]{'output'}; + # Figure out max/and min width by summing us and then + # apply that to the current column of the table we nest in + # if it's larger than the current width or the current width + # is undefined. + # + my $min_nested_width = 0; + my $max_nested_width = 0; + for (my $col = 0; $col <= $Apache::londefdef::table[-1]{'counter_columns'}; $col++) { + $min_nested_width += $min_len[$col]; + $max_nested_width += $max_len[$col]; + + } + # Fudge in an extra 5 mm for borders etc: + + $min_nested_width += 5; + $max_nested_width += 5; + + my $outer_column = $Apache::londefdef::table[-2]{'counter_columns'}; + my $outer_row = $Apache::londefdef::table[-2]{'row_number'}; + if ($min_nested_width > $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column]) { + $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column] = $min_nested_width; + } + if ($max_nested_width > $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column]) { + $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column] = $max_nested_width; + } + pop @Apache::londefdef::table; push @{$Apache::londefdef::table[-1]{'include'}}, $inmemory; } else { @@ -2191,6 +2525,7 @@ sub end_table { undef @Apache::londefdef::table; } } + } return $currentstring; } @@ -2198,7 +2533,7 @@ sub end_table { sub start_tr { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $Apache::londefdef::table[-1]{'row_number'}++; @@ -2209,6 +2544,10 @@ sub start_tr { push @ {$Apache::londefdef::table[-1]{'rows'} }, 'l'; } push ( @{ $Apache::londefdef::table[-1]{'rowdata'} }, $Apache::londefdef::table[-1]{'hinc'}); + # + # Need to save the number of table columns to preserve the max # columns. + # + $Apache::londefdef::table[-1]{'prior_columns'} = $Apache::londefdef::table[-1]{'counter_columns'}; $Apache::londefdef::table[-1]{'counter_columns'} = -1; push @ {$Apache::londefdef::table[-1]{'TeXlen'}}, []; push @ {$Apache::londefdef::table[-1]{'objectlen'}}, []; @@ -2222,12 +2561,20 @@ sub start_tr { sub end_tr { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close any pending <p> in the row. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { if ($Apache::londefdef::TD_redirection) { &end_td_tex($parstack,$parser,$safeeval); } + # Counter columns must be the maximum number of columns seen + # in the table so far so: + if ($Apache::londefdef::table[-1]{'prior_columns'} > $Apache::londefdef::table[-1]{'counter_columns'}) { + $Apache::londefdef::table[-1]{'counter_columns'} = $Apache::londefdef::table[-1]{'prior_columns'}; + } + + + } return $currentstring; } @@ -2236,7 +2583,7 @@ sub end_tr { sub start_td { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $Apache::londefdef::TD_redirection = 1; @@ -2282,13 +2629,58 @@ sub start_td_tex { sub end_td_tex { my ($parstack,$parser,$safeeval) = @_; - my $current_row = $Apache::londefdef::table[-1]{'row_number'}; - my $data=&Apache::lonxml::endredirection(); + my $current_row = $Apache::londefdef::table[-1]{'row_number'}; + my $current_column = $Apache::londefdef::table[-1]{'counter_columns'}; + my $data = &Apache::lonxml::endredirection(); + + # The rowspan array of the table indicates which cells are part of a span. + # n indicates the start of a span set of n rows. + # ^ indicates a cell that continues a span set. + # _ indicates the cell is at the bottom of a span set. + # If this and subsequent cells are part of a rowspan, we must + # push along the row until we find one that is not. + + while ((defined $Apache::londefdef::table[-1]{'rowspan'}[$current_row] [$current_column]) + && ($Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column] =~ /[\^\_]/)) { + # Part of a span. + push @ {$Apache::londefdef::table[-1]{'content'}[-1]}, ''; + $current_column++; + } + $Apache::londefdef::table[-1]{'counter_columns'} = $current_column; + + + # Get the column and row spans. + # Colspan can be done via \multicolumn if I can figure out the data structs. + + my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 0); + if (!$colspan) { + $colspan = 1; + } + + my $rowspan = &Apache::lonxml::get_param('rowspan', $parstack, $safeeval, undef, 0); + if (!$rowspan) { + $rowspan = 1; + } + + + + for (my $c = 0; $c < $colspan; $c++) { + $Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column+$c] = $rowspan; + for (my $i = 1; $i < $rowspan; $i++) { + $Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column+$c] = '^'; + if ($i == ($rowspan-1)) { + $Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column+$c] = '_'; + } + } + } + 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; @@ -2304,10 +2696,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; @@ -2323,10 +2717,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/; @@ -2354,23 +2750,57 @@ 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; + } } } - for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) { - $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/; - } + # Substitute all of the tables nested in this cell in their appropriate places. + + + my $nested_count = $#{$Apache::londefdef::table[-1]{'include'}}; # This one is constant... + for (my $in=0; $in<=$nested_count; $in++) { + my $nested = shift @{$Apache::londefdef::table[-1]{'include'}}; + $nested =~ s/\\end\{tabular\}\\strut\\\\/\\end\{tabular\}/; + # $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/; + $data =~ s/\\keephidden\{NEW TABLE ENTRY\}/$nested/; + + } + # Should be be killing off the 'include' elements as they're used up? + push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data; - return''; + + + + + # the colspan array will indicate how many columns will be spanned by this + # cell..this requires that counter_columns also be adjusted accordingly + # so that the next bunch of text goes in the right cell. Note that since + # counter_columns is incremented in the start_td_tex, we adjust by colspan-1. + # + + $Apache::londefdef::table[-1]{'counter_columns'} += $colspan -1; + for (my $i = 0; $i < ($colspan -1); $i++) { + push @ {$Apache::londefdef::table[-1]{'content'}[-1] },''; + } + for (my $r = 0; $r < $rowspan; $r++) { + $Apache::londefdef::table[-1]{'colspan'}[$current_row+$r][$current_column] = $colspan; + # Put empty text in spanned cols. + + } + + + + return ''; } sub end_td { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $Apache::londefdef::TD_redirection =0; @@ -2383,7 +2813,7 @@ sub end_td { sub start_th { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $Apache::londefdef::TD_redirection = 1; @@ -2499,7 +2929,7 @@ sub end_th_tex { sub end_th { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # Close any open <p> in the row. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $Apache::londefdef::TD_redirection =0; @@ -2520,28 +2950,34 @@ sub end_th { # (Note there seems to also be support for this as a % of page size) # sub start_img { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval, undef,1); - if (not $src and ($target eq 'web' or $target eq 'tex')) { - my $inside = &Apache::lonxml::get_all_text("/img",$parser); + if (! $src && + ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex') + ) { + my $inside = &Apache::lonxml::get_all_text("/img",$parser,$style); return ''; } - $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$src; + &Apache::lonxml::extlink($src); my $currentstring = ''; my $scaling = .3; # Render unto browsers that which are the browser's... - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { if ($env{'browser.imagesuppress'} ne 'on') { - $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src}); + my $enc = ('yes' eq + lc(&Apache::lonxml::get_param('encrypturl',$parstack, + $safeeval))); + $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src}, + $enc); } else { - my $alttag= &Apache::lonxml::get_param - ('alt',$parstack,$safeeval,undef,1); - unless ($alttag) { - $alttag=&Apache::lonmeta::alttag - ($Apache::lonxml::pwd[-1],$src); + my $alttag = &Apache::lonxml::get_param('alt',$parstack,$safeeval, + undef,1); + if (!$alttag) { + $alttag = &Apache::lonmeta::alttag($Apache::lonxml::pwd[-1], + $src); } $currentstring.='[IMAGE: '.$alttag.']'; } @@ -2560,7 +2996,7 @@ sub start_img { $safeeval, undef,1)); if(!$align) { - $align = "bottom"; # This is html's default so it's ours too. + $align = "bottom"; # This is html's default so it's ours too. } # &Apache::lonxml::debug("Alignemnt = $align"); @@ -2575,64 +3011,48 @@ sub start_img { $parstack, $safeeval, undef,0); - &Apache::lonxml::debug("LaTeX rendering = $latex_rendering"); + # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering"); if(!$latex_rendering) { - $latex_rendering = "parbox"; + $latex_rendering = "texwrap"; + } + # using texwrap inside a table does not work. So, if after all of this, + # texwrap is on, we turn it off if we detect we're in a table: + # + if (($latex_rendering eq 'texwrap') && &is_inside_of($tagstack, "table")) { + $latex_rendering = 'parpic'; } - &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src"); - #if original gif/jpg/png file exist do following: + # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src"); + + #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"); $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src); &Apache::lonxml::debug("path = $path file = $file src = $src"); if (-e $src) { &Apache::lonxml::debug("$src exists"); my ($height_param,$width_param)= &image_size($origsrc,0.3,$parstack,$safeeval); - my $destpath = $path; - $destpath =~ s/ /\_/g; # Spaces in path cause LaTex to vomit. - my $destfile = $file; - $destfile =~ s/ /\_/g; my $size; if ($width_param) { $size.='width='.$width_param.' mm,'; } if ($height_param) { $size.='height='.$height_param.' mm]'; } + # Default size if not able to extract that (e.g. eps image). + + # &Apache::lonnet::logthis("Size = $size"); + $size='['.$size; $size=~s/,$/]/; - $currentstring .= '\graphicspath{{'.$destpath.'}}' - .'\includegraphics'.$size.'{'.$destfile.'} '; - - # 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, - # and that's used for illegal values too. - # - # 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.. - if ($align eq "top") { - $currentstring = '\raisebox{-'.$height_param.'mm}{'.$currentstring.'}'; - } elsif (($align eq "center") || ($align eq "middle")) { # Being kind - my $offset = $height_param/2; - $currentstring = '\raisebox{-'.$offset.'mm}{'.$currentstring.'}'; - } elsif ($align eq "left") { - if ($latex_rendering eq "parpic") { - $currentstring = '\parpic[l]{'.$currentstring.'}'; - } else { # wrapfig render - $currentstring = '\begin{wrapfigure}{l}{'.$width_param.'mm}' - .'\scalebox{1.0}{'.$currentstring.'}\end{wrapfigure}'; - } - } elsif ($align eq "right") { - if ($latex_rendering eq "parpic") { - $currentstring = '\parpic[r]{'.$currentstring.'}'; - } else { # wrapfig rendering - $currentstring = '\begin{wrapfigure}{r}{'.$width_param.'mm}' - .'\scalebox{1.0}{'.$currentstring.'}\end{wrapfigure}'; - - } - } else { # Bottom is also default. - # $currentstring = '\raisebox{'.$height_param.'mm}{'.$currentstring.'}'; - } + $currentstring .= '\graphicspath{{'.$path.'}}' + .'\includegraphics'.$size.'{'.$file.'} '; + 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"); #original image file doesn't exist so check the alt attribute @@ -2648,9 +3068,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').'<br />'; $currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />'; $currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5); @@ -2660,25 +3081,30 @@ sub start_img { $currentstring .=&Apache::edit::select_arg('Alignment:','align', ['','bottom','middle','top','left','right'],$token,5); $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap', - ['', 'parbox', 'parpic'], $token, 2); + ['', 'none','parbox', 'parpic', 'wrapfigure'], $token, 2); + $currentstring .=&Apache::edit::select_arg('Encrypt URL:','encrypturl', + ['no','yes'], $token, 2); $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row(); my $src= &Apache::lonxml::get_param('src',$parstack,$safeeval); my $alt= &Apache::lonxml::get_param('alt',$parstack,$safeeval); my $width= &Apache::lonxml::get_param('width',$parstack,$safeeval); my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval); - - $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" '; - if ($width) { $currentstring.=' width="'.$width.'" '; } - if ($height) { $currentstring.=' height="'.$height.'" '; } - $currentstring .= ' />'; + if ($token->[2]{'src'}=~/\$/) { + $currentstring.='Variable image source'; + } else { + $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" '; + if ($width) { $currentstring.=' width="'.$width.'" '; } + if ($height) { $currentstring.=' height="'.$height.'" '; } + $currentstring .= ' />'; + } } elsif ($target eq 'modified') { my ($osrc,$owidth,$oheight)= ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'}); my $ctag=&Apache::edit::get_new_args($token,$parstack, $safeeval,'src','alt','align', 'TeXwidth','TeXheight', 'TeXwrap', - 'width','height'); + 'width','height','encrypturl'); my ($nsrc,$nwidth,$nheight)= ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'}); my $loc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$nsrc); @@ -2720,7 +3146,7 @@ sub start_img { sub end_img { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring = ''; @@ -2733,14 +3159,12 @@ sub start_applet { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,undef,1); - $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$code; - + &Apache::lonxml::extlink($code); my $archive=&Apache::lonxml::get_param('archive',$parstack,$safeeval, undef,1); - $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$archive; - + &Apache::lonxml::extlink($archive); my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { if ($env{'browser.appletsuppress'} ne 'on') { $currentstring = &Apache::lonenc::encrypt_ref($token, {'code'=>$code, @@ -2756,6 +3180,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 <sub> and <sup> 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) { @@ -2766,6 +3213,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; } @@ -2773,7 +3231,7 @@ sub start_applet { sub end_applet { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { } @@ -2784,9 +3242,9 @@ sub end_applet { sub start_embed { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); - $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$src; + &Apache::lonxml::extlink($src); my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { if ($env{'browser.embedsuppress'} ne 'on') { $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src}); } else { @@ -2805,7 +3263,7 @@ sub start_embed { sub end_embed { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { } @@ -2815,15 +3273,17 @@ sub end_embed { #-- <param> tag (end tag forbidden) sub start_param { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; - if (&Apache::lonxml::get_param - ('name',$parstack,$safeeval,undef,1)=~/^cabbase$/i) { - $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]= - &Apache::lonxml::get_param('value',$parstack,$safeeval,undef,1); - } - $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]= - &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); + if (&Apache::lonxml::get_param('name',$parstack, + $safeeval,undef,1)=~/^cabbase$/i) { + my $value=&Apache::lonxml::get_param('value',$parstack, + $safeeval,undef,1); + &Apache::lonxml::extlink($value); + } + + my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); + &Apache::lonxml::extlink($src); my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { my %toconvert; my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); if ($src) { $toconvert{'src'}= $src; } @@ -2842,7 +3302,7 @@ sub start_param { sub end_param { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { } @@ -2853,9 +3313,8 @@ sub end_param { sub start_allow { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); - $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src); - $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]= - &Apache::lonnet::clutter($src); + &Apache::lonxml::extlink($src); + if ($target eq 'tex') { &image_replication($src); } my $result; if ($target eq 'edit') { @@ -2881,35 +3340,15 @@ sub end_allow { sub start_frameset { my ($target,$token) = @_; my $currentstring = ''; # Close any pending para. - if ($target eq 'web') { - if (!$Apache::lonxml::registered && - $env{'request.state'} eq 'published') { - $currentstring.='<head>'. - &Apache::lonmenu::registerurl(undef,$target).'</head>'; - } - my $onLoad=''; - foreach my $key (keys(%{$token->[2]})) { - if ($key =~ /^onload$/i) { - $onLoad.=$token->[2]->{$key}.';'; - delete($token->[2]->{$key}); - } - } - $token->[2]->{'onload'}=&Apache::lonmenu::loadevents().';'.$onLoad; - my $onUnload=''; - foreach my $key (keys(%{$token->[2]})) { - if ($key =~ /^onunload$/i) { - $onUnload.=$token->[2]->{$key}.';'; - delete($token->[2]->{$key}); - } - } - $token->[2]->{'onunload'}=&Apache::lonmenu::unloadevents(). - ';'.$onUnload; - - $currentstring .= '<'.$token->[1]; - foreach (keys %{$token->[2]}) { - $currentstring.=' '.$_.'="'.$token->[2]->{$_}.'"'; - } - $currentstring.='>'; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = + &Apache::loncommon::start_page($Apache::londefdef::title, + $Apache::londefdef::head, + {'add_entries' => $token->[2], + 'no_title' => 1, + 'force_register' => 1, + 'frameset' => 1,}); + } return $currentstring; } @@ -2917,7 +3356,7 @@ sub start_frameset { sub end_frameset { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -2927,7 +3366,7 @@ sub end_frameset { sub start_xmp { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\begin{verbatim}'; @@ -2938,7 +3377,7 @@ sub start_xmp { sub end_xmp { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '\end{verbatim}'; @@ -2950,10 +3389,11 @@ sub end_xmp { sub start_pre { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = &end_p(); # close off pending <p> - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } elsif ($target eq 'tex') { $currentstring .= '\begin{verbatim}'; + &Apache::lonxml::disable_LaTeX_substitutions(); } return $currentstring; } @@ -2961,10 +3401,11 @@ sub start_pre { sub end_pre { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[2]; } elsif ($target eq 'tex') { $currentstring .= '\end{verbatim}'; + &Apache::lonxml::enable_LaTeX_substitutions(); } return $currentstring; } @@ -2973,7 +3414,7 @@ sub end_pre { sub start_insert { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1); $currentstring .= '<b>'.$display.'</b>';; } @@ -2983,7 +3424,7 @@ sub start_insert { sub end_insert { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= ''; } return $currentstring; @@ -2993,7 +3434,7 @@ sub end_insert { sub start_externallink { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1); $currentstring .= '<b>'.$display.'</b>';; } @@ -3003,7 +3444,7 @@ sub start_externallink { sub end_externallink { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= ''; } return $currentstring; @@ -3033,7 +3474,7 @@ sub end_blankspace { sub start_abbr { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3042,7 +3483,7 @@ sub start_abbr { sub end_abbr { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3052,7 +3493,7 @@ sub end_abbr { sub start_acronym { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3061,7 +3502,7 @@ sub start_acronym { sub end_acronym { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3071,7 +3512,7 @@ sub end_acronym { sub start_area { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3080,7 +3521,7 @@ sub start_area { sub end_area { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3090,7 +3531,7 @@ sub end_area { sub start_base { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3099,7 +3540,7 @@ sub start_base { sub end_base { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3109,7 +3550,7 @@ sub end_base { sub start_bdo { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3118,7 +3559,7 @@ sub start_bdo { sub end_bdo { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3128,7 +3569,7 @@ sub end_bdo { sub start_bgsound { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3137,7 +3578,7 @@ sub start_bgsound { sub end_bgsound { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3147,7 +3588,7 @@ sub end_bgsound { sub start_blink { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3156,7 +3597,7 @@ sub start_blink { sub end_blink { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3166,18 +3607,24 @@ sub end_blink { sub start_blockquote { my ($target,$token) = @_; my $currentstring = &end_p(); # Close any unclosed <p> - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } + if ($target eq 'tex') { + $currentstring .= '\begin{quote}'; + } return $currentstring; } sub end_blockquote { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } + if ($target eq 'tex') { + $currentstring = '\end{quote}'; + } return $currentstring; } @@ -3185,7 +3632,7 @@ sub end_blockquote { sub start_button { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3194,7 +3641,7 @@ sub start_button { sub end_button { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3204,7 +3651,7 @@ sub end_button { sub start_caption { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3213,7 +3660,7 @@ sub start_caption { sub end_caption { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3223,7 +3670,7 @@ sub end_caption { sub start_col { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3232,7 +3679,7 @@ sub start_col { sub end_col { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3242,7 +3689,7 @@ sub end_col { sub start_colgroup { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3251,7 +3698,7 @@ sub start_colgroup { sub end_colgroup { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3261,7 +3708,7 @@ sub end_colgroup { sub start_del { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3270,7 +3717,7 @@ sub start_del { sub end_del { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3280,7 +3727,7 @@ sub end_del { sub start_fieldset { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3289,7 +3736,7 @@ sub start_fieldset { sub end_fieldset { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3299,7 +3746,7 @@ sub end_fieldset { sub start_frame { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3308,7 +3755,7 @@ sub start_frame { sub end_frame { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3318,7 +3765,7 @@ sub end_frame { sub start_iframe { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3327,7 +3774,7 @@ sub start_iframe { sub end_iframe { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3337,7 +3784,7 @@ sub end_iframe { sub start_ins { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3346,7 +3793,7 @@ sub start_ins { sub end_ins { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3356,7 +3803,7 @@ sub end_ins { sub start_isindex { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3365,7 +3812,7 @@ sub start_isindex { sub end_isindex { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3375,7 +3822,7 @@ sub end_isindex { sub start_keygen { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3384,7 +3831,7 @@ sub start_keygen { sub end_keygen { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3394,7 +3841,7 @@ sub end_keygen { sub start_label { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3403,7 +3850,7 @@ sub start_label { sub end_label { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3413,7 +3860,7 @@ sub end_label { sub start_layer { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3422,7 +3869,7 @@ sub start_layer { sub end_layer { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3432,7 +3879,7 @@ sub end_layer { sub start_legend { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3441,7 +3888,7 @@ sub start_legend { sub end_legend { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3449,9 +3896,12 @@ sub end_legend { #-- <link> tag (end tag forbidden) sub start_link { - my ($target,$token) = @_; + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { + my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval, + undef,1); + &Apache::lonxml::extlink($href); $currentstring = $token->[4]; } return $currentstring; @@ -3460,7 +3910,7 @@ sub start_link { sub end_link { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3470,7 +3920,7 @@ sub end_link { sub start_marquee { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3479,7 +3929,7 @@ sub start_marquee { sub end_marquee { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3489,7 +3939,7 @@ sub end_marquee { sub start_multicol { my ($target,$token) = @_; my $currentstring = &end_p(); # Close any pending <p> - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } return $currentstring; @@ -3498,7 +3948,7 @@ sub start_multicol { sub end_multicol { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3508,7 +3958,7 @@ sub end_multicol { sub start_nobr { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $currentstring='\mbox{'; @@ -3519,7 +3969,7 @@ sub start_nobr { sub end_nobr { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring='}'; @@ -3531,7 +3981,7 @@ sub end_nobr { sub start_noembed { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3540,7 +3990,7 @@ sub start_noembed { sub end_noembed { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3550,7 +4000,7 @@ sub end_noembed { sub start_noframes { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3559,7 +4009,7 @@ sub start_noframes { sub end_noframes { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3569,7 +4019,7 @@ sub end_noframes { sub start_nolayer { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3578,7 +4028,7 @@ sub start_nolayer { sub end_nolayer { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3588,7 +4038,7 @@ sub end_nolayer { sub start_noscript { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3597,7 +4047,7 @@ sub start_noscript { sub end_noscript { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3607,7 +4057,7 @@ sub end_noscript { sub start_object { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3616,7 +4066,7 @@ sub start_object { sub end_object { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3626,7 +4076,7 @@ sub end_object { sub start_optgroup { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3635,7 +4085,7 @@ sub start_optgroup { sub end_optgroup { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3645,7 +4095,7 @@ sub end_optgroup { sub start_samp { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $currentstring='\texttt{'; @@ -3656,7 +4106,7 @@ sub start_samp { sub end_samp { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring='}'; @@ -3668,7 +4118,7 @@ sub end_samp { sub start_server { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3677,7 +4127,7 @@ sub start_server { sub end_server { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3687,7 +4137,7 @@ sub end_server { sub start_spacer { my ($target,$token) = @_; my $currentstring = &end_p(); # Close off any open <p> tag. - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring .= $token->[4]; } return $currentstring; @@ -3696,7 +4146,7 @@ sub start_spacer { sub end_spacer { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3706,7 +4156,7 @@ sub end_spacer { sub start_span { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3715,7 +4165,7 @@ sub start_span { sub end_span { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3725,7 +4175,7 @@ sub end_span { sub start_tbody { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3734,7 +4184,7 @@ sub start_tbody { sub end_tbody { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3744,7 +4194,7 @@ sub end_tbody { sub start_tfoot { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3753,7 +4203,7 @@ sub start_tfoot { sub end_tfoot { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3763,7 +4213,7 @@ sub end_tfoot { sub start_thead { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3772,7 +4222,7 @@ sub start_thead { sub end_thead { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3782,7 +4232,7 @@ sub end_thead { sub start_var { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $currentstring = '\textit{'; @@ -3793,7 +4243,7 @@ sub start_var { sub end_var { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { $currentstring = '}'; @@ -3805,7 +4255,7 @@ sub end_var { sub start_wbr { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[4]; } return $currentstring; @@ -3814,7 +4264,7 @@ sub start_wbr { sub end_wbr { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = $token->[2]; } return $currentstring; @@ -3823,7 +4273,7 @@ sub end_wbr { #-- <hideweboutput> tag sub start_hideweboutput { my ($target,$token) = @_; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { &Apache::lonxml::startredirection(); } return ''; @@ -3832,7 +4282,7 @@ sub start_hideweboutput { sub end_hideweboutput { my ($target,$token) = @_; my $currentstring = ''; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'webgrade') { $currentstring = &Apache::lonxml::endredirection(); } return ''; @@ -3975,8 +4425,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) { @@ -4000,17 +4450,33 @@ sub get_eps_image { my $newsrc=$orig_src; $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|; &Apache::lonxml::debug("queueing $newsrc for dynamic eps production."); - print FILE "$newsrc\n"; - close FILE; + print FILE ("$newsrc\n"); + close(FILE); $src=~s|/home/httpd/html/res|/home/httpd/prtspool|; $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|; if ($sext ne "") { # Put the ext. back in to uniquify. $src =~ s/\.eps$/$sext.eps/; } + } + } + } else { + # If the postscript file has spaces in its name, + # LaTeX will gratuitiously vomit. Therefore + # queue such files for copy with " " replaced by "_". + # printout.pm will know them by their .ps or .eps extensions. + my $newsrc = $orig_src; + $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|; + open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat"); + print FILE "$src\n"; + close FILE; + $src=~s|/home/httpd/html/res|/home/httpd/prtspool|; + $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|; } my ($path,$file)=($src=~m|(.*)/([^/]*)$|); + $path =~ s/ /\_/g; + $file =~ s/ /\_/g; &Apache::lonxml::debug("get_eps_image returning: $path / $file<BR />"); return ($path.'/',$file); } @@ -4021,16 +4487,16 @@ 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/\/home\/httpd\/html\/res//; - $newsrc=~s/\/home\/([^\/]*)\/public_html\//\/$1\//; - $newsrc=~s/\/\.\//\//; - $newsrc=~s/\/([^\/]+)\.(ps|eps)/\//; - if ($newsrc=~/\/home\/httpd\/lonUsers\//) { - $newsrc=~s/\/home\/httpd\/lonUsers//; - $newsrc=~s/\/([^\/]+)\/(\w)\/(\w)\/(\w)\//\/$1\//; + $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{/\./}{/}; + $newsrc=~s{/([^/]+)\.(ps|eps)}{/}; + if ($newsrc=~m{/home/httpd/lonUsers/}) { + $newsrc=~s{/home/httpd/lonUsers}{}; + $newsrc=~s{/($LONCAPA::domain_re)/./././}{/$1/}; } - if ($newsrc=~/\/userfiles\//) { + if ($newsrc=~m{/userfiles/}) { return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} '; } else { return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} '; @@ -4046,7 +4512,11 @@ sub file_path { } return $file,$path; } - +# Converts a measurement in to mm from any of +# the other valid LaTeX units of measure. +# If the units of measure are missing from the +# parameter, it is assumed to be in and returned +# with mm units of measure sub recalc { my $argument = shift; if (not $argument=~/(mm|cm|in|pc|pt)/) {return $argument.' mm';} @@ -4090,7 +4560,105 @@ sub LATEX_length { return $value; } - +# Wrap image 'stuff' inside of the LaTeX required to implement +# alignment: +# align_tex_image(align, latex_rendering, image) +# Where: +# align - The HTML alignment specification. +# 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 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, + # and that's used for illegal values too. + # + # 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; + $closure = '}'; + } elsif (($align eq "center") || ($align eq "middle")) { # Being kind + my $offset = $height/2; + $currentstring .= '\raisebox{-'.$offset.'mm}{'.$image; + $closure = '}'; + } elsif ($align eq "left") { + if ($latex_rendering eq "parpic") { + $currentstring .= '\parpic[l]{'.$image; + $closure = '}'; + } elsif ($latex_rendering eq "parbox") { + $currentstring .= '\begin{minipage}[l]{'.$width.'mm}' + .$image; + $closure = '\end{minipage}'; + } elsif ($latex_rendering eq "wrapfigure" + || $latex_rendering ne 'none') { # wrapfig render + $currentstring .= + '\begin{wrapfigure}{l}{'.$width.'mm}' + .'\scalebox{1.0}{'.$image; + $closure = '}\end{wrapfigure}'; + } + } elsif ($align eq "right") { + if ($latex_rendering eq "parpic") { + $currentstring .= '\parpic[r]{'.$image; + $closure = '}'; + } elsif ($latex_rendering eq "parbox") { + $currentstring .= '\begin{minipage}[r]{'.$width.'mm}' + .$image; + $closure = '\end{minipage}'; + } elsif ($latex_rendering eq "wrapfigure" + || $latex_rendering ne 'none') { # wrapfig render + $currentstring .= + '\begin{wrapfigure}{r}{'.$width.'mm}' + .'\scalebox{1.0}{'.$image; + $closure = '}\end{wrapfigure}'; + } + } else { # Bottom is also default. + # $currentstring = '\raisebox{'.$height.'mm}{'.$image.'}'; + $currentstring .= "{$image"; + $closure = '}'; + } + $currentstring .= "\n% end wrappage\n"; + $closure = "\n% Begin closure\n".$closure."\n% End closure\n"; + return ($currentstring, $closure); +} + +# is_inside_of $tagstack $tag +# This sub returns true if the current state of Xml processing +# is inside of the tag. +# Parameters: +# tagstack - The tagstack from the parser. +# tag - The tag (without the <>'s.). +# Sample usage: +# if (is_inside_of($tagstack "table")) { +# # I'm in a table.... +# } +sub is_inside_of { + my ($tagstack, $tag) = @_; + my @stack = @$tagstack; + for (my $i = ($#stack - 1); $i >= 0; $i--) { + if ($stack[$i] eq $tag) { + return 1; + } + } + return 0; +} 1;