Diff for /loncom/xml/londefdef.pm between versions 1.158 and 1.278

version 1.158, 2003/08/01 13:35:20 version 1.278, 2005/07/10 21:43:35
Line 36 Line 36
 # 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.
 #  #
 #  
 # last modified 06/26/00 by Alexander Sakharuk  
 # 11/6,11/30,02/01/01,5/4 Gerd Kortemeyer  
 # 01/18 Alex Sakharuk  
   
 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::File();
 use Image::Magick;  use Image::Magick;
 use Apache::lonmenu();  use Apache::lonmenu();
 use Apache::lonmeta();  use Apache::lonmeta();
   use Apache::Constants qw(:common);
   
   
 BEGIN {  BEGIN {
   
Line 57  BEGIN { Line 55  BEGIN {
   
 }  }
   
   sub initialize_londefdef {
       $Apache::londefdef::TD_redirection=0;
       @Apache::londefdef::table = ();
       $Apache::londefdef::select=0;
       undef(@Apache::londefdef::description);
       @Apache::londefdef::DD=(0);
       @Apache::londefdef::DT=(0);
       @Apache::londefdef::seenDT=(0);
       $Apache::londefdef::list_index=0;
   }
   
 #======================= TAG SUBROUTINES =====================  #======================= TAG SUBROUTINES =====================
 #-- <output>  #-- <output>
 sub start_output {  sub start_output {
Line 71  sub end_output { Line 80  sub end_output {
 }  }
 #-- <m> tag  #-- <m> tag
 sub start_m {  sub start_m {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);
  $Apache::lonxml::prevent_entity_encode++;      if ($target eq 'web' || $target eq 'analyze') {
  my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);  
  $inside ='\\documentstyle{article}'.$inside;  
  &Apache::lonxml::debug("M is starting with:$inside:");   &Apache::lonxml::debug("M is starting with:$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') {
     $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 evaulated to:$inside:");
  }   }
  $currentstring = &Apache::lontexconvert::converted(\$inside);   my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval);
    $currentstring = &Apache::lontexconvert::converted(\$inside,$display);
  if ($Apache::lontexconvert::errorstring) {   if ($Apache::lontexconvert::errorstring) {
     &Apache::lonxml::warning("tth error: ".      &Apache::lonxml::warning("tth error: ".
      $Apache::lontexconvert::errorstring);       $Apache::lontexconvert::errorstring);
     $Apache::lontexconvert::errorstring='';      $Apache::lontexconvert::errorstring='';
  }   }
  #&Apache::lonxml::debug("M is ends with:$currentstring:");   #&Apache::lonxml::debug("M is ends with:$currentstring:");
    $Apache::lonxml::post_evaluate=0;
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);   $currentstring = $inside;
    my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
    if ($eval eq 'on') {
       $currentstring=&Apache::run::evaluate($currentstring,$safeeval,$$parstack[-1]);
    }
  if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';}   if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';}
     } else {   # detect simple math mode entry exits, and convert them
  my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);          # to use \ensuremath
    if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) {
       $currentstring=~s/^\$//;
       $currentstring=~s/\$$//;
       $currentstring='\ensuremath{'.$currentstring.'}';
    }
    $Apache::lonxml::post_evaluate=0;
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 102  sub start_m { Line 121  sub start_m {
 sub end_m {  sub end_m {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'tex') {
  $Apache::lonxml::prevent_entity_encode--;  
     } elsif ($target eq 'tex') {  
  $currentstring = "";   $currentstring = "";
     } elsif ($target eq 'meta') {  
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 117  sub start_tthoption { Line 133  sub start_tthoption {
     if ($target eq 'web') {      if ($target eq 'web') {
  my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser);   my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser);
  $inside=~s/^\s*//;   $inside=~s/^\s*//;
  if ($ENV{'browser.mathml'}) {   if ($env{'browser.mathml'}) {
     &tth::ttmoptions($inside);      &tth::ttmoptions($inside);
  } else {   } else {
     &tth::tthoptions($inside);      &tth::tthoptions($inside);
Line 132  sub end_tthoption { Line 148  sub end_tthoption {
     return $result;      return $result;
 }  }
   
 #-- <html> tag      #-- <html> tag (end tag optional)
 sub start_html {  sub start_html {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($ENV{'browser.mathml'}) {      my $options=$env{'course.'.$env{'request.course.id'}.'.tthoptions'};
  &tth::ttminit();      &Apache::lontexconvert::init_tth();
  if ($ENV{'browser.unicode'}) {      if ($target eq 'web' || $target eq 'edit' || $target eq 'webgrade' ) {
     &tth::ttmoptions('-L -u1');   $currentstring = &Apache::lonxml::xmlbegin();
  } else {  
     &tth::ttmoptions('-L -u0');  
  }  
     } else {  
  &tth::tthinit();  
  if ($ENV{'browser.unicode'}) {  
     &tth::tthoptions('-L -u1');  
  } else {  
     &tth::tthoptions('-L -u0');  
  }  
     }  
     if ($target eq 'web') {  
  $currentstring = &Apache::lonxml::xmlbegin().  
     &Apache::lonxml::fontsettings();       
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  @Apache::londefdef::table = ();  
  $currentstring .= '\documentclass[letterpaper]{article}';   $currentstring .= '\documentclass[letterpaper]{article}';
  if ($ENV{'form.latex_type'}=~'batchmode') {$currentstring .='\batchmode';}    if (($env{'form.latex_type'}=~'batchmode') ||
  $currentstring .= '\newcommand{\keephidden}[1]{}              (!$env{'request.role.adv'})) {$currentstring .='\batchmode';} 
                            \renewcommand{\deg}{$^{\circ}$}   $currentstring .= '\newcommand{\keephidden}[1]{}'.
                            \usepackage{longtable}                            '\renewcommand{\deg}{$^{\circ}$}'.
                            \usepackage{textcomp}                            '\usepackage{longtable}'.
                            \usepackage[dvips]{graphicx}                            '\usepackage{textcomp}'.
                            \usepackage{epsfig}\usepackage{calc}                            '\usepackage{makeidx}'.
 \newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}';                            '\usepackage[dvips]{graphicx}'.
     '\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;
 }  }
   
 sub end_html {  sub end_html {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = &Apache::lonxml::xmlend();   $currentstring = '</html>';
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <head> tag  #-- <head> tag (end tag optional)
 sub start_head {  sub start_head {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4].&Apache::lonxml::fontsettings();
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 191  sub start_head { Line 202  sub start_head {
 sub end_head {  sub end_head {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web' && $env{'request.state'} eq 'published') {
  $currentstring = &Apache::lonmenu::registerurl(undef,$target).   $currentstring = &Apache::lonmenu::registerurl(undef,$target).
     $token->[2];          $token->[2];    
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <map> tag  #-- <map> tag (end tag required)
 sub start_map {  sub start_map {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 217  sub end_map { Line 228  sub end_map {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <select> tag  #-- <select> tag (end tag required)
 sub start_select {  sub start_select {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     }       }  elsif ($target eq 'tex') {
    $Apache::londefdef::select=0;
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 236  sub end_select { Line 249  sub end_select {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <option> tag  #-- <option> tag (end tag optional)
 sub start_option {  sub start_option {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     }       } elsif ($target eq 'tex') {
    $Apache::londefdef::select++;
    if ($Apache::londefdef::select == 1) {
       $currentstring='\noindent\fbox{'.&Apache::lonxml::get_param('value',$parstack,$safeeval).'}\keephidden{';
    } else {
       $currentstring='\keephidden{';
    }
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 251  sub end_option { Line 271  sub end_option {
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];       $currentstring = $token->[2];    
     }       }  elsif ($target eq 'tex') {
    $currentstring='}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <input> tag  #-- <input> tag (end tag forbidden)
 sub start_input {  sub start_input {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 274  sub end_input { Line 296  sub end_input {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <textarea> tag  #-- <textarea> tag (end tag required)
 sub start_textarea {  sub start_textarea {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 293  sub end_textarea { Line 315  sub end_textarea {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <form> tag  #-- <form> tag (end tag required)
 sub start_form {  sub start_form {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 312  sub end_form { Line 334  sub end_form {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <title> tag  #-- <title> tag (end tag required)
 sub start_title {  sub start_title {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\keephidden{'    $currentstring .= '\keephidden{Title of the document:  ' 
     }      }
     if ($target eq 'meta') {      if ($target eq 'meta') {
  $currentstring='<title>';   $currentstring='<title>';
  &start_output();   &start_output($target);
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 337  sub end_title { Line 359  sub end_title {
  $currentstring .= '}';   $currentstring .= '}';
     }        }  
     if ($target eq 'meta') {      if ($target eq 'meta') {
  &end_output();   &end_output($target);
  $currentstring='</title>';   $currentstring='</title>';
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <meta> tag  #-- <meta> tag (end tag forbidden)
 sub start_meta {  sub start_meta {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 378  sub start_meta { Line 400  sub start_meta {
             my $display=&Apache::lonxml::get_param              my $display=&Apache::lonxml::get_param
  ('display',$parstack,$safeeval,undef,1);   ('display',$parstack,$safeeval,undef,1);
             if ($display) {              if ($display) {
  $display=&HTML::Entities::encode($display);   $display=&HTML::Entities::encode($display,'<>&"');
  $currentstring.='<'.$name.'.display>'.$display.   $currentstring.='<'.$name.'.display>'.$display.
                                '</'.$name.'.display>';                                 '</'.$name.'.display>';
             }              }
Line 394  sub start_meta { Line 416  sub start_meta {
 }  }
   
 sub end_meta {  sub end_meta {
     my ($target,$token,$tagstack,$parstack,$parser) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  my $args='';   my $args='';
Line 403  sub end_meta { Line 425  sub end_meta {
     $currentstring = $token->[4];      $currentstring = $token->[4];
  }   }
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring=&Apache::lonxml::endredirection();   my $content=&Apache::lonxml::get_param('content',$parstack,$safeeval);
  $currentstring='';   my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval);
    if ((not defined $content) && (not defined $name)) {
       &Apache::lonxml::endredirection();
    }
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 454  sub end_accessrule { Line 479  sub end_accessrule {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <body> tag  #-- <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') {
  if (!$Apache::lonxml::registered) {   if ($Apache::lonhomework::parsing_a_problem) {
       &Apache::lonxml::warning("<body> tag found inside of <problem> tag this can cause problems.");
       return '';
    }
    if (!$Apache::lonxml::registered && 
       $env{'request.state'} eq 'published') {
     $currentstring.='<head>'.      $currentstring.='<head>'.
  &Apache::lonmenu::registerurl(undef,$target).'</head>';   &Apache::lonmenu::registerurl(undef,$target).'</head>';
  }   }
 # Accessibility  # Accessibility
  if ($ENV{'browser.imagesuppress'} eq 'on') {   if ($env{'browser.imagesuppress'} eq 'on') {
     delete($token->[2]->{'background'});      delete($token->[2]->{'background'});
  }   }
  if ($ENV{'browser.fontenhance'} eq 'on') {   if ($env{'browser.fontenhance'} eq 'on') {
     my $style='';      my $style='';
     foreach my $key (keys(%{$token->[2]})) {      foreach my $key (keys(%{$token->[2]})) {
  if ($key =~ /^style$/i) {   if ($key =~ /^style$/i) {
Line 477  sub start_body { Line 508  sub start_body {
     }      }
     $token->[2]->{'style'}=$style.'; font-size: x-large;';      $token->[2]->{'style'}=$style.'; font-size: x-large;';
  }   }
  if ($ENV{'browser.blackwhite'} eq 'on') {   if ($env{'browser.blackwhite'} eq 'on') {
     delete($token->[2]->{'font'});      delete($token->[2]->{'font'});
     delete($token->[2]->{'link'});      delete($token->[2]->{'link'});
     delete($token->[2]->{'alink'});      delete($token->[2]->{'alink'});
Line 509  sub start_body { Line 540  sub start_body {
     $currentstring.=' '.$_.'="'.$token->[2]->{$_}.'"';      $currentstring.=' '.$_.'="'.$token->[2]->{$_}.'"';
  }   }
  $currentstring.='>';   $currentstring.='>';
  if ($ENV{'request.state'} ne 'published') {   if ($env{'request.state'} ne 'published') {
       if ($env{'environment.remote'} eq 'off') {
    $currentstring.= 
       &Apache::lonmenu::constspaceform().
       &Apache::lonmenu::menubuttons(1,'web',1);
       }
     $currentstring.=(<<EDITBUTTON);      $currentstring.=(<<EDITBUTTON);
  <form method="post">  <form method="post">
  <input type="submit" name="editmode" value="Edit" />  <input type="submit" name="editmode" accesskey="e" value="Edit" />
  </form>  </form>
 EDITBUTTON  EDITBUTTON
  } else {   } else {
     $currentstring.=&Apache::lonmenu::menubuttons(undef,$target,1);      $currentstring.=&Apache::lonmenu::menubuttons(undef,$target,1);
  }   }
    $currentstring.=&Apache::lonxml::message_location();
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\begin{document}';     $currentstring = '\begin{document}';  
     }       } 
Line 525  EDITBUTTON Line 562  EDITBUTTON
 }  }
   
 sub end_body {  sub end_body {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off unclosed <p>
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];        $currentstring .= &Apache::lonxml::xmlend($target,$parser);
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{document}';     $currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}';  
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <center> tag  #-- <center> tag (end tag required)
 sub start_center {  sub start_center {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring .= $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\begin{center}';     $currentstring .= '\begin{center}';  
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 558  sub end_center { Line 595  sub end_center {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <b> tag  #-- <b> tag (end tag required)
 sub start_b {  sub start_b {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 581  sub end_b { Line 618  sub end_b {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <strong> tag  #-- <strong> tag (end tag required)
 sub start_strong {  sub start_strong {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 596  sub start_strong { Line 633  sub start_strong {
 sub end_strong {  sub end_strong {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
   
  $currentstring = $token->[2];        $currentstring = $token->[2];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '}';     $currentstring = '}';  
Line 605  sub end_strong { Line 641  sub end_strong {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <h1> tag  #-- <h1> tag (end tag required)
 sub start_h1 {  sub start_h1 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
  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') || (not defined $align)) {   if ($align eq 'center') {
     $pre='\begin{center}';      $pre='\begin{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $pre='\rlap{';      $pre='\rlap{';
Line 623  sub start_h1 { Line 659  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 .= $pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
     } elsif ($target eq 'meta') {      } elsif ($target eq 'meta') {
  $currentstring='<subject>';   $currentstring.='<subject>';
  &start_output();   &start_output($target);
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 637  sub end_h1 { Line 673  sub end_h1 {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post;   my $post='\vskip 0 mm ';
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $post='\end{center}';      $post='\end{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $post='} \hfill'.'\vskip 0 mm ';      $post='} \hfill'.'\vskip 0 mm ';
Line 648  sub end_h1 { Line 684  sub end_h1 {
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     } elsif ($target eq 'meta') {      } elsif ($target eq 'meta') {
  &end_output();   &end_output($target);
  $currentstring='</subject>';   $currentstring='</subject>';
     }       } 
     return $currentstring;      return $currentstring;
Line 657  sub end_h1 { Line 693  sub end_h1 {
 #-- <h2> tag  #-- <h2> tag
 sub start_h2 {  sub start_h2 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $pre='\begin{center}';      $pre='\begin{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $pre='\rlap{';      $pre='\rlap{';
Line 672  sub start_h2 { Line 708  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 .= $pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 683  sub end_h2 { Line 719  sub end_h2 {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post;   my $post='\vskip 0 mm ';
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $post='\end{center}';      $post='\end{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $post='} \hfill'.'\vskip 0 mm ';      $post='} \hfill'.'\vskip 0 mm ';
Line 700  sub end_h2 { Line 736  sub end_h2 {
 #-- <h3> tag  #-- <h3> tag
 sub start_h3 {  sub start_h3 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $pre='\begin{center}';      $pre='\begin{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $pre='\rlap{';      $pre='\rlap{';
Line 715  sub start_h3 { Line 751  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 .= $pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 726  sub end_h3 { Line 762  sub end_h3 {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post;   my $post='\vskip 0 mm ';
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $post='\end{center}';      $post='\end{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $post='} \hfill'.'\vskip 0 mm ';      $post='} \hfill'.'\vskip 0 mm ';
Line 743  sub end_h3 { Line 779  sub end_h3 {
 #-- <h4> tag  #-- <h4> tag
 sub start_h4 {  sub start_h4 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off any prior para.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $pre='\begin{center}';      $pre='\begin{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $pre='\rlap{';      $pre='\rlap{';
Line 758  sub start_h4 { Line 794  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 .= $pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 769  sub end_h4 { Line 805  sub end_h4 {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post;   my $post='\vskip 0 mm ';
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $post='\end{center}';      $post='\end{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $post='} \hfill'.'\vskip 0 mm ';      $post='} \hfill'.'\vskip 0 mm ';
Line 786  sub end_h4 { Line 822  sub end_h4 {
 #-- <h5> tag  #-- <h5> tag
 sub start_h5 {  sub start_h5 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off any prior paras.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $pre='\begin{center}';      $pre='\begin{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $pre='\rlap{';      $pre='\rlap{';
Line 801  sub start_h5 { Line 837  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 .= $pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 812  sub end_h5 { Line 848  sub end_h5 {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post;   my $post='\vskip 0 mm ';
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $post='\end{center}';      $post='\end{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $post='} \hfill'.'\vskip 0 mm ';      $post='} \hfill'.'\vskip 0 mm ';
Line 829  sub end_h5 { Line 865  sub end_h5 {
 #-- <h6> tag  #-- <h6> tag
 sub start_h6 {  sub start_h6 {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off any prior paras.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $pre;   my $pre;
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $pre='\begin{center}';      $pre='\begin{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $pre='\rlap{';      $pre='\rlap{';
Line 844  sub start_h6 { Line 880  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 .= $pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 855  sub end_h6 { Line 891  sub end_h6 {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post;   my $post='\vskip 0 mm ';
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if (($align eq 'center') || (not defined $align)) {   if ($align eq 'center') {
     $post='\end{center}';      $post='\end{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $post='} \hfill'.'\vskip 0 mm ';      $post='} \hfill'.'\vskip 0 mm ';
Line 869  sub end_h6 { Line 905  sub end_h6 {
     return $currentstring;      return $currentstring;
 }  }
   
 #--- <cite> tag  #--- <cite> tag (end tag required)
 sub start_cite {  sub start_cite {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "\\textit{";   $currentstring .= '\textit{';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 887  sub end_cite { Line 923  sub end_cite {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "}";   $currentstring .= '}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <i> tag  #-- <i> tag (end tag required)
 sub start_i {  sub start_i {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 915  sub end_i { Line 951  sub end_i {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <address> tag  #-- <address> tag (end tag required)
 sub start_address {  sub start_address {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "\\textit{";   $currentstring .= '\textit{';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 933  sub end_address { Line 969  sub end_address {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "}";   $currentstring .= '}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <dfn> tag  #-- <dfn> tag (end tag required)
 sub start_dfn {  sub start_dfn {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "\\textit{";   $currentstring .= '\textit{';
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 956  sub end_dfn { Line 992  sub end_dfn {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "}";   $currentstring .= '}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <tt> tag  #-- <tt> tag (end tag required)
 sub start_tt {  sub start_tt {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 984  sub end_tt { Line 1020  sub end_tt {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <kbd> tag  #-- <kbd> tag (end tag required)
 sub start_kbd {  sub start_kbd {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "\\texttt";   $currentstring .= '\texttt{';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1002  sub end_kbd { Line 1038  sub end_kbd {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "}";   $currentstring .= '}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <code> tag  #-- <code> tag (end tag required)
 sub start_code {  sub start_code {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1030  sub end_code { Line 1066  sub end_code {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <em> tag  #-- <em> tag (end tag required)
 sub start_em {  sub start_em {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1053  sub end_em { Line 1089  sub end_em {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <q> tag  #-- <q> tag (end tag required)
 sub start_q {  sub start_q {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "\\emph{";   $currentstring .= '\emph{';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1071  sub end_q { Line 1107  sub end_q {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "}";   $currentstring .= '}';
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <p> tag  #  <p> is a bit strange since it does not require a closing </p>
   #  However in latex, we must often output closing stuff to end
   #  environments and {}'s etc.  Therefore we do all the work
   #  of figuring out the ending strings in the start tag processing,
   #  and provide a mechanism to output the stop text external
   #  to tag processing.
   #
   {
   
       my $closing_string = ''; # String required to close <p>
   
   #-- <p> tag (end tag optional)
   #optional attribute - align="center|left|right"
 sub start_p {  sub start_p {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # close off prior para if in progress.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
    $closing_string = '</p>'; # Not sure this is correct.
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $signal=1;   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  foreach my $tag (@$tagstack) {if (lc($tag) eq 'b') {$signal=0;}}   if ($align eq 'center') {
  if ($signal) {$currentstring .= '\par ';}      $currentstring .='\begin{center}\par';
     }      $closing_string = '\end{center}';
     return $currentstring;   } elsif ($align eq 'right') {
 }      $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';
       $closing_string= '}}';
    } elsif ($align eq 'left') {
       $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{\rlap{';
       $closing_string = '}\hfill}';
    } else {
               $currentstring.='\par ';
       $closing_string = '\strut\\\\\strut';
           }
    my $signal=1;#<p> does not work inside <b>...</b> 
    foreach my $tag (@$tagstack) {
       if (lc($tag) eq 'b') {
    $signal=0;
       }
    }
    if (!$signal) {
       $currentstring = &end_p; # Just close the prior? Not sure this is correct
       $closing_string = '';    # Probably correct?
    }
   
 sub end_p {  
     my ($target,$token) = @_;  
     my $currentstring = '';  
     if ($target eq 'web') {  
  $currentstring .= $token->[2];  
     }      }
     return $currentstring;      return $currentstring;
 }  }
   #
   #  End paragraph processing just requires that we output the
   #  closing string that was saved and blank it.
   sub end_p {
       my $current_string = $closing_string;
       $closing_string = ''; # Not in a para anymore.
       return $current_string;
   
 #-- <br> tag  }
   }
   #-- <br> tag (end tag forbidden)
 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') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($$tagstack[-2] ne 'sub' && $$tagstack[-2] ne 'sup') {   my @tempo=@$tagstack;
     $currentstring .= '\vskip 0.2 mm ';   my $signal=0;
    for (my $i=$#tempo;$i>=0;$i--) {
       if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') ||
                   ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul') ||
                   ($tempo[$i] eq 'td') || ($tempo[$i] eq 'th'))  {
    $signal=1;
    last;
       }
    }
    if ($signal) {
       $currentstring .= ' \vskip 0 mm ';
    } elsif ($$tagstack[-2] ne 'sub' && $$tagstack[-2] ne 'sup') {
       $currentstring .= '\strut \\\\ \strut ';
  }   }
     }      }
     return $currentstring;      return $currentstring;
Line 1122  sub end_br { Line 1205  sub end_br {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <big> tag  #-- <big> tag (end tag required)
 sub start_big {  sub start_big {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1145  sub end_big { Line 1228  sub end_big {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <small> tag  #-- <small> tag (end tag required)
 sub start_small {  sub start_small {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1168  sub end_small { Line 1251  sub end_small {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <basefont> tag  #-- <basefont> tag (end tag forbidden)
 sub start_basefont {  sub start_basefont {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
     my $currentstring = '';      my $currentstring = '';
Line 1197  sub end_basefont { Line 1280  sub end_basefont {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <font> tag  #-- <font> tag (end tag required)
 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') {
  my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);   my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);
  if ($face=~/symbol/i) {   if ($face!~/symbol/i) {
     $Apache::lonxml::prevent_entity_encode++;      if (($env{'browser.fontenhance'} eq 'on') || 
  } else {   ($env{'browser.blackwhite'} eq 'on')) { return ''; }
     if (($ENV{'browser.fontenhance'} eq 'on') ||   
  ($ENV{'browser.blackwhite'} eq 'on')) { return ''; }  
  }   }
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
Line 1223  sub end_font { Line 1304  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') {
  my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);  
  if ($face=~/symbol/i) {$Apache::lonxml::prevent_entity_encode--;}  
  $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);
Line 1235  sub end_font { Line 1314  sub end_font {
     return $currentstring;      return $currentstring;
 }  }
     
 #-- <strike> tag  #-- <strike> tag (end tag required)
 sub start_strike {  sub start_strike {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1261  sub end_strike { Line 1340  sub end_strike {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <s> tag  #-- <s> tag (end tag required)
 sub start_s {  sub start_s {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1287  sub end_s { Line 1366  sub end_s {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <sub> tag  #-- <sub> tag (end tag required)
 sub start_sub {  sub start_sub {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "\$_{ ";   $currentstring .= '\ensuremath{_{';
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 1305  sub end_sub { Line 1384  sub end_sub {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= " }\$";   $currentstring .= '}}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <sup> tag  #-- <sup> tag (end tag required)
 sub start_sup {  sub start_sup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= "\$^{ ";   $currentstring .= '\ensuremath{^{';
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 1328  sub end_sup { Line 1407  sub end_sup {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= " }\$";   $currentstring .= '}}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <hr> tag  #-- <hr> tag (end tag forbidden)
 sub start_hr {  sub start_hr {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # End enclosing para.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
Line 1373  sub end_hr { Line 1452  sub end_hr {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <div> tag  #-- <div> tag (end tag required)
 sub start_div {  sub start_div {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close enclosing para.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     }       } 
Line 1392  sub end_div { Line 1471  sub end_div {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <a> tag  #-- <a> tag (end tag required)
 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') {
  $currentstring .= $token->[4];   my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
       undef,1);
    $currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href});
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $a=&Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);   my $a=&Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);
  $a=~s/([^\\])%/$1\\\%/g;   my $b=&Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1);
  $currentstring .= '\ref{'.$a.'}';   if ($a=~/\S/) {
       $a=~s/([^\\])%/$1\\\%/g;
       $currentstring .= '\ref{URI: '.$a.'}';
    } elsif ($b=~/\S/) {
       $currentstring .= '\ref{Anchor: '.$b.'}';
    } else {
       $currentstring.='';
    }
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_a {  sub end_a {
     my ($target,$token,$tagstack,$parstack,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
Line 1415  sub end_a { Line 1503  sub end_a {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <li> tag  #-- <li> tag (end tag optional)
 sub start_li {  sub start_li {
     my ($target,$token,$tagstack,$parstack,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my  $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,1);   my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
  if ($type=~/circle/) {   my $value=&Apache::lonxml::get_param('value',$parstack,$safeeval,undef,0);
     $currentstring .= ' \item[o] ';   #FIXME need to support types i and I 
    if ($type=~/disc/) {
       $currentstring .= ' \item[$\bullet$] ';
    } elsif ($type=~/circle/) {
       $currentstring .= ' \item[$\circ$] ';
  } elsif ($type=~/square/) {   } elsif ($type=~/square/) {
     $currentstring .= ' \item[$\Box$] ';      $currentstring .= ' \item[$\diamond$] ';
  } elsif ($type ne '') {    } elsif ($type eq '1') {
     $currentstring .= ' \item['.$type.'] ';      $currentstring .= ' \item['.($Apache::londefdef::list_index+1).'.]';
    } elsif ($type eq 'A') {
       $currentstring .= ' \item['.('A'..'Z')[$Apache::londefdef::list_index].'.]';
    } elsif ($type eq 'a') {
       $currentstring .= ' \item['.('a'..'z')[$Apache::londefdef::list_index].'.]';
    } elsif ($value ne '') {
       $currentstring .= ' \item['.$value.'] ';
  } else {   } else {
     $currentstring .= ' \item ';      $currentstring .= ' \item ';
  }     }  
     }    $Apache::londefdef::list_index++;
       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_li {  sub end_li {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # In case there's a <p> in the <li>
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];        $currentstring .= $token->[2];     
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <u> tag  #-- <u> tag (end tag required)
 sub start_u {  sub start_u {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1471  sub end_u { Line 1570  sub end_u {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <ul> tag  #-- <ul> tag (end tag required)
 sub start_ul {  sub start_ul {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off enclosing list.
     if ($target eq 'web') {      if ($target eq 'web') {
  $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;
  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 .= '\begin{itemize}';     $currentstring .= '\strut \begin{itemize}';  
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 1506  sub end_ul { Line 1606  sub end_ul {
     if ($target eq 'web') {      if ($target eq 'web') {
  $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$}';                                   '\renewcommand{\labelitemiv}{$\bullet$}\strut ';  
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <menu> tag  #-- <menu> tag (end tag required)
 sub start_menu {  sub start_menu {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1537  sub end_menu { Line 1637  sub end_menu {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <dir> tag  #-- <dir> tag (end tag required)
 sub start_dir {  sub start_dir {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # In case there's a <p> prior to the list.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring .= $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\begin{itemize} ";     $currentstring .= " \\begin{itemize} ";  
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 1560  sub end_dir { Line 1660  sub end_dir {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <ol> tag  #-- <ol> tag (end tag required)
 sub start_ol {  sub start_ol {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # In case there's a <p> prior to the list.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring .= $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
    $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') {
     $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 'i') {   } elsif ($type eq 'i') {
     $currentstring .= ' \renewcommand{\labelenumi}{\roman{enumi}.}      $currentstring .= '\renewcommand{\labelenumi}{\roman{enumi}.}'.
                                 \renewcommand{\labelenumii}{\roman{enumii}.}                                '\renewcommand{\labelenumii}{\roman{enumii}.}'.
                                 \renewcommand{\labelenumiii}{\roman{enumiii}.}                                '\renewcommand{\labelenumiii}{\roman{enumiii}.}'.
                                 \renewcommand{\labelenumiv}{\roman{enumiv}.} ';                                '\renewcommand{\labelenumiv}{\roman{enumiv}.}';
  } elsif ($type eq 'I') {   } elsif ($type eq 'I') {
     $currentstring .= ' \renewcommand{\labelenumi}{\Roman{enumi}.}      $currentstring .= '\renewcommand{\labelenumi}{\Roman{enumi}.}'.
                                 \renewcommand{\labelenumii}{\Roman{enumii}.}                                '\renewcommand{\labelenumii}{\Roman{enumii}.}'.
                                 \renewcommand{\labelenumiii}{\Roman{enumiii}.}                                '\renewcommand{\labelenumiii}{\Roman{enumiii}.}'.
                                 \renewcommand{\labelenumiv}{\Roman{enumiv}.} ';                                '\renewcommand{\labelenumiv}{\Roman{enumiv}.}';
  }   }
  $currentstring .= '\begin{enumerate}';     $currentstring .= '\strut \begin{enumerate}';  
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 1605  sub end_ol { Line 1706  sub end_ol {
     if ($target eq 'web') {      if ($target eq 'web') {
  $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}.}';                                            '\renewcommand{\labelenumiv}{\arabic{enumiv}.}\strut ';  
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <dl> tag  #-- <dl> tag (end tag required)
 sub start_dl {  sub start_dl {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # In case there's a <p> unclosed prior to the list.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring .= $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\begin{description}';     $currentstring .= '\begin{description}';
    $Apache::londefdef::DL++;
    push(@Apache::londefdef::description,[]);
    $Apache::londefdef::DD[$Apache::londefdef::DL]=0;
    $Apache::londefdef::DT[$Apache::londefdef::DL]=0;
    $Apache::londefdef::seenDT[$Apache::londefdef::DL]=0;
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_dl {  sub end_dl {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];        $currentstring = $token->[2];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{description}';     if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
    if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
    foreach my $element (@{$Apache::londefdef::description[-1]}) {
       $currentstring.=' '.$element.' ';
    }
    pop(@Apache::londefdef::description);
    $currentstring.='\end{description}';  
    delete($Apache::londefdef::DD[$Apache::londefdef::DL]);
    delete($Apache::londefdef::DT[$Apache::londefdef::DL]);
    delete($Apache::londefdef::seenDT[$Apache::londefdef::DL]);
    $Apache::londefdef::DL--;
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <dt> tag  #-- <dt> tag (end tag optional)
 sub start_dt {  sub start_dt {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring='';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\item[';     if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
    if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
    &Apache::lonxml::startredirection();
    $Apache::londefdef::DT[-1]++;
    $Apache::londefdef::seenDT[-1]=1;
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_dt {  sub end_dt {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];       $currentstring = $token->[2];    
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = ']';     if ($Apache::londefdef::DT[-1]) {
       my $data=&item_cleanup();
       push(@{$Apache::londefdef::description[-1]},'\item['.$data.'] \strut \vskip 0mm');
       $Apache::londefdef::DT[-1]--;
    }
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <dd> tag  sub item_cleanup {
       my $item=&Apache::lonxml::endredirection();
       $item=~s/\\begin{center}//g;
       $item=~s/\\end{center}//g;
       return $item;
   }
   
   #-- <dd> tag (end tag optional)
 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') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($$tagstack[-2] eq 'dl') {   if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
     $currentstring = ' \item [] ';     if ($Apache::londefdef::DD[-1]) { &end_dd(@_);}
  } elsif ($$tagstack[-2] eq 'dt') {   if (!$Apache::londefdef::seenDT[-1]) {
     $currentstring = ']';       push(@{$Apache::londefdef::description[-1]},'\item[\strut] \strut \vskip 0mm ');
  }   }
    push(@{$Apache::londefdef::description[-1]},'');
    $Apache::londefdef::description[-1]->[-1].=' \strut ';
    $Apache::londefdef::DD[-1]++;
    &Apache::lonxml::startredirection();
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_dd {  sub end_dd {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];       $currentstring = $token->[2];    
     }       }  elsif ($target eq 'tex') {
    $Apache::londefdef::description[-1]->[-1].=
       &Apache::lonxml::endredirection().' \vskip 0mm ';
    $Apache::londefdef::DD[-1]--;
       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <table> tag  #-- <table> tag (end tag required)
   #       <table> also ends any prior <p> that is not closed.
   #               but, unless I allow <p>'s to nest, that's the
   #               only way I could think of to allow <p> in 
   #               <tr> <th> bodies
   #
   #list of supported attributes: border,width,TeXwidth
 sub start_table {  sub start_table {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $textwidth='';      my $textwidth = '';
     if (not defined @Apache::londefdef::table) {      my $currentstring = &end_p;
  $textwidth=&recalc($ENV{'form.textwidth'});  
  $textwidth=~/(\d+\.?\d*)/;  
  $textwidth=0.95*$1;  
     } else {  
  $textwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);  
     }  
     my $currentstring = '';  
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring .= $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $aa = {};   my $aa = {};
  push @Apache::londefdef::table, $aa;    push @Apache::londefdef::table, $aa; 
  $Apache::londefdef::table[-1]{'row_number'} = -1;   $Apache::londefdef::table[-1]{'row_number'} = -1;
         #table's width          #maximum table's width (default coincides with text line length)
    if ($#Apache::londefdef::table==0) {
       $textwidth=&recalc($env{'form.textwidth'}); #result is always in mm
       $textwidth=~/(\d+\.?\d*)/;
       $textwidth=0.95*$1; #accounts "internal" LaTeX space for table frame
    } else {
       if ($Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]=~/\d/) {
    #the maximum width of nested table is determined by LATeX width of parent cell
    $textwidth=$Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]; 
       } else {
                 #try to use all space not used before (minus 5% for LaTeX table internal) - rather silly
    $textwidth=$Apache::londefdef::table[-2]{'width'};
    for (my $i=0;$i<$Apache::londefdef::table[-2]{'counter_columns'};$i++) {
       $textwidth=$textwidth-$Apache::londefdef::table[-2]{'TeXlen'}[0][$i];
    }
       }
    }
  my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);   my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
  if (not defined $TeXwidth) {   if (not defined $TeXwidth) {
     my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,$safeeval,undef,1);      my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,$safeeval,undef,1);
     if ($htmlwidth=~/%/) {      if ($htmlwidth=~/%/) {
                   $Apache::londefdef::table[-1]{'percent'}=1;
  $htmlwidth=~/(\d+)/;   $htmlwidth=~/(\d+)/;
  my $value=$1*$textwidth/100;   $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;;
  $Apache::londefdef::table[-1]{'width'}=$value;  
     } else {      } else {
  $Apache::londefdef::table[-1]{'width'}=$textwidth;   $Apache::londefdef::table[-1]{'width'}=$textwidth;
     }      }
  } elsif ($TeXwidth=~/%/) {   } elsif ($TeXwidth=~/%/) {
       $Apache::londefdef::table[-1]{'percent'}=1;
     $TeXwidth=~/(\d+)/;      $TeXwidth=~/(\d+)/;
     my $value=$1*$textwidth/100;              $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;
             $Apache::londefdef::table[-1]{'width'}=$value;  
  } else {   } else {
     $Apache::londefdef::table[-1]{'width'}=$textwidth;      $Apache::londefdef::table[-1]{'forcetablewidth'}=1;
       $Apache::londefdef::table[-1]{'width'}=$TeXwidth;
  }           }        
         #table's border          #table's border
  my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval,undef,1);    my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval); 
           my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);
  unless (defined $border) { $border = 0; }   unless (defined $border) { $border = 0; }
  if ($border) {    if ($border) { 
     $Apache::londefdef::table[-1]{'hinc'} = '\hline ';       $Apache::londefdef::table[-1]{'hinc'} = '\hline '; 
Line 1732  sub start_table { Line 1888  sub start_table {
     $Apache::londefdef::table[-1]{'vinc'} = '&';       $Apache::londefdef::table[-1]{'vinc'} = '&'; 
     $Apache::londefdef::table[-1]{'vvinc'} = '';      $Apache::londefdef::table[-1]{'vvinc'} = '';
  }   }
  $Apache::londefdef::table[-1]{'output'} = ' \noindent \begin{tabular} ';   if ($#Apache::londefdef::table==0) {
  $currentstring = '\keephidden{NEW TABLE ENTRY}';      $Apache::londefdef::table[-1]{'output'}='\strut\newline\strut\setlength{\tabcolsep}{1 mm}';
     }   }
    $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}';
      }
     return $currentstring;      return $currentstring;
 }  }
     
Line 1746  sub end_table { Line 1912  sub end_table {
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $inmemory = '';   my $inmemory = '';
  my $output = '';   my $output = '';
  #construct header of the table   my $WARNING='';
  my $header_of_table = '{'.$Apache::londefdef::table[-1]{'vvinc'};          #width of columns from TeXwidth attributes
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'counter_columns'};$in++) {   for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
     $header_of_table .= $Apache::londefdef::table[-1]{'columns'}[$in].$Apache::londefdef::table[-1]{'vvinc'};      for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
    if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]<$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]) {
       $Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]=$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn];
    }
       }
  }   }
  $header_of_table .= '}';          #free space and number of empty columns
  #define the length of the table cells   my ($available_space,$empty_columns)=($Apache::londefdef::table[-1]{'width'},0);
  #always starts with TeXwidth (if defined everything else is ignored)   if ($#Apache::londefdef::table ne 0) {$available_space=0.9*$available_space;} 
  my @length_row_final = split(/,/,$Apache::londefdef::table[-1]{'TeXlengthrow'}[0]);   for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
  for (my $in=1;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {      if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]==0) {
     my @length_row = split(/,/,$Apache::londefdef::table[-1]{'TeXlengthrow'}[$in]);   $empty_columns++;
     for (my $jn=0;$jn<=$#length_row;$jn++) {      } else {
  if ($length_row_final[$jn]<$length_row[$jn]) {$length_row_final[$jn]=$length_row[$jn];}   $available_space=$available_space-$Apache::londefdef::table[-1]{'TeXlen'}[0][$jn];
     }      }
  }   }
  #continues trying estimate the width of raw data          #boundaries for contents columns
  my @length_raw_row = split(/,/,$Apache::londefdef::table[-1]{'lengthrow'}[0]);   my @min_len=();#columns can not be narrower 
  for (my $in=1;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {   my @max_len=();#maximum length of column
     my @length_row = split(/,/,$Apache::londefdef::table[-1]{'lengthrow'}[$in]);   for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
     for (my $jn=0;$jn<=$#length_row;$jn++) {   my ($localmin,$localmax)=(0,0);
  if ($length_raw_row[$jn]<$length_row[$jn]) {$length_raw_row[$jn]=$length_row[$jn];}   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];
         #comparing of TeXwidth and raw data width      }
  my $available_length=$Apache::londefdef::table[-1]{'width'};      if ($localmax<$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn]) {
  my $needed=0;   $localmax=$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn];
  for (my $jn=0;$jn<=$#length_row_final;$jn++) {      }
     if ($length_row_final[$jn]!=0) {   }
  $available_length=$available_length-$length_row_final[$jn];   push @min_len, $localmin;
  $needed++;   push @max_len, $localmax;
     }   }
  }   for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
  $needed=$#length_row_final-$needed+1;      my $localmin=0,;
  for (my $jn=0;$jn<=$#length_row_final;$jn++) {      for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
     if ($length_row_final[$jn]==0) {   if ($localmin<$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn]) {
  if ($length_raw_row[$jn]<$available_length/3) {      $localmin=$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn];
     $length_row_final[$jn]=$length_raw_row[$jn];   }
     $available_length=$available_length-$length_raw_row[$jn];      }
     $needed--;      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];
       }
  }   }
     }      }
  }   }
  for (my $jn=0;$jn<=$#length_row_final;$jn++) {          #use all available width if it is defined in % or as TeXwidth
     if ($length_row_final[$jn]==0) {          if (($Apache::londefdef::table[-1]{'percent'}==1) || ($Apache::londefdef::table[-1]{'forcetablewidth'}==1)) {
  $length_row_final[$jn]=0.9*$available_length/$needed;      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   #fill the table
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {   for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
     for (my $jn=0;$jn<=$#length_row_final;$jn++) {      for (my $jn=0;$jn<=$#fwidth;$jn++) {
  my $substituted=$length_row_final[$jn];   if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
  $Apache::londefdef::table[-1]{'rowdata'}[$in]=~s/TOBECHANGEDONNUMBER/$substituted mm/;      $output.='\vspace*{-6 mm}\begin{center}';
     }   } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {
     $output .=  $Apache::londefdef::table[-1]{'rowdata'}[$in];      $output.=' \hfill \llap{'
     chop $output;   }
     $output .= ' \\\\ ';   $output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn];
    if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
       $output.='\end{center}\vspace*{-6 mm}';
    } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {
       $output.='} ';
    }
                   if ($jn!=$#fwidth) {$output.=' '.$Apache::londefdef::table[-1]{'vinc'};}
       }
       $output.=' \\\\ '.$Apache::londefdef::table[-1]{'hinc'}.' ';
  }   }
  $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$output.$Apache::londefdef::table[-1]{'hinc'}.'\end{tabular}\vskip 0 mm ';   $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut\newline\strut ';
  if ($#Apache::londefdef::table > 0) {       if ($#Apache::londefdef::table > 0) {    
     my $inmemory = $Apache::londefdef::table[-1]{'output'};      my $inmemory = $Apache::londefdef::table[-1]{'output'};
     pop @Apache::londefdef::table;      pop @Apache::londefdef::table;
Line 1817  sub end_table { Line 2126  sub end_table {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <tr> tag  #-- <tr> tag (end tag optional)
 sub start_tr {  sub start_tr {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 1825  sub start_tr { Line 2134  sub start_tr {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::table[-1]{'row_number'}++;   $Apache::londefdef::table[-1]{'row_number'}++;
  my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);   my $alignchar=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if ($alignchar ne '') {   if ($alignchar ne '') {
     push @ {$Apache::londefdef::table[-1]{'rows'} }, $alignchar;      push @ {$Apache::londefdef::table[-1]{'rows'} },substr($alignchar,0,1);
  } else {   } else {
     push @ {$Apache::londefdef::table[-1]{'rows'} }, 'l';      push @ {$Apache::londefdef::table[-1]{'rows'} }, 'l';
  }   }
  push ( @{ $Apache::londefdef::table[-1]{'rowdata'} }, $Apache::londefdef::table[-1]{'hinc'});   push ( @{ $Apache::londefdef::table[-1]{'rowdata'} }, $Apache::londefdef::table[-1]{'hinc'});
  $Apache::londefdef::table[-1]{'counter_columns'} = -1;   $Apache::londefdef::table[-1]{'counter_columns'} = -1;
  $Apache::londefdef::table[-1]{'TeXlength'} = '';   push @ {$Apache::londefdef::table[-1]{'TeXlen'}}, [];
   $Apache::londefdef::table[-1]{'length'} = '';   push @ {$Apache::londefdef::table[-1]{'objectlen'}}, [];
    push @ {$Apache::londefdef::table[-1]{'minlen'}}, [];
    push @ {$Apache::londefdef::table[-1]{'maxlen'}}, [];
    push @ {$Apache::londefdef::table[-1]{'content'}}, [];
     }       } 
     return $currentstring;      return $currentstring;
 }  }
                   
 sub end_tr {  sub end_tr {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close any pending <p> in the row.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];        $currentstring .= $token->[2];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  push @{ $Apache::londefdef::table[-1]{'TeXlengthrow'} },$Apache::londefdef::table[-1]{'TeXlength'};   if ($Apache::londefdef::TD_redirection) {
  push @{ $Apache::londefdef::table[-1]{'lengthrow'} },$Apache::londefdef::table[-1]{'length'};      &end_td_tex($parstack,$parser,$safeeval);    
    }
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <td> tag  #-- <td> tag (end tag optional)
 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') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $what_to_push = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);   $Apache::londefdef::TD_redirection = 1;
  if ($what_to_push eq '') {   &tag_check('tr','td',$tagstack,$parstack,$parser,$safeeval);
     $what_to_push = substr($Apache::londefdef::table[-1]{'rows'}[0],0,1);;  
  }  
  push @{ $Apache::londefdef::table[-1]{'columns'} }, $what_to_push;  
  $Apache::londefdef::table[-1]{'counter_columns'}++;  
  &Apache::lonxml::startredirection();  
     }       } 
     return $currentstring;      return $currentstring;
 }     }   
            
   sub tag_check {
       my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
       my @ar=@$parstack; 
       for (my $i=$#ar-1;$i>=0;$i--) {
    if (lc($$tagstack[$i]) eq $good_tag) {
       &start_td_tex($parstack,$parser,$safeeval);
       last;
    } elsif (lc($$tagstack[$i]) eq $bad_tag) {
       splice @ar, $i+1;
       &end_td_tex(\@ar,$parser,$safeeval);
       &start_td_tex($parstack,$parser,$safeeval);
       last;
    }
       }
       return '';
   }
    
   sub start_td_tex {
       my ($parstack,$parser,$safeeval) = @_;
       my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
       if ($alignchar eq '') {
    $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
       }
       push @{ $Apache::londefdef::table[-1]{'align'}[$Apache::londefdef::table[-1]{'row_number'}] }, $alignchar;
       $Apache::londefdef::table[-1]{'counter_columns'}++;
       my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
       if (defined $TeXwidth) {
    my $current_length=&recalc($TeXwidth);
    $current_length=~/(\d+\.?\d*)/;
    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
       }
       &Apache::lonxml::startredirection();
       return '';
   }
   
   sub end_td_tex {
       my ($parstack,$parser,$safeeval) = @_;
       my $current_row = $Apache::londefdef::table[-1]{'row_number'};
       my $data=&Apache::lonxml::endredirection();
       my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
       if (defined $TeXwidth) {
    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       } else {
    if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {
       my $garbage_data=$data;
       my $fwidth=0;
               while ($garbage_data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
    my $current_length=&recalc($1);
    $current_length=~/(\d+\.?\d*)/;
    if ($fwidth<$1) {$fwidth=$1;}
    $garbage_data=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
       }
               while ($garbage_data=~m/\[(\d+\.?\d*)\s*mm\]/) {
    my $current_length=$1;
    if ($fwidth<$current_length) {$fwidth=$current_length;}
    $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;
       }
       push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
       push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    } elsif ($data=~/\\parbox\{\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*\s*\}/ or $data=~/\\epsfxsize\s*=\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*/) {
       my $garbage_data=$data;
       my $fwidth=0;
               while ($garbage_data=~/\\parbox\{\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)\s*\}/) {
    my $current_length=&recalc($1);
    $current_length=~/(\d+\.?\d*)/;
    if ($fwidth<$1) {$fwidth=$1;}
    $garbage_data=~s/\\parbox\{\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
       }
               while ($garbage_data=~/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
    my $current_length=&recalc($1);
    $current_length=~/(\d+\.?\d*)/;
    if ($fwidth<$1) {$fwidth=$1;}
    $garbage_data=~s/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
       }
       push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
       push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       $data=~s/\\\\\s*$//; 
    } else {  
       $data=~s/^\s+(\S.*)/$1/; 
       $data=~s/(.*\S)\s+$/$1/;
       $data=~s/(\s)+/$1/;
       my ($current_length,$min_length)=(0,0);
       if ($data=~/\\vskip/) {
                   my $newdata=$data;
    $newdata=~s/\\vskip \d*\.?\d*\s*mm/THISISJUSTTEMPORARYSEPARATOR/g;
    my @newdata=split(/THISISJUSTTEMPORARYSEPARATOR/,$newdata);
    foreach my $elementdata (@newdata) {
       my $lengthnewdata=2.5*&LATEX_length($elementdata);
       if ($lengthnewdata>$current_length) {$current_length=$lengthnewdata;}
                       my @words=split(/ /,$elementdata);
       foreach my $word (@words) {
    my $lengthword=2.5*&LATEX_length($word);
    if ($min_length<$lengthword) {$min_length=$lengthword;}
       }
    }
       } else {
    $current_length=2.5*&LATEX_length($data);
                       my @words=split(/ /,$data);
       foreach my $word (@words) {
    my $lengthword=2*&LATEX_length($word);
    if ($min_length<$lengthword) {$min_length=$lengthword;}
       }
       }
       push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
       push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
    }        
       }
    for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {         
       $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
    }
       push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
       return'';
   }
   
 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') {
  $currentstring = $token->[2];        $currentstring = $token->[2];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $current_row = $Apache::londefdef::table[-1]{'row_number'};          $Apache::londefdef::TD_redirection =0;
  my $data=&Apache::lonxml::endredirection();   &end_td_tex($parstack,$parser,$safeeval);
  my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);  
  if (defined $TeXwidth) {  
     my $current_length=&recalc($TeXwidth);  
     $current_length=~/(\d+)/;  
     $Apache::londefdef::table[-1]{'TeXlength'} .= $1.',';  
     $Apache::londefdef::table[-1]{'length'} .= '0,';  
  } else {  
     if ($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {  
  my $current_length=&recalc($1);  
  $current_length=~/(\d+\.?\d*)/;  
  $Apache::londefdef::table[-1]{'TeXlength'} .= $1.',';  
  $Apache::londefdef::table[-1]{'length'} .= '0,';  
     } else {    
  $data=~s/^\s+(\S.*)/$1/;  
  $data=~s/(.*\S)\s+$/$1/;  
  my $current_length=2*length($data);  
  $Apache::londefdef::table[-1]{'length'} .= $current_length.',';  
  $Apache::londefdef::table[-1]{'TeXlength'} .= '0,';  
     }          
  }  
  for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {           
     $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;  
  }  
  @{ $Apache::londefdef::table[-1]{'rowdata'} }[$current_row] .= '\parbox{TOBECHANGEDONNUMBER}{'.$data.'} '.$Apache::londefdef::table[-1]{'vinc'};  
     }      }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <th> tag  #-- <th> tag (end tag optional)
 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') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $what_to_push = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);   $Apache::londefdef::TD_redirection = 1;
  if ($what_to_push eq '') {   &tagg_check('tr','th',$tagstack,$parstack,$parser,$safeeval);
     $what_to_push = substr($Apache::londefdef::table[-1]{'rows'}[0],0,1);;  
  }  
  push @{ $Apache::londefdef::table[-1]{'columns'} }, $what_to_push;  
  $Apache::londefdef::table[-1]{'counter_columns'}++;  
  &Apache::lonxml::startredirection();  
     }       } 
     return $currentstring;      return $currentstring;
 }     }   
            
   sub tagg_check {
       my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
       my @ar=@$parstack; 
       for (my $i=$#ar-1;$i>=0;$i--) {
    if (lc($$tagstack[$i]) eq $good_tag) {
       &start_th_tex($parstack,$parser,$safeeval);
       last;
    } elsif (lc($$tagstack[$i]) eq $bad_tag) {
       splice @ar, $i+1;
       &end_th_tex(\@ar,$parser,$safeeval);
       &start_th_tex($parstack,$parser,$safeeval);
       last;
    }
       }
       return '';
   }
    
   sub start_th_tex {
       my ($parstack,$parser,$safeeval) = @_;
       my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
       if ($alignchar eq '') {
    $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
       }
       push @{ $Apache::londefdef::table[-1]{'align'}[$Apache::londefdef::table[-1]{'row_number'}] }, $alignchar;
       $Apache::londefdef::table[-1]{'counter_columns'}++;
       my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
       if (defined $TeXwidth) {
    my $current_length=&recalc($TeXwidth);
    $current_length=~/(\d+\.?\d*)/;
    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
       }
       &Apache::lonxml::startredirection();
       return '';
   }
   
   sub end_th_tex {
       my ($parstack,$parser,$safeeval) = @_;
       my $current_row = $Apache::londefdef::table[-1]{'row_number'};
       my $data=&Apache::lonxml::endredirection();
       my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
       if (defined $TeXwidth) {
    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       } else {
    if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {
       my $garbage_data=$data;
       my $fwidth=0;
               while ($garbage_data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
    my $current_length=&recalc($1);
    $current_length=~/(\d+\.?\d*)/;
    if ($fwidth<$1) {$fwidth=$1;}
    $garbage_data=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
       }
               while ($garbage_data=~m/\[(\d+\.?\d*)\s*mm\]/) {
    my $current_length=$1;
    if ($fwidth<$current_length) {$fwidth=$current_length;}
    $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;
       }
       push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
       push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    } else {  
       $data=~s/^\s+(\S.*)/$1/; 
       $data=~s/(.*\S)\s+$/$1/;
       $data=~s/(\s)+/$1/;
       my ($current_length,$min_length)=(0,0);
       if ($data=~/\\vskip/) {
                   my $newdata=$data;
    $newdata=~s/\\vskip \d*\.?\d*\s*mm/THISISJUSTTEMPORARYSEPARATOR/g;
    my @newdata=split(/THISISJUSTTEMPORARYSEPARATOR/,$newdata);
    foreach my $elementdata (@newdata) {
       my $lengthnewdata=2.5*&LATEX_length($elementdata);
       if ($lengthnewdata>$current_length) {$current_length=$lengthnewdata;}
                       my @words=split(/ /,$elementdata);
       foreach my $word (@words) {
    my $lengthword=2.5*&LATEX_length($word);
    if ($min_length<$lengthword) {$min_length=$lengthword;}
       }
    }
       } else {
    $current_length=2.5*&LATEX_length($data);
                       my @words=split(/ /,$data);
       foreach my $word (@words) {
    my $lengthword=2*&LATEX_length($word);
    if ($min_length<$lengthword) {$min_length=$lengthword;}
       }
       }
       push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
       push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
    }        
       }
    for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {         
       $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
    }
       #make data bold
       $data='\textbf{'.$data.'}';
       push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
       return'';
   }
   
 sub end_th {  sub end_th {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close any open <p> in the row.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];        $currentstring .= $token->[2];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $current_row = $Apache::londefdef::table[-1]{'row_number'};          $Apache::londefdef::TD_redirection =0;
  my $data=&Apache::lonxml::endredirection();   &end_th_tex($parstack,$parser,$safeeval);
  my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);  
  if (defined $TeXwidth) {  
     my $current_length=&recalc($TeXwidth);  
     $current_length=~/(\d+)/;  
     $Apache::londefdef::table[-1]{'TeXlength'} .= $1.',';  
     $Apache::londefdef::table[-1]{'length'} .= '0,';  
  } else {  
     if ($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {  
  my $current_length=&recalc($1);  
  $current_length=~/(\d+)/;  
  $Apache::londefdef::table[-1]{'TeXlength'} .= $1.',';  
  $Apache::londefdef::table[-1]{'length'} .= '0,';  
     } else {       
  $data=~/^\s*(\S.*)/;  
  $data=$1;  
  $data=~/(.*\S)\s*$/;  
  $data=$1;  
  my $current_length=2*length($data);  
  $Apache::londefdef::table[-1]{'length'} .= $current_length.',';  
  $Apache::londefdef::table[-1]{'TeXlength'} .= '0,';  
     }          
  }  
  for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {                                  
     $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;  
  }  
  $data='\textbf{'.$data.'}';  
  @{ $Apache::londefdef::table[-1]{'rowdata'} }[$current_row] .= '\parbox{TOBECHANGEDONNUMBER}{'.$data.'} '.$Apache::londefdef::table[-1]{'vinc'};  
     }      }
     return $currentstring;      return $currentstring;
 }  }
 #-- <img> tag       
   #-- <img> tag (end tag forbidden)
   #
   #  Render the <IMG> tag.
   #     <IMG> has the following attributes (in addition to the 
   #     standard HTML ones:
   #      TeXwrap   - Governs how the tex target will try to wrap text around
   #                  horizontally aligned images.
   #      TeXwidth  - The width 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)
   #      
 sub start_img {  sub start_img {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     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')) { 
    my $inside = &Apache::lonxml::get_all_text("/img",$parser);
    return '';
       }
     $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$src;      $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$src;
     my $currentstring = '';      my $currentstring = '';
     my $width_param = '';  
     my $height_param = '';  
     my $scaling = .3;      my $scaling = .3;
   
      # Render unto browsers that which are the browser's...
   
     if ($target eq 'web') {      if ($target eq 'web') {
  if ($ENV{'browser.imagesuppress'} ne 'on') {   if ($env{'browser.imagesuppress'} ne 'on') {
     $currentstring.= $token->[4];      $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});
  } else {   } else {
     my $alttag= &Apache::lonxml::get_param      my $alttag= &Apache::lonxml::get_param
  ('alt',$parstack,$safeeval,undef,1);   ('alt',$parstack,$safeeval,undef,1);
Line 1983  sub start_img { Line 2477  sub start_img {
     }      }
     $currentstring.='[IMAGE: '.$alttag.']';      $currentstring.='[IMAGE: '.$alttag.']';
  }   }
   
    # and render unto TeX that which is LaTeX
   
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);   #
  &image_replication($src);   #  The alignment will require some superstructure to be put around
    #  the \includegraphics stuff.  At present we can only partially
    #  simulate the alignments offered by html.
    #
    #
    my $align = lc(&Apache::lonxml::get_param('align', 
     $parstack,
     $safeeval,
     undef,1));
    if(!$align) {
       $align = "bottom"; # This is html's default so it's ours too.
    }
    #
    &Apache::lonxml::debug("Alignemnt = $align");
    #  LaTeX's image/text wrapping is really bad since it wants to
    #  make figures float.  
           #   The user has the optional parameter (applicable only to l/r
    # alignment to use the picins/parpic directive to get wrapped text
    # this is also imperfect.. that's why we give them a choice...
    # so they can't yell at us for our choice.
    #
    my $latex_rendering = &Apache::lonxml::get_param('TeXwrap',
       $parstack,
       $safeeval,
       undef,0);
    &Apache::lonxml::debug("LaTeX rendering = $latex_rendering");
    if(!$latex_rendering) {
       $latex_rendering = "parbox";
    }
    &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src");
   
  #if original gif/jpg/png file exist do following:   #if original gif/jpg/png file exist do following:
  if (-e $src) {             my $origsrc=$src;
     #defines the default size of image   my ($path,$file) = &get_eps_image($src);
     my $image = Image::Magick->new;   $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
     my $current_figure = $image->Read($src);   &Apache::lonxml::debug("path = $path file = $file src = $src");
     $width_param = $image->Get('width') * $scaling;;   if (-e $src) {
     $height_param = $image->Get('height') * $scaling;;      &Apache::lonxml::debug("$src exists");
     undef $image;      my ($height_param,$width_param)=
     #do we have any specified size of the picture?   &image_size($origsrc,0.3,$parstack,$safeeval);
     my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval);      my $destpath = $path;
     my $TeXheight = &Apache::lonxml::get_param('TeXheight',$parstack,$safeeval);      $destpath    =~ s/ /\_/g; # Spaces in path cause LaTex to vomit.
     my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval,      my $destfile = $file;
    undef,1);      $destfile    =~ s/ /\_/g;
     if ($TeXwidth ne '') {        my $size;
  if ($TeXwidth=~/(\d+)\s*\%/) {      if ($width_param)  { $size.='width='.$width_param.' mm,'; }
     $width_param = $1*$ENV{'form.textwidth'}/100;      if ($height_param) { $size.='height='.$height_param.' mm]'; }
  } else {       $size='['.$size;
     $width_param = $TeXwidth;      $size=~s/,$/]/; 
       $currentstring .= '\graphicspath{{'.$destpath.'}}'
    .'\includegraphics'.$size.'{'.$destfile.'} ';
   
       #    If there's an alignment specification we need to honor it here.
       #    For the horizontal alignments, we will also honor the
       #    value of the latex specfication.  The default is parbox,
       #    and that's used for illegal values too.  
       #    
       #    Even though we set a default alignment value, the user
       #    could have given us an illegal value.  In that case we
       #    just use the default alignment of bottom..
       if      ($align eq "top")    {
    $currentstring = '\raisebox{-'.$height_param.'mm}{'.$currentstring.'}';
       } elsif (($align eq "center") || ($align eq "middle")) { # Being kind
    my $offset = $height_param/2;
    $currentstring = '\raisebox{-'.$offset.'mm}{'.$currentstring.'}';
       } elsif ($align eq "left")   { 
    if ($latex_rendering eq "parpic") { 
       $currentstring = '\parpic[l]{'.$currentstring.'}';
    } else {                                     # parbox rendering
       $currentstring = "\\strut\\newline\n".
    '\parbox{'.$width_param.'mm}{'.$currentstring.'}';
  }   }
     } elsif ($TeXheight ne '') {      } elsif ($align eq "right")  {   
  $width_param = $TeXheight/$height_param*$width_param;   if ($latex_rendering eq "parpic") {
     } elsif ($width ne '') {      $currentstring = '\parpic[r]{'.$currentstring.'}';
  $width_param = $width*$scaling;         } else {                                 # parbox rendering. 
     }      $currentstring = '\parbox{'.$width_param.'mm}{\begin{flushright}'
     if ($width_param > $ENV{'form.textwidth'}) {$width_param =0.95*$ENV{'form.textwidth'}}               .$currentstring.'\end{flushright}} \newline'."\n";
     my $file;  
     my $path;  
     if ($src =~ m!(.*)/([^/]*)$!) {  
  $file = $2;   
  $path = $1.'/';   
     }   
     my $newsrc = $src;  
     $newsrc =~ s/\.(gif|jpg|png)$/.eps/i;  
     $file=~s/\.(gif|jpg|png)$/.eps/i;  
     #where can we find the picture?  
     if (-e $newsrc) {  
  #eps counterpart for image exist   
  if ($path) {  
     $currentstring .= '\vskip 1 mm \noindent\graphicspath{{'.$path.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';  
  }  
     } else {  
  #there is no eps counterpart for image - check for ps one  
  $newsrc =~ s/\.eps$/\.ps/;  
  if (-e $newsrc) {  
     #ps counterpart for image exist   
     $file =~ s/\.eps$/\.ps/;  
     if ($path) {  
  $currentstring .= '\vskip 1 mm \noindent\graphicspath{{'.$path.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';  
     }  
  } else {  
     #there aren't eps or ps - so create eps   
     my $temp_file;  
     my $filename = "/home/httpd/prtspool/$ENV{'user.name'}_$ENV{'user.domain'}_printout.dat";  
     $temp_file = Apache::File->new('>>'.$filename);   
     print $temp_file "$src\n";  
     $currentstring .= '\vskip 1 mm \graphicspath{{/home/httpd/prtspool/}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';  
  }   }
       } else { # Bottom is also default.
    # $currentstring = '\raisebox{'.$height_param.'mm}{'.$currentstring.'}';
     }      }
  } else {   } else {
       &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);
Line 2052  sub start_img { Line 2573  sub start_img {
  $alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);   $alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);
     }      }
   
     if ($alt) {      if ($alt) { $currentstring .= ' '.$alt.' '; }
  $currentstring .= ' '.$alt.' ';   }
     } else {  
  #<allow> tag will care about replication    # And here's where the semi-quote breaks down: allow the user
           # to edit the beast as well by rendering the problem for edit:
       } elsif ($target eq 'edit') {
    $currentstring .=&Apache::edit::tag_start($target,$token);
    $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).
       &Apache::edit::browse('src',undef,'alt').' '.
       &Apache::edit::search('src',undef,'alt').'<br />';
    $currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />';
    $currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5);
    $currentstring .=&Apache::edit::text_arg('height (pixel):','height',$token,5).'<br />';
    $currentstring .=&Apache::edit::text_arg('TeXwidth (mm):','TeXwidth',$token,5);
    $currentstring .=&Apache::edit::text_arg('TeXheight (mm):','TeXheight',$token,5);
    $currentstring .=&Apache::edit::select_arg('Alignment:','align',
      ['','bottom','middle','top','left','right'],$token,5);
    $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',
      ['', 'parbox', 'parpic'], $token, 2);
    $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
    my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);
    my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);
    my $width=  &Apache::lonxml::get_param('width',$parstack,$safeeval);
    my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);
   
   
    $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';
    if ($width) { $currentstring.=' width="'.$width.'" '; }
    if ($height) { $currentstring.=' height="'.$height.'" '; }
    $currentstring .= ' />';
       } elsif ($target eq 'modified') {
    my ($osrc,$owidth,$oheight)=
       ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
    my $ctag=&Apache::edit::get_new_args($token,$parstack,
        $safeeval,'src','alt','align',
        'TeXwidth','TeXheight', 'TeXwrap',
        'width','height');
    my ($nsrc,$nwidth,$nheight)=
       ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
    my $loc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$nsrc);
    &image_replication($loc);
    my ($iwidth,$iheight);
    if (-e $loc) {
       my $image = Image::Magick->new;
       $image->Read($loc);
       ($iwidth, $iheight) = ($image->Get('width'),
      $image->Get('height'));
    }
    if ($osrc ne $nsrc || (!$nwidth && !$nheight)) {
       # changed image or no size specified,
               # if they didn't explicitly change the 
               # width or height use the ones from the image
       if ($iwidth && $iheight) {
    if ($owidth == $nwidth || (!$nwidth && !$nheight)) {
       $token->[2]{'width'} = $iwidth;$ctag=1;
    }
    if ($oheight == $nheight || (!$nwidth && !$nheight)) {
       $token->[2]{'height'}=$iheight;$ctag=1;
    }
     }      }
  }   }
    my ($cwidth,$cheight)=($token->[2]{'width'},$token->[2]{'height'});
    # if we don't have a width or height
    if ($iwidth && $cwidth && !$cheight) {
       $token->[2]{'height'}=int(($cwidth/$iwidth)*$iheight);$ctag=1;
    }
    if ($iheight && $cheight && !$cwidth) {
       $token->[2]{'width'}=int(($cheight/$iheight)*$iwidth);$ctag=1;
    }
    if ($ctag) {$currentstring=&Apache::edit::rebuild_tag($token);}
     }      }
   
     return $currentstring;      return $currentstring;
 }  }
   
Line 2073  sub end_img { Line 2659  sub end_img {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <applet> tag  #-- <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) = @_;
           
Line 2086  sub start_applet { Line 2672  sub start_applet {
           
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  if ($ENV{'browser.appletsuppress'} ne 'on') {   if ($env{'browser.appletsuppress'} ne 'on') {
     $currentstring = $token->[4];      $currentstring = &Apache::lonenc::encrypt_ref($token,
     {'code'=>$code,
      'archive'=>$archive}
     );
  } else {   } else {
     my $alttag= &Apache::lonxml::get_param('alt',$parstack,      my $alttag= &Apache::lonxml::get_param('alt',$parstack,
    $safeeval,undef,1);     $safeeval,undef,1);
Line 2098  sub start_applet { Line 2687  sub start_applet {
     $currentstring='[APPLET: '.$alttag.']';      $currentstring='[APPLET: '.$alttag.']';
  }   }
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\begin{figure} ";   my $alttag= &Apache::lonxml::get_param('alt',$parstack,
          $safeeval,undef,1);
    unless ($alttag) {
       my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,
    undef,1);
       $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],
        $code);
    }
    $currentstring.='\begin{center} \fbox{Java Applet: '.$alttag.
       '.}\end{center}';
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 2109  sub end_applet { Line 2707  sub end_applet {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];   $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\end{figure}";  
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <embed> tag  #-- <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::extlinks[$#Apache::lonxml::extlinks+1]=$src;      $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$src;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  if ($ENV{'browser.embedsuppress'} ne 'on') {   if ($env{'browser.embedsuppress'} ne 'on') {
     $currentstring = $token->[4];      $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});
  } else {   } else {
     my $alttag=&Apache::lonxml::get_param      my $alttag=&Apache::lonxml::get_param
  ('alt',$parstack,$safeeval,undef,1);   ('alt',$parstack,$safeeval,undef,1);
Line 2132  sub start_embed { Line 2729  sub start_embed {
     $currentstring='[EMBED: '.$alttag.']';      $currentstring='[EMBED: '.$alttag.']';
  }   }
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\begin{figure} ";    
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 2142  sub end_embed { Line 2738  sub end_embed {
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];        $currentstring = $token->[2];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {  
  $currentstring = " \\end{figure}";    
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <param> tag  #-- <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      if (&Apache::lonxml::get_param
Line 2160  sub start_param { Line 2755  sub start_param {
  &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);   &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        my %toconvert;
    my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
    if ($src) { $toconvert{'src'}= $src; }
    my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval,
       undef,1);
    if ($name=~/^cabbase$/i) {
       $toconvert{'value'}=&Apache::lonxml::get_param('value',$parstack,
      $safeeval,undef,1);
    }
    $currentstring = &Apache::lonenc::encrypt_ref($token,\%toconvert);
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\begin{figure} ";    
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 2173  sub end_param { Line 2776  sub end_param {
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];        $currentstring = $token->[2];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\end{figure}";    
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 2185  sub start_allow { Line 2787  sub start_allow {
     $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);      $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
     $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=      $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=
  &Apache::lonnet::clutter($src);   &Apache::lonnet::clutter($src);
     &image_replication($src);      if ($target eq 'tex') { &image_replication($src); }
     my $result;      my $result;
     if ($target eq 'edit') {      if ($target eq 'edit') {
  $result .=&Apache::edit::tag_start($target,$token);   $result .=&Apache::edit::tag_start($target,$token);
Line 2205  sub end_allow { Line 2807  sub end_allow {
     return '';      return '';
 }  }
   
 #-- Frames  #-- Frames (end tag required)
   #-- <frameset>
 sub start_frameset {  sub start_frameset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = ''; # Close any pending para.
     if ($target eq 'web') {       if ($target eq 'web') { 
  if (!$Apache::lonxml::registered) {   if (!$Apache::lonxml::registered &&
       $env{'request.state'} eq 'published') {
     $currentstring.='<head>'.      $currentstring.='<head>'.
  &Apache::lonmenu::registerurl(undef,$target).'</head>';   &Apache::lonmenu::registerurl(undef,$target).'</head>';
  }   }
Line 2250  sub end_frameset { Line 2854  sub end_frameset {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <pre>  #-- <xmp> (end tag required)
 sub start_pre {  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') {
Line 2262  sub start_pre { Line 2866  sub start_pre {
     return $currentstring;      return $currentstring;
 }  }
   
   sub end_xmp {
       my ($target,$token) = @_;
       my $currentstring = '';
       if ($target eq 'web') {
    $currentstring .= $token->[2];
       } elsif ($target eq 'tex') {
    $currentstring .= '\end{verbatim}';
       }
       return $currentstring;
   }
   
   #-- <pre> (end tag required)
   sub start_pre {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
       my $currentstring = &end_p; # close off pending <p>
       if ($target eq 'web') {
    $currentstring .= $token->[4];
       } elsif ($target eq 'tex') {
    $currentstring .= '\begin{verbatim}';
       } 
       return $currentstring;
   }
   
 sub end_pre {  sub end_pre {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2316  sub end_externallink { Line 2943  sub end_externallink {
 #-- <blankspace heigth="">  #-- <blankspace heigth="">
 sub start_blankspace {  sub start_blankspace {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      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('heigth',$parstack,$safeeval,undef,1);
  $currentstring .= '\vskip '.$howmuch.' ';   $currentstring .= '\vskip '.$howmuch.' ';
Line 2333  sub end_blankspace { Line 2960  sub end_blankspace {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <abbr> tag  #-- <abbr> tag (end tag required)
 sub start_abbr {  sub start_abbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2352  sub end_abbr { Line 2979  sub end_abbr {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <acronym> tag  #-- <acronym> tag (end tag required)
 sub start_acronym {  sub start_acronym {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2371  sub end_acronym { Line 2998  sub end_acronym {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <area> tag  #-- <area> tag (end tag forbidden)
 sub start_area {  sub start_area {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2390  sub end_area { Line 3017  sub end_area {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <base> tag  #-- <base> tag (end tag forbidden)
 sub start_base {  sub start_base {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 2409  sub end_base { Line 3036  sub end_base {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <bdo> tag  #-- <bdo> tag (end tag required)
 sub start_bdo {  sub start_bdo {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2428  sub end_bdo { Line 3055  sub end_bdo {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <bgsound> tag  #-- <bgsound> tag (end tag optional)
 sub start_bgsound {  sub start_bgsound {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2447  sub end_bgsound { Line 3074  sub end_bgsound {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <blink> tag  #-- <blink> tag (end tag required)
 sub start_blink {  sub start_blink {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2466  sub end_blink { Line 3093  sub end_blink {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <blockquote> tag  #-- <blockquote> tag (end tag required)
 sub start_blockquote {  sub start_blockquote {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close any unclosed <p>
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring .= $token->[4];     
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 2485  sub end_blockquote { Line 3112  sub end_blockquote {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <button> tag  #-- <button> tag (end tag required)
 sub start_button {  sub start_button {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2504  sub end_button { Line 3131  sub end_button {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <caption> tag  #-- <caption> tag (end tag required)
 sub start_caption {  sub start_caption {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2523  sub end_caption { Line 3150  sub end_caption {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <col> tag  #-- <col> tag (end tag forbdden)
 sub start_col {  sub start_col {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2542  sub end_col { Line 3169  sub end_col {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <colgroup> tag  #-- <colgroup> tag (end tag optional)
 sub start_colgroup {  sub start_colgroup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2561  sub end_colgroup { Line 3188  sub end_colgroup {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <del> tag  #-- <del> tag (end tag required)
 sub start_del {  sub start_del {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2580  sub end_del { Line 3207  sub end_del {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <fieldset> tag  #-- <fieldset> tag (end tag required)
 sub start_fieldset {  sub start_fieldset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2599  sub end_fieldset { Line 3226  sub end_fieldset {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <frame> tag  #-- <frame> tag (end tag forbidden)
 sub start_frame {  sub start_frame {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2618  sub end_frame { Line 3245  sub end_frame {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <iframe> tag  #-- <iframe> tag (end tag required)
 sub start_iframe {  sub start_iframe {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2637  sub end_iframe { Line 3264  sub end_iframe {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <ins> tag  #-- <ins> tag (end tag required)
 sub start_ins {  sub start_ins {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2656  sub end_ins { Line 3283  sub end_ins {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <isindex> tag  #-- <isindex> tag (end tag forbidden)
 sub start_isindex {  sub start_isindex {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2675  sub end_isindex { Line 3302  sub end_isindex {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <keygen> tag  #-- <keygen> tag (end tag forbidden)
 sub start_keygen {  sub start_keygen {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2713  sub end_label { Line 3340  sub end_label {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <layer> tag  #-- <layer> tag (end tag required)
 sub start_layer {  sub start_layer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2732  sub end_layer { Line 3359  sub end_layer {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <legend> tag  #-- <legend> tag (end tag required)
 sub start_legend {  sub start_legend {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2751  sub end_legend { Line 3378  sub end_legend {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <link> tag  #-- <link> tag (end tag forbidden)
 sub start_link {  sub start_link {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2770  sub end_link { Line 3397  sub end_link {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <marquee> tag  #-- <marquee> tag (end tag optional)
 sub start_marquee {  sub start_marquee {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2789  sub end_marquee { Line 3416  sub end_marquee {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <malticol> tag  #-- <multicol> tag (end tag required)
 sub start_malticol {  sub start_multicol {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close any pending <p>
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring .= $token->[4];     
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 sub end_malticol {  sub end_multicol {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
Line 2808  sub end_malticol { Line 3435  sub end_malticol {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <nobr> tag  #-- <nobr> tag (end tag required)
 sub start_nobr {  sub start_nobr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     }       }  elsif ($target eq 'tex') {
    $currentstring='\mbox{';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 2823  sub end_nobr { Line 3452  sub end_nobr {
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];       $currentstring = $token->[2];    
     }       }   elsif ($target eq 'tex') {
    $currentstring='}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <noembed> tag  #-- <noembed> tag (end tag required)
 sub start_noembed {  sub start_noembed {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2846  sub end_noembed { Line 3477  sub end_noembed {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <noframes> tag  #-- <noframes> tag (end tag required)
 sub start_noframes {  sub start_noframes {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2865  sub end_noframes { Line 3496  sub end_noframes {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <nolayer> tag  #-- <nolayer> tag (end tag required)
 sub start_nolayer {  sub start_nolayer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2884  sub end_nolayer { Line 3515  sub end_nolayer {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <noscript> tag  #-- <noscript> tag (end tag required)
 sub start_noscript {  sub start_noscript {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2903  sub end_noscript { Line 3534  sub end_noscript {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <object> tag  #-- <object> tag (end tag required)
 sub start_object {  sub start_object {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2922  sub end_object { Line 3553  sub end_object {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <optgroup> tag  #-- <optgroup> tag (end tag required)
 sub start_optgroup {  sub start_optgroup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 2941  sub end_optgroup { Line 3572  sub end_optgroup {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <samp> tag  #-- <samp> tag (end tag required)
 sub start_samp {  sub start_samp {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     }       } elsif ($target eq 'tex') {
    $currentstring='\texttt{';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 2956  sub end_samp { Line 3589  sub end_samp {
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];       $currentstring = $token->[2];    
     }       } elsif ($target eq 'tex') {
    $currentstring='}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 2979  sub end_server { Line 3614  sub end_server {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <spacer> tag  #-- <spacer> tag (end tag forbidden)
 sub start_spacer {  sub start_spacer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = &end_p; # Close off any open <p> tag.
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring .= $token->[4];     
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 2998  sub end_spacer { Line 3633  sub end_spacer {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <span> tag  #-- <span> tag (end tag required)
 sub start_span {  sub start_span {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 3017  sub end_span { Line 3652  sub end_span {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <tbody> tag  #-- <tbody> tag (end tag optional)
 sub start_tbody {  sub start_tbody {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 3036  sub end_tbody { Line 3671  sub end_tbody {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <tfoot> tag  #-- <tfoot> tag (end tag optional)
 sub start_tfoot {  sub start_tfoot {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 3055  sub end_tfoot { Line 3690  sub end_tfoot {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <thead> tag  #-- <thead> tag (end tag optional)
 sub start_thead {  sub start_thead {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 3080  sub start_var { Line 3715  sub start_var {
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     }       } elsif ($target eq 'tex') {
    $currentstring = '\textit{'; 
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3088  sub end_var { Line 3725  sub end_var {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web') {      if ($target eq 'web') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
       } elsif ($target eq 'tex') {
    $currentstring = '}'; 
     }       } 
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <wbr> tag  #-- <wbr> tag (end tag forbidden)
 sub start_wbr {  sub start_wbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
Line 3112  sub end_wbr { Line 3751  sub end_wbr {
     return $currentstring;      return $currentstring;
 }  }
   
   
 #-- <hideweboutput> tag  #-- <hideweboutput> tag
 sub start_hideweboutput {  sub start_hideweboutput {
     my ($target,$token) = @_;      my ($target,$token) = @_;
Line 3134  sub end_hideweboutput { Line 3772  sub end_hideweboutput {
   
 sub image_replication {  sub image_replication {
     my $src = shift;      my $src = shift;
     if (not -e $src) {      if (not -e $src) { &Apache::lonnet::repcopy($src); }
  #replicates image itself      #replicates eps or ps 
  &Apache::lonnet::repcopy($src);      my $epssrc = my $pssrc = $src;
  #replicates eps or ps       $epssrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i;
  my $newsrc = $src;      $pssrc  =~ s/\.(gif|jpg|jpeg|png)$/.ps/i;
  $newsrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i;      if (not -e $epssrc && not -e $pssrc) {
  if (not -e $newsrc) {   my $result=&Apache::lonnet::repcopy($epssrc);
     if (&Apache::lonnet::repcopy($newsrc) ne 'OK') {   if ($result ne 'ok') { &Apache::lonnet::repcopy($pssrc); }
  $newsrc =~ s/\.eps$/\.ps/;      }
  &Apache::lonnet::repcopy($newsrc);      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 {
       my ($height_param, $width_param, $scaling,
    $parstack, $safeeval, $depth, $cis) = @_;
   
       # First apply the scaling...
   
       $height_param = $height_param * $scaling;
       $width_param  = $width_param  * $scaling;
   
       #do we have any specified LaTeX size of the picture?
       my $toget='TeXwidth'; 
       if ($cis) { 
    $toget=lc($toget); 
       }
       my $TeXwidth = &Apache::lonxml::get_param($toget,$parstack,
         $safeeval,$depth,$cis);
       $toget='TeXheight'; if ($cis) { $toget=lc($toget); }
       my $TeXheight = &Apache::lonxml::get_param($toget,$parstack,
          $safeeval,$depth,$cis);
       #do we have any specified web size of the picture?
       my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval,
      $depth,1);
       if ($TeXwidth) { 
    my $old_width_param=$width_param;
    if ($TeXwidth=~/(\d+)\s*\%/) {
       $width_param = $1*$env{'form.textwidth'}/100;
    } else { 
       $width_param = $TeXwidth;
    }
    if ($TeXheight) {
       $height_param = $TeXheight;
    } elsif ($old_width_param) {
       $height_param=$TeXwidth/$old_width_param*$height_param;
    }
       } elsif ($TeXheight) {
    $height_param = $TeXheight;
    if ($height_param) {
       $width_param  = $TeXheight/$height_param*$width_param;
    }
       } elsif ($width) {
    my $old_width_param=$width_param;
    $width_param = $width*$scaling;
    if ($old_width_param) {
       $height_param=$width_param/$old_width_param*$height_param;
    }
       }
       if ($width_param > $env{'form.textwidth'}) {
           my $old_width_param=$width_param;
    $width_param =0.95*$env{'form.textwidth'};
    if ($old_width_param) {
       $height_param=$width_param/$old_width_param*$height_param;
    }
       }
   
       return ($height_param, $width_param);
   }
   
   sub image_size {
       my ($src,$scaling,$parstack,$safeeval,$depth,$cis)=@_;
   
       #size of image from gif/jpg/jpeg/png 
       my $ressrc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
       if (-e $ressrc) {
    $src = $ressrc;
       }
       my $image = Image::Magick->new;
       my $current_figure = $image->Read($src);
       my $width_param = $image->Get('width');
       my $height_param = $image->Get('height');
       &Apache::lonxml::debug("Image magick says: $src :  Height = $height_param width = $width_param");
       undef($image);
   
       ($height_param, $width_param) = &resize_image($height_param, $width_param,
     $scaling, $parstack, $safeeval, 
     $depth, $cis);
   
       return ($height_param, $width_param);
   }
   
   sub image_width {
       my ($height, $width) = &image_size(@_);
       return $width;
   }
   #  Not yet 100% sure this is correct in all circumstances..
   #  due to my uncertainty about mods to image_size.
   #
   sub image_height {
       my ($height, $width) = &image_size(@_);
       return $height;
   }
   
   sub get_eps_image {
       my ($src)=@_;
       my $orig_src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1], $src);
       &Apache::lonxml::debug("get_eps_image: Original image: $orig_src");
       $src=~s/\.(gif|png|jpg|jpeg)$/\.eps/i;
       $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
       &Apache::lonxml::debug("Filelocation gives: $src");
       if (! -e $src) {
    &Apache::lonxml::debug("$src does not exist");
    if (&Apache::lonnet::repcopy($src) ne 'ok' ) {
       &Apache::lonxml::debug("Repcopy of $src failed (1)");
       #if replication failed try to find ps file
       $src=~s/\.eps$/\.ps/;
       &Apache::lonxml::debug("Now looking for $src");
       #if no ps file try to replicate it.
       my $didrepcopy = &Apache::lonnet::repcopy($src);
       &Apache::lonxml::debug("repcopy of $src ... $didrepcopy");
       if ( (not -e $src) ||
    ($didrepcopy ne 'ok')) {
    &Apache::lonxml::debug("Failed to find or replicate $src");
   
    #if replication failed try to produce eps file dynamically
    $src=~s/\.ps$/\.eps/;
    my $temp_file;
    open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat");
    my $newsrc=$orig_src;
    $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|;
    &Apache::lonxml::debug("queueing $newsrc for dynamic eps production.");
    print FILE "$newsrc\n";
    close FILE;
    $src=~s|/home/httpd/html/res|/home/httpd/prtspool|;
    $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;
     }      }
  }   }
     }      }
     return '';      my ($path,$file)=($src=~m|(.*)/([^/]*)$|);
       &Apache::lonxml::debug("get_eps_image returning: $path / $file<BR />");
       return ($path.'/',$file);
   }
   
   sub eps_generation {
       my ($src,$file,$width_param) = @_;     
       my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
       my $temp_file = Apache::File->new('>>'.$filename); 
       print $temp_file "$src\n";
       my $newsrc = $src;
       $newsrc =~ s/(\.gif|\.jpg|\.jpeg)$/\.eps/i;
       $newsrc=~s/\/home\/httpd\/html\/res//;
       $newsrc=~s/\/home\/([^\/]*)\/public_html\//\/$1\//;
       $newsrc=~s/\/\.\//\//;
       $newsrc=~s/\/([^\/]+)\.(ps|eps)/\//;
       if ($newsrc=~/\/home\/httpd\/lonUsers\//) {
    $newsrc=~s/\/home\/httpd\/lonUsers//;
    $newsrc=~s/\/([^\/]+)\/(\w)\/(\w)\/(\w)\//\/$1\//;
       }
       if ($newsrc=~/\/userfiles\//) {
    return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
       } else {
    return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
       }
   }
   
   sub file_path {     
       my $src=shift;
       my ($file,$path); 
       if ($src =~ m!(.*)/([^/]*)$!) {
    $file = $2; 
    $path = $1.'/'; 
       } 
       return $file,$path;
 }  }
   
 sub recalc {  sub recalc {
Line 3168  sub recalc { Line 3985  sub recalc {
     return $value.' mm';      return $value.' mm';
 }  }
   
   sub LATEX_length {
       my $garbage=shift;
       $garbage=~s/^\s+$//;
       $garbage=~s/^\s+(\S.*)/$1/;#space before 
       $garbage=~s/(.*\S)\s+$/$1/;#space after 
       $garbage=~s/(\s)+/$1/;#only one space
       $garbage=~s/(\\begin{([^\}]+)}|\\end{([^\}]+)})//g;#remove LaTeX \begin{...} and \end{...}
       $garbage=~s/(\$\_\{|\$\_|\$\^{|\$\^|\}\$)//g;#remove $_{,$_,$^{,$^,}$
       $garbage=~s/([^\\])\$/$1/g;#$
       $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/(\\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/(\\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/(\\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;
       #remove some other LaTeX command
       $garbage=~s|\\(\w+)\\|\\|g;  
       $garbage=~s|\\(\w+)(\s*)|$2|g;  
       $garbage=~s|\+|11|g;
       my  $value=length($garbage);
       return $value;
   }
   
   
   
   
 1;  1;
 __END__  __END__

Removed from v.1.158  
changed lines
  Added in v.1.278


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.