Diff for /loncom/xml/londefdef.pm between versions 1.322 and 1.470

version 1.322, 2006/03/22 19:37:44 version 1.470, 2023/03/25 18:38:27
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # Tags Default Definition Module   # Tags Default Definition Module
 #  #
 # $Id$  # $Id$
 #   #
 #  #
 # Copyright Michigan State University Board of Trustees  # Copyright Michigan State University Board of Trustees
 #  #
Line 25 Line 25
 # /home/httpd/html/adm/gpl.txt  # /home/httpd/html/adm/gpl.txt
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 ## Copyright for TtHfunc and TtMfunc by Ian Hutchinson.   ## Copyright for TtHfunc and TtMfunc by Ian Hutchinson.
 # TtHfunc and TtMfunc (the "Code") may be compiled and linked into   # TtHfunc and TtMfunc (the "Code") may be compiled and linked into
 # binary executable programs or libraries distributed by the   # binary executable programs or libraries distributed by the
 # Michigan State University (the "Licensee"), but any binaries so   # Michigan State University (the "Licensee"), but any binaries so
 # distributed are hereby licensed only for use in the context  # distributed are hereby licensed only for use in the context
 # of a program or computational system for which the Licensee is the   # of a program or computational system for which the Licensee is the
 # primary author or distributor, and which performs substantial   # primary author or distributor, and which performs substantial
 # additional tasks beyond the translation of (La)TeX into HTML.  # additional tasks beyond the translation of (La)TeX into HTML.
 # The C source of the Code may not be distributed by the Licensee  # The C source of the Code may not be distributed by the Licensee
 # to any other parties under any circumstances.  # to any other parties under any circumstances.
 #  #
   
 package Apache::londefdef;   package Apache::londefdef;
   
 use Apache::lonnet;  use Apache::lonnet;
 use strict;  use strict;
 use Apache::lonxml;  use Apache::lonxml;
 use Apache::File();  use Apache::lontable;
 use Image::Magick;  use Image::Magick;
 use Apache::lonmenu();  use Apache::lonmenu();
 use Apache::lonmeta();  use Apache::lonmeta();
   use Apache::lonlocal;
   use Apache::loncommon();
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use File::Basename;  use File::Basename;
   use LONCAPA();
 # use Data::Dumper;  # use Data::Dumper;
   
 BEGIN {  BEGIN {
   
     &Apache::lonxml::register('Apache::londefdef',('a','abbr','acronym','accessrule','address','allow','applet','area','b','base','basefont','bgo','bgsound','big','blink','blockquote','blankspace','body','br','button','caption','center','cite','code','col','colgroup','dd','del','dfn','dir','div','dl','dt','em','embed','externallink','fieldset','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','i','iframe','img','input','ins','insert','isindex','kbd','keygen','label','layer','legend','li','link','m','map','marquee','menu','meta','multicol','nobr','noembed','noframes','nolayer','noscript','object','ol','optgroup','option','output','p','param','pre','q','s','samp','select','server','small','spacer','span','strike','strong','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','tthoption','u','ul','var','wbr','hideweboutput'));      &Apache::lonxml::register('Apache::londefdef',('a','abbr','acronym','accessrule','address','allow','applet','area','b','base','basefont','bgo','bgsound','big','blink','blockquote','blankspace','body','br','button','caption','center','cite','code','col','colgroup','dd','del','dfn','dir','div','dl','dt','em','embed','externallink','fieldset','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','i','iframe','img','input','ins','insert','isindex','kbd','keygen','label','layer','legend','li','link','m','map','marquee','menu','meta','multicol','nobr','noembed','noframes','nolayer','noscript','object','ol','optgroup','option','output','p','param','pre','q','s','samp','select','server','small','spacer','span','strike','strong','style','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','tthoption','u','ul','var','wbr','hideweboutput'));
   
 }  }
   
 #  
 #   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 {  sub initialize_londefdef {
     $Apache::londefdef::TD_redirection=0;      $Apache::londefdef::TD_redirection=0;
     @Apache::londefdef::table = ();      @Apache::londefdef::table = ();
Line 79  sub initialize_londefdef { Line 69  sub initialize_londefdef {
     @Apache::londefdef::DT=(0);      @Apache::londefdef::DT=(0);
     @Apache::londefdef::seenDT=(0);      @Apache::londefdef::seenDT=(0);
     $Apache::londefdef::list_index=0;      $Apache::londefdef::list_index=0;
       undef($Apache::londefdef::head);
       undef($Apache::londefdef::title);
 }  }
   
 #======================= TAG SUBROUTINES =====================  #======================= TAG SUBROUTINES =====================
Line 100  sub start_m { Line 92  sub start_m {
     my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);      my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);
     if ($target eq 'web' || $target eq 'analyze') {      if ($target eq 'web' || $target eq 'analyze') {
  &Apache::lonxml::debug("M is starting with:$inside:");   &Apache::lonxml::debug("M is starting with:$inside:");
           if (!($inside =~ /^\s*\$.*\$\s*$/ || $inside =~ /^\s*\\[([].*\\[)\]]\s*$/)) {
               # Non-math LaTeX will not be rendered correctly with MathJax
               # and it should be avoided anyway.
               # On top of that, MathJax will render math without $, but
               # it will fail with tth. This is worth a warning.
               # (even though some people might just use latex for printing)
               &Apache::lonxml::warning(&mt('Missing $ in [_1].','&lt;m&gt;'));
           } elsif (($env{'browser.type'} eq 'safari') && ($env{'form.editxmltext'}) &&
                    (($env{'form.problemmode'} eq 'view') || ($env{'form.problemmode'} eq 'discard'))) {
               my $delimiter;
               if ($inside =~ /\$$/) {
                   $delimiter = '$';
               } elsif ($inside =~ /\\([)\]])$/) {
                   $delimiter = $1;
               }
               if ($delimiter) {
                   &Apache::lonxml::warning(&mt('Insert a space between [_1] and [_2].',
                                                $delimiter,'&lt;/m&gt;'));
               }
           }
  my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);   my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
  if ($eval eq 'on') {   if ($eval eq 'on') {
     $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);      $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 $tex = $inside;
  my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval);   my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval);
  $currentstring = &Apache::lontexconvert::converted(\$inside,$display);   $currentstring = &Apache::lontexconvert::converted(\$inside,$display);
  if ($Apache::lontexconvert::errorstring) {   if ($Apache::lontexconvert::errorstring) {
     my $errormsg='<pre>'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'</pre> occured while attempting to convert this TeX: <pre>';      my $errormsg='<pre>'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'</pre> occurred while attempting to convert this TeX: <pre>';
     $tex = &HTML::Entities::encode($tex,'<>&"');      $tex = &HTML::Entities::encode($tex,'<>&"');
     my ($linenumber) =      my ($linenumber) =
  ($Apache::lontexconvert::errorstring =~ /Line (\d+)/);   ($Apache::lontexconvert::errorstring =~ /Line (\d+)/);
Line 125  sub start_m { Line 137  sub start_m {
  #&Apache::lonxml::debug("M is ends with:$currentstring:");   #&Apache::lonxml::debug("M is ends with:$currentstring:");
  $Apache::lonxml::post_evaluate=0;   $Apache::lonxml::post_evaluate=0;
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
   
  $currentstring = $inside;   $currentstring = $inside;
  my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);   my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
  if ($eval eq 'on') {   if ($eval eq 'on') {
Line 132  sub start_m { Line 145  sub start_m {
  }   }
  if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';}   if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';}
  # detect simple math mode entry exits, and convert them   # detect simple math mode entry exits, and convert them
         # to use \ensuremath          # to use \ensuremath ... unless there's a \verb inside.
  if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) {   if (! ($currentstring=~/\\verb/)) {
     $currentstring=~s/^(\s*)\$/$1/;      if ($currentstring=~/^\s*\$[^\$].*\$\s*$/) {
     $currentstring=~s/\$(\s*)$/$1/;   $currentstring=~s/^(\s*)\$/$1/;
     $currentstring='\ensuremath{'.$currentstring.'}';   $currentstring=~s/\$(\s*)$/$1/;
    $currentstring='\ensuremath{'.$currentstring.'}';
       }
  }   }
  $Apache::lonxml::post_evaluate=0;   $Apache::lonxml::post_evaluate=0;
     }      }
Line 155  sub end_m { Line 170  sub end_m {
 sub start_tthoption {  sub start_tthoption {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $result;      my $result;
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser,   my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser,
    $style);     $style);
  $inside=~s/^\s*//;   $inside=~s/^\s*//;
Line 178  sub end_tthoption { Line 193  sub end_tthoption {
 sub start_html {  sub start_html {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      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' ) {      if ($target eq 'web' || $target eq 'edit' || $target eq 'webgrade' ) {
  $currentstring = &Apache::lonxml::xmlbegin();   # start_body() takes care of emitting the <html>
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\documentclass[letterpaper,twoside]{article}';  
  if (($env{'form.latex_type'}=~'batchmode') ||   $currentstring .= &latex_header();
             (!$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{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}}'.  
                           '\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;      return $currentstring;
 }  }
Line 211  sub start_html { Line 205  sub start_html {
 sub end_html {  sub end_html {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = '</html>';   # end_body takes care of the </html>
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 221  sub end_html { Line 215  sub end_html {
 sub start_head {  sub start_head {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4].&Apache::lonxml::fontsettings();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_head {  sub end_head {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' && $env{'request.state'} eq 'published') {      if (($target eq 'web'      && $env{'request.state'} eq 'published') ||
  $currentstring = &Apache::lonmenu::registerurl(undef,$target).   ($target eq 'webgrade' && $env{'request.state'} eq 'published')) {
     $token->[2];       # in case there is a </head> but no <head>
     }    if ($Apache::lonxml::redirection) {
       $Apache::londefdef::head = &Apache::lonxml::endredirection();
    }
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 241  sub end_head { Line 238  sub end_head {
 sub start_map {  sub start_map {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_map {  sub end_map {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 260  sub end_map { Line 257  sub end_map {
 sub start_select {  sub start_select {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  $Apache::londefdef::select=0;   $Apache::londefdef::select=0;
     }      }
Line 271  sub start_select { Line 268  sub start_select {
 sub end_select {  sub end_select {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 281  sub end_select { Line 278  sub end_select {
 sub start_option {  sub start_option {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::select++;   $Apache::londefdef::select++;
  if ($Apache::londefdef::select == 1) {   if ($Apache::londefdef::select == 1) {
Line 297  sub start_option { Line 294  sub start_option {
 sub end_option {  sub end_option {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  $currentstring='}';   $currentstring='}';
     }      }
Line 309  sub end_option { Line 306  sub end_option {
 sub start_input {  sub start_input {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_input {  sub end_input {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 328  sub end_input { Line 325  sub end_input {
 sub start_textarea {  sub start_textarea {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_textarea {  sub end_textarea {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 347  sub end_textarea { Line 344  sub end_textarea {
 sub start_form {  sub start_form {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_form {  sub end_form {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <title> tag (end tag required)  #-- <title> tag (end tag required)
 sub start_title {  sub start_title {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $Apache::londefdef::title =
       &Apache::lonxml::get_all_text('/title',$parser,$style);
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\keephidden{Title of the document:  '    $currentstring .= '\keephidden{Title of the document:  ';
     }      }
     if ($target eq 'meta') {      if ($target eq 'meta') {
  $currentstring='<title>';   $currentstring='<title>';
Line 381  sub start_title { Line 379  sub start_title {
 sub end_title {  sub end_title {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       # start_title takes care of swallowing the title
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }        }
     if ($target eq 'meta') {      if ($target eq 'meta') {
  &end_output($target);   &end_output($target);
  $currentstring='</title>';   $currentstring='</title>';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 397  sub end_title { Line 395  sub end_title {
 sub start_meta {  sub start_meta {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $args='';   my $args='';
  if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }   if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
  if ($args eq '') {   if ($args eq '') {
Line 405  sub start_meta { Line 403  sub start_meta {
  } else {   } else {
     $currentstring = $token->[4];      $currentstring = $token->[4];
  }   }
           if ($env{'form.grade_imsexport'}) {
               $currentstring = '';
           }
     } elsif ($target eq 'meta') {      } elsif ($target eq 'meta') {
  unless (&Apache::lonxml::get_param   unless (&Apache::lonxml::get_param
  ('http-equiv',$parstack,$safeeval,undef,1)) {   ('http-equiv',$parstack,$safeeval,undef,1)) {
Line 439  sub start_meta { Line 440  sub start_meta {
  if ((not defined $content) && (not defined $name)) {   if ((not defined $content) && (not defined $name)) {
     &Apache::lonxml::startredirection();      &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;      return $currentstring;
 }  }
Line 446  sub start_meta { Line 457  sub start_meta {
 sub end_meta {  sub end_meta {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $args='';   my $args='';
  if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }   if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
  if ($args ne '') {   if ($args ne '') {
Line 462  sub end_meta { Line 473  sub end_meta {
     return $currentstring;      return $currentstring;
 }  }
   
   sub insert_meta {
       return '
       <meta />';
   }
   
   #-- <start> tag
   sub start_style {
    my ($target, $token, $tagstack, $parstack, $parser, $safeeval, $style) = @_;
    my $currentstring = '';
   
    if ($target eq 'tex') {
    Apache::lonxml::startredirection();
    } else {
    $currentstring = $token->[4];
    }
   
    return $currentstring;
   }
   
   sub end_style {
    my ($target, $token, $tagstack, $parstack, $parser, $safeeval) = @_;
    my $currentstring = '';
   
    if ($target eq 'tex') {
    Apache::lonxml::endredirection();
    } else {
    $currentstring = $token->[2];
    }
    return $currentstring;
   }
   
 # accessrule  # accessrule
 sub start_accessrule {  sub start_accessrule {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $currentstring = '';      my $currentstring = '';
     my $eff=&Apache::lonxml::get_param      my $eff  =&Apache::lonxml::get_param('effect',$parstack,$safeeval,undef,1);
  ('effect',$parstack,$safeeval,undef,1);      my $realm=&Apache::lonxml::get_param('realm', $parstack,$safeeval,undef,1);
     my $realm=&Apache::lonxml::get_param      my $role =&Apache::lonxml::get_param('role',  $parstack,$safeeval,undef,1);
  ('realm',$parstack,$safeeval,undef,1);      my $type =&Apache::lonxml::get_param('type',  $parstack,$safeeval,undef,1);
     my $role=&Apache::lonxml::get_param  
  ('role',$parstack,$safeeval,undef,1);      my ($dom,$crs,$sec,$separator);
     $realm=~s/\s+//g;      if ($type eq 'user') {
     $realm=~s/\//\_/g;   ($dom,$crs,$sec)=split(m{/},$realm);
     $realm=~s/^\_//;   $crs = &LONCAPA::clean_username($crs);
     $realm=~s/\W/\;/g;   $separator = '/';
     $role=~s/\s+//g;      } else {
     $role=~s/\//\_/g;   ($dom,$crs,$sec)=split(/\_/,$realm);
     $role=~s/\W/\;/g;   $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') {      if ($target eq 'web') {
  my $args='';   my $args='';
  if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }   if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
Line 489  sub start_accessrule { Line 541  sub start_accessrule {
  }   }
     }      }
     if ($target eq 'meta') {      if ($target eq 'meta') {
  $currentstring='<rule>'.$eff.':'.$realm.':'.$role.'</rule>';   $currentstring='<rule>'.$eff.':'.$realm.':'.$role.':'.$type.'</rule>';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 503  sub end_accessrule { Line 555  sub end_accessrule {
  if ($args ne '') {   if ($args ne '') {
     $currentstring = $token->[4];      $currentstring = $token->[4];
  }   }
     }       }
     return $currentstring;      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)  #-- <body> tag (end tag required)
 sub start_body {  sub start_body {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
   
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  if ($Apache::lonhomework::parsing_a_problem) {   if ($Apache::lonhomework::parsing_a_problem) {
     &Apache::lonxml::warning("<body> tag found inside of <problem> tag this can cause problems.");      &Apache::lonxml::warning("<body> tag found inside of <problem> tag this can cause problems.");
     return '';      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];   if (&is_inside_of($tagstack, "head")) {
  foreach (keys %{$token->[2]}) {      &end_head(@_);
     $currentstring.=' '.$_.'="'.$token->[2]->{$_}.'"';  
  }  
  $currentstring.='>';  
  &Apache::lontexconvert::jsMath_reset();  
  if ($env{'environment.texengine'} eq 'jsMath') {  
     $currentstring.=&Apache::lontexconvert::jsMath_header();  
  }  
  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::lonxml::message_location();  
    my $extra_head = &generate_css_links();
   
       # Breadcrumbs
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       if ($env{'request.state'} eq 'construct') {
           my $url=&Apache::lonnet::hreflocation('',$env{'request.filename'});
           &Apache::lonhtmlcommon::add_breadcrumb({
               'text'  => 'Authoring Space',
               'href'  => &Apache::loncommon::authorspace($url),
           });
           &Apache::lonhtmlcommon::add_breadcrumb({
               'text'  => 'HTML Editor',
               'href'  => '',
           });
           # breadcrumbs (and tools) will be created
           # in start_page->bodytag->innerregister
       } else {
           # FIXME Where are we?
       }
   
           my $args = {'add_entries'    => $token->[2],
                       'force_register' => 1,};
           if ($target eq 'web') {
               $args->{'print_suppress'} = 1;
               if ($env{'request.use_absolute'}) {
                   $args->{'use_absolute'} = $env{'request.use_absolute'};
               }
           }
    $currentstring =
       &Apache::loncommon::start_page($Apache::londefdef::title,
      $Apache::londefdef::head
         .$extra_head,$args);
           my $header = '';
           if ($env{'request.state'} ne 'published' &&
               $env{'request.state'} ne 'construct') {
               $header=&Apache::lonmenu::constspaceform();
           }
           if ($env{'request.state'} ne 'published') {
               unless ($env{'form.inhibitmenu'} eq 'yes') {
                   $header.=&edit_controls();
               }
           }
           if ($env{'request.state'} eq 'construct') {
               unless ($env{'form.inhibitmenu'} eq 'yes') {
                   $currentstring.=&Apache::loncommon::head_subbox(
                                       &Apache::loncommon::CSTR_pageheader()
                                      .$header);
               }
           } elsif ($env{'request.state'} eq 'edit') {
               $currentstring.=&Apache::loncommon::head_subbox($header);
           }
           $currentstring.=&Apache::lonxml::message_location();
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\begin{document}';            $currentstring = '';   #  '\begin{document}' is in header.
     }       }
   
     return $currentstring;      return $currentstring;
 }  }
   
   sub edit_controls {
       my ($nochgview) = @_;
       my $result .= '
   <form method="post" action="">
   <div class="LC_edit_problem_header">';
       unless ($nochgview) {
           $result .= '
   <div class="LC_edit_problem_header_row1">'.
   &Apache::lonxml::renderingoptions().'
   <input type="submit" name="changeproblemmode" value="'.&mt('Change View').'" />
   </div>';
       }
       $result .= '
   <div><input type="submit" name="editmode" accesskey="e" value="'.&mt('Edit').'" />';
       if ($env{'browser.type'} ne 'explorer' || $env{'browser.version'} > 9) {
           my $uri = $env{'request.uri'};
           my $daxeurl = '/daxepage'.$uri;
           $result .= '<input type="button" value="'.&mt('Edit with Daxe').'" '.
                     'onclick="window.open(\''.$daxeurl.'\',\'_blank\');" />';
       }
       if (($env{'request.course.id'}) && ($env{'form.forceedit'})) {
           my $url=&Apache::lonnet::hreflocation('',$env{'request.filename'});
           if ($url =~ /\.html?$/i) {
               my ($cdom,$cnum);
               if ($env{'request.course.id'}) {
                   $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   if ($env{'request.filename'} =~ m{/userfiles/supplemental/default|\d+/}) {
                       if (&Apache::lonnet::is_course_upload($env{'request.filename'},
                                                             $cnum,$cdom)) {
                           &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                                                   ['folderpath','title']);
                       }
                   }
               }
               my ($symb,$itemtitle,$displayfile,$caller);
               if ($url =~ m{^/uploaded/$cdom/$cnum/portfolio/syllabus/}) {
                   $itemtitle = &mt('Syllabus');
                   $caller = "/public/$cdom/$cnum/syllabus";
               } else {
                   $caller = $url;
                   ($symb,$itemtitle,$displayfile) =
                       &Apache::lonxml::get_courseupload_hierarchy($url,
                                                                   $env{'form.folderpath'},
                                                                   $env{'form.title'});
               }
               if (($symb ne '') || ($env{'httpref.'.$url} ne '') ||
                   ($url =~ m{^/uploaded/$cdom/$cnum/portfolio/syllabus/})) {
                     $result .= ('&nbsp;' x 3).
                                &Apache::lonhtmlcommon::dependencies_button()."\n".
                                &Apache::lonhtmlcommon::dependencycheck_js($symb,
                                    $itemtitle,$url,$env{'form.folderpath'},$caller)."\n";
               }
           }
       }
       $result .= '</div>
   </div>
   </form>
   ';
       return $result;
   }
   
 sub end_body {  sub end_body {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off unclosed <p>      my $currentstring = &end_p(); # Close off unclosed <p>
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= &Apache::lonxml::xmlend($target,$parser);   $currentstring .= &Apache::loncommon::end_page({'discussion' => 1});
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}';     $currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 # \begin{center} causes a new paragprah spacing that looks odd inside   # \begin{center} causes a new paragprah spacing that looks odd inside
 # of a table cell  # 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_correction { return '\vspace*{-6 mm}'; }
   sub center_end_correction { return '\vspace*{-7 mm}'; }
   
 #-- <center> tag (end tag required)  #-- <center> tag (end tag required)
 sub start_center {  sub start_center {
     my ($target,$token,$tagstack) = @_;      my ($target,$token,$tagstack) = @_;
     my $currentstring = &end_p(); # Close off any prior para.      my $currentstring = &end_p(); # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if (&is_inside_of($tagstack, "table")) {   if (&is_inside_of($tagstack, "table")) {
     $currentstring .= &center_correction();      $currentstring .= &center_correction();
  }   }
  $currentstring .= '\begin{center}';     $currentstring .= '\begin{center}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 625  sub start_center { Line 742  sub start_center {
 sub end_center {  sub end_center {
     my ($target,$token,$tagstack) = @_;      my ($target,$token,$tagstack) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{center}';     $currentstring = '\end{center}';
    if (&is_inside_of($tagstack, "table")) {
       $currentstring .= &center_end_correction();
    }
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 638  sub end_center { Line 758  sub end_center {
 sub start_b {  sub start_b {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &disable_para();   &disable_para();
  $currentstring .= '\textbf{';     $currentstring .= '\textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_b {  sub end_b {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &enable_para();   &enable_para();
  $currentstring = '}';   $currentstring = '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 664  sub end_b { Line 784  sub end_b {
 sub start_strong {  sub start_strong {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &disable_para();   &disable_para();
  $currentstring = '\textbf{';     $currentstring = '\textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_strong {  sub end_strong {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &enable_para();   &enable_para();
  $currentstring = '}';     $currentstring = '}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 689  sub end_strong { Line 809  sub end_strong {
 sub start_h1 {  sub start_h1 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off any prior para.      my $currentstring = &end_p(); # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
Line 703  sub start_h1 { Line 823  sub start_h1 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     } elsif ($target eq 'meta') {      } elsif ($target eq 'meta') {
  $currentstring.='<subject>';   $currentstring.='<subject>';
  &start_output($target);   &start_output($target);
Line 714  sub start_h1 { Line 834  sub start_h1 {
 sub end_h1 {  sub end_h1 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post='\vskip 0 mm ';   my $post='\vskip 0 mm ';
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=lc(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1));
  if ($align eq 'center') {   if ($align eq 'center') {
     $post='\end{center}';      $post='\end{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
Line 730  sub end_h1 { Line 850  sub end_h1 {
     } elsif ($target eq 'meta') {      } elsif ($target eq 'meta') {
  &end_output($target);   &end_output($target);
  $currentstring='</subject>';   $currentstring='</subject>';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 738  sub end_h1 { Line 858  sub end_h1 {
 sub start_h2 {  sub start_h2 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off any prior para.      my $currentstring = &end_p(); # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
Line 752  sub start_h2 { Line 872  sub start_h2 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_h2 {  sub end_h2 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post='\vskip 0 mm ';   my $post='\vskip 0 mm ';
Line 773  sub end_h2 { Line 893  sub end_h2 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 781  sub end_h2 { Line 901  sub end_h2 {
 sub start_h3 {  sub start_h3 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off any prior para.      my $currentstring = &end_p(); # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
Line 795  sub start_h3 { Line 915  sub start_h3 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_h3 {  sub end_h3 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post='\vskip 0 mm ';   my $post='\vskip 0 mm ';
Line 816  sub end_h3 { Line 936  sub end_h3 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 824  sub end_h3 { Line 944  sub end_h3 {
 sub start_h4 {  sub start_h4 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off any prior para.      my $currentstring = &end_p(); # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
Line 838  sub start_h4 { Line 958  sub start_h4 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_h4 {  sub end_h4 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post='\vskip 0 mm ';   my $post='\vskip 0 mm ';
Line 859  sub end_h4 { Line 979  sub end_h4 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 867  sub end_h4 { Line 987  sub end_h4 {
 sub start_h5 {  sub start_h5 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off any prior paras.      my $currentstring = &end_p(); # Close off any prior paras.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
Line 881  sub start_h5 { Line 1001  sub start_h5 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_h5 {  sub end_h5 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post='\vskip 0 mm ';   my $post='\vskip 0 mm ';
Line 902  sub end_h5 { Line 1022  sub end_h5 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 910  sub end_h5 { Line 1030  sub end_h5 {
 sub start_h6 {  sub start_h6 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off any prior paras.      my $currentstring = &end_p(); # Close off any prior paras.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
Line 924  sub start_h6 { Line 1044  sub start_h6 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_h6 {  sub end_h6 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post='\vskip 0 mm ';   my $post='\vskip 0 mm ';
Line 945  sub end_h6 { Line 1065  sub end_h6 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 953  sub end_h6 { Line 1073  sub end_h6 {
 sub start_cite {  sub start_cite {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\textit{';   $currentstring .= '\textit{';
Line 964  sub start_cite { Line 1084  sub start_cite {
 sub end_cite {  sub end_cite {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
Line 976  sub end_cite { Line 1096  sub end_cite {
 sub start_i {  sub start_i {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\textit{';   $currentstring .= '\textit{';
Line 987  sub start_i { Line 1107  sub start_i {
 sub end_i {  sub end_i {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 999  sub end_i { Line 1119  sub end_i {
 sub start_address {  sub start_address {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\textit{';   $currentstring .= '\textit{';
Line 1010  sub start_address { Line 1130  sub start_address {
 sub end_address {  sub end_address {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
Line 1022  sub end_address { Line 1142  sub end_address {
 sub start_dfn {  sub start_dfn {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\textit{';   $currentstring .= '\textit{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_dfn {  sub end_dfn {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
Line 1045  sub end_dfn { Line 1165  sub end_dfn {
 sub start_tt {  sub start_tt {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\texttt{';   $currentstring .= '\texttt{';
Line 1056  sub start_tt { Line 1176  sub start_tt {
 sub end_tt {  sub end_tt {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
Line 1068  sub end_tt { Line 1188  sub end_tt {
 sub start_kbd {  sub start_kbd {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\texttt{';   $currentstring .= '\texttt{';
Line 1079  sub start_kbd { Line 1199  sub start_kbd {
 sub end_kbd {  sub end_kbd {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
Line 1091  sub end_kbd { Line 1211  sub end_kbd {
 sub start_code {  sub start_code {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\texttt{';   $currentstring .= '\texttt{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_code {  sub end_code {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1114  sub end_code { Line 1234  sub end_code {
 sub start_em {  sub start_em {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\emph{';   $currentstring .= '\emph{';
Line 1125  sub start_em { Line 1245  sub start_em {
 sub end_em {  sub end_em {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1137  sub end_em { Line 1257  sub end_em {
 sub start_q {  sub start_q {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\emph{';   $currentstring .= '\emph{';
Line 1148  sub start_q { Line 1268  sub start_q {
 sub end_q {  sub end_q {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1168  sub end_q { Line 1288  sub end_q {
     my $closing_string = ''; # String required to close <p>      my $closing_string = ''; # String required to close <p>
   
 #   Some tags are <p> fragile meaning that <p> inside of them  #   Some tags are <p> fragile meaning that <p> inside of them
 #   does not work within TeX mode.  This is managed via the   #   does not work within TeX mode.  This is managed via the
 #   counter below:  #   counter below:
 #  #
   
Line 1187  sub enable_para { Line 1307  sub enable_para {
 sub start_p {  sub start_p {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= &end_p(); # close off prior para if in progress.   $currentstring .= &end_p(); # close off prior para if in progress.
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
  if (! ($currentstring =~ /\//)) {   if (! ($currentstring =~ /\//)) {
Line 1197  sub start_p { Line 1317  sub start_p {
   
  $currentstring .= &end_p(); # close off prior para if in progress.   $currentstring .= &end_p(); # close off prior para if in progress.
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
    if (!defined $align) {
             # check inline CSS
             $align = &get_css_property('text-align',$parstack,$safeeval);
           }
  if ($align eq 'center') {   if ($align eq 'center') {
     $currentstring .='\begin{center}\par';      $currentstring .='\begin{center}\par ';
     $closing_string = '\end{center}';      $closing_string = '\end{center}';
     if (&is_inside_of($tagstack, "table")) {      if (&is_inside_of($tagstack, "table")) {
  $currentstring = &center_correction().$currentstring;   $currentstring = &center_correction().$currentstring;
     }      }
  } elsif ($align eq 'right') {   } elsif ($align eq 'right') {
     $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';      $currentstring.="\n".'\begin{flushright}';
     $closing_string= '}}';  #    $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';
       $closing_string= '\end{flushright}'."\n";
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{\rlap{';      $currentstring.= "\n".'\begin{flushleft}';
     $closing_string = '}\hfill}';  #    $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{{';
       $closing_string = '\end{flushleft}'."\n";
  } else {   } else {
             $currentstring.='\par ';              $currentstring.='\par ';
     if (&is_inside_of($tagstack, 'table')) {      if (&is_inside_of($tagstack, 'table')) {
Line 1242  sub end_p { Line 1368  sub end_p {
 sub start_br {  sub start_br {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my @tempo=@$tagstack;   my @tempo=@$tagstack;
Line 1252  sub start_br { Line 1378  sub start_br {
  #   #
  for (my $i=$#tempo;$i>=0;$i--) {   for (my $i=$#tempo;$i>=0;$i--) {
     if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') ||      if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') ||
                 ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul') ||                  ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul'))  {
                 ($tempo[$i] eq 'td') || ($tempo[$i] eq 'th'))  {  
  $signal=1;   $signal=1;
  last;      }
       if (($tempo[$i] eq 'td') || ($tempo[$i] eq 'th')) {
    $signal = 1;
     }      }
  }   }
  if ($signal) {   if ($signal != 1) {
     $currentstring .= ' \vskip 0 mm ';  
  } elsif ($$tagstack[-2] ne 'sub' && $$tagstack[-2] ne 'sup') {  
     $currentstring .= '\strut \\\\ \strut ';      $currentstring .= '\strut \\\\ \strut ';
  }   }
   
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1270  sub start_br { Line 1396  sub start_br {
 sub end_br {  sub end_br {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     }      }
     return $currentstring;      return $currentstring;
Line 1280  sub end_br { Line 1406  sub end_br {
 sub start_big {  sub start_big {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '{\large ';   $currentstring .= '{\large ';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_big {  sub end_big {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
Line 1303  sub end_big { Line 1429  sub end_big {
 sub start_small {  sub start_small {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '{\footnotesize ';   $currentstring .= '{\footnotesize ';
Line 1314  sub start_small { Line 1440  sub start_small {
 sub end_small {  sub end_small {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
Line 1326  sub end_small { Line 1452  sub end_small {
 sub start_basefont {  sub start_basefont {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
  if (defined $basesize) {   if (defined $basesize) {
Line 1340  sub start_basefont { Line 1466  sub start_basefont {
 sub end_basefont {  sub end_basefont {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
  if (defined $basesize) {   if (defined $basesize) {
Line 1355  sub end_basefont { Line 1481  sub end_basefont {
 sub start_font {  sub start_font {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);   my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);
  if ($face!~/symbol/i) {   $currentstring = $token->[4];
     if (($env{'browser.fontenhance'} eq 'on') ||   
  ($env{'browser.blackwhite'} eq 'on')) { return ''; }  
  }  
  $currentstring = $token->[4];       
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
  if (defined $fontsize) {   if (defined $fontsize) {
Line 1374  sub start_font { Line 1496  sub start_font {
 sub end_font {  sub end_font {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
  if (defined $fontsize) {   if (defined $fontsize) {
Line 1384  sub end_font { Line 1506  sub end_font {
     }      }
     return $currentstring;      return $currentstring;
 }  }
    
 #-- <strike> tag (end tag required)  #-- <strike> tag (end tag required)
 sub start_strike {  sub start_strike {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_strike {  sub end_strike {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring=&Apache::lonxml::endredirection();   $currentstring=&Apache::lonxml::endredirection();
  $currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g;    $currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g;
  $currentstring=~s/^\s*(\S)/\\underline\{$1/;    $currentstring=~s/^\s*(\S)/\\underline\{$1/;
  $currentstring=~s/(\S)\s*$/$1\}/;   $currentstring=~s/(\S)\s*$/$1\}/;
     }      }
     return $currentstring;      return $currentstring;
Line 1415  sub end_strike { Line 1537  sub end_strike {
 sub start_s {  sub start_s {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_s {  sub end_s {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring=&Apache::lonxml::endredirection();   $currentstring=&Apache::lonxml::endredirection();
Line 1441  sub end_s { Line 1563  sub end_s {
 sub start_sub {  sub start_sub {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\ensuremath{_{';   $currentstring .= '\raisebox{-\smallskipamount}{\scriptsize{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_sub {  sub end_sub {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}}';   $currentstring .= '}}';
Line 1464  sub end_sub { Line 1586  sub end_sub {
 sub start_sup {  sub start_sup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\ensuremath{^{';   $currentstring .= '\raisebox{\smallskipamount}{\scriptsize{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_sup {  sub end_sup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}}';   $currentstring .= '}}';
Line 1487  sub end_sup { Line 1609  sub end_sup {
 sub start_hr {  sub start_hr {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # End enclosing para.      my $currentstring = &end_p(); # End enclosing para.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } 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);   my $LaTeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
  if (defined $LaTeXwidth) {   if (defined $LaTeXwidth) {
     if ($LaTeXwidth=~/^%/) {      if ($LaTeXwidth=~/^%/) {
Line 1510  sub start_hr { Line 1653  sub start_hr {
  }   }
  $currentstring .= ' \vskip 0 mm \noindent\makebox['.$LaTeXwidth.']{'.$pre.'\makebox['.   $currentstring .= ' \vskip 0 mm \noindent\makebox['.$LaTeXwidth.']{'.$pre.'\makebox['.
                                     $LaTeXwidth.'][b]{\hrulefill}'.$post.'}\vskip 0 mm ';                                      $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;      return $currentstring;
 }  }
   
 sub end_hr {  sub end_hr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     }      }
     return $currentstring;      return $currentstring;
Line 1535  sub end_hr { Line 1688  sub end_hr {
 sub start_div {  sub start_div {
     my ($target,$token, $tagstack, $parstack, $parser, $safeeval) = @_;      my ($target,$token, $tagstack, $parstack, $parser, $safeeval) = @_;
     my $currentstring = &end_p(); # Close enclosing para.      my $currentstring = &end_p(); # Close enclosing para.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     }       }
     if ($target eq 'tex') {      if ($target eq 'tex') {
  # 4 possible alignments: left, right, center, and -missing-.   # 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 = '';   my $endstring = '';
   
Line 1550  sub start_div { Line 1706  sub start_div {
     $endstring      = '\end{center}';      $endstring      = '\end{center}';
     if (&is_inside_of($tagstack, "table")) {      if (&is_inside_of($tagstack, "table")) {
  $currentstring = &center_correction().$currentstring;   $currentstring = &center_correction().$currentstring;
    $endstring    .= &center_end_correction();
     }      }
  }   }
  elsif ($align eq 'right') {   elsif ($align eq 'right') {
Line 1571  sub start_div { Line 1728  sub start_div {
 sub end_div {  sub end_div {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     }      }
     if ($target eq 'tex') {      if ($target eq 'tex') {
Line 1586  sub end_div { Line 1743  sub end_div {
 sub start_a {  sub start_a {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,   my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
     undef,1);      undef,1);
  $currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href});   $currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href});
     } elsif ($target eq 'tex') {          if ($href =~ /\S/) {
  my $a=&Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);              if ($href !~ m{^https?://}) {
  my $b=&Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1);                  my $url=&Apache::lonnet::hreflocation('',$env{'request.filename'});
  if ($a=~/\S/) {                  my $linkurl;
     $a=~s/([^\\])%/$1\\\%/g;                  if ($href =~ m{^/uploaded/}) {
     $currentstring .= '\ref{URI: '.$a.'}';                      $linkurl = $href;
  } elsif ($b=~/\S/) {                  } elsif ($href =~ m{^[^/]}) {
     $currentstring .= '\ref{Anchor: '.$b.'}';                      my $path = $url;
  } else {                      $path  =~ s{[^/]*$}{};
     $currentstring.='';                      $linkurl = $path.$href;
  }                  }
                   if ($linkurl =~ m{^/uploaded/}) {
                       if (!&Apache::lonnet::allowed('bre',$linkurl)) {
                           if (&Apache::lonnet::is_on_map($url)) {
                               &Apache::lonxml::extlink($linkurl);
                           } elsif ($env{'request.course.id'}) {
                               my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                               my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                               if ($linkurl =~ m{^([^/]|/uploaded/$cdom/$cnum/(docs|supplemental)/)}) {
                                   my $cleanhref = &clean_docs_httpref($linkurl,$url,$cdom,$cnum);
                                   if ($cleanhref) {
                                       &Apache::lonxml::extlink($cleanhref);
                                   }
                               }
                           }
                       }
                   }
               }
           }
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1608  sub start_a { Line 1783  sub start_a {
 sub end_a {  sub end_a {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $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;      return $currentstring;
 }  }
   
Line 1618  sub end_a { Line 1815  sub end_a {
 sub start_li {  sub start_li {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);   my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
  my $value=&Apache::lonxml::get_param('value',$parstack,$safeeval,undef,0);   my $value=&Apache::lonxml::get_param('value',$parstack,$safeeval,undef,0);
  #FIXME need to support types i and I    #FIXME need to support types i and I
  if ($type=~/disc/) {   if ($type=~/disc/) {
     $currentstring .= ' \item[$\bullet$] ';      $currentstring .= ' \item[$\bullet$] ';
  } elsif ($type=~/circle/) {   } elsif ($type=~/circle/) {
Line 1640  sub start_li { Line 1837  sub start_li {
     $currentstring .= ' \item['.$value.'] ';      $currentstring .= ' \item['.$value.'] ';
  } else {   } else {
     $currentstring .= ' \item ';      $currentstring .= ' \item ';
  }     }
  $Apache::londefdef::list_index++;   $Apache::londefdef::list_index++;
     }      }
     return $currentstring;      return $currentstring;
Line 1649  sub start_li { Line 1846  sub start_li {
 sub end_li {  sub end_li {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # In case there's a <p> in the <li>      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];        $currentstring .= $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1659  sub end_li { Line 1856  sub end_li {
 sub start_u {  sub start_u {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_u {  sub end_u {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring=&Apache::lonxml::endredirection();   $currentstring=&Apache::lonxml::endredirection();
Line 1685  sub end_u { Line 1882  sub end_u {
 sub start_ul {  sub start_ul {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off enclosing list.      my $currentstring = &end_p(); # Close off enclosing list.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $TeXtype=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);   my $TeXtype=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
  $Apache::londefdef::list_index=0;   $Apache::londefdef::list_index=0;
  if ($TeXtype eq 'disc') {   if ($TeXtype eq 'disc') {
     $currentstring .= '\renewcommand{\labelitemi}{$\bullet$}'.      $currentstring .= '\renewcommand{\labelitemi}{$\bullet$}'.
                               '\renewcommand{\labelitemii}{$\bullet$}'.                                 '\renewcommand{\labelitemii}{$\bullet$}'.
                               '\renewcommand{\labelitemiii}{$\bullet$}'.                                '\renewcommand{\labelitemiii}{$\bullet$}'.
                               '\renewcommand{\labelitemiv}{$\bullet$}';                                '\renewcommand{\labelitemiv}{$\bullet$}';
  } elsif ($TeXtype eq 'circle') {   } elsif ($TeXtype eq 'circle') {
     $currentstring .= '\renewcommand{\labelitemi}{$\circ$}'.      $currentstring .= '\renewcommand{\labelitemi}{$\circ$}'.
                               '\renewcommand{\labelitemii}{$\circ$}'.                                 '\renewcommand{\labelitemii}{$\circ$}'.
                               '\renewcommand{\labelitemiii}{$\circ$}'.                                '\renewcommand{\labelitemiii}{$\circ$}'.
                               '\renewcommand{\labelitemiv}{$\circ$}';                                '\renewcommand{\labelitemiv}{$\circ$}';
  } elsif ($TeXtype eq 'square') {   } elsif ($TeXtype eq 'square') {
     $currentstring .= '\renewcommand{\labelitemi}{$\diamond$}'.      $currentstring .= '\renewcommand{\labelitemi}{$\diamond$}'.
                               '\renewcommand{\labelitemii}{$\diamond$}'.                                 '\renewcommand{\labelitemii}{$\diamond$}'.
                               '\renewcommand{\labelitemiii}{$\diamond$}'.                                '\renewcommand{\labelitemiii}{$\diamond$}'.
                               '\renewcommand{\labelitemiv}{$\diamond$}';                                '\renewcommand{\labelitemiv}{$\diamond$}';
  }   }
  $currentstring .= '\strut \begin{itemize}';     $currentstring .= '\strut \begin{itemize}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_ul {  sub end_ul {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{itemize} \renewcommand{\labelitemi}{$\bullet$}'.   $currentstring = '\end{itemize} \renewcommand{\labelitemi}{$\bullet$}'.
                                '\renewcommand{\labelitemii}{$\bullet$}'.                                  '\renewcommand{\labelitemii}{$\bullet$}'.
                                '\renewcommand{\labelitemiii}{$\bullet$}'.                                 '\renewcommand{\labelitemiii}{$\bullet$}'.
                                '\renewcommand{\labelitemiv}{$\bullet$}\strut ';                                   '\renewcommand{\labelitemiv}{$\bullet$}\strut ';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1729  sub end_ul { Line 1926  sub end_ul {
 sub start_menu {  sub start_menu {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\begin{itemize} ";     $currentstring = " \\begin{itemize} ";
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_menu {  sub end_menu {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\end{itemize}";     $currentstring = " \\end{itemize}";
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1752  sub end_menu { Line 1949  sub end_menu {
 sub start_dir {  sub start_dir {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # In case there's a <p> prior to the list.      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];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= " \\begin{itemize} ";     $currentstring .= " \\begin{itemize} ";
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_dir {  sub end_dir {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\end{itemize}";     $currentstring = " \\end{itemize}";
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1775  sub end_dir { Line 1972  sub end_dir {
 sub start_ol {  sub start_ol {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # In case there's a <p> prior to the list.      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];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::list_index=0;   $Apache::londefdef::list_index=0;
  my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);   my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
  if ($type eq '1') {   if ($type eq '1') {
     $currentstring .= '\renewcommand{\labelenumi}{\arabic{enumi}.}'.      $currentstring .= '\renewcommand{\labelenumi}{\arabic{enumi}.}'.
                               '\renewcommand{\labelenumii}{\arabic{enumii}.}'.                                 '\renewcommand{\labelenumii}{\arabic{enumii}.}'.
                               '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.                                '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.
                               '\renewcommand{\labelenumiv}{\arabic{enumiv}.}';                                '\renewcommand{\labelenumiv}{\arabic{enumiv}.}';
  } elsif ($type eq 'A') {   } elsif ($type eq 'A') {
     $currentstring .= '\renewcommand{\labelenumi}{\Alph{enumi}.}'.      $currentstring .= '\renewcommand{\labelenumi}{\Alph{enumi}.}'.
                               '\renewcommand{\labelenumii}{\Alph{enumii}.}'.                                 '\renewcommand{\labelenumii}{\Alph{enumii}.}'.
                               '\renewcommand{\labelenumiii}{\Alph{enumiii}.}'.                                '\renewcommand{\labelenumiii}{\Alph{enumiii}.}'.
                               '\renewcommand{\labelenumiv}{\Alph{enumiv}.}';                                '\renewcommand{\labelenumiv}{\Alph{enumiv}.}';
  } elsif ($type eq 'a') {   } elsif ($type eq 'a') {
Line 1806  sub start_ol { Line 2003  sub start_ol {
                               '\renewcommand{\labelenumiii}{\Roman{enumiii}.}'.                                '\renewcommand{\labelenumiii}{\Roman{enumiii}.}'.
                               '\renewcommand{\labelenumiv}{\Roman{enumiv}.}';                                '\renewcommand{\labelenumiv}{\Roman{enumiv}.}';
  }   }
  $currentstring .= '\strut \begin{enumerate}';     $currentstring .= '\strut \begin{enumerate}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_ol {  sub end_ol {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{enumerate}\renewcommand{\labelenumi}{\arabic{enumi}.}'.   $currentstring = '\end{enumerate}\renewcommand{\labelenumi}{\arabic{enumi}.}'.
                                         '\renewcommand{\labelenumii}{\arabic{enumii}.}'.                                          '\renewcommand{\labelenumii}{\arabic{enumii}.}'.
                                         '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.                                          '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.
                                         '\renewcommand{\labelenumiv}{\arabic{enumiv}.}\strut ';                                            '\renewcommand{\labelenumiv}{\arabic{enumiv}.}\strut ';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1829  sub end_ol { Line 2026  sub end_ol {
 sub start_dl {  sub start_dl {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # In case there's a <p> unclosed prior to the list.      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];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\begin{description}';   $currentstring .= '\begin{description}';
  $Apache::londefdef::DL++;   $Apache::londefdef::DL++;
Line 1838  sub start_dl { Line 2035  sub start_dl {
  $Apache::londefdef::DD[$Apache::londefdef::DL]=0;   $Apache::londefdef::DD[$Apache::londefdef::DL]=0;
  $Apache::londefdef::DT[$Apache::londefdef::DL]=0;   $Apache::londefdef::DT[$Apache::londefdef::DL]=0;
  $Apache::londefdef::seenDT[$Apache::londefdef::DL]=0;   $Apache::londefdef::seenDT[$Apache::londefdef::DL]=0;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_dl {  sub end_dl {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }   if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
  if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }   if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
Line 1854  sub end_dl { Line 2051  sub end_dl {
     $currentstring.=' '.$element.' ';      $currentstring.=' '.$element.' ';
  }   }
  pop(@Apache::londefdef::description);   pop(@Apache::londefdef::description);
  $currentstring.='\end{description}';     $currentstring.='\end{description}';
  delete($Apache::londefdef::DD[$Apache::londefdef::DL]);   delete($Apache::londefdef::DD[$Apache::londefdef::DL]);
  delete($Apache::londefdef::DT[$Apache::londefdef::DL]);   delete($Apache::londefdef::DT[$Apache::londefdef::DL]);
  delete($Apache::londefdef::seenDT[$Apache::londefdef::DL]);   delete($Apache::londefdef::seenDT[$Apache::londefdef::DL]);
  $Apache::londefdef::DL--;   $Apache::londefdef::DL--;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1867  sub end_dl { Line 2064  sub end_dl {
 sub start_dt {  sub start_dt {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring='';      my $currentstring='';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }   if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
  if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }   if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
  $Apache::londefdef::DT[-1]++;   $Apache::londefdef::DT[-1]++;
  $Apache::londefdef::seenDT[-1]=1;   $Apache::londefdef::seenDT[-1]=1;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_dt {  sub end_dt {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($Apache::londefdef::DT[-1]) {   if ($Apache::londefdef::DT[-1]) {
     my $data=&item_cleanup();      my $data=&item_cleanup();
     push(@{$Apache::londefdef::description[-1]},'\item['.$data.'] \strut \vskip 0mm');      push(@{$Apache::londefdef::description[-1]},'\item['.$data.'] \strut \vskip 0mm');
     $Apache::londefdef::DT[-1]--;      $Apache::londefdef::DT[-1]--;
  }   }
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub item_cleanup {  sub item_cleanup {
     my $item=&Apache::lonxml::endredirection();      my $item=&Apache::lonxml::endredirection();
     $item=~s/\\begin{center}//g;      $item=~s/\\begin\{center}//g;
     $item=~s/\\end{center}//g;      $item=~s/\\end\{center}//g;
     return $item;      return $item;
 }  }
   
Line 1905  sub item_cleanup { Line 2102  sub item_cleanup {
 sub start_dd {  sub start_dd {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }   if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
  if ($Apache::londefdef::DD[-1]) { &end_dd(@_);}   if ($Apache::londefdef::DD[-1]) { &end_dd(@_);}
Line 1917  sub start_dd { Line 2114  sub start_dd {
  $Apache::londefdef::description[-1]->[-1].=' \strut ';   $Apache::londefdef::description[-1]->[-1].=' \strut ';
  $Apache::londefdef::DD[-1]++;   $Apache::londefdef::DD[-1]++;
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_dd {  sub end_dd {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  $Apache::londefdef::description[-1]->[-1].=   $Apache::londefdef::description[-1]->[-1].=
     &Apache::lonxml::endredirection().' \vskip 0mm ';      &Apache::lonxml::endredirection().' \vskip 0mm ';
Line 1937  sub end_dd { Line 2134  sub end_dd {
 #-- <table> tag (end tag required)  #-- <table> tag (end tag required)
 #       <table> also ends any prior <p> that is not closed.  #       <table> also ends any prior <p> that is not closed.
 #               but, unless I allow <p>'s to nest, that's the  #               but, unless I allow <p>'s to nest, that's the
 #               only way I could think of to allow <p> in   #               only way I could think of to allow <p> in
 #               <tr> <th> bodies  #               <tr> <th> bodies
 #  #
 #list of supported attributes: border,width,TeXwidth  #list of supported attributes: border,width,TeXwidth,TeXtheme
   #                              align
 sub start_table {  sub start_table {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $textwidth = '';      my $textwidth = '';
     my $currentstring = &end_p();      my $currentstring = &end_p();
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $aa = {};   &disable_para(); # Can't have paras in a table.
  push @Apache::londefdef::table, $aa;   
  $Apache::londefdef::table[-1]{'row_number'} = -1;   #  Get the parameters that we can do something about:
         #maximum table's width (default coincides with text line length)  
  if ($#Apache::londefdef::table==0) {   my $border = &Apache::lonxml::get_param('border', $parstack, $safeeval, undef, 0);
     $textwidth=&recalc($env{'form.textwidth'}); #result is always in mm   my $width  = &Apache::lonxml::get_param('TeXwidth', $parstack, $safeeval, undef, 0);
     $textwidth=~/(\d+\.?\d*)/;   my $theme  = &Apache::lonxml::get_param('TeXtheme', $parstack, $safeeval, undef, 0);
     $textwidth=0.95*$1; #accounts "internal" LaTeX space for table frame   my $align  = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef, 0);
  } else {   my $cell_border = &Apache::lonxml::get_param('rules', $parstack, $safeeval, undef, 0);
     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   # The only thing that needs any figuring out is the width.. and then only if it is
  $textwidth=$Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}];    # a percent. If not it's assumed to be some valid TeX measurement unit e.g. 3.0cm
     } else {   #
               #try to use all space not used before (minus 5% for LaTeX table internal) - rather silly  
  $textwidth=$Apache::londefdef::table[-2]{'width'};   my $table = new Apache::lontable();
  for (my $i=0;$i<$Apache::londefdef::table[-2]{'counter_columns'};$i++) {   if ((defined $border) && ($border > 0)) {
     $textwidth=$textwidth-$Apache::londefdef::table[-2]{'TeXlen'}[0][$i];   #    &Apache::lonnet::logthis("Turning on table borders: $border");
  }      $table->table_border(1);
       if (!defined $cell_border) {
    $table->cell_border(1); # Default for rules is all if rules not defined.
     }      }
  }   }
   
  # width either comes forced from the TeXwidth or the width parameters.   if ((defined $cell_border)) {
  # in either case it can be a percentage or absolute width.      if ($cell_border eq 'all') {
  # in the width case we ignore absolute width    $table->cell_border(1);
  my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);      } elsif ($cell_border eq 'rows') {
  if (!defined($TeXwidth)) {   $table->cell_border(2);
     my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,      } elsif ($cell_border eq 'cols') {
        $safeeval,undef,1);   $table->cell_border(3);
     if ($htmlwidth =~ /%/) {      } elsif($cell_border eq 'groups') {
  $TeXwidth = $htmlwidth;   $table->cell_border(4);
     } else {       } else {
  $TeXwidth = $textwidth;   $table->cell_border(0);
     }      }
  } else {  
     $Apache::londefdef::table[-1]{'forcedtablewidth'} = 1;  
  }   }
  if ($TeXwidth=~/%/) {   if (defined $theme) {
     $Apache::londefdef::table[-1]{'percent'}=1;      $table->theme($theme);
     $TeXwidth=~/(\d+)/;  
             $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;  
  } else {  
     $Apache::londefdef::table[-1]{'width'}=$TeXwidth;  
  }   }
         #  In the end, however the table width cannot be wider than $textwidth...   if (defined $align) {
       $table->alignment($align);
  if ($Apache::londefdef::table[-1]{'width'} > $textwidth) {  
     $Apache::londefdef::table[-1]{'width'} = $textwidth;  
  }   }
   
         #table's border   # Missing width is most of page width
  my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval);   
         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);   if (!(defined $width)) {
  unless (defined $border) { $border = 0; }      $width = '70%';
  if ($border) {   
     $Apache::londefdef::table[-1]{'hinc'} = '\hline ';   
     $Apache::londefdef::table[-1]{'vinc'} = '&';   
     $Apache::londefdef::table[-1]{'vvinc'} = '|';  
  } else {  
     $Apache::londefdef::table[-1]{'hinc'} = '';   
     $Apache::londefdef::table[-1]{'vinc'} = '&';   
     $Apache::londefdef::table[-1]{'vvinc'} = '';  
  }   }
  if ($#Apache::londefdef::table==0) {  
     #    Note that \newline seems to destroy the alignment envs.   # If a percentage, need to calculate what this means in terms of
     # $Apache::londefdef::table[-1]{'output'}='\strut\newline\strut\setlength{\tabcolsep}{1 mm}';   # page width:
     $Apache::londefdef::table[-1]{'output'}='\strut'.'\\\\'."\n".'\strut\setlength{\tabcolsep}{1 mm}';  
    if ($width =~ /%$/) {
       my $textwidth = &recalc($env{'form.textwidth'});  # Page width in mm.
       $width =~ s/%//;
       $width = $width * $textwidth / 100.0;
       $width .= " mm";
       $table->width($width);
  }   }
  $Apache::londefdef::table[-1]{'output'}.=' \noindent \begin{tabular} ';  
         $Apache::londefdef::table[-1]{'TeXlen'}=[];  
         $Apache::londefdef::table[-1]{'objectlen'}=[];  
         $Apache::londefdef::table[-1]{'objectsignal'}=[];  
         $Apache::londefdef::table[-1]{'maxlen'}=[];  
         $Apache::londefdef::table[-1]{'minlen'}=[];  
         $Apache::londefdef::table[-1]{'content'}=[];  
         $Apache::londefdef::table[-1]{'align'}=[];  
         $currentstring.='\keephidden{NEW TABLE ENTRY}';  
   
    push(@Apache::londefdef::table, $table);
           $currentstring.=' \keephidden{NEW TABLE ENTRY}';
   
     }      }
     return $currentstring;      return $currentstring;
 }  }
    
 sub end_table {  sub end_table {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $inmemory = '';  
  my $output = '';  
  my $WARNING='';   my $table = pop(@Apache::londefdef::table);
         #width of columns from TeXwidth attributes   my $t     = $table->generate();
    # &Apache::lonnet::logthis("Generating string");
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {   $currentstring = $t->generate_string();
     for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {   # &Apache::lonnet::logthis("Generated: $currentstring");
  if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]<$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]) {   &enable_para();
     $Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]=$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn];  
  }  
     }  
  }  
         #free space and number of empty columns  
  my ($available_space,$empty_columns)=($Apache::londefdef::table[-1]{'width'},0);  
  if ($#Apache::londefdef::table ne 0) {$available_space=0.9*$available_space;}   
  for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {  
     if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]==0) {  
  $empty_columns++;  
     } else {  
  $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 ($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]) {  
  $localmin=$Apache::londefdef::table[-1]{'minlen'}[$in][$jn];  
     }  
     if ($localmax<$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn]) {  
  $localmax=$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn];  
     }  
  }  
  push @min_len, $localmin;  
  push @max_len, $localmax;  
  }  
  for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$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]) {  
     $localmin=$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn];  
  }  
     }  
     if ($max_len[$jn]<$localmin) {  
  $max_len[$jn]=$localmin;  
      $Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;  
     }#object size is bigger  
     if ($min_len[$jn]<$localmin) {  
  $min_len[$jn]=$localmin;  
  $Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;  
     }#object size is bigger  
     if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]!=0) {  
  $min_len[$jn]=0;  
  $max_len[$jn]=0;  
     }  
  }  
        #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;  
  for (my $jn=0;$jn<=$#max_len;$jn++) {  
     $space_neeeded=$space_neeeded+$max_len[$jn];  
  }  
  if ($space_neeeded<=$available_space) {  
     for (my $jn=0;$jn<=$#max_len;$jn++) {  
  if ($fwidth[$jn]==0) {  
     $fwidth[$jn]=$max_len[$jn];  
  }  
     }  
  } else {  
         #step 2. adjustment by minimum value (estimation)  
     $space_neeeded=0;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  $space_neeeded+=$min_len[$jn];  
     }  
     if ($space_neeeded>$available_space) {  
  $WARNING=' \textbf{NOT ENOUGH SPACE FOR TABLE} ';  
  for (my $jn=0;$jn<=$#max_len;$jn++) {  
     if ($fwidth[$jn]==0) {  
  $fwidth[$jn]=$min_len[$jn];  
     }  
  }  
  #check if we have objects which can be scaled  
  my $how_many_to_scale=0;  
  my @to_scale=();  
  for (my $jn=0;$jn<=$#max_len;$jn++) {  
     if ($Apache::londefdef::table[-1]{'objectsignal'}[$jn] eq '1') {  
  $how_many_to_scale++;  
  push @to_scale, $jn;  
     }  
  }  
  if ($how_many_to_scale>0) {  
     my $space_to_adjust=($space_neeeded-$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)*)/;  
     if ($1 ne '') {  
  my $current_length=&recalc($1);  
  $current_length=~/(\d+\.?\d*)/;  
  $current_length=$current_length-$space_to_adjust;  
  $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/width=$current_length mm/;  
     }  
     $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/\[(\d+\.?\d*)\s*mm\]/;  
     if ($1 ne '') {  
  my $current_length=$1;  
  $current_length=$current_length-$space_to_adjust;  
  $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/\[(\d+\.?\d*)\s*mm\]/\[$current_length mm\]/;  
     }  
  }  
  $fwidth[$jn]=$fwidth[$jn]-$space_to_adjust;  
     }  
  }  
     } else {  
       #step 3. adjustment over minimal + corrections  
  my $enlarge_coef=$available_space/$space_neeeded;  
  my $acsessive=0;  
  for (my $jn=0;$jn<=$#min_len;$jn++) {  
     $adjust[$jn]=$min_len[$jn]*$enlarge_coef;  
     if ($adjust[$jn]>$max_len[$jn]) {  
  $fwidth[$jn]=$max_len[$jn];  
  $acsessive=$acsessive+$adjust[$jn]-$max_len[$jn];  
  $adjust[$jn]=0;  
     }  
  }  
  if ($acsessive>0) {  
  #we have an excess of space and can redistribute it  
     my $notempty_columns=0;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  if ($adjust[$jn]!=0) {  
     $notempty_columns++;  
  }  
     }  
     my $per_column=$acsessive/$notempty_columns;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  if ($adjust[$jn]!=0) {  
     $adjust[$jn]+=$per_column;  
     $fwidth[$jn]=$adjust[$jn];  
  }  
     }  
  } else {  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  $fwidth[$jn]=$adjust[$jn];  
     }  
  }  
     }  
  }  
         #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;  
     }  
  }  
         #removing of empty columns if allowed  
         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);  
  if ($permission eq 'yes') {  
     my @cleaned_table=();  
             my @cleaned_header=();  
     my $colind=0;  
     for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {  
  if ($fwidth[$jn]!=0) {  
     #we need to copy column  
     for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
  $cleaned_table[$in][$colind]=$Apache::londefdef::table[-1]{'content'}[$in][$jn];  
  $cleaned_header[$colind]=$fwidth[$jn];  
     }  
     $colind++;  
  }  
     }  
     $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++) {  
   
  #-----------------------------------------------------------  
                 #   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 $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  
  #   
   
  if ($colspan > 1) {  
     $output .= '\multicolumn{'.  
  $colspan  
  .'}{|l|}{';  
  }  
   
  if ($rowspan > 1) {  
     $have_rowspan++;  
     $output .= '\multirow{'.$rowspan.'}[0]{'.$fwidth[$jn].'mm}{';  
  }  
  if (($rowspan eq '^') || ($rowspan eq '_')) {  
     $have_rowspan++;  
  }  
  #--------------------------------------------------------------  
   
  if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {  
     $output.=&center_correction().'\begin{center}';  
  } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {  
     $output.=' \hfill \llap{'  
  }  
  $output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn];  
  if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {  
     $output.='\end{center}';  
  } elsif ($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'};}  
     }  
     #  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 {  
     $currentstring .= $Apache::londefdef::table[-1]{'output'};  
     pop @Apache::londefdef::table;  
     undef @Apache::londefdef::table;  
  }  
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 2346  sub end_table { Line 2236  sub end_table {
 sub start_tr {  sub start_tr {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
   
    my $align = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef, 1);
    $Apache::londefdef::table[-1]->start_row();
   
    if ($align ne '') {
       $Apache::londefdef::table[-1]->configure_row({default_halign => $align});
    }
   
    #---------------------------------------------------------------
    # Old table code.
    #---------------------------------------------------------------
   
    if (0) {
  $Apache::londefdef::table[-1]{'row_number'}++;   $Apache::londefdef::table[-1]{'row_number'}++;
  my $alignchar=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $alignchar=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if ($alignchar ne '') {   if ($alignchar ne '') {
Line 2367  sub start_tr { Line 2270  sub start_tr {
  push @ {$Apache::londefdef::table[-1]{'minlen'}}, [];   push @ {$Apache::londefdef::table[-1]{'minlen'}}, [];
  push @ {$Apache::londefdef::table[-1]{'maxlen'}}, [];   push @ {$Apache::londefdef::table[-1]{'maxlen'}}, [];
  push @ {$Apache::londefdef::table[-1]{'content'}}, [];   push @ {$Apache::londefdef::table[-1]{'content'}}, [];
     }       }
       }
     return $currentstring;      return $currentstring;
 }  }
           
 sub end_tr {  sub end_tr {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close any pending <p> in the row.      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];        $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
   
    # In case the user is missing a </td> or </th> tag:
   
    if ($Apache::londefdef::TD_redirection) {
       &end_td_tex($parstack,$parser,$safeeval);
    }
    $Apache::londefdef::table[-1]->end_row();
   
    #-----------------------------------------------
    # Old table code
    #-----------------------------------------------
   
    if (0) {
  if ($Apache::londefdef::TD_redirection) {   if ($Apache::londefdef::TD_redirection) {
     &end_td_tex($parstack,$parser,$safeeval);          &end_td_tex($parstack,$parser,$safeeval);
  }   }
  # Counter columns must be the maximum number of columns seen   # Counter columns must be the maximum number of columns seen
  # in the table so far so:   # in the table so far so:
  if ($Apache::londefdef::table[-1]{'prior_columns'} > $Apache::londefdef::table[-1]{'counter_columns'}) {   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'};      $Apache::londefdef::table[-1]{'counter_columns'} = $Apache::londefdef::table[-1]{'prior_columns'};
  }   }
       }
   
   
     }      }
Line 2396  sub end_tr { Line 2313  sub end_tr {
 sub start_td {  sub start_td {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::TD_redirection = 1;   $Apache::londefdef::TD_redirection = 1;
  &tag_check('tr','td',$tagstack,$parstack,$parser,$safeeval);   &tag_check('tr','td',$tagstack,$parstack,$parser,$safeeval);
     }       }
     return $currentstring;      return $currentstring;
 }     }
       
 sub tag_check {  sub tag_check {
     my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
     my @ar=@$parstack;       my @ar=@$parstack;
     for (my $i=$#ar-1;$i>=0;$i--) {      for (my $i=$#ar-1;$i>=0;$i--) {
  if (lc($$tagstack[$i]) eq $good_tag) {   if (lc($$tagstack[$i]) eq $good_tag) {
     &start_td_tex($parstack,$parser,$safeeval);      &start_td_tex($parstack,$parser,$safeeval);
Line 2421  sub tag_check { Line 2338  sub tag_check {
     }      }
     return '';      return '';
 }  }
    
   #
   #  Factor out cell configuration hash generation:
   #
   
   sub cell_config_hash {
       my ($align, $rowspan, $colspan, $width) = @_;
       if ($rowspan ne '') {
           $rowspan =~ s/^\s+|\s+$//g;
       }
       if ($colspan ne '') {
           $colspan =~ s/^\s+|\s+$//g;
       }
       my %config;
       if ($align ne '') {
    $config{'halign'} = $align;
       }
       if (($colspan =~ /^\d+$/) && ($colspan > 0)) {
    $config{'colspan'} = $colspan;
       }
       if (($rowspan =~ /^\d+$/) && ($rowspan > 0)) {
    $config{'rowspan'} = $rowspan;
       }
       if ($width ne '') {
    $config{'width'} = $width;
       }
       return \%config;
   }
   
 sub start_td_tex {  sub start_td_tex {
     my ($parstack,$parser,$safeeval) = @_;      my ($parstack,$parser,$safeeval) = @_;
   
       # At this stage, an empty cell is created with the
       # appropriate rowspan/colspan and alignment
       # attributes, but empty of text.  end_td_tex will
       # fetch the contents from the recursive parse and
       # fill the cell with them:
       my $align   = &Apache::lonxml::get_param('align', $parstack, $safeeval);
       my $rowspan = &Apache::lonxml::get_param('rowspan', $parstack, $safeeval);
       my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval);
       my $width   = &Apache::lonxml::get_param('TeXwidth', $parstack, $safeeval);
       my $config = &cell_config_hash($align, $rowspan, $colspan, $width);
   
       my $table = $Apache::londefdef::table[-1];
       $table->add_cell('', $config);
   
   
       #------------------------------------------------
       #  Old table code.
       #------------------------------------------------
   
       if (0) {
   
     my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);      my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
     if ($alignchar eq '') {      if ($alignchar eq '') {
  $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];   $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
Line 2436  sub start_td_tex { Line 2403  sub start_td_tex {
  $current_length=~/(\d+\.?\d*)/;   $current_length=~/(\d+\.?\d*)/;
  push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
     }      }
       }
     &Apache::lonxml::startredirection();      &Apache::lonxml::startredirection();
     return '';      return '';
 }  }
   
 sub end_td_tex {  sub end_td_tex {
   
       my $text = &Apache::lonxml::endredirection();
       my $table = $Apache::londefdef::table[-1];
       $table->append_cell_text($text);
   
       #-------------------------------------------------
       # Old table code
       #-------------------------------------------------
   
       if (0) {
     my ($parstack,$parser,$safeeval) = @_;      my ($parstack,$parser,$safeeval) = @_;
     my $current_row    = $Apache::londefdef::table[-1]{'row_number'};      my $current_row    = $Apache::londefdef::table[-1]{'row_number'};
     my $current_column = $Apache::londefdef::table[-1]{'counter_columns'};       my $current_column = $Apache::londefdef::table[-1]{'counter_columns'};
     my $data = &Apache::lonxml::endredirection();      my $data = &Apache::lonxml::endredirection();
   
     #  The rowspan array of the table indicates which cells are part of a span.      #  The rowspan array of the table indicates which cells are part of a span.
Line 2453  sub end_td_tex { Line 2431  sub end_td_tex {
     #  If this and subsequent cells are part of a rowspan, we must      #  If this and subsequent cells are part of a rowspan, we must
     #  push along the row until we find one that is not.      #  push along the row until we find one that is not.
   
     while ((defined $Apache::londefdef::table[-1]{'rowspan'}[$current_row] [$current_column])       while ((defined $Apache::londefdef::table[-1]{'rowspan'}[$current_row] [$current_column])
    && ($Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column] =~ /[\^\_]/)) {     && ($Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column] =~ /[\^\_]/)) {
  # Part of a span.   # Part of a span.
  push @ {$Apache::londefdef::table[-1]{'content'}[-1]}, '';   push @ {$Apache::londefdef::table[-1]{'content'}[-1]}, '';
  $current_column++;   $current_column++;
     }      }
     $Apache::londefdef::table[-1]{'counter_columns'} = $current_column;      $Apache::londefdef::table[-1]{'counter_columns'} = $current_column;
      
   
     # Get the column and row spans.      # Get the column and row spans.
     # Colspan can be done via \multicolumn if I can figure out the data structs.      # Colspan can be done via \multicolumn if I can figure out the data structs.
Line 2489  sub end_td_tex { Line 2467  sub end_td_tex {
   
     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);      my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
     if (defined $TeXwidth) {      if (defined $TeXwidth) {
  push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   for (my $c = 0; $c < $colspan; $c++) {
  push @ {$Apache::londefdef::table[-1]{'minlen'}[$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'}] },'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 {      } else {
  if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {   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;      my $garbage_data=$data;
Line 2507  sub end_td_tex { Line 2487  sub end_td_tex {
  if ($fwidth<$current_length) {$fwidth=$current_length;}   if ($fwidth<$current_length) {$fwidth=$current_length;}
  $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;   $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;
     }      }
     push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$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'}] },$fwidth;   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$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]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
     push @ {$Apache::londefdef::table[-1]{'maxlen'}[$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';
       }
  } 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)*/) {   } 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 $garbage_data=$data;
     my $fwidth=0;      my $fwidth=0;
Line 2526  sub end_td_tex { Line 2508  sub end_td_tex {
  if ($fwidth<$1) {$fwidth=$1;}   if ($fwidth<$1) {$fwidth=$1;}
  $garbage_data=~s/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;   $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';      for (my $c = 0; $c < $colspan; $c++) {
     push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$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]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
     push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     $data=~s/\\\\\s*$//;    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
  } else {        }
     $data=~s/^\s+(\S.*)/$1/;       $data=~s/\\\\\s*$//;
    } else {
       $data=~s/^\s+(\S.*)/$1/;
     $data=~s/(.*\S)\s+$/$1/;      $data=~s/(.*\S)\s+$/$1/;
     $data=~s/(\s)+/$1/;      $data=~s/(\s)+/$1/;
     my ($current_length,$min_length)=(0,0);      my ($current_length,$min_length)=(0,0);
Line 2557  sub end_td_tex { Line 2541  sub end_td_tex {
  if ($min_length<$lengthword) {$min_length=$lengthword;}   if ($min_length<$lengthword) {$min_length=$lengthword;}
     }      }
     }      }
     push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$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]{'TeXlen'}[$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]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;   push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
  }           push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
       }
    }
     }      }
     # Substitute all of the tables nested in this cell in their appropriate places.      # 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...      my $nested_count = $#{$Apache::londefdef::table[-1]{'include'}}; # This one is constant...
     for (my $in=0; $in<=$nested_count; $in++) {          for (my $in=0; $in<=$nested_count; $in++) {
  my $nested = shift @{$Apache::londefdef::table[-1]{'include'}};   my $nested = shift @{$Apache::londefdef::table[-1]{'include'}};
  $nested =~ s/\\end\{tabular\}\\strut\\\\/\\end\{tabular\}/;   $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\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
Line 2597  sub end_td_tex { Line 2583  sub end_td_tex {
   
     }      }
   
       }
   
     return '';      return '';
 }  }
Line 2605  sub end_td_tex { Line 2591  sub end_td_tex {
 sub end_td {  sub end_td {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
         $Apache::londefdef::TD_redirection =0;          $Apache::londefdef::TD_redirection =0;
  &end_td_tex($parstack,$parser,$safeeval);   &end_td_tex($parstack,$parser,$safeeval);
Line 2618  sub end_td { Line 2604  sub end_td {
 sub start_th {  sub start_th {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::TD_redirection = 1;   $Apache::londefdef::TD_redirection = 1;
  &tagg_check('tr','th',$tagstack,$parstack,$parser,$safeeval);   &tagg_check('tr','th',$tagstack,$parstack,$parser,$safeeval);
     }       }
     return $currentstring;      return $currentstring;
 }     }
       
 sub tagg_check {  sub tagg_check {
     my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
     my @ar=@$parstack;       my @ar=@$parstack;
     for (my $i=$#ar-1;$i>=0;$i--) {      for (my $i=$#ar-1;$i>=0;$i--) {
  if (lc($$tagstack[$i]) eq $good_tag) {   if (lc($$tagstack[$i]) eq $good_tag) {
     &start_th_tex($parstack,$parser,$safeeval);      &start_th_tex($parstack,$parser,$safeeval);
Line 2643  sub tagg_check { Line 2629  sub tagg_check {
     }      }
     return '';      return '';
 }  }
    
 sub start_th_tex {  sub start_th_tex {
     my ($parstack,$parser,$safeeval) = @_;      my ($parstack,$parser,$safeeval) = @_;
   
       my $alignment = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef,1);
       my $rowspan  =  &Apache::lonxml::get_param('rowspan', $parstack, $safeeval, undef, 1);
       my $colspan  =  &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 1);
   
       my $config   = cell_config_hash($alignment, $rowspan, $colspan);
       my $table    = $Apache::londefdef::table[-1];
       $table->add_cell('\textbf{', $config);
   
       #-------------------------------------------------------------------------------------
       #
       #  Old table code.
       #
       #--------------------------------------------------------------------------------------
   
       if (0) {
   
   
     my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);      my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
     if ($alignchar eq '') {      if ($alignchar eq '') {
  $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];   $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
Line 2658  sub start_th_tex { Line 2662  sub start_th_tex {
  $current_length=~/(\d+\.?\d*)/;   $current_length=~/(\d+\.?\d*)/;
  push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
     }      }
       }
   
       # Accept xml until the </th> tag.
   
     &Apache::lonxml::startredirection();      &Apache::lonxml::startredirection();
     return '';      return '';
 }  }
   
 sub end_th_tex {  sub end_th_tex {
     my ($parstack,$parser,$safeeval) = @_;      my ($parstack,$parser,$safeeval) = @_;
   
       my $table = $Apache::londefdef::table[-1];
       my $text  = &Apache::lonxml::endredirection();
       $table->append_cell_text($text.'}');
   
       #-----------------------------------------------------------------------------
       #  Old table code:
       #-----------------------------------------------------------------------------
   
       if (0) {
     my $current_row = $Apache::londefdef::table[-1]{'row_number'};      my $current_row = $Apache::londefdef::table[-1]{'row_number'};
     my $data=&Apache::lonxml::endredirection();      my $data=&Apache::lonxml::endredirection();
     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);      my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
Line 2690  sub end_th_tex { Line 2708  sub end_th_tex {
     push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;      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]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
  } else {     } else {
     $data=~s/^\s+(\S.*)/$1/;       $data=~s/^\s+(\S.*)/$1/;
     $data=~s/(.*\S)\s+$/$1/;      $data=~s/(.*\S)\s+$/$1/;
     $data=~s/(\s)+/$1/;      $data=~s/(\s)+/$1/;
     my ($current_length,$min_length)=(0,0);      my ($current_length,$min_length)=(0,0);
Line 2720  sub end_th_tex { Line 2738  sub end_th_tex {
     push @ {$Apache::londefdef::table[-1]{'objectlen'}[$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]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
     push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_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++) {            for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {
     $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;      $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
  }   }
     #make data bold      #make data bold
     $data='\textbf{'.$data.'}';      $data='\textbf{'.$data.'}';
     push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;      push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
       }
     return'';      return'';
 }  }
   
 sub end_th {  sub end_th {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close any open <p> in the row.      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];        $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
         $Apache::londefdef::TD_redirection =0;          $Apache::londefdef::TD_redirection =0;
  &end_th_tex($parstack,$parser,$safeeval);   &end_th_tex($parstack,$parser,$safeeval);
     }      }
     return $currentstring;      return $currentstring;
 }  }
        
 #-- <img> tag (end tag forbidden)  #-- <img> tag (end tag forbidden)
 #  #
 #  Render the <IMG> tag.  #  Render the <IMG> tag.
 #     <IMG> has the following attributes (in addition to the   #     <IMG> has the following attributes (in addition to the
 #     standard HTML ones:  #     standard HTML ones:
 #      TeXwrap   - Governs how the tex target will try to wrap text around  #      TeXwrap   - Governs how the tex target will try to wrap text around
 #                  horizontally aligned images.  #                  horizontally aligned images.
 #      TeXwidth  - The width of the image when rendered for print (mm).  #      TeXwidth  - The width of the image when rendered for print (mm).
 #      TeXheight - The height of the image when rendered for print (mm)  #      TeXheight - The height of the image when rendered for print (mm)
 #         (Note there seems to also be support for this as a % of page size)  #         (Note there seems to also be support for this as a % of page size)
 #        #
 sub start_img {  sub start_img {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,      my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,
  undef,1);   undef,1);
     if (not $src and ($target eq 'web' or $target eq 'tex')) {       if (! $src &&
    ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex')
    ) {
  my $inside = &Apache::lonxml::get_all_text("/img",$parser,$style);   my $inside = &Apache::lonxml::get_all_text("/img",$parser,$style);
  return '';   return '';
     }      }
     &Apache::lonxml::extlink($src);      unless ($src =~ m{^data\:image/gif;base64,}) {
           &Apache::lonxml::extlink($src);
       }
     my $currentstring = '';      my $currentstring = '';
     my $scaling = .3;      my $scaling = .3;
   
    # Render unto browsers that which are the browser's...     # 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') {          my $enc = ('yes' eq
     my $enc = ('yes' eq                      lc(&Apache::lonxml::get_param('encrypturl',$parstack,
        lc(&Apache::lonxml::get_param('encrypturl',$parstack,                        $safeeval)));
      $safeeval)));          unless ($src =~ m{^data\:image/gif;base64,}) {
     $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src},              $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src},
  $enc);                              $enc);
  } else {          }
     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.']';  
  }  
   
  # and render unto TeX that which is LaTeX  
   
       # and render unto TeX that which is LaTeX
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  #   #
  #  The alignment will require some superstructure to be put around   #  The alignment will require some superstructure to be put around
Line 2794  sub start_img { Line 2808  sub start_img {
  #  simulate the alignments offered by html.   #  simulate the alignments offered by html.
  #   #
  #   #
  my $align = lc(&Apache::lonxml::get_param('align',    my $align = lc(&Apache::lonxml::get_param('align',
   $parstack,    $parstack,
   $safeeval,    $safeeval,
   undef,1));    undef,1));
Line 2804  sub start_img { Line 2818  sub start_img {
  #   #
  &Apache::lonxml::debug("Alignemnt = $align");   &Apache::lonxml::debug("Alignemnt = $align");
  #  LaTeX's image/text wrapping is really bad since it wants to   #  LaTeX's image/text wrapping is really bad since it wants to
  #  make figures float.     #  make figures float.
         #   The user has the optional parameter (applicable only to l/r          #   The user has the optional parameter (applicable only to l/r
  # alignment to use the picins/parpic directive to get wrapped text   # alignment to use the picins/parpic directive to get wrapped text
  # this is also imperfect.. that's why we give them a choice...   # this is also imperfect.. that's why we give them a choice...
Line 2824  sub start_img { Line 2838  sub start_img {
  if (($latex_rendering eq 'texwrap') && &is_inside_of($tagstack, "table")) {   if (($latex_rendering eq 'texwrap') && &is_inside_of($tagstack, "table")) {
     $latex_rendering = 'parpic';      $latex_rendering = 'parpic';
  }   }
   
  # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src");   # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src");
   
  #if original gif/jpg/png file exist do following:   #if original bmp/gif/jpg/png/svg file exist do following:
  my $origsrc=$src;   my $origsrc=$src;
  my ($path,$file) = &get_eps_image($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);   $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
  &Apache::lonxml::debug("path = $path file = $file src = $src");   &Apache::lonxml::debug("path = $path file = $file src = $src");
  if (-e $src) {   if (-e $src) {
     &Apache::lonxml::debug("$src exists");      &Apache::lonxml::debug("$src exists");
     my ($height_param,$width_param)=      my ($height_param,$width_param)=
  &image_size($origsrc,0.3,$parstack,$safeeval);   &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;      my $size;
     if ($width_param)  { $size.='width='.$width_param.' mm,'; }      if ($width_param)  { $size.='width='.$width_param.' mm,'; }
     if ($height_param) { $size.='height='.$height_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='['.$size;
     $size=~s/,$/]/;       $size=~s/,$/]/;
     $currentstring .= '\graphicspath{{'.$destpath.'}}'      $currentstring .= '\graphicspath{{'.$path.'}}'
  .'\includegraphics'.$size.'{'.$destfile.'} ';   .'\includegraphics'.$size.'{'.$file.'} ';
       my $closure;
     #    If there's an alignment specification we need to honor it here.      ($currentstring, $closure) = &align_latex_image($align,
     #    For the horizontal alignments, we will also honor the      $latex_rendering,
     #    value of the latex specfication.  The default is parbox,      $currentstring,
     #    and that's used for illegal values too.        $width_param,
     #          $height_param);
     #    Even though we set a default alignment value, the user      $currentstring .= $closure;
     #    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.'}';  
     }  
  } else {   } else {
     &Apache::lonxml::debug("$src does not exist");      &Apache::lonxml::debug("$src does not exist");
     #original image file doesn't exist so check the alt attribute      #original image file doesn't exist so check the alt attribute
     my $alt =       my $alt =
  &Apache::lonxml::get_param('alt',$parstack,$safeeval,undef,1);   &Apache::lonxml::get_param('alt',$parstack,$safeeval,undef,1);
     unless ($alt) {      unless ($alt) {
  $alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);   $alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);
Line 2893  sub start_img { Line 2885  sub start_img {
  # And here's where the semi-quote breaks down: allow the user   # And here's where the semi-quote breaks down: allow the user
         # to edit the beast as well by rendering the problem for edit:          # to edit the beast as well by rendering the problem for edit:
     } elsif ($target eq 'edit') {      } elsif ($target eq 'edit') {
           my $only = join(',',&Apache::loncommon::filecategorytypes('Pictures'));
  $currentstring .=&Apache::edit::tag_start($target,$token);   $currentstring .=&Apache::edit::tag_start($target,$token);
  $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).   $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).
     &Apache::edit::browse('src',undef,'alt').' '.                           &Apache::edit::browse_or_search('src',undef,'alt',$only,undef,1).
     &Apache::edit::search('src',undef,'alt').'<br />';                           '<br />';
  $currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />';   $currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />';
  $currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5);   $currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5);
  $currentstring .=&Apache::edit::text_arg('height (pixel):','height',$token,5).'<br />';   $currentstring .=&Apache::edit::text_arg('height (pixel):','height',$token,5).'<br />';
Line 2905  sub start_img { Line 2898  sub start_img {
  $currentstring .=&Apache::edit::select_arg('Alignment:','align',   $currentstring .=&Apache::edit::select_arg('Alignment:','align',
    ['','bottom','middle','top','left','right'],$token,5);     ['','bottom','middle','top','left','right'],$token,5);
  $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',   $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',
    ['', 'parbox', 'parpic'], $token, 2);     ['', 'none','parbox', 'parpic', 'wrapfigure'], $token, 2);
  $currentstring .=&Apache::edit::select_arg('Encyrpt URL:','encrypturl',          my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);
           my $enc=    &Apache::lonxml::get_param('encrypturl',$parstack,$safeeval);
   
    $currentstring .=&Apache::edit::select_arg('Encrypt URL:','encrypturl',
    ['no','yes'], $token, 2);     ['no','yes'], $token, 2);
           if (($alt=~/\S/) && (lc($enc) eq 'yes')) {
              $currentstring.='<br /><span class="LC_warning">'.&mt('Warning: the description "[_1]" will be available, even for encrypted URL',$alt).'</span><br />';
           }
  $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();   $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
  my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);   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 $width=  &Apache::lonxml::get_param('width',$parstack,$safeeval);
  my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);   my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);
           my $element = &Apache::edit::get_element('src');
           my $text;
  $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';          if ($token->[2]{'src'}=~/\$/) {
  if ($width) { $currentstring.=' width="'.$width.'" '; }             $text = &mt('Variable image source');
  if ($height) { $currentstring.=' height="'.$height.'" '; }          } elsif ($token->[2]{'src'}=~/\S/) {
  $currentstring .= ' />';     $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';
      if ($width) { $currentstring.=' width="'.$width.'" '; }
      if ($height) { $currentstring.=' height="'.$height.'" '; }
      $currentstring .= ' id="previewimg_'.$element.'" />';
           } else {
              $text = &mt("No image source specified");
           }
           $currentstring .= ' <span id="showimg_'.$element.'">'.$text.'</span>';
     } elsif ($target eq 'modified') {      } elsif ($target eq 'modified') {
  my ($osrc,$owidth,$oheight)=   my ($osrc,$owidth,$oheight)=
     ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});      ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
Line 2939  sub start_img { Line 2944  sub start_img {
  }   }
  if ($osrc ne $nsrc || (!$nwidth && !$nheight)) {   if ($osrc ne $nsrc || (!$nwidth && !$nheight)) {
     # changed image or no size specified,      # changed image or no size specified,
             # if they didn't explicitly change the               # if they didn't explicitly change the
             # width or height use the ones from the image              # width or height use the ones from the image
     if ($iwidth && $iheight) {      if ($iwidth && $iheight) {
  if ($owidth == $nwidth || (!$nwidth && !$nheight)) {   if ($owidth == $nwidth || (!$nwidth && !$nheight)) {
Line 2967  sub start_img { Line 2972  sub start_img {
 sub end_img {  sub end_img {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];   $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '';   $currentstring = '';
Line 2978  sub end_img { Line 2983  sub end_img {
 #-- <applet> tag (end tag required)  #-- <applet> tag (end tag required)
 sub start_applet {  sub start_applet {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
       
     my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,undef,1);      my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,undef,1);
     &Apache::lonxml::extlink($code);      &Apache::lonxml::extlink($code);
     my $archive=&Apache::lonxml::get_param('archive',$parstack,$safeeval,      my $archive=&Apache::lonxml::get_param('archive',$parstack,$safeeval,
    undef,1);     undef,1);
     &Apache::lonxml::extlink($archive);      &Apache::lonxml::extlink($archive);
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  if ($env{'browser.appletsuppress'} ne 'on') {          $currentstring = $token->[4];
     $currentstring = &Apache::lonenc::encrypt_ref($token,  
   {'code'=>$code,  
    'archive'=>$archive}  
   );  
  } else {  
     my $alttag= &Apache::lonxml::get_param('alt',$parstack,  
    $safeeval,undef,1);  
     unless ($alttag) {  
  $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],  
  $code);  
     }  
     $currentstring='[APPLET: '.$alttag.']';  
  }  
     } elsif ($target eq 'tex') {      } 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,   my $alttag= &Apache::lonxml::get_param('alt',$parstack,
        $safeeval,undef,1);         $safeeval,undef,1);
  unless ($alttag) {   unless ($alttag) {
Line 3011  sub start_applet { Line 3025  sub start_applet {
  }   }
  $currentstring.='\begin{center} \fbox{Java Applet: '.$alttag.   $currentstring.='\begin{center} \fbox{Java Applet: '.$alttag.
     '.}\end{center}';      '.}\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;      return $currentstring;
 }  }
   
 sub end_applet {  sub end_applet {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];   $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <embed> tag (end tag optional/required)  #-- <embed> tag (end tag optional/required)
 sub start_embed {      sub start_embed {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);      my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
     &Apache::lonxml::extlink($src);      &Apache::lonxml::extlink($src);
     my $currentstring = '';      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});
     $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});  
  } else {  
     my $alttag=&Apache::lonxml::get_param  
  ('alt',$parstack,$safeeval,undef,1);  
     unless ($alttag) {  
  $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);  
     }  
     $currentstring='[EMBED: '.$alttag.']';  
  }  
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_embed {  sub end_embed {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];               $currentstring = $token->[2];
     } elsif ($target eq 'tex') {        } elsif ($target eq 'tex') {
     }           # ./.
       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <param> tag (end tag forbidden)  #-- <param> tag (end tag forbidden)
 sub start_param {  sub start_param {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     if (&Apache::lonxml::get_param('name',$parstack,      my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval,
    $safeeval,undef,1)=~/^cabbase$/i) {                                            undef,1);
       if ($name =~/^cabbase$/i) {
  my $value=&Apache::lonxml::get_param('value',$parstack,   my $value=&Apache::lonxml::get_param('value',$parstack,
      $safeeval,undef,1);       $safeeval,undef,1);
  &Apache::lonxml::extlink($value);   &Apache::lonxml::extlink($value);
     }       } elsif ($name eq 'flashvars') {
             if (lc(&Apache::lonxml::get_param('type',$parstack,$safeeval,-2,1))
               eq 'application/x-shockwave-flash') {
               my $launcher =
                   &Apache::lonxml::get_param('data',$parstack,$safeeval,-2,1);
               if ($launcher) {
                   &Apache::lonxml::extlink($launcher);
               }
               my $flashvars=&Apache::lonxml::get_param('value',$parstack,
                                                        $safeeval,undef,1);
               if ($flashvars ne '') {
                   foreach my $item (split(/\&/,$flashvars)) {
                       my ($key,$value)=split(/=/,$item,2);
                       if ($key eq 'content') {
                           if ($value ne '') {
                               my ($dir) = ($launcher =~ m{(.+/)[^/]+$});
                               &Apache::lonxml::extlink($dir.$value);
                           }
                       } elsif ($key eq 'thumb') {
                           if ($value ne '') {
                               &Apache::lonxml::extlink($value);
                           }
                       }
                   }
               }
           }
       }
     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);      my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
     &Apache::lonxml::extlink($src);      if ($src ne '') {
           &Apache::lonxml::extlink($src);
       }
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my %toconvert;   my %toconvert;
  my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);  
  if ($src) { $toconvert{'src'}= $src; }   if ($src) { $toconvert{'src'}= $src; }
  my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval,  
     undef,1);  
  if ($name=~/^cabbase$/i) {   if ($name=~/^cabbase$/i) {
     $toconvert{'value'}=&Apache::lonxml::get_param('value',$parstack,      $toconvert{'value'}=&Apache::lonxml::get_param('value',$parstack,
    $safeeval,undef,1);     $safeeval,undef,1);
  }   }
  $currentstring = &Apache::lonenc::encrypt_ref($token,\%toconvert);   $currentstring = &Apache::lonenc::encrypt_ref($token,\%toconvert);
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_param {  sub end_param {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3127  sub end_allow { Line 3169  sub end_allow {
 sub start_frameset {  sub start_frameset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = ''; # Close any pending para.      my $currentstring = ''; # Close any pending para.
     if ($target eq 'web') {       if ($target eq 'web' || $target eq 'webgrade') {
  if (!$Apache::lonxml::registered &&   $currentstring =
     $env{'request.state'} eq 'published') {      &Apache::loncommon::start_page($Apache::londefdef::title,
     $currentstring.='<head>'.     $Apache::londefdef::head,
  &Apache::lonmenu::registerurl(undef,$target).'</head>';     {'add_entries'    => $token->[2],
  }  #    'no_title'       => 1,
  my $onLoad='';      'force_register' => 1,
  foreach my $key (keys(%{$token->[2]})) {      'frameset'       => 1,});
     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.='>';  
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 3163  sub start_frameset { Line 3185  sub start_frameset {
 sub end_frameset {  sub end_frameset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];   $currentstring = $token->[2];
     }      }
     return $currentstring;      return $currentstring;
Line 3173  sub end_frameset { Line 3195  sub end_frameset {
 sub start_xmp {  sub start_xmp {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\begin{verbatim}';   $currentstring .= '\begin{verbatim}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_xmp {  sub end_xmp {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\end{verbatim}';   $currentstring .= '\end{verbatim}';
Line 3196  sub end_xmp { Line 3218  sub end_xmp {
 sub start_pre {  sub start_pre {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # close off pending <p>      my $currentstring = &end_p(); # close off pending <p>
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\begin{verbatim}';   $currentstring .= '\begin{verbatim}';
  &Apache::lonxml::disable_LaTeX_substitutions();   &Apache::lonxml::disable_LaTeX_substitutions();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_pre {  sub end_pre {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\end{verbatim}';   $currentstring .= '\end{verbatim}';
Line 3221  sub end_pre { Line 3243  sub end_pre {
 sub start_insert {  sub start_insert {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1);   my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1);
  $currentstring .= '<b>'.$display.'</b>';;   $currentstring .= '<b>'.$display.'</b>';;
     }      }
Line 3231  sub start_insert { Line 3253  sub start_insert {
 sub end_insert {  sub end_insert {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= '';   $currentstring .= '';
     }      }
     return $currentstring;      return $currentstring;
Line 3241  sub end_insert { Line 3263  sub end_insert {
 sub start_externallink {  sub start_externallink {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1);   my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1);
  $currentstring .= '<b>'.$display.'</b>';;   $currentstring .= '<b>'.$display.'</b>';;
     }      }
Line 3251  sub start_externallink { Line 3273  sub start_externallink {
 sub end_externallink {  sub end_externallink {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= '';   $currentstring .= '';
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <blankspace heigth="">  #-- <blankspace height="">
 sub start_blankspace {  sub start_blankspace {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # closes off any unclosed <p>      my $currentstring = &end_p(); # closes off any unclosed <p>
     if ($target eq 'tex') {      if ($target eq 'tex') {
  my $howmuch = &Apache::lonxml::get_param('heigth',$parstack,$safeeval,undef,1);   my $howmuch = &Apache::lonxml::get_param('height',$parstack,$safeeval,undef,1);
  $currentstring .= '\vskip '.$howmuch.' ';   $currentstring .= '\vskip '.$howmuch.' ';
     }      }
     return $currentstring;      return $currentstring;
Line 3281  sub end_blankspace { Line 3303  sub end_blankspace {
 sub start_abbr {  sub start_abbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_abbr {  sub end_abbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3300  sub end_abbr { Line 3322  sub end_abbr {
 sub start_acronym {  sub start_acronym {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_acronym {  sub end_acronym {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3319  sub end_acronym { Line 3341  sub end_acronym {
 sub start_area {  sub start_area {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_area {  sub end_area {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3338  sub end_area { Line 3360  sub end_area {
 sub start_base {  sub start_base {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 3347  sub start_base { Line 3369  sub start_base {
 sub end_base {  sub end_base {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3357  sub end_base { Line 3379  sub end_base {
 sub start_bdo {  sub start_bdo {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_bdo {  sub end_bdo {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3376  sub end_bdo { Line 3398  sub end_bdo {
 sub start_bgsound {  sub start_bgsound {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_bgsound {  sub end_bgsound {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3395  sub end_bgsound { Line 3417  sub end_bgsound {
 sub start_blink {  sub start_blink {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_blink {  sub end_blink {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3414  sub end_blink { Line 3436  sub end_blink {
 sub start_blockquote {  sub start_blockquote {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # Close any unclosed <p>      my $currentstring = &end_p(); # Close any unclosed <p>
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     }       }
       if ($target eq 'tex') {
    $currentstring .= '\begin{quote}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_blockquote {  sub end_blockquote {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
       if ($target eq 'tex') {
    $currentstring = '\end{quote}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3433  sub end_blockquote { Line 3461  sub end_blockquote {
 sub start_button {  sub start_button {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_button {  sub end_button {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3452  sub end_button { Line 3480  sub end_button {
 sub start_caption {  sub start_caption {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_caption {  sub end_caption {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3471  sub end_caption { Line 3499  sub end_caption {
 sub start_col {  sub start_col {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_col {  sub end_col {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <colgroup> tag (end tag optional)  #-- <colgroup tag (end tag optional)
 sub start_colgroup {  sub start_colgroup {
     my ($target,$token) = @_;      my ($target,$token,$tagstack, $parstack, $parser, $safeeval, $style) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
       if ($target eq 'tex') {
    # TODO: Ensure this tag is in a table:
   
    # Fetch the attributes and build the hash for the
    # call to define_colgroup.
   
    my $span    = &Apache::lonxml::get_param('span',   $parstack, $safeeval);
    my $halign  = &Apache::lonxml::get_param('halign', $parstack, $safeeval);
   
    my %colgroup_params;
    if ($span ne '') {
       $colgroup_params{'span'} = $span;
    }
    if ($halign ne '') {
       $colgroup_params{'halign'} = $halign;
    }
   
    my $table = $Apache::londefdef::table[-1];
    $table->define_colgroup(\%colgroup_params);
   
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_colgroup {  sub end_colgroup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
   
 #-- <del> tag (end tag required)  #-- <del> tag (end tag required)
 sub start_del {  sub start_del {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       } elsif ($target eq 'tex') {
    &disable_para();
    $currentstring .= '\st{';
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_del {  sub end_del {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       } elsif ($target eq 'tex') {
    &enable_para();
    $currentstring = '}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3528  sub end_del { Line 3584  sub end_del {
 sub start_fieldset {  sub start_fieldset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_fieldset {  sub end_fieldset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3547  sub end_fieldset { Line 3603  sub end_fieldset {
 sub start_frame {  sub start_frame {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_frame {  sub end_frame {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3566  sub end_frame { Line 3622  sub end_frame {
 sub start_iframe {  sub start_iframe {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];               my ($src,$url,$query);
     }           if ($token->[2]->{'src'}) {
               $src = $token->[2]->{'src'};
           } elsif ($token->[2]->{'SRC'}) {
               $src = $token->[2]->{'SRC'};
           }
           if ($src) {
               ($url,$query) = ($src =~ /^([^?]+)\??([^?]*)$/);
               if ($query =~ /inhibitmenu=yes/) {
                   $currentstring = $token->[4];
               } else {
                   my $inhibit;
                   if ($url =~ m{^[^/.].*\.x?html?$}) {
                       $inhibit = 1;
                   } elsif ($url =~ m{^/(uploaded|res)/.*\.x?html?$}) {
                       $inhibit = 1;
                   }
                   if ($inhibit) {
                       $currentstring = '<iframe ';
                       foreach my $attrib (@{$token->[3]}) {
                           if (lc($attrib) eq 'src') {
                               if ($query) {
                                   $query.='&amp;inhibitmenu=yes';
                               } else {
                                   $query = 'inhibitmenu=yes';
                               }
                               $currentstring .= 'src="'.$url.'?'.$query.'" ';
                           } else {
                               $currentstring .= lc($attrib).'="'.$token->[2]->{$attrib}.'" ';
                           }
                       }
                       $currentstring =~ s/\s+$//;
                       if ($token->[4] =~ m{/>$}) {
                           $currentstring .= ' />';
                       } else {
                           $currentstring .= '>';
                       }
                   } else {
                       $currentstring = $token->[4];
                   }
               }
               if (($url !~ m{^https?://}) && ($env{'request.course.id'})) {
                   my $docuri = &Apache::lonnet::hreflocation('',$env{'request.filename'});
                   my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   if ($url =~ m{^([^/]|/uploaded/)}) {
                       my $cleanhref = &clean_docs_httpref($url,$docuri,$cdom,$cnum);
                       if ($cleanhref) {
                           &Apache::lonxml::extlink($cleanhref);
                       }
                   } elsif (($url =~ m{/res/$LONCAPA::domain_re/}) && ($docuri =~ m{^\Q/uploaded/$cdom/$cnum/docs/\E})) {
                       if (!&Apache::lonnet::allowed('bre',$url)) {
                           if (&Apache::lonnet::is_on_map($url)) {
                               &Apache::lonxml::extlink($url);
                           }
                       }
                   }
               }
           } else {
               $currentstring = $token->[4];
           }
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_iframe {  sub end_iframe {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3585  sub end_iframe { Line 3701  sub end_iframe {
 sub start_ins {  sub start_ins {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_ins {  sub end_ins {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3604  sub end_ins { Line 3720  sub end_ins {
 sub start_isindex {  sub start_isindex {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_isindex {  sub end_isindex {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3623  sub end_isindex { Line 3739  sub end_isindex {
 sub start_keygen {  sub start_keygen {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_keygen {  sub end_keygen {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3642  sub end_keygen { Line 3758  sub end_keygen {
 sub start_label {  sub start_label {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_label {  sub end_label {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3661  sub end_label { Line 3777  sub end_label {
 sub start_layer {  sub start_layer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_layer {  sub end_layer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3680  sub end_layer { Line 3796  sub end_layer {
 sub start_legend {  sub start_legend {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_legend {  sub end_legend {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3699  sub end_legend { Line 3815  sub end_legend {
 sub start_link {  sub start_link {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,   my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
     undef,1);      undef,1);
  &Apache::lonxml::extlink($href);   &Apache::lonxml::extlink($href);
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_link {  sub end_link {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3721  sub end_link { Line 3837  sub end_link {
 sub start_marquee {  sub start_marquee {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_marquee {  sub end_marquee {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3740  sub end_marquee { Line 3856  sub end_marquee {
 sub start_multicol {  sub start_multicol {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # Close any pending <p>      my $currentstring = &end_p(); # Close any pending <p>
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_multicol {  sub end_multicol {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3759  sub end_multicol { Line 3875  sub end_multicol {
 sub start_nobr {  sub start_nobr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  $currentstring='\mbox{';   $currentstring='\mbox{';
     }      }
Line 3770  sub start_nobr { Line 3886  sub start_nobr {
 sub end_nobr {  sub end_nobr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }   elsif ($target eq 'tex') {      }   elsif ($target eq 'tex') {
  $currentstring='}';   $currentstring='}';
     }      }
Line 3782  sub end_nobr { Line 3898  sub end_nobr {
 sub start_noembed {  sub start_noembed {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_noembed {  sub end_noembed {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3801  sub end_noembed { Line 3917  sub end_noembed {
 sub start_noframes {  sub start_noframes {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_noframes {  sub end_noframes {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3820  sub end_noframes { Line 3936  sub end_noframes {
 sub start_nolayer {  sub start_nolayer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_nolayer {  sub end_nolayer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3839  sub end_nolayer { Line 3955  sub end_nolayer {
 sub start_noscript {  sub start_noscript {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_noscript {  sub end_noscript {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3858  sub end_noscript { Line 3974  sub end_noscript {
 sub start_object {  sub start_object {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_object {  sub end_object {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3877  sub end_object { Line 3993  sub end_object {
 sub start_optgroup {  sub start_optgroup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_optgroup {  sub end_optgroup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3896  sub end_optgroup { Line 4012  sub end_optgroup {
 sub start_samp {  sub start_samp {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring='\texttt{';   $currentstring='\texttt{';
     }      }
Line 3907  sub start_samp { Line 4023  sub start_samp {
 sub end_samp {  sub end_samp {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring='}';   $currentstring='}';
     }      }
Line 3919  sub end_samp { Line 4035  sub end_samp {
 sub start_server {  sub start_server {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_server {  sub end_server {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3938  sub end_server { Line 4054  sub end_server {
 sub start_spacer {  sub start_spacer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # Close off any open <p> tag.      my $currentstring = &end_p(); # Close off any open <p> tag.
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_spacer {  sub end_spacer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
   my @span_end_stack; # for span tex target
   
 #-- <span> tag (end tag required)  #-- <span> tag (end tag required)
 sub start_span {  sub start_span {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       } elsif ($target eq 'tex') {
           my $endstring = '';
           my $family = &get_css_property('font-family',$parstack,$safeeval);
           if ($family eq 'monospace') {
               $currentstring .= '\texttt{';
               $endstring .= '}';
           }
           my $weight = &get_css_property('font-weight',$parstack,$safeeval);
           if ($weight eq 'bold') {
               $currentstring .= '\textbf{';
               $endstring .= '}';
           }
           my $style = &get_css_property('font-style',$parstack,$safeeval);
           if ($style eq 'italic') {
               $currentstring .= '\textit{';
               $endstring .= '}';
           }
           push(@span_end_stack, $endstring);
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_span {  sub end_span {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       } elsif ($target eq 'tex') {
           my $endstring = pop @span_end_stack;
           $currentstring .= $endstring;
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3976  sub end_span { Line 4115  sub end_span {
 sub start_tbody {  sub start_tbody {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
       if ($target eq 'tex') {
    # TODO: Ensure this tag is within a table:
   
    my $table = $Apache::londefdef::table[-1];
    $table->start_body();
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_tbody {  sub end_tbody {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
       if($target eq 'tex') {
    # TODO: Ensure this tag is within a table:
   
    my $table = $Apache::londefdef::table[-1];
    $table->end_body();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3995  sub end_tbody { Line 4146  sub end_tbody {
 sub start_tfoot {  sub start_tfoot {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
       if ($target eq 'tex') {
           # TODO: ensure this is within a table tag.
    my $table = $Apache::londefdef::table[-1];
    $table->start_foot();
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_tfoot {  sub end_tfoot {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
       if ($target eq 'tex') {
    #  TODO: Ensure this is in side a table
    my $table = $Apache::londefdef::table[-1];
    $table->end_foot();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4014  sub end_tfoot { Line 4175  sub end_tfoot {
 sub start_thead {  sub start_thead {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
       if ($target eq 'tex') {
    # Assume we're in a table... TODO: Verify that and ignore tag if not.
    my $table = $Apache::londefdef::table[-1];
    $table->start_head();
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_thead {  sub end_thead {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
       if ($target eq 'tex') {
         # TODO: Verify we are in a table and ignore tag if not.
   
    my $table = $Apache::londefdef::table[-1];
    $table->end_head();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4033  sub end_thead { Line 4205  sub end_thead {
 sub start_var {  sub start_var {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\textit{';    $currentstring = '\textit{';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 4044  sub start_var { Line 4216  sub start_var {
 sub end_var {  sub end_var {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];   $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '}';    $currentstring = '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4056  sub end_var { Line 4228  sub end_var {
 sub start_wbr {  sub start_wbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_wbr {  sub end_wbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <hideweboutput> tag  #-- <hideweboutput> tag
 sub start_hideweboutput {  sub start_hideweboutput {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  &Apache::lonxml::startredirection();        &Apache::lonxml::startredirection();
     }       }
     return '';      return '';
 }  }
   
 sub end_hideweboutput {  sub end_hideweboutput {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = &Apache::lonxml::endredirection();       $currentstring = &Apache::lonxml::endredirection();
     }       }
     return '';      return '';
 }  }
   
Line 4093  sub end_hideweboutput { Line 4265  sub end_hideweboutput {
 sub image_replication {  sub image_replication {
     my $src = shift;      my $src = shift;
     if (not -e $src) { &Apache::lonnet::repcopy($src); }      if (not -e $src) { &Apache::lonnet::repcopy($src); }
     #replicates eps or ps       #replicates eps or ps
     my $epssrc = my $pssrc = $src;      my $epssrc = my $pssrc = $src;
     $epssrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i;      $epssrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i;
     $pssrc  =~ s/\.(gif|jpg|jpeg|png)$/.ps/i;      $pssrc  =~ s/\.(gif|jpg|jpeg|png)$/.ps/i;
Line 4103  sub image_replication { Line 4275  sub image_replication {
     }      }
     return '';      return '';
 }  }
 #  
 #   Get correct sizing parameter for an image given  
 #   it's initial ht. and wid.  This allows sizing of  
 #   images that are generated on-the-fly (e.g. gnuplot)  
 #   as well as serving as a utility for image_size.  
 #   
 #  Parameter:  
 #        height_param  
 #        width_param    - Initial picture dimensions.  
 #        scaling        - A scale factor.  
 #        parstack,      - the current stack of tag attributes   
 #                         from the xml parser  
 #        safeeval,      - pointer to the safespace  
 #        depth,         - from what level in the stack to look for attributes  
 #                         (assumes -1 if unspecified)  
 #        cis            - look for attrubutes case insensitively  
 #                         (assumes false)  
 #  
 # Returns:  
 #   height, width   - new dimensions.  
 #  
 sub resize_image {  sub resize_image {
     my ($height_param, $width_param, $scaling,      my ($height_param, $width_param, $scaling,
  $parstack, $safeeval, $depth, $cis) = @_;   $parstack, $safeeval, $depth, $cis) = @_;
Line 4134  sub resize_image { Line 4288  sub resize_image {
     $width_param  = $width_param  * $scaling;      $width_param  = $width_param  * $scaling;
   
     #do we have any specified LaTeX size of the picture?      #do we have any specified LaTeX size of the picture?
     my $toget='TeXwidth';       my $toget='TeXwidth';
     if ($cis) {       if ($cis) {
  $toget=lc($toget);    $toget=lc($toget);
     }      }
     my $TeXwidth = &Apache::lonxml::get_param($toget,$parstack,      my $TeXwidth = &Apache::lonxml::get_param($toget,$parstack,
       $safeeval,$depth,$cis);        $safeeval,$depth,$cis);
Line 4146  sub resize_image { Line 4300  sub resize_image {
     #do we have any specified web size of the picture?      #do we have any specified web size of the picture?
     my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval,      my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval,
    $depth,1);     $depth,1);
     if ($TeXwidth) {       if ($TeXwidth) {
  my $old_width_param=$width_param;   my $old_width_param=$width_param;
  if ($TeXwidth=~/(\d+)\s*\%/) {   if ($TeXwidth=~/(\d+)\s*\%/) {
     $width_param = $1*$env{'form.textwidth'}/100;      $width_param = $1*$env{'form.textwidth'}/100;
  } else {    } else {
     $width_param = $TeXwidth;      $width_param = $TeXwidth;
  }   }
  if ($TeXheight) {   if ($TeXheight) {
Line 4184  sub resize_image { Line 4338  sub resize_image {
 sub image_size {  sub image_size {
     my ($src,$scaling,$parstack,$safeeval,$depth,$cis)=@_;      my ($src,$scaling,$parstack,$safeeval,$depth,$cis)=@_;
   
     #size of image from gif/jpg/jpeg/png       #size of image from gif/jpg/jpeg/png
     my $ressrc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);      my $ressrc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
     if (-e $ressrc) {      if (-e $ressrc) {
  $src = $ressrc;   $src = $ressrc;
Line 4197  sub image_size { Line 4351  sub image_size {
     undef($image);      undef($image);
   
     ($height_param, $width_param) = &resize_image($height_param, $width_param,      ($height_param, $width_param) = &resize_image($height_param, $width_param,
   $scaling, $parstack, $safeeval,     $scaling, $parstack, $safeeval,
   $depth, $cis);    $depth, $cis);
   
     return ($height_param, $width_param);      return ($height_param, $width_param);
Line 4226  sub get_eps_image { Line 4380  sub get_eps_image {
  &Apache::lonnet::repcopy($orig_src); # Failure is not completely fatal.   &Apache::lonnet::repcopy($orig_src); # Failure is not completely fatal.
     }      }
     &Apache::lonxml::debug("get_eps_image: Original image: $orig_src");      &Apache::lonxml::debug("get_eps_image: Original image: $orig_src");
     my ($spath, $sname, $sext) = fileparse($src, qr/\.(gif|png|jpg|jpeg)/i);      my ($spath, $sname, $sext) = &fileparse($src, qr/\.(bmp|gif|png|jpg|jpeg|svg)/i);
     $src=~s/\.(gif|png|jpg|jpeg)$/\.eps/i;      $src=~s/\.(bmp|gif|png|jpg|jpeg|svg)$/\.eps/i;
     $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);      $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
     &Apache::lonxml::debug("Filelocation gives: $src");      &Apache::lonxml::debug("Filelocation gives: $src");
     if (! -e $src) {      if (! -e $src) {
Line 4246  sub get_eps_image { Line 4400  sub get_eps_image {
   
  #if replication failed try to produce eps file dynamically   #if replication failed try to produce eps file dynamically
  $src=~s/\.ps$/\.eps/;   $src=~s/\.ps$/\.eps/;
  my $temp_file;   if (open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat")) {
  open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat");      my $newsrc=$orig_src;
  my $newsrc=$orig_src;      $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|;
  $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|;      &Apache::lonxml::debug("queueing $newsrc for dynamic eps production.");
  &Apache::lonxml::debug("queueing $newsrc for dynamic eps production.");      print FILE ("$newsrc\n");
  print FILE "$newsrc\n";      close(FILE);
  close FILE;                  }
  $src=~s|/home/httpd/html/res|/home/httpd/prtspool|;   $src=~s|/home/httpd/html/res|/home/httpd/prtspool|;
  $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;   $src=~s|/home/httpd/html/priv/[^/]+/([^/]*)/|/home/httpd/prtspool/$1/|;
  if ($sext ne "") { # Put the ext. back in to uniquify.   if ($sext ne "") { # Put the ext. back in to uniquify.
     $src =~ s/\.eps$/$sext.eps/;      $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/httpd/html/priv/[^/]+/([^/]*)/|/home/httpd/prtspool/$1/|;
     }      }
     my ($path,$file)=($src=~m|(.*)/([^/]*)$|);      my ($path,$file)=($src=~m|(.*)/([^/]*)$|);
       $path =~ s/ /\_/g;
       $file =~ s/ /\_/g;
     &Apache::lonxml::debug("get_eps_image returning: $path / $file<BR />");      &Apache::lonxml::debug("get_eps_image returning: $path / $file<BR />");
     return ($path.'/',$file);      return ($path.'/',$file);
 }  }
   
 sub eps_generation {  sub eps_generation {
     my ($src,$file,$width_param) = @_;           my ($src,$file,$width_param) = @_;
     my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";      my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
     my $temp_file = Apache::File->new('>>'.$filename);       if (open(my $tmpfile,">>$filename")) {
     print $temp_file "$src\n";          print $tmpfile "$src\n";
           close($tmpfile);
       }
     my $newsrc = $src;      my $newsrc = $src;
     $newsrc =~ s/(\.gif|\.jpg|\.jpeg)$/\.eps/i;      $newsrc =~ s/(\.bmp|\.gif|\.jpg|\.jpeg)$/\.eps/i;
     $newsrc=~s/\/home\/httpd\/html\/res//;      $newsrc=~s{/home/httpd/html/res}{};
     $newsrc=~s/\/home\/([^\/]*)\/public_html\//\/$1\//;      $newsrc=~s{/home/httpd/html/priv/[^/]+/($LONCAPA::username_re)/}{/$1/};
     $newsrc=~s/\/\.\//\//;      $newsrc=~s{/\./}{/};
     $newsrc=~s/\/([^\/]+)\.(ps|eps)/\//;      $newsrc=~s{/([^/]+)\.(ps|eps)}{/};
     if ($newsrc=~/\/home\/httpd\/lonUsers\//) {      if ($newsrc=~m{/home/httpd/lonUsers/}) {
  $newsrc=~s/\/home\/httpd\/lonUsers//;   $newsrc=~s{/home/httpd/lonUsers}{};
  $newsrc=~s/\/([^\/]+)\/(\w)\/(\w)\/(\w)\//\/$1\//;   $newsrc=~s{/($LONCAPA::domain_re)/./././}{/$1/};
     }      }
     if ($newsrc=~/\/userfiles\//) {      if ($newsrc=~m{/userfiles/}) {
  return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';   return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
     } else {      } else {
  return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';   return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
     }      }
 }  }
   
 sub file_path {       sub file_path {
     my $src=shift;      my $src=shift;
     my ($file,$path);       my ($file,$path);
     if ($src =~ m!(.*)/([^/]*)$!) {      if ($src =~ m!(.*)/([^/]*)$!) {
  $file = $2;    $file = $2;
  $path = $1.'/';    $path = $1.'/';
     }       }
     return $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 {  sub recalc {
     my $argument = shift;      my $argument = shift;
     if (not $argument=~/(mm|cm|in|pc|pt)/) {return $argument.' mm';}      if (not $argument=~/(mm|cm|in|pc|pt)/) {return $argument.' mm';}
Line 4323  sub recalc { Line 4492  sub recalc {
 sub LATEX_length {  sub LATEX_length {
     my $garbage=shift;      my $garbage=shift;
     $garbage=~s/^\s+$//;      $garbage=~s/^\s+$//;
     $garbage=~s/^\s+(\S.*)/$1/;#space before       $garbage=~s/^\s+(\S.*)/$1/;#space before
     $garbage=~s/(.*\S)\s+$/$1/;#space after       $garbage=~s/(.*\S)\s+$/$1/;#space after
     $garbage=~s/(\s)+/$1/;#only one space      $garbage=~s/(\s)+/$1/;#only one space
     $garbage=~s/(\\begin{([^\}]+)}|\\end{([^\}]+)})//g;#remove LaTeX \begin{...} and \end{...}      $garbage=~s/(\\begin\{([^\}]+)}|\\end\{([^\}]+)})//g;#remove LaTeX \begin{...} and \end{...}
     $garbage=~s/(\$\_\{|\$\_|\$\^{|\$\^|\}\$)//g;#remove $_{,$_,$^{,$^,}$      $garbage=~s/(\$\_\{|\$\_|\$\^\{|\$\^|\}\$)//g;#remove $_{,$_,$^{,$^,}$
     $garbage=~s/([^\\])\$/$1/g;#$      $garbage=~s/([^\\])\$/$1/g;#$
     $garbage=~s/(\\ensuremath\{\_\{|\\ensuremath\{\_|\\ensuremath\{\^{|\\ensuremath\{\^|\})//g;#remove \ensuremath{...}      $garbage=~s/(\\ensuremath\{\_\{|\\ensuremath\{\_|\\ensuremath\{\^\{|\\ensuremath\{\^|\})//g;#remove \ensuremath{...}
    $garbage=~s/(\\alpha|\\beta|\\gamma|\\delta|\\epsilon|\\verepsilon|\\zeta|\\eta|\\theta|\\vartheta|\\iota|\\kappa|\\lambda|\\mu|\\nu|\\xi|\\pi|\\varpi|\\rho|\\varrho|\\sigma|\\varsigma|\\tau|\\upsilon|\\phi|\\varphi|\\chi|\\psi|\\omega|\\Gamma|\\Delta|\\Theta|\\Lambda|\\Xi|\\Pi|\\Sigma|\\Upsilon|\\Phi|\\Psi|\\Omega)/1/g;     $garbage=~s/(\\alpha|\\beta|\\gamma|\\delta|\\epsilon|\\verepsilon|\\zeta|\\eta|\\theta|\\vartheta|\\iota|\\kappa|\\lambda|\\mu|\\nu|\\xi|\\pi|\\varpi|\\rho|\\varrho|\\sigma|\\varsigma|\\tau|\\upsilon|\\phi|\\varphi|\\chi|\\psi|\\omega|\\Gamma|\\Delta|\\Theta|\\Lambda|\\Xi|\\Pi|\\Sigma|\\Upsilon|\\Phi|\\Psi|\\Omega)/1/g;
     $garbage=~s/(\\pm|\\mp|\\times|\\div|\\cdot|\\ast|\\star|\\dagger|\\ddagger|\\amalg|\\cap|\\cup|\\uplus|\\sqcap|\\sqcup|\\vee|\\wedge|\\oplus|\\ominus|\\otimes|\\circ|\\bullet|\\diamond|\\lhd|\\rhd|\\unlhd|\\unrhd|\\oslash|\\odot|\\bigcirc|\\Box|\\Diamond|\\bigtriangleup|\\bigtriangledown|\\triangleleft|\\triangleright|\\setminus|\\wr)/1/g;      $garbage=~s/(\\pm|\\mp|\\times|\\div|\\cdot|\\ast|\\star|\\dagger|\\ddagger|\\amalg|\\cap|\\cup|\\uplus|\\sqcap|\\sqcup|\\vee|\\wedge|\\oplus|\\ominus|\\otimes|\\circ|\\bullet|\\diamond|\\lhd|\\rhd|\\unlhd|\\unrhd|\\oslash|\\odot|\\bigcirc|\\Box|\\Diamond|\\bigtriangleup|\\bigtriangledown|\\triangleleft|\\triangleright|\\setminus|\\wr)/1/g;
     $garbage=~s/(\\le|\\ll|\\leq|\\ge|\\geq|\\gg|\\neq|\\doreq|\\sim|\\simeq|\\subset|\\subseteq|\\sqsubset|\\sqsubseteq|\\in|\\vdash|\\models|\\supset|\\supseteq|\\sqsupset|\\sqsupseteq|\\ni|\\dash|\\perp|\\approx|\\cong|\\equiv|\\propto|\\prec|\\preceq|\\parallel|\\asymp|\\smile|\\frown|\\bowtie|\\succ|\\succeq|\\mid)/1/g;      $garbage=~s/(\\le|\\ll|\\leq|\\ge|\\geq|\\gg|\\neq|\\doreq|\\sim|\\simeq|\\subset|\\subseteq|\\sqsubset|\\sqsubseteq|\\in|\\vdash|\\models|\\supset|\\supseteq|\\sqsupset|\\sqsupseteq|\\ni|\\dash|\\perp|\\approx|\\cong|\\equiv|\\propto|\\prec|\\preceq|\\parallel|\\asymp|\\smile|\\frown|\\bowtie|\\succ|\\succeq|\\mid)/1/g;
     $garbage=~s/(\\not<|\\\\not\\le|\\not\\prec|\\not\\preceq|\\not\\subset|\\not\\subseteq|\\not\\sqsubseteq|\\not\\in|\\not>|\\not\\ge|\\not\\succ|\\notsucceq|\\not\\supset|\\notsupseteq|\\not\\sqsupseteq|\\notin|\\not=|\\not\\equiv|\\not\\sim|\\not\\simeq|\\not\\approx|\\not\\cong|\\not\\asymp)/1/g;      $garbage=~s/(\\not<|\\\\not\\le|\\not\\prec|\\not\\preceq|\\not\\subset|\\not\\subseteq|\\not\\sqsubseteq|\\not\\in|\\not>|\\not\\ge|\\not\\succ|\\notsucceq|\\not\\supset|\\notsupseteq|\\not\\sqsupseteq|\\notin|\\not=|\\not\\equiv|\\not\\sim|\\not\\simeq|\\not\\approx|\\not\\cong|\\not\\asymp)/1/g;
     $garbage=~s/(\\leftarrow|\\gets|\\Leftarrow|\\rightarrow|\\to|\\Rightarrow|\\leftrightarrow|\\Leftrightarrow|\\mapsto|\\hookleftarrow|\\leftharpoonup|\\leftkarpoondown|\\rightleftharpoons|\\longleftarrow|\\Longleftarrow|\\longrightarrow|\\Longrightarrow|\\longleftrightarrow|\\Longleftrightarrow|\\longmapsto|\\hookrightarrow|\\rightharpoonup|\\rightharpoondown|\\uparrow|\\Uparrow|\\downarrow|\\Downarrow|\\updownarrow|\\Updownarrow|\\nearrow|\\searrow|\\swarrow|\\nwarrow)/11/g;      $garbage=~s/(\\leftarrow|\\gets|\\Leftarrow|\\rightarrow|\\to|\\Rightarrow|\\leftrightarrow|\\Leftrightarrow|\\mapsto|\\hookleftarrow|\\leftharpoonup|\\leftkarpoondown|\\rightleftharpoons|\\longleftarrow|\\Longleftarrow|\\longrightarrow|\\Longrightarrow|\\longleftrightarrow|\\Longleftrightarrow|\\longmapsto|\\hookrightarrow|\\rightharpoonup|\\rightharpoondown|\\uparrow|\\Uparrow|\\downarrow|\\Downarrow|\\updownarrow|\\Updownarrow|\\nearrow|\\searrow|\\swarrow|\\nwarrow)/11/g;
     $garbage=~s/(\\aleph|\\hbar|\\imath|\\jmath|\\ell|\\wp|\\Re|\\Im|\\mho|\\prime|\\emptyset|\\nabla|\\surd|\\partial|\\top|\\bot|\\vdash|\\dashv|\\forall|\\exists|\\neg|\\flat|\\natural|\\sharp|\\\||\\angle|\\backslash|\\Box|\\Diamond|\\triangle|\\clubsuit|\\diamondsuit|\\heartsuit|\\spadesuit|\\Join|\\infty)/11/g;      $garbage=~s/(\\aleph|\\hbar|\\imath|\\jmath|\\ell|\\wp|\\Re|\\Im|\\mho|\\prime|\\emptyset|\\nabla|\\surd|\\partial|\\top|\\bot|\\vdash|\\dashv|\\forall|\\exists|\\neg|\\flat|\\natural|\\sharp|\\\||\\angle|\\backslash|\\Box|\\Diamond|\\triangle|\\clubsuit|\\diamondsuit|\\heartsuit|\\spadesuit|\\Join|\\infty)/11/g;
     $garbage=~s/(\\hat{([^}]+)}|\\check{([^}]+)}|\\dot{([^}]+)}|\\breve{([^}]+)}|\\acute{([^}]+)}|\\ddot{([^}]+)}|\\grave{([^}]+)}|\\tilde{([^}]+)}|\\mathring{([^}]+)}|\\bar{([^}]+)}|\\vec{([^}]+)})/$1/g;      $garbage=~s/(\\hat\{([^}]+)}|\\check\{([^}]+)}|\\dot\{([^}]+)}|\\breve\{([^}]+)}|\\acute\{([^}]+)}|\\ddot\{([^}]+)}|\\grave\{([^}]+)}|\\tilde\{([^}]+)}|\\mathring\{([^}]+)}|\\bar\{([^}]+)}|\\vec\{([^}]+)})/$1/g;
     #remove some other LaTeX command      #remove some other LaTeX command
     $garbage=~s|\\(\w+)\\|\\|g;        $garbage=~s|\\(\w+)\\|\\|g;
     $garbage=~s|\\(\w+)(\s*)|$2|g;        $garbage=~s|\\(\w+)(\s*)|$2|g;
     $garbage=~s|\+|11|g;      $garbage=~s|\+|11|g;
     my  $value=length($garbage);      my  $value=length($garbage);
     return $value;      return $value;
 }  }
   
   
 # is_inside_of $tagstack $tag  sub align_latex_image {
 #    This sub returns true if the current state of Xml processing      my ($align, $latex_rendering, $image, $width, $height) = @_;
 #    is inside of the tag.         my $currentstring;        # The 1/2 wrapped image.
 # Parameters:      my $closure;              # The closure of the wrappage.
 #     tagstack   - The tagstack from the parser.  
 #     tag        - The tag (without the <>'s.).      # if it's none just return it back
 # Sample usage:      if ($latex_rendering eq 'none') {
 #     if (is_inside_of($tagstack "table")) {   return ($image,'');
 #          # I'm in a table....      }
 #      }  
       #    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 = '';
       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       = '}';
       }
       return ($currentstring, $closure);
   }
   
   
 sub is_inside_of {  sub is_inside_of {
     my ($tagstack, $tag) = @_;      my ($tagstack, $tag) = @_;
     my @stack = @$tagstack;      my @stack = @$tagstack;
Line 4368  sub is_inside_of { Line 4592  sub is_inside_of {
 }  }
   
   
   #
   #   This sub provides the typical LaTeX prefix matter for tex output:
   #
   sub latex_header {
       my ($mode) = @_;
       my $currentstring = '';
   
       $currentstring .=
    "\n% &Apache::lonxml::londefdef \n" .
    '\documentclass[letterpaper,twoside]{article}\raggedbottom';
       if (($env{'form.latex_type'}=~'batchmode') ||
    (!$env{'request.role.adv'}) ||
    ($mode eq 'batchmode')) {$currentstring .='\batchmode';}
       $currentstring .= '\newcommand{\keephidden}[1]{}'.
    '\renewcommand{\deg}{$^{\circ}$}'.
    '\usepackage{multirow}'."\n".
    '\usepackage{longtable}'."\n".
    '\usepackage{textcomp}'."\n".
    '\usepackage{makeidx}'."\n".
    '\usepackage[dvips]{graphicx}'."\n".
    '\usepackage{wrapfig}'."\n".
    '\usepackage{picins}'."\n".
    '\usepackage[T1]{fontenc}'."\n".
    '\usepackage{lmodern}'."\n".
    '\usepackage[postscript]{ucs}'."\n".
    '\usepackage[utf8x]{inputenc}'."\n".
    '\usepackage{pifont}'."\n".
    '\usepackage{latexsym}'."\n".
    '\usepackage{epsfig}'."\n".
    '\usepackage{xtab}'."\n".
    '\usepackage{tabularx}'."\n".
    '\usepackage{booktabs}'."\n".
    '\usepackage{array}'."\n".
    '\usepackage{colortbl}'."\n".
    '\usepackage{xcolor}'."\n".
    '\usepackage{calc}'."\n".
    '\usepackage{amsmath}'."\n".
    '\usepackage{soul}'."\n".
    '\usepackage{amssymb}'."\n".
    '\usepackage{amsfonts}'."\n".
    '\usepackage{amsthm}'."\n".
    '\usepackage{amscd}'."\n".
    '\usepackage{actuarialangle}'."\n";
       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}}';
       $currentstring .= '\begin{document}';
   
       return $currentstring;
   
   }
   
   sub clean_docs_httpref {
       my ($href,$docuri,$cdom,$cnum) = @_;
       if ($docuri eq '') {
           $docuri = &Apache::lonnet::hreflocation('',$env{'request.filename'});
       }
       if ($cdom eq '') {
           $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       }
       if ($cnum eq '') {
           $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       }
       my $cleanhref;
       if ($docuri =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/)(.+/)[^/]+$}) {
           my $prefix = $1;
           my $relpath = $2;
           my ($hrefpath,$fname);
           if ($href =~ m{^/}) {
               if ($href =~ m{^\Q$prefix\E(.+/)([^/]+)$}) {
                   $hrefpath = $1;
                   $fname = $2;
               } else {
                   return $cleanhref;
               }
           } else {
               if ($href =~ m{/}) {
                   (my $path,$fname) = ($href =~ m{^(.*)/([^/]*)$});
                   $hrefpath = $relpath.$path;
                   if ($path eq '') {
                       $hrefpath =~ s{/$}{};
                   }
               } else {
                   $fname = $href;
                   $hrefpath = $relpath;
                   $hrefpath =~ s{/$}{};
               }
           }
           if ($fname ne '') {
               my $cleanrelpath;
               foreach my $dir (split(/\//,$hrefpath)) {
                   next if ($dir eq '.');
                   if ($dir eq '..') {
                       $cleanrelpath =~ s{([^/]+/)$}{};
                   } else {
                       $cleanrelpath .= $dir.'/';
                   }
               }
               if ($cleanrelpath ne '') {
                   $cleanhref = $prefix.$cleanrelpath.$fname;
               } else {
                   $cleanhref = $prefix.$fname;
               }
           }
       }
       return $cleanhref;
   }
   
   # This is retrieving a CSS property from the style attribute of the current element.
   # It is not checking <style> elements or linked stylesheets yet.
   sub get_css_property {
       my ($property,$parstack,$safeeval) = @_;
       my $style=&Apache::lonxml::get_param('style',$parstack,$safeeval,undef,1);
       my @style_components=split(/;/,$style);
       foreach my $css_pair (@style_components) {
           my ($name, $value) = split(/:/, $css_pair);
           $name =~ s/^\s+|\s+$//g;
           $value =~ s/^\s+|\s+$//g;
           if ($name eq $property) {
               return $value;
           }
       }
       return undef;
   }
   
   =pod
   
   =head1 NAME
   
   Apache::londefdef.pm
   
   =head1 SYNOPSIS
   
   Tags Default Definition Module
   
   This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   
   =head1 NOTABLE SUBROUTINES
   
   =over
   
   =item start_hideweboutput()
   
   =item end_hideweboutput()
   
   =item image_replication()
   
   =item resize_image()
   
    Get correct sizing parameter for an image given
    it's initial ht. and wid.  This allows sizing of
    images that are generated on-the-fly (e.g. gnuplot)
    as well as serving as a utility for image_size.
   
    Parameter:
           height_param
           width_param    - Initial picture dimensions.
           scaling        - A scale factor.
           parstack,      - the current stack of tag attributes
                            from the xml parser
           safeeval,      - pointer to the safespace
           depth,         - from what level in the stack to look for attributes
                            (assumes -1 if unspecified)
           cis            - look for attrubutes case insensitively
                            (assumes false)
   
    Returns:
    height, width   - new dimensions.
   
   =item image_size()
   
   =item image_width()
   
   =item image_height()
   
   =item get_eps_image()
   
   =item eps_generation()
   
   =item file_path()
   
   =item recalc()
   
    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
   
   =item LATEX_length()
   
   =item align_latex_image()
   
     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.
   
   
   =item 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....
         }
   
   =item clean_docs_httpref($href,$docuri,$cdom,$cnum)
           HTML pages uploaded to a course which contain dependencies either from iframes,
           javascript files or objects (FlashPlayerSwf, MediaSrc, XMPSrc, ConfigurationSrc,
           and PosterImageSrc) for which dependency is another file uploaded to the same
           course.
   
           Required input:
           href - dependency (either a relative URL, or an absolute URL)
           Optional inputs:
           docuri - URL of HTML page containing the dependency
           cdom - Course domain
           cnum - CourseID
   
           Output:
           returns an absolute URL constructed from the href provided, and the calling context.
           (this will be null, if the URL does not begin: /uploaded/$cdom/$cnum/docs/ or
           /uploaded/$cdom/$cnum/supplemental/).
   
   =back
   
   =cut
   
   
 1;  1;
 __END__  __END__

Removed from v.1.322  
changed lines
  Added in v.1.470


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>