Diff for /loncom/xml/londefdef.pm between versions 1.375.2.1 and 1.475

version 1.375.2.1, 2007/10/15 20:00:12 version 1.475, 2024/04/14 17:12:28
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # Tags Default Definition Module   # Tags Default Definition Module
 #  #
 # $Id$  # $Id$
 #   #
 #  #
 # Copyright Michigan State University Board of Trustees  # Copyright Michigan State University Board of Trustees
 #  #
Line 25 Line 25
 # /home/httpd/html/adm/gpl.txt  # /home/httpd/html/adm/gpl.txt
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 ## Copyright for TtHfunc and TtMfunc by Ian Hutchinson.   ## Copyright for TtHfunc and TtMfunc by Ian Hutchinson.
 # TtHfunc and TtMfunc (the "Code") may be compiled and linked into   # TtHfunc and TtMfunc (the "Code") may be compiled and linked into
 # binary executable programs or libraries distributed by the   # binary executable programs or libraries distributed by the
 # Michigan State University (the "Licensee"), but any binaries so   # Michigan State University (the "Licensee"), but any binaries so
 # distributed are hereby licensed only for use in the context  # distributed are hereby licensed only for use in the context
 # of a program or computational system for which the Licensee is the   # of a program or computational system for which the Licensee is the
 # primary author or distributor, and which performs substantial   # primary author or distributor, and which performs substantial
 # additional tasks beyond the translation of (La)TeX into HTML.  # additional tasks beyond the translation of (La)TeX into HTML.
 # The C source of the Code may not be distributed by the Licensee  # The C source of the Code may not be distributed by the Licensee
 # to any other parties under any circumstances.  # to any other parties under any circumstances.
 #  #
   
 package Apache::londefdef;   package Apache::londefdef;
   
 use Apache::lonnet;  use Apache::lonnet;
 use strict;  use strict;
 use Apache::lonxml;  use Apache::lonxml;
 use Apache::File();  use Apache::lontable;
 use Image::Magick;  use Image::Magick;
 use Apache::lonmenu();  use Apache::lonmenu();
 use Apache::lonmeta();  use Apache::lonmeta();
   use Apache::lonlocal;
   use Apache::loncommon();
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use File::Basename;  use File::Basename;
 use LONCAPA();  use LONCAPA;
 # use Data::Dumper;  # use Data::Dumper;
   
 BEGIN {  BEGIN {
   
     &Apache::lonxml::register('Apache::londefdef',('a','abbr','acronym','accessrule','address','allow','applet','area','b','base','basefont','bgo','bgsound','big','blink','blockquote','blankspace','body','br','button','caption','center','cite','code','col','colgroup','dd','del','dfn','dir','div','dl','dt','em','embed','externallink','fieldset','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','i','iframe','img','input','ins','insert','isindex','kbd','keygen','label','layer','legend','li','link','m','map','marquee','menu','meta','multicol','nobr','noembed','noframes','nolayer','noscript','object','ol','optgroup','option','output','p','param','pre','q','s','samp','select','server','small','spacer','span','strike','strong','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','tthoption','u','ul','var','wbr','hideweboutput'));      &Apache::lonxml::register('Apache::londefdef',('a','abbr','acronym','accessrule','address','allow','applet','area','b','base','basefont','bgo','bgsound','big','blink','blockquote','blankspace','body','br','button','caption','center','cite','code','col','colgroup','dd','del','dfn','dir','div','dl','dt','em','embed','externallink','fieldset','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','i','iframe','img','input','ins','insert','isindex','kbd','keygen','label','layer','legend','li','link','m','map','marquee','menu','meta','multicol','nobr','noembed','noframes','nolayer','noscript','object','ol','optgroup','option','output','p','param','pre','q','s','samp','select','server','small','spacer','span','strike','strong','style','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','tthoption','u','ul','var','wbr','hideweboutput'));
   
 }  }
   
 #  
 #   Dumps all elements of the table structure.  
 #   Need this 'cause evidently when given an array, Data::Dumper only seems  
 #   to dump element 0.  
 #  
 #sub debug_dump_table {  
 #    my $lastrow = $#Apache::londefdef::table;  
 #    &Apache::lonnet::logthis("Dumping table:  Last row index: $lastrow");  
 #    my $row;  
 #    for ($row =0; $row <= $lastrow; $row++ ) {  
 # my $text = Dumper($Apache::londefdef::table[$row]);  
 # &Apache::lonnet::logthis("table [ $row ]".$text);  
 #    }  
 #}  
 sub initialize_londefdef {  sub initialize_londefdef {
     $Apache::londefdef::TD_redirection=0;      $Apache::londefdef::TD_redirection=0;
     @Apache::londefdef::table = ();      @Apache::londefdef::table = ();
Line 103  sub start_m { Line 92  sub start_m {
     my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);      my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);
     if ($target eq 'web' || $target eq 'analyze') {      if ($target eq 'web' || $target eq 'analyze') {
  &Apache::lonxml::debug("M is starting with:$inside:");   &Apache::lonxml::debug("M is starting with:$inside:");
           if (!($inside =~ /^\s*\$.*\$\s*$/ || $inside =~ /^\s*\\[([].*\\[)\]]\s*$/)) {
               # Non-math LaTeX will not be rendered correctly with MathJax
               # and it should be avoided anyway.
               # On top of that, MathJax will render math without $, but
               # it will fail with tth. This is worth a warning.
               # (even though some people might just use latex for printing)
               &Apache::lonxml::warning(&mt('Missing $ in [_1].','&lt;m&gt;'));
           } elsif (($env{'browser.type'} eq 'safari') && ($env{'form.editxmltext'}) &&
                    (($env{'form.problemmode'} eq 'view') || ($env{'form.problemmode'} eq 'discard'))) {
               my $delimiter;
               if ($inside =~ /\$$/) {
                   $delimiter = '$';
               } elsif ($inside =~ /\\([)\]])$/) {
                   $delimiter = $1;
               }
               if ($delimiter) {
                   &Apache::lonxml::warning(&mt('Insert a space between [_1] and [_2].',
                                                $delimiter,'&lt;/m&gt;'));
               }
           }
  my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);   my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
  if ($eval eq 'on') {   if ($eval eq 'on') {
     $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);      $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
     #&Apache::lonxml::debug("M is evaulated to:$inside:");      #&Apache::lonxml::debug("M is evaluated to:$inside:");
  }   }
  my $tex = $inside;   my $tex = $inside;
  my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval);   my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval);
  $currentstring = &Apache::lontexconvert::converted(\$inside,$display);   $currentstring = &Apache::lontexconvert::converted(\$inside,$display);
  if ($Apache::lontexconvert::errorstring) {   if ($Apache::lontexconvert::errorstring) {
     my $errormsg='<pre>'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'</pre> occured while attempting to convert this TeX: <pre>';      my $errormsg='<pre>'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'</pre> occurred while attempting to convert this TeX: <pre>';
     $tex = &HTML::Entities::encode($tex,'<>&"');      $tex = &HTML::Entities::encode($tex,'<>&"');
     my ($linenumber) =      my ($linenumber) =
  ($Apache::lontexconvert::errorstring =~ /Line (\d+)/);   ($Apache::lontexconvert::errorstring =~ /Line (\d+)/);
Line 138  sub start_m { Line 147  sub start_m {
  # detect simple math mode entry exits, and convert them   # detect simple math mode entry exits, and convert them
         # to use \ensuremath ... unless there's a \verb inside.          # to use \ensuremath ... unless there's a \verb inside.
  if (! ($currentstring=~/\\verb/)) {   if (! ($currentstring=~/\\verb/)) {
     if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) {      if ($currentstring=~/^\s*\$[^\$].*\$\s*$/) {
  $currentstring=~s/^(\s*)\$/$1/;   $currentstring=~s/^(\s*)\$/$1/;
  $currentstring=~s/\$(\s*)$/$1/;   $currentstring=~s/\$(\s*)$/$1/;
  $currentstring='\ensuremath{'.$currentstring.'}';   $currentstring='\ensuremath{'.$currentstring.'}';
Line 185  sub start_html { Line 194  sub start_html {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'edit' || $target eq 'webgrade' ) {      if ($target eq 'web' || $target eq 'edit' || $target eq 'webgrade' ) {
  # start_body() takes care of emitting the <html>    # start_body() takes care of emitting the <html>
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .=   
     '\documentclass[letterpaper,twoside]{article}\raggedbottom';   $currentstring .= &latex_header();
  if (($env{'form.latex_type'}=~'batchmode') ||  
             (!$env{'request.role.adv'})) {$currentstring .='\batchmode';}   
  $currentstring .= '\newcommand{\keephidden}[1]{}'.  
                           '\renewcommand{\deg}{$^{\circ}$}'.  
   '\usepackage{multirow}'.  
                           '\usepackage{longtable}'.  
                           '\usepackage{textcomp}'.  
                           '\usepackage{makeidx}'.  
                           '\usepackage[dvips]{graphicx}'.  
   '\usepackage{wrapfig}'.  
   '\usepackage{picins}'.  
                           '\usepackage{epsfig}'.  
                           '\usepackage{calc}'.  
                           '\usepackage{amsmath}'.  
                           '\usepackage{amssymb}'.  
                           '\usepackage{amsfonts}'.  
                           '\usepackage{amsthm}'.  
                           '\usepackage{amscd}'.  
                           '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'.  
                           '\renewenvironment{theindex}{\begin{list}{}{{\vskip 1mm \noindent \large\textbf{Index}} \newline \setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.01in}\setlength{\itemsep}{0.1in}\setlength{\parsep}{-0.02in}\setlength{\belowdisplayskip}{0.01in}\setlength{\abovedisplayskip}{0.01in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.01in}}}{\end{list}}';  
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 228  sub start_head { Line 217  sub start_head {
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 241  sub end_head { Line 230  sub end_head {
  if ($Apache::lonxml::redirection) {   if ($Apache::lonxml::redirection) {
     $Apache::londefdef::head = &Apache::lonxml::endredirection();      $Apache::londefdef::head = &Apache::lonxml::endredirection();
  }   }
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 250  sub start_map { Line 239  sub start_map {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 259  sub end_map { Line 248  sub end_map {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 269  sub start_select { Line 258  sub start_select {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  $Apache::londefdef::select=0;   $Apache::londefdef::select=0;
     }      }
Line 280  sub end_select { Line 269  sub end_select {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 290  sub start_option { Line 279  sub start_option {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::select++;   $Apache::londefdef::select++;
  if ($Apache::londefdef::select == 1) {   if ($Apache::londefdef::select == 1) {
Line 306  sub end_option { Line 295  sub end_option {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  $currentstring='}';   $currentstring='}';
     }      }
Line 318  sub start_input { Line 307  sub start_input {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 327  sub end_input { Line 316  sub end_input {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 337  sub start_textarea { Line 326  sub start_textarea {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 346  sub end_textarea { Line 335  sub end_textarea {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 356  sub start_form { Line 345  sub start_form {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 365  sub end_form { Line 354  sub end_form {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 375  sub start_title { Line 364  sub start_title {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $Apache::londefdef::title =    $Apache::londefdef::title =
     &Apache::lonxml::get_all_text('/title',$parser,$style);      &Apache::lonxml::get_all_text('/title',$parser,$style);
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\keephidden{Title of the document:  '    $currentstring .= '\keephidden{Title of the document:  ';
     }      }
     if ($target eq 'meta') {      if ($target eq 'meta') {
  $currentstring='<title>';   $currentstring='<title>';
Line 394  sub end_title { Line 383  sub end_title {
  # start_title takes care of swallowing the title   # start_title takes care of swallowing the title
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }        }
     if ($target eq 'meta') {      if ($target eq 'meta') {
  &end_output($target);   &end_output($target);
  $currentstring='</title>';   $currentstring='</title>';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 414  sub start_meta { Line 403  sub start_meta {
  } else {   } else {
     $currentstring = $token->[4];      $currentstring = $token->[4];
  }   }
           if ($env{'form.grade_imsexport'}) {
               $currentstring = '';
           }
     } elsif ($target eq 'meta') {      } elsif ($target eq 'meta') {
  unless (&Apache::lonxml::get_param   unless (&Apache::lonxml::get_param
  ('http-equiv',$parstack,$safeeval,undef,1)) {   ('http-equiv',$parstack,$safeeval,undef,1)) {
Line 486  sub insert_meta { Line 478  sub insert_meta {
     <meta />';      <meta />';
 }  }
   
   #-- <start> tag
   sub start_style {
    my ($target, $token, $tagstack, $parstack, $parser, $safeeval, $style) = @_;
    my $currentstring = '';
   
    if ($target eq 'tex') {
    Apache::lonxml::startredirection();
    } else {
    $currentstring = $token->[4];
    }
   
    return $currentstring;
   }
   
   sub end_style {
    my ($target, $token, $tagstack, $parstack, $parser, $safeeval) = @_;
    my $currentstring = '';
   
    if ($target eq 'tex') {
    Apache::lonxml::endredirection();
    } else {
    $currentstring = $token->[2];
    }
    return $currentstring;
   }
   
 # accessrule  # accessrule
 sub start_accessrule {  sub start_accessrule {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
Line 537  sub end_accessrule { Line 555  sub end_accessrule {
  if ($args ne '') {   if ($args ne '') {
     $currentstring = $token->[4];      $currentstring = $token->[4];
  }   }
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 546  sub generate_css_links { Line 564  sub generate_css_links {
     my $css_href = &Apache::lonnet::EXT('resource.0.cssfile');      my $css_href = &Apache::lonnet::EXT('resource.0.cssfile');
     if ($css_href =~ /\S/) {      if ($css_href =~ /\S/) {
  &Apache::lonxml::extlink($css_href);   &Apache::lonxml::extlink($css_href);
  $links .=    $links .=
     '<link rel="stylesheet" type="text/css" href="'.$css_href.'" />';      '<link rel="stylesheet" type="text/css" href="'.$css_href.'" />';
     }      }
     return $links;      return $links;
Line 569  sub start_body { Line 587  sub start_body {
   
  my $extra_head = &generate_css_links();   my $extra_head = &generate_css_links();
   
  $currentstring =       # Breadcrumbs
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       if ($env{'request.state'} eq 'construct') {
           my $url=&Apache::lonnet::hreflocation('',$env{'request.filename'});
           my $text = 'Authoring Space';
           my $href = &Apache::loncommon::authorspace($url);
           if ($env{'request.course.id'}) {
               my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
               my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
               if ($href eq "/priv/$cdom/$cnum/") {
                   $text = 'Course Authoring Space';
               }
           }
           &Apache::lonhtmlcommon::add_breadcrumb({
               'text'  => $text,
               'href'  => $href,
           });
           &Apache::lonhtmlcommon::add_breadcrumb({
               'text'  => 'HTML Editor',
               'href'  => '',
           });
           # breadcrumbs (and tools) will be created
           # in start_page->bodytag->innerregister
       } else {
           # FIXME Where are we?
       }
   
           my $args = {'add_entries'    => $token->[2],
                       'force_register' => 1,};
           if ($target eq 'web') {
               $args->{'print_suppress'} = 1;
               if ($env{'request.use_absolute'}) {
                   $args->{'use_absolute'} = $env{'request.use_absolute'};
               }
               if ($env{'form.only_body'}) {
                   $args->{'only_body'} = 1;
               }
           }
    $currentstring =
     &Apache::loncommon::start_page($Apache::londefdef::title,      &Apache::loncommon::start_page($Apache::londefdef::title,
    $Apache::londefdef::head     $Apache::londefdef::head
       .$extra_head,        .$extra_head,$args);
    {'add_entries'    => $token->[2],          my $header = '';
     'no_title'       => 1,          if ($env{'request.state'} ne 'published' &&
     'force_register' => 1});              $env{'request.state'} ne 'construct') {
               $header=&Apache::lonmenu::constspaceform();
  if ($env{'request.state'} ne 'published') {          }
     $currentstring.=&Apache::lonmenu::constspaceform();          if ($env{'request.state'} ne 'published') {
     $currentstring.=(<<EDITBUTTON);              unless ($env{'form.inhibitmenu'} eq 'yes') {
 <form method="post">                  $header.=&edit_controls();
 <input type="submit" name="editmode" accesskey="e" value="Edit" />              }
 </form>          }
 <br />          if ($env{'request.state'} eq 'construct') {
 EDITBUTTON              unless ($env{'form.inhibitmenu'} eq 'yes') {
  }                  $currentstring.=&Apache::loncommon::head_subbox(
  $currentstring.=&Apache::lonxml::message_location();                                      &Apache::loncommon::CSTR_pageheader()
                                      .$header);
               }
           } elsif ($env{'request.state'} eq 'edit') {
               $currentstring.=&Apache::loncommon::head_subbox($header);
           }
           $currentstring.=&Apache::lonxml::message_location();
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\begin{document}';            $currentstring = '';   #  '\begin{document}' is in header.
     }       }
   
     return $currentstring;      return $currentstring;
 }  }
   
   sub edit_controls {
       my ($nochgview) = @_;
       my ($is_course_doc,$is_supp,$supp_path,$supp_title);
       my $result = '
   <form method="post" action="">
   <div class="LC_edit_problem_header">'."\n";
       unless ($nochgview) {
           $result .= '
   <div class="LC_edit_problem_header_row1">'.
   &Apache::lonxml::renderingoptions().'
   <input type="submit" name="changeproblemmode" value="'.&mt('Change View').'" />
   </div>';
       }
       $result .= '
   <div>
   <input type="hidden" name="editmode" value="" />
   <input type="button" name="editordefault" accesskey="e" value="'.&mt('Edit').
   '" onclick="seteditmode(this.form,'."'edit'".');" />'."\n";
       if ($env{'browser.type'} ne 'explorer' || $env{'browser.version'} > 9) {
           my $uri = $env{'request.uri'};
           if ($uri =~ /\.(xml|html|htm|xhtml|xhtm)$/) {
               my %editors = &Apache::loncommon::permitted_editors($uri);
               if ($editors{'daxe'}) {
                   my $daxeurl = '/daxepage'.$uri;
                   $result .= '<input type="button" name="editordaxe" value="'.&mt('Edit with Daxe').
                              '" onclick="seteditmode(this.form,'."'daxe'".');" />'."\n";
               }
           }
       }
       if (($env{'request.course.id'}) && ($env{'form.forceedit'})) {
           my $url=&Apache::lonnet::hreflocation('',$env{'request.filename'});
           if ($url =~ /\.html?$/i) {
               my ($cdom,$cnum);
               if ($env{'request.course.id'}) {
                   $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   if ($url =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental|docs)/}) {
                       if ($1 eq 'supplemental') {
                           $is_supp = 1;
                       }
                       $is_course_doc = 1;
                   }
                   if ($env{'request.filename'} =~ m{/userfiles/supplemental/default|\d+/}) {
                       my $fn=&Apache::lonnet::declutter($env{'request.filename'});
                       if (&Apache::lonnet::is_course_upload($fn,$cnum,$cdom)) {
                           &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                                                                   ['folderpath','title']);
                           $supp_path = &escape(&HTML::Entities::decode($Apache::lonnet::env{'form.folderpath'}));
                           $supp_title = &escape(&HTML::Entities::decode($Apache::lonnet::env{'form.title'}));
                       }
                   }
               }
               my ($symb,$itemtitle,$displayfile,$caller);
               if ($url =~ m{^/uploaded/$cdom/$cnum/portfolio/syllabus/}) {
                   $itemtitle = &mt('Syllabus');
                   $caller = "/public/$cdom/$cnum/syllabus";
               } else {
                   $caller = $url;
                   ($symb,$itemtitle,$displayfile) =
                       &Apache::lonxml::get_courseupload_hierarchy($url,
                                                                   $env{'form.folderpath'},
                                                                   $env{'form.title'});
               }
               if (($symb ne '') || ($env{'httpref.'.$url} ne '') ||
                   ($url =~ m{^/uploaded/$cdom/$cnum/portfolio/syllabus/})) {
                     $result .= ('&nbsp;' x 3).
                                &Apache::lonhtmlcommon::dependencies_button()."\n".
                                &Apache::lonhtmlcommon::dependencycheck_js($symb,
                                    $itemtitle,$url,$env{'form.folderpath'},$caller)."\n";
               }
           }
       }
       $result .= '</div>
   </div>
   </form>
   ';
       my $setedit_js = &Apache::lonxml::seteditor_javascript($is_course_doc,$is_supp,
                                                              $supp_path,$supp_title);
       return $setedit_js."\n".$result;
   }
   
 sub end_body {  sub end_body {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off unclosed <p>      my $currentstring = &end_p(); # Close off unclosed <p>
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= &Apache::loncommon::end_page({'discussion' => 1});   $currentstring .= &Apache::loncommon::end_page({'discussion' => 1});
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}';     $currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 # \begin{center} causes a new paragprah spacing that looks odd inside   # \begin{center} causes a new paragprah spacing that looks odd inside
 # of a table cell.  Same at the end of a \center but with a slightly  # of a table cell.  Same at the end of a \center but with a slightly
 # larger space .. hence center_correction and center_end_correction.  # larger space .. hence center_correction and center_end_correction.
 #  #
 sub center_correction { return '\vspace*{-6 mm}'; }   sub center_correction { return '\vspace*{-6 mm}'; }
 sub center_end_correction { return '\vspace*{-7 mm}'; }  sub center_end_correction { return '\vspace*{-7 mm}'; }
   
 #-- <center> tag (end tag required)  #-- <center> tag (end tag required)
Line 616  sub start_center { Line 760  sub start_center {
     my ($target,$token,$tagstack) = @_;      my ($target,$token,$tagstack) = @_;
     my $currentstring = &end_p(); # Close off any prior para.      my $currentstring = &end_p(); # Close off any prior para.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if (&is_inside_of($tagstack, "table")) {   if (&is_inside_of($tagstack, "table")) {
     $currentstring .= &center_correction();      $currentstring .= &center_correction();
  }   }
  $currentstring .= '\begin{center}';     $currentstring .= '\begin{center}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 630  sub end_center { Line 774  sub end_center {
     my ($target,$token,$tagstack) = @_;      my ($target,$token,$tagstack) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{center}';     $currentstring = '\end{center}';
  if (&is_inside_of($tagstack, "table")) {   if (&is_inside_of($tagstack, "table")) {
     $currentstring .= &center_end_correction();      $currentstring .= &center_end_correction();
  }   }
Line 646  sub start_b { Line 790  sub start_b {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &disable_para();   &disable_para();
  $currentstring .= '\textbf{';     $currentstring .= '\textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 658  sub end_b { Line 802  sub end_b {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &enable_para();   &enable_para();
  $currentstring = '}';   $currentstring = '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 672  sub start_strong { Line 816  sub start_strong {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &disable_para();   &disable_para();
  $currentstring = '\textbf{';     $currentstring = '\textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 684  sub end_strong { Line 828  sub end_strong {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &enable_para();   &enable_para();
  $currentstring = '}';     $currentstring = '}';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 710  sub start_h1 { Line 854  sub start_h1 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     } elsif ($target eq 'meta') {      } elsif ($target eq 'meta') {
  $currentstring.='<subject>';   $currentstring.='<subject>';
  &start_output($target);   &start_output($target);
Line 725  sub end_h1 { Line 869  sub end_h1 {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $post='\vskip 0 mm ';   my $post='\vskip 0 mm ';
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=lc(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1));
  if ($align eq 'center') {   if ($align eq 'center') {
     $post='\end{center}';      $post='\end{center}';
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
Line 737  sub end_h1 { Line 881  sub end_h1 {
     } elsif ($target eq 'meta') {      } elsif ($target eq 'meta') {
  &end_output($target);   &end_output($target);
  $currentstring='</subject>';   $currentstring='</subject>';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 759  sub start_h2 { Line 903  sub start_h2 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 780  sub end_h2 { Line 924  sub end_h2 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 802  sub start_h3 { Line 946  sub start_h3 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 823  sub end_h3 { Line 967  sub end_h3 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 845  sub start_h4 { Line 989  sub start_h4 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 866  sub end_h4 { Line 1010  sub end_h4 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 888  sub start_h5 { Line 1032  sub start_h5 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 909  sub end_h5 { Line 1053  sub end_h5 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 931  sub start_h6 { Line 1075  sub start_h6 {
  }   }
  my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);   my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  if (not defined $TeXsize) {$TeXsize="large";}   if (not defined $TeXsize) {$TeXsize="large";}
  $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';    $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 952  sub end_h6 { Line 1096  sub end_h6 {
     $post='}'.'\vskip 0 mm ';      $post='}'.'\vskip 0 mm ';
  }   }
  $currentstring .= '}}'.$post;   $currentstring .= '}}'.$post;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 998  sub end_i { Line 1142  sub end_i {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1033  sub start_dfn { Line 1177  sub start_dfn {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\textit{';   $currentstring .= '\textit{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1102  sub start_code { Line 1246  sub start_code {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\texttt{';   $currentstring .= '\texttt{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1113  sub end_code { Line 1257  sub end_code {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1136  sub end_em { Line 1280  sub end_em {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1159  sub end_q { Line 1303  sub end_q {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '}';   $currentstring .= '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1175  sub end_q { Line 1319  sub end_q {
     my $closing_string = ''; # String required to close <p>      my $closing_string = ''; # String required to close <p>
   
 #   Some tags are <p> fragile meaning that <p> inside of them  #   Some tags are <p> fragile meaning that <p> inside of them
 #   does not work within TeX mode.  This is managed via the   #   does not work within TeX mode.  This is managed via the
 #   counter below:  #   counter below:
 #  #
   
Line 1204  sub start_p { Line 1348  sub start_p {
   
  $currentstring .= &end_p(); # close off prior para if in progress.   $currentstring .= &end_p(); # close off prior para if in progress.
  my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
    if (!defined $align) {
             # check inline CSS
             $align = &get_css_property('text-align',$parstack,$safeeval);
           }
  if ($align eq 'center') {   if ($align eq 'center') {
     $currentstring .='\begin{center}\par ';      $currentstring .='\begin{center}\par ';
     $closing_string = '\end{center}';      $closing_string = '\end{center}';
Line 1211  sub start_p { Line 1359  sub start_p {
  $currentstring = &center_correction().$currentstring;   $currentstring = &center_correction().$currentstring;
     }      }
  } elsif ($align eq 'right') {   } elsif ($align eq 'right') {
     $currentstring.="\n".'{\flushright ';      $currentstring.="\n".'\begin{flushright}';
 #    $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';  #    $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';
     $closing_string= "}\n";      $closing_string= '\end{flushright}'."\n";
  } elsif ($align eq 'left') {   } elsif ($align eq 'left') {
     $currentstring.= "\n".'{\flushleft ';      $currentstring.= "\n".'\begin{flushleft}';
 #    $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{{';  #    $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{{';
     $closing_string = "}\n";      $closing_string = '\end{flushleft}'."\n";
  } else {   } else {
             $currentstring.='\par ';              $currentstring.='\par ';
     if (&is_inside_of($tagstack, 'table')) {      if (&is_inside_of($tagstack, 'table')) {
Line 1271  sub start_br { Line 1419  sub start_br {
  if ($signal != 1) {   if ($signal != 1) {
     $currentstring .= '\strut \\\\ \strut ';      $currentstring .= '\strut \\\\ \strut ';
  }   }
       
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1293  sub start_big { Line 1441  sub start_big {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '{\large ';   $currentstring .= '{\large ';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1336  sub start_basefont { Line 1484  sub start_basefont {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
  if (defined $basesize) {   if (defined $basesize) {
Line 1350  sub end_basefont { Line 1498  sub end_basefont {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
  if (defined $basesize) {   if (defined $basesize) {
Line 1366  sub start_font { Line 1514  sub start_font {
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);   my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);
  if ($face!~/symbol/i) {   $currentstring = $token->[4];
     if (($env{'browser.fontenhance'} eq 'on') ||   
  ($env{'browser.blackwhite'} eq 'on')) { return ''; }  
  }  
  $currentstring = $token->[4];       
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
  if (defined $fontsize) {   if (defined $fontsize) {
Line 1384  sub end_font { Line 1528  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' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
  if (defined $fontsize) {   if (defined $fontsize) {
Line 1393  sub end_font { Line 1537  sub end_font {
     }      }
     return $currentstring;      return $currentstring;
 }  }
    
 #-- <strike> tag (end tag required)  #-- <strike> tag (end tag required)
 sub start_strike {  sub start_strike {
     my ($target,$token) = @_;      my ($target,$token) = @_;
Line 1402  sub start_strike { Line 1546  sub start_strike {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1413  sub end_strike { Line 1557  sub end_strike {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring=&Apache::lonxml::endredirection();   $currentstring=&Apache::lonxml::endredirection();
  $currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g;    $currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g;
  $currentstring=~s/^\s*(\S)/\\underline\{$1/;    $currentstring=~s/^\s*(\S)/\\underline\{$1/;
  $currentstring=~s/(\S)\s*$/$1\}/;   $currentstring=~s/(\S)\s*$/$1\}/;
     }      }
     return $currentstring;      return $currentstring;
Line 1428  sub start_s { Line 1572  sub start_s {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1454  sub start_sub { Line 1598  sub start_sub {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\raisebox{-\smallskipamount}{\scriptsize{';   $currentstring .= '\raisebox{-\smallskipamount}{\scriptsize{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1477  sub start_sup { Line 1621  sub start_sup {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\raisebox{\smallskipamount}{\scriptsize{';   $currentstring .= '\raisebox{\smallskipamount}{\scriptsize{';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1501  sub start_hr { Line 1645  sub start_hr {
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
   
  # <hr /> can't be inside of <sup><sub> thank you LaTeX.   # <hr /> can't be inside of <sup><sub> thank you LaTeX.
  #    #
  my $restart_sub = 0;   my $restart_sub = 0;
  my $restart_sup = 0;   my $restart_sup = 0;
   
Line 1511  sub start_hr { Line 1655  sub start_hr {
   
  if (&is_inside_of($tagstack, "sub")) {   if (&is_inside_of($tagstack, "sub")) {
     $restart_sub = 1;      $restart_sub = 1;
     $currentstring .= &end_sub($target, $token, $tagstack,       $currentstring .= &end_sub($target, $token, $tagstack,
        $parstack, $parser, $safeeval);         $parstack, $parser, $safeeval);
  }   }
  if (&is_inside_of($tagstack, "sup")) {   if (&is_inside_of($tagstack, "sup")) {
Line 1550  sub start_hr { Line 1694  sub start_hr {
     $currentstring .= &start_sup($target, $token, $tagstack,      $currentstring .= &start_sup($target, $token, $tagstack,
  $parstack, $parser, $safeeval);   $parstack, $parser, $safeeval);
  }   }
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1577  sub start_div { Line 1721  sub start_div {
     my $currentstring = &end_p(); # Close enclosing para.      my $currentstring = &end_p(); # Close enclosing para.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     }       }
     if ($target eq 'tex') {      if ($target eq 'tex') {
  # 4 possible alignments: left, right, center, and -missing-.   # 4 possible alignments: left, right, center, and -missing-.
           # If inside a table row, we must let the table logic
    # do the alignment, however.
    #
   
  my $endstring = '';   my $endstring = '';
   
Line 1590  sub start_div { Line 1737  sub start_div {
     $endstring      = '\end{center}';      $endstring      = '\end{center}';
     if (&is_inside_of($tagstack, "table")) {      if (&is_inside_of($tagstack, "table")) {
  $currentstring = &center_correction().$currentstring;   $currentstring = &center_correction().$currentstring;
    $endstring    .= &center_end_correction();
     }      }
  }   }
  elsif ($align eq 'right') {   elsif ($align eq 'right') {
Line 1630  sub start_a { Line 1778  sub start_a {
  my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,   my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
     undef,1);      undef,1);
  $currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href});   $currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href});
           if ($href =~ /\S/) {
               if ($href !~ m{^https?://}) {
                   my $url=&Apache::lonnet::hreflocation('',$env{'request.filename'});
                   my $linkurl;
                   if ($href =~ m{^/uploaded/}) {
                       $linkurl = $href;
                   } elsif ($href =~ m{^[^/]}) {
                       my $path = $url;
                       $path  =~ s{[^/]*$}{};
                       $linkurl = $path.$href;
                   }
                   if ($linkurl =~ m{^/uploaded/}) {
                       if (!&Apache::lonnet::allowed('bre',$linkurl)) {
                           if (&Apache::lonnet::is_on_map($url)) {
                               &Apache::lonxml::extlink($linkurl);
                           } elsif ($env{'request.course.id'}) {
                               my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                               my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                               if ($linkurl =~ m{^([^/]|/uploaded/$cdom/$cnum/(docs|supplemental)/)}) {
                                   my $cleanhref = &clean_docs_httpref($linkurl,$url,$cdom,$cnum);
                                   if ($cleanhref) {
                                       &Apache::lonxml::extlink($cleanhref);
                                   }
                               }
                           }
                       }
                   }
               }
           }
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1645  sub end_a { Line 1822  sub end_a {
     &Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);      &Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);
  my $name =   my $name =
     &Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1);      &Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1);
  if ($href =~ /\S/) {          my $uriprint =
               &Apache::lonxml::get_param('uriprint',$parstack,$safeeval,undef,1);
           my $anchorprint =
               &Apache::lonxml::get_param('anchorprint',$parstack,$safeeval,undef,1);
    if (($href =~ /\S/) && ($uriprint=~/^on|uriprint|yes|1$/i)) {
     $href =~ s/([^\\])%/$1\\\%/g;      $href =~ s/([^\\])%/$1\\\%/g;
     # Substitute special symbols... and allow line breaks at each /      # Substitute special symbols... and allow line breaks at each /
     #      #
     $href = &Apache::lonxml::latex_special_symbols($href);      $href = &Apache::lonxml::latex_special_symbols($href);
     $href =~ s/\//\/\\-/g;              # Map / to /\- to allow hyphenation.      $href =~ s/\//\/\\-/g;              # Map / to /\- to allow hyphenation.
     $currentstring .= ' ({\tt URI:'.$href.'})';      $currentstring .= ' ({\tt URI:'.$href.'})';
  } elsif ($name =~ /\S/) {   } elsif (($name =~ /\S/) && ($anchorprint=~/^on|anchorprint|yes|1$/i)) {
     $currentstring .= ' ({\tt Anchor:'.&Apache::lonxml::latex_special_symbols($name).'})';      $currentstring .= ' ({\tt Anchor:'.&Apache::lonxml::latex_special_symbols($name).'})';
  } else {   } else {
     $currentstring.='';      $currentstring.='';
Line 1666  sub start_li { Line 1847  sub start_li {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);   my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
  my $value=&Apache::lonxml::get_param('value',$parstack,$safeeval,undef,0);   my $value=&Apache::lonxml::get_param('value',$parstack,$safeeval,undef,0);
  #FIXME need to support types i and I    #FIXME need to support types i and I
  if ($type=~/disc/) {   if ($type=~/disc/) {
     $currentstring .= ' \item[$\bullet$] ';      $currentstring .= ' \item[$\bullet$] ';
  } elsif ($type=~/circle/) {   } elsif ($type=~/circle/) {
Line 1687  sub start_li { Line 1868  sub start_li {
     $currentstring .= ' \item['.$value.'] ';      $currentstring .= ' \item['.$value.'] ';
  } else {   } else {
     $currentstring .= ' \item ';      $currentstring .= ' \item ';
  }     }
  $Apache::londefdef::list_index++;   $Apache::londefdef::list_index++;
     }      }
     return $currentstring;      return $currentstring;
Line 1697  sub end_li { Line 1878  sub end_li {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # In case there's a <p> in the <li>      my $currentstring = &end_p(); # In case there's a <p> in the <li>
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];        $currentstring .= $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1710  sub start_u { Line 1891  sub start_u {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1733  sub start_ul { Line 1914  sub start_ul {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off enclosing list.      my $currentstring = &end_p(); # Close off enclosing list.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  my $TeXtype=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);   my $TeXtype=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
  $Apache::londefdef::list_index=0;   $Apache::londefdef::list_index=0;
  if ($TeXtype eq 'disc') {   if ($TeXtype eq 'disc') {
     $currentstring .= '\renewcommand{\labelitemi}{$\bullet$}'.      $currentstring .= '\renewcommand{\labelitemi}{$\bullet$}'.
                               '\renewcommand{\labelitemii}{$\bullet$}'.                                 '\renewcommand{\labelitemii}{$\bullet$}'.
                               '\renewcommand{\labelitemiii}{$\bullet$}'.                                '\renewcommand{\labelitemiii}{$\bullet$}'.
                               '\renewcommand{\labelitemiv}{$\bullet$}';                                '\renewcommand{\labelitemiv}{$\bullet$}';
  } elsif ($TeXtype eq 'circle') {   } elsif ($TeXtype eq 'circle') {
     $currentstring .= '\renewcommand{\labelitemi}{$\circ$}'.      $currentstring .= '\renewcommand{\labelitemi}{$\circ$}'.
                               '\renewcommand{\labelitemii}{$\circ$}'.                                 '\renewcommand{\labelitemii}{$\circ$}'.
                               '\renewcommand{\labelitemiii}{$\circ$}'.                                '\renewcommand{\labelitemiii}{$\circ$}'.
                               '\renewcommand{\labelitemiv}{$\circ$}';                                '\renewcommand{\labelitemiv}{$\circ$}';
  } elsif ($TeXtype eq 'square') {   } elsif ($TeXtype eq 'square') {
     $currentstring .= '\renewcommand{\labelitemi}{$\diamond$}'.      $currentstring .= '\renewcommand{\labelitemi}{$\diamond$}'.
                               '\renewcommand{\labelitemii}{$\diamond$}'.                                 '\renewcommand{\labelitemii}{$\diamond$}'.
                               '\renewcommand{\labelitemiii}{$\diamond$}'.                                '\renewcommand{\labelitemiii}{$\diamond$}'.
                               '\renewcommand{\labelitemiv}{$\diamond$}';                                '\renewcommand{\labelitemiv}{$\diamond$}';
  }   }
  $currentstring .= '\strut \begin{itemize}';     $currentstring .= '\strut \begin{itemize}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1762  sub end_ul { Line 1943  sub end_ul {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{itemize} \renewcommand{\labelitemi}{$\bullet$}'.   $currentstring = '\end{itemize} \renewcommand{\labelitemi}{$\bullet$}'.
                                '\renewcommand{\labelitemii}{$\bullet$}'.                                  '\renewcommand{\labelitemii}{$\bullet$}'.
                                '\renewcommand{\labelitemiii}{$\bullet$}'.                                 '\renewcommand{\labelitemiii}{$\bullet$}'.
                                '\renewcommand{\labelitemiv}{$\bullet$}\strut ';                                   '\renewcommand{\labelitemiv}{$\bullet$}\strut ';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1777  sub start_menu { Line 1958  sub start_menu {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\begin{itemize} ";     $currentstring = " \\begin{itemize} ";
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1788  sub end_menu { Line 1969  sub end_menu {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\end{itemize}";     $currentstring = " \\end{itemize}";
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1800  sub start_dir { Line 1981  sub start_dir {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # In case there's a <p> prior to the list.      my $currentstring = &end_p(); # In case there's a <p> prior to the list.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= " \\begin{itemize} ";     $currentstring .= " \\begin{itemize} ";
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1811  sub end_dir { Line 1992  sub end_dir {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = " \\end{itemize}";     $currentstring = " \\end{itemize}";
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1823  sub start_ol { Line 2004  sub start_ol {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # In case there's a <p> prior to the list.      my $currentstring = &end_p(); # In case there's a <p> prior to the list.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::list_index=0;   $Apache::londefdef::list_index=0;
  my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);   my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
  if ($type eq '1') {   if ($type eq '1') {
     $currentstring .= '\renewcommand{\labelenumi}{\arabic{enumi}.}'.      $currentstring .= '\renewcommand{\labelenumi}{\arabic{enumi}.}'.
                               '\renewcommand{\labelenumii}{\arabic{enumii}.}'.                                 '\renewcommand{\labelenumii}{\arabic{enumii}.}'.
                               '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.                                '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.
                               '\renewcommand{\labelenumiv}{\arabic{enumiv}.}';                                '\renewcommand{\labelenumiv}{\arabic{enumiv}.}';
  } elsif ($type eq 'A') {   } elsif ($type eq 'A') {
     $currentstring .= '\renewcommand{\labelenumi}{\Alph{enumi}.}'.      $currentstring .= '\renewcommand{\labelenumi}{\Alph{enumi}.}'.
                               '\renewcommand{\labelenumii}{\Alph{enumii}.}'.                                 '\renewcommand{\labelenumii}{\Alph{enumii}.}'.
                               '\renewcommand{\labelenumiii}{\Alph{enumiii}.}'.                                '\renewcommand{\labelenumiii}{\Alph{enumiii}.}'.
                               '\renewcommand{\labelenumiv}{\Alph{enumiv}.}';                                '\renewcommand{\labelenumiv}{\Alph{enumiv}.}';
  } elsif ($type eq 'a') {   } elsif ($type eq 'a') {
Line 1853  sub start_ol { Line 2034  sub start_ol {
                               '\renewcommand{\labelenumiii}{\Roman{enumiii}.}'.                                '\renewcommand{\labelenumiii}{\Roman{enumiii}.}'.
                               '\renewcommand{\labelenumiv}{\Roman{enumiv}.}';                                '\renewcommand{\labelenumiv}{\Roman{enumiv}.}';
  }   }
  $currentstring .= '\strut \begin{enumerate}';     $currentstring .= '\strut \begin{enumerate}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1862  sub end_ol { Line 2043  sub end_ol {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{enumerate}\renewcommand{\labelenumi}{\arabic{enumi}.}'.   $currentstring = '\end{enumerate}\renewcommand{\labelenumi}{\arabic{enumi}.}'.
                                         '\renewcommand{\labelenumii}{\arabic{enumii}.}'.                                          '\renewcommand{\labelenumii}{\arabic{enumii}.}'.
                                         '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.                                          '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.
                                         '\renewcommand{\labelenumiv}{\arabic{enumiv}.}\strut ';                                            '\renewcommand{\labelenumiv}{\arabic{enumiv}.}\strut ';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1877  sub start_dl { Line 2058  sub start_dl {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # In case there's a <p> unclosed prior to the list.      my $currentstring = &end_p(); # In case there's a <p> unclosed prior to the list.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\begin{description}';   $currentstring .= '\begin{description}';
  $Apache::londefdef::DL++;   $Apache::londefdef::DL++;
Line 1885  sub start_dl { Line 2066  sub start_dl {
  $Apache::londefdef::DD[$Apache::londefdef::DL]=0;   $Apache::londefdef::DD[$Apache::londefdef::DL]=0;
  $Apache::londefdef::DT[$Apache::londefdef::DL]=0;   $Apache::londefdef::DT[$Apache::londefdef::DL]=0;
  $Apache::londefdef::seenDT[$Apache::londefdef::DL]=0;   $Apache::londefdef::seenDT[$Apache::londefdef::DL]=0;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1893  sub end_dl { Line 2074  sub end_dl {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }   if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
  if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }   if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
Line 1901  sub end_dl { Line 2082  sub end_dl {
     $currentstring.=' '.$element.' ';      $currentstring.=' '.$element.' ';
  }   }
  pop(@Apache::londefdef::description);   pop(@Apache::londefdef::description);
  $currentstring.='\end{description}';     $currentstring.='\end{description}';
  delete($Apache::londefdef::DD[$Apache::londefdef::DL]);   delete($Apache::londefdef::DD[$Apache::londefdef::DL]);
  delete($Apache::londefdef::DT[$Apache::londefdef::DL]);   delete($Apache::londefdef::DT[$Apache::londefdef::DL]);
  delete($Apache::londefdef::seenDT[$Apache::londefdef::DL]);   delete($Apache::londefdef::seenDT[$Apache::londefdef::DL]);
  $Apache::londefdef::DL--;   $Apache::londefdef::DL--;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1915  sub start_dt { Line 2096  sub start_dt {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring='';      my $currentstring='';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }   if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
  if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }   if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
  $Apache::londefdef::DT[-1]++;   $Apache::londefdef::DT[-1]++;
  $Apache::londefdef::seenDT[-1]=1;   $Apache::londefdef::seenDT[-1]=1;
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1930  sub end_dt { Line 2111  sub end_dt {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($Apache::londefdef::DT[-1]) {   if ($Apache::londefdef::DT[-1]) {
     my $data=&item_cleanup();      my $data=&item_cleanup();
     push(@{$Apache::londefdef::description[-1]},'\item['.$data.'] \strut \vskip 0mm');      push(@{$Apache::londefdef::description[-1]},'\item['.$data.'] \strut \vskip 0mm');
     $Apache::londefdef::DT[-1]--;      $Apache::londefdef::DT[-1]--;
  }   }
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 sub item_cleanup {  sub item_cleanup {
     my $item=&Apache::lonxml::endredirection();      my $item=&Apache::lonxml::endredirection();
     $item=~s/\\begin{center}//g;      $item=~s/\\begin\{center}//g;
     $item=~s/\\end{center}//g;      $item=~s/\\end\{center}//g;
     return $item;      return $item;
 }  }
   
Line 1953  sub start_dd { Line 2134  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' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }   if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
  if ($Apache::londefdef::DD[-1]) { &end_dd(@_);}   if ($Apache::londefdef::DD[-1]) { &end_dd(@_);}
Line 1964  sub start_dd { Line 2145  sub start_dd {
  $Apache::londefdef::description[-1]->[-1].=' \strut ';   $Apache::londefdef::description[-1]->[-1].=' \strut ';
  $Apache::londefdef::DD[-1]++;   $Apache::londefdef::DD[-1]++;
  &Apache::lonxml::startredirection();   &Apache::lonxml::startredirection();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1972  sub end_dd { Line 2153  sub end_dd {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  $Apache::londefdef::description[-1]->[-1].=   $Apache::londefdef::description[-1]->[-1].=
     &Apache::lonxml::endredirection().' \vskip 0mm ';      &Apache::lonxml::endredirection().' \vskip 0mm ';
Line 1984  sub end_dd { Line 2165  sub end_dd {
 #-- <table> tag (end tag required)  #-- <table> tag (end tag required)
 #       <table> also ends any prior <p> that is not closed.  #       <table> also ends any prior <p> that is not closed.
 #               but, unless I allow <p>'s to nest, that's the  #               but, unless I allow <p>'s to nest, that's the
 #               only way I could think of to allow <p> in   #               only way I could think of to allow <p> in
 #               <tr> <th> bodies  #               <tr> <th> bodies
 #  #
 #list of supported attributes: border,width,TeXwidth  #list of supported attributes: border,width,TeXwidth,TeXtheme
   #                              align
 sub start_table {  sub start_table {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $textwidth = '';      my $textwidth = '';
     my $currentstring = &end_p();      my $currentstring = &end_p();
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  push(@Apache::londefdef::table, {});    &disable_para(); # Can't have paras in a table.
  $Apache::londefdef::table[-1]{'row_number'} = -1;  
         #maximum table's width (default coincides with text line length)  
  if ($#Apache::londefdef::table==0) {  
     $textwidth=&recalc($env{'form.textwidth'}); #result is always in mm  
     $textwidth=~/(\d+\.?\d*)/;  
     $textwidth=0.85*$1; #accounts "internal" LaTeX space for table frame  
  } else {  
     if ($Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]=~/\d/) {  
  #the maximum width of nested table is determined by LATeX width of parent cell  
  $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];  
  }  
     }  
  }  
   
  # width either comes forced from the TeXwidth or the width parameters.   #  Get the parameters that we can do something about:
  # in either case it can be a percentage or absolute width.  
  # in the width case we ignore absolute width   
  my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);  
  if (!defined($TeXwidth)) {  
     my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,  
        $safeeval,undef,1);  
     if ($htmlwidth =~ /%/) {  
  $TeXwidth = $htmlwidth;  
     } else {   
  $TeXwidth = $textwidth;  
     }  
  }  
  # if the width is specified as a % it is converted to an absolute width.  
  # otherwise.. just plugged right in the hash  
   
  if ($TeXwidth=~/%/) {   my $border = &Apache::lonxml::get_param('border', $parstack, $safeeval, undef, 0);
     $TeXwidth=~/(\d+)/;   my $width  = &Apache::lonxml::get_param('TeXwidth', $parstack, $safeeval, undef, 0);
             $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;   my $theme  = &Apache::lonxml::get_param('TeXtheme', $parstack, $safeeval, undef, 0);
  } else {   my $align  = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef, 0);
     $Apache::londefdef::table[-1]{'width'}=$TeXwidth;   my $cell_border = &Apache::lonxml::get_param('rules', $parstack, $safeeval, undef, 0);
  }  
         #  In the end, however the table width cannot be wider than $textwidth...  
   
  if ($Apache::londefdef::table[-1]{'width'} > $textwidth) {  
     $Apache::londefdef::table[-1]{'width'} = $textwidth;  
  }  
         #table's border  
  my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval);   
         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);  
  unless (defined $border) { $border = 0; }  
  if ($border) {   
     $Apache::londefdef::table[-1]{'hinc'} = '\hline ';   
     $Apache::londefdef::table[-1]{'vinc'} = '&';   
     $Apache::londefdef::table[-1]{'vvinc'} = '|';  
  } else {  
     $Apache::londefdef::table[-1]{'hinc'} = '';   
     $Apache::londefdef::table[-1]{'vinc'} = '&';   
     $Apache::londefdef::table[-1]{'vvinc'} = '';  
  }  
  if ($#Apache::londefdef::table==0) {  
     #    Note that \newline seems to destroy the alignment envs.  
     # $Apache::londefdef::table[-1]{'output'}='\strut\newline\strut\setlength{\tabcolsep}{1 mm}';  
     $Apache::londefdef::table[-1]{'output'}='\strut'.'\\\\'."\n".'\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}';  
   
    # The only thing that needs any figuring out is the width.. and then only if it is
    # a percent. If not it's assumed to be some valid TeX measurement unit e.g. 3.0cm
    #
   
     }   my $table = new Apache::lontable();
     return $currentstring;   if ((defined $border) && ($border > 0)) {
 }   #    &Apache::lonnet::logthis("Turning on table borders: $border");
        $table->table_border(1);
 sub end_table {      if (!defined $cell_border) {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;   $table->cell_border(1); # Default for rules is all if rules not defined.
     my $currentstring = '';  
     if ($target eq 'web' || $target eq 'webgrade') {  
  $currentstring = $token->[2];       
     } elsif ($target eq 'tex') {  
  my $border =  &Apache::lonxml::get_param('border',$parstack,$safeeval);  
  my $inmemory = '';  
  my $output = '';  
  my $WARNING='';  
         #width of columns from TeXwidth attributes  
   
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
     for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {  
  if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]<$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]) {  
     $Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]=$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn];  
  }  
     }      }
  }   }
         #free space and number of empty columns  
  my ($available_space,$empty_columns)=($Apache::londefdef::table[-1]{'width'},0);   if ((defined $cell_border)) {
  if ($#Apache::londefdef::table ne 0) {$available_space=0.9*$available_space;}       if ($cell_border eq 'all') {
  for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {   $table->cell_border(1);
     if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]==0) {      } elsif ($cell_border eq 'rows') {
  $empty_columns++;   $table->cell_border(2);
       } elsif ($cell_border eq 'cols') {
    $table->cell_border(3);
       } elsif($cell_border eq 'groups') {
    $table->cell_border(4);
     } else {      } else {
  $available_space=$available_space-$Apache::londefdef::table[-1]{'TeXlen'}[0][$jn];   $table->cell_border(0);
     }      }
  }   }
    if (defined $theme) {
         #boundaries for contents columns      $table->theme($theme);
  my @min_len=();#columns can not be narrower   
  my @max_len=();#maximum length of column  
  my $avg_max;  
  my $avg_min;  
  my $counter_cols = $Apache::londefdef::table[-1]{'counter_columns'};  
  for (my $jn=0;$jn<=$counter_cols; $jn++) {  
  my ($localmin,$localmax)=(0,0);  
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
     if ($localmin<$Apache::londefdef::table[-1]{'minlen'}[$in][$jn]) {  
  $localmin=$Apache::londefdef::table[-1]{'minlen'}[$in][$jn];  
     }  
     if ($localmax<$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn]) {  
  $localmax=$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn];  
     }  
  }  
  push @min_len, $localmin;  
  push @max_len, $localmax;  
  $avg_max = $localmax + $avg_max;  
  $avg_min = $localmin + $avg_min;  
  }  
  # Does not really matter what the average max/min are if there are no cols.  
  # and this prevents div 0 in that case.  
   
  if ($counter_cols != 0) {  
     $avg_max = $avg_max/$counter_cols;  
     $avg_min = $avg_min/$counter_cols;  
  }   }
    if (defined $align) {
       $table->alignment($align);
  #  I don't think the below is needed.. but just in case:  
   
  if ($avg_min > $avg_max) {  
     my $temp = $avg_min;  
     $avg_min = $avg_max;  
     $avg_max = $temp;  
  }   }
   
    # Missing width is most of page width
   
  for (my $jn=0;$jn<=$counter_cols;$jn++) {   if (!(defined $width)) {
     my $localmin=0,;      $width = '70%';
     for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
  if ($localmin<$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn]) {  
     $localmin=$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn];  
  }  
     }  
     if ($max_len[$jn]<$localmin) {  
  $max_len[$jn]=$localmin;  
      $Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;  
     }#object size is bigger  
     if ($min_len[$jn]<$localmin) {  
  $min_len[$jn]=$localmin;  
  $Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;  
     }#object size is bigger  
     if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]!=0) {  
  $min_len[$jn]=0;  
  $max_len[$jn]=0;  
     }  
     #  Spans seem to be really bothered by max/min = 0.  So if we have one  
     #  make it an average joe max/min.  
       
     if ($max_len[$jn] == 0) {  
  $max_len[$jn] = $avg_max;  
     }  
     if ($min_len[$jn] == 0) {  
  $min_len[$jn] = $avg_min;  
     }  
   
  }  
        #final adjustment of column width  
  my @fwidth=@{$Apache::londefdef::table[-1]{'TeXlen'}[0]};#final width array  
  my @adjust=();  
         #step 1. adjustment by maximum value  
  my $space_needed=0;  
  for (my $jn=0;$jn<=$#max_len;$jn++) {  
     $space_needed=$space_needed+$max_len[$jn];  
  }  
  if ($space_needed<=$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_needed=0;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  $space_needed+=$min_len[$jn];  
     }  
     if ($space_needed>$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_needed-$available_space)/$how_many_to_scale;  
     foreach my $jn (@to_scale) {  
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
     $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/;  
     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_needed;  
  my $acsessive=0;  
  for (my $jn=0;$jn<=$#min_len;$jn++) {  
     $adjust[$jn]=$min_len[$jn]*$enlarge_coef;  
     if ($adjust[$jn]>$max_len[$jn]) {  
  $fwidth[$jn]=$max_len[$jn];  
  $acsessive=$acsessive+$adjust[$jn]-$max_len[$jn];  
  $adjust[$jn]=0;  
   
     }  
  }  
  if ($acsessive>0) {  
  #we have an excess of space and can redistribute it  
     my $notempty_columns=0;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  if ($adjust[$jn]!=0) {  
     $notempty_columns++;  
  }  
     }  
     my $per_column=$acsessive/$notempty_columns;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  if ($adjust[$jn]!=0) {  
     $adjust[$jn]+=$per_column;  
     $fwidth[$jn]=$adjust[$jn];  
  }  
     }  
  } else {  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  $fwidth[$jn]=$adjust[$jn];  
     }  
  }  
     }  
  }   }
         # use all available width or specified width as if not specified,  
  # the specified width gets defaulted to the available width.  
   
  my $current=0;    # If a percentage, need to calculate what this means in terms of
  for (my $i=0;$i<=$#fwidth;$i++) {     # page width:
     $current+=$fwidth[$i];  
  }   if ($width =~ /%$/) {
  if ($current == 0) {      my $textwidth = &recalc($env{'form.textwidth'});  # Page width in mm.
             $current = $Apache::londefdef::table[-1]{'width'};      $width =~ s/%//;
         }      $width = $width * $textwidth / 100.0;
  my $coef=$Apache::londefdef::table[-1]{'width'}/$current;      $width .= " mm";
  for (my $i=0;$i<=$#fwidth;$i++) {        $table->width($width);
     $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;  
  }   }
   
    push(@Apache::londefdef::table, $table);
           $currentstring.=' \keephidden{NEW TABLE ENTRY}';
   
  #construct header of the table      }
  my $header_of_table = '{'.$Apache::londefdef::table[-1]{'vvinc'};      return $currentstring;
  for (my $in=0;$in<=$#fwidth;$in++) {  }
     $header_of_table.='p{'.$fwidth[$in].' mm}'.$Apache::londefdef::table[-1]{'vvinc'};  
  }  
  $header_of_table .= '}';  
   
  #fill the table  
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
     my $have_rowspan = 0;  
     for (my $jn=0;$jn<=$#fwidth;$jn++) {  
   
  #-----------------------------------------------------------  
                 #   I think this order of doing things will ensure that  
  #   single rowspan, columspan and combined row/colspans will  
                 #   work correctly.  LaTeX is delicate here.  
  #    RF.  
   
  # Start a rowspan if necessary:  
   
  my $primary_col_width = $fwidth[$jn]; # Width of primary column.  
  my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];  
  my $colspan = $Apache::londefdef::table[-1]{'colspan'}[$in][$jn];  
  #  
  #  Do the appropriate magic if this has a colspan  
  #   
   
  my $border_char = "";  
  if ($border) {  
     $border_char = "|";  
  }  
  my $spanwidth = 0;  
  if ($colspan > 1) {  
     for (my $spancol = $jn; $spancol < $jn + $colspan; $spancol++) {  
  $spanwidth += $fwidth[$spancol];  
     }  
     $output .= '\multicolumn{'.  
  $colspan  
  ."}";  
     if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {  
  $output .= '{'.$border_char.'c'.$border_char.'}{';  
     } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {  
  $output .= '{'.$border_char.'r'.$border_char.'}{';  
     }  
     else {  
  $output .= '{'.$border_char."p{$spanwidth mm}".$border_char.'}{';  
     }  
       
  } else {  
     $spanwidth = $primary_col_width; # If no span width will be just colwidth  
  }  
   
  # Rowspan... if colspan is 1, and there's an alignment we'll need  
  # to kick in a multicolumn in order to get the alignment spec.  
  # this must precede the multirow or LaTex gets quite upset.  
  # Naturally if colspan > 1 we've already done that above ^  
  #  
  my $multirow_aligned = 0;  
  if ($rowspan > 1) {  
     if ($colspan == 1) {  
  if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {  
     $output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{';  
     $multirow_aligned = 1;  
  } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {  
     $output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{';  
     $multirow_aligned = 1;  
  }  
     }  
     $have_rowspan++;  
     if ($multirow_aligned) {  
  $output .= '\multirow{'.$rowspan.'}[0]{*}{';  
     } else {  
  $output .= '\multirow{'.$rowspan."}[0]{$spanwidth mm}{";  
     }  
       
     $Apache::londefdef::table[-1]{'content'}[$in][$jn] =~  
  s{^\s*\\par\s*}{};  
     $Apache::londefdef::table[-1]{'content'}[$in][$jn] =~  
  s{\s*\\vskip\s*0pt\s*$}{};  
     
     #  
     # If we did not throw in a multicolumn to align, then add   
     # an extra {  
     # so we close correctly without having to keep additional state  
     # around  
     #  
     if (!$multirow_aligned) {  
  $output .= '{';  
     }  
  }  
  if (($rowspan eq '^') || ($rowspan eq '_')) {  
     $have_rowspan++;  
  }  
     #--------------------------------------------------------------  
   
   
  # For right and center alignment of single cells.  
  # we are going to use a multicolumn with a span of 1 to specify alignment.  
  #  
  if ($colspan == 1  && $rowspan == 1) {  
     if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {  
  $output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{';  
     } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {  
  $output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{';  
     }  
  }  
   
  $output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn];  
   
  if (($colspan == 1 && $rowspan == 1)   &&  
     (($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') ||  
      ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r'))) {  
     $output .= '}';  
  }  
   
  # Close off any open multirow:  
   
  if ($rowspan > 1) {  
     $output .= '}}';  
  }  
  #  Close off the colspan...  
  #  
  if ($colspan > 1)  {  
     $output .= '}';  
     $jn += $colspan-1; # Adjust for number of rows really left.  
  }  
                 if ($jn!=$#fwidth) {$output.=' '.$Apache::londefdef::table[-1]{'vinc'};}  
     }  
     #  If have_rowspan > 0, and borders are on, then   
     #  we need to do more than put an \hline at the bottom of row.  
     #  we need to do the appropriate \cline to ensure that  
     #  the spanned rows don't have \hlines through them.  
   
     if (($Apache::londefdef::table[-1]{'hinc'} =~ /\\hline/) && $have_rowspan) {  
  $output .= ' \\\\ ';  
  for (my $jn=0; $jn<=$#fwidth;$jn++) {  
     my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];  
     if ($rowspan ne "^") {  
  if (($rowspan <= 1) || ($rowspan eq '_')) {  
     my $column = $jn+1;  
     $output .= '\cline{'.$column.'-'.$column.'} ';  
  }  
     }  
  }  
   
     } else {  
  $output.=' \\\\ '.$Apache::londefdef::table[-1]{'hinc'}.' ';  
     }  
  }  
  # Note that \newline destroys alignment env's produced  by e.g. <div>  
  # $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut\newline\strut ';  
  $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut'.'\\\\'."\n".'\strut ';  
  if ($#Apache::londefdef::table > 0) {      
     my $inmemory = $Apache::londefdef::table[-1]{'output'};  
     # Figure out max/and min width  by summing us and then  
     # apply that to the current column of the table we nest in  
     # if it's larger than the current width or the current width  
     # is undefined.  
     #  
     my $min_nested_width = 0;  
     my $max_nested_width = 0;  
     for (my $col = 0; $col <= $Apache::londefdef::table[-1]{'counter_columns'}; $col++) {  
  $min_nested_width +=  $min_len[$col];  
  $max_nested_width +=  $max_len[$col];  
   
     }  
     # Fudge in an extra 5 mm for borders etc:  
       
     $min_nested_width += 5;  
     $max_nested_width += 5;  
   
     my $outer_column = $Apache::londefdef::table[-2]{'counter_columns'};  
     my $outer_row    = $Apache::londefdef::table[-2]{'row_number'};  
     if ($min_nested_width > $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column]) {  
  $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column] = $min_nested_width;  
     }  
     if ($max_nested_width > $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column]) {  
  $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column] = $max_nested_width;  
     }  
   
     pop @Apache::londefdef::table;  sub end_table {
     push @{$Apache::londefdef::table[-1]{'include'}}, $inmemory;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  } else {      my $currentstring = '';
     $currentstring .= $Apache::londefdef::table[-1]{'output'};      if ($target eq 'web' || $target eq 'webgrade') {
     pop @Apache::londefdef::table;   $currentstring = $token->[2];
     undef @Apache::londefdef::table;      } elsif ($target eq 'tex') {
  }  
   
    my $table = pop(@Apache::londefdef::table);
    my $t     = $table->generate();
    # &Apache::lonnet::logthis("Generating string");
    $currentstring = $t->generate_string();
    # &Apache::lonnet::logthis("Generated: $currentstring");
    &enable_para();
   
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 2498  sub start_tr { Line 2268  sub start_tr {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
   
    my $align = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef, 1);
    $Apache::londefdef::table[-1]->start_row();
   
    if ($align ne '') {
       $Apache::londefdef::table[-1]->configure_row({default_halign => $align});
    }
   
    #---------------------------------------------------------------
    # Old table code.
    #---------------------------------------------------------------
   
    if (0) {
  $Apache::londefdef::table[-1]{'row_number'}++;   $Apache::londefdef::table[-1]{'row_number'}++;
  my $alignchar=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);   my $alignchar=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  if ($alignchar ne '') {   if ($alignchar ne '') {
Line 2518  sub start_tr { Line 2301  sub start_tr {
  push @ {$Apache::londefdef::table[-1]{'minlen'}}, [];   push @ {$Apache::londefdef::table[-1]{'minlen'}}, [];
  push @ {$Apache::londefdef::table[-1]{'maxlen'}}, [];   push @ {$Apache::londefdef::table[-1]{'maxlen'}}, [];
  push @ {$Apache::londefdef::table[-1]{'content'}}, [];   push @ {$Apache::londefdef::table[-1]{'content'}}, [];
     }       }
       }
     return $currentstring;      return $currentstring;
 }  }
           
 sub end_tr {  sub end_tr {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close any pending <p> in the row.      my $currentstring = &end_p(); # Close any pending <p> in the row.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];        $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
   
    # In case the user is missing a </td> or </th> tag:
   
  if ($Apache::londefdef::TD_redirection) {   if ($Apache::londefdef::TD_redirection) {
     &end_td_tex($parstack,$parser,$safeeval);          &end_td_tex($parstack,$parser,$safeeval);
    }
    $Apache::londefdef::table[-1]->end_row();
   
    #-----------------------------------------------
    # Old table code
    #-----------------------------------------------
   
    if (0) {
    if ($Apache::londefdef::TD_redirection) {
       &end_td_tex($parstack,$parser,$safeeval);
  }   }
  # Counter columns must be the maximum number of columns seen   # Counter columns must be the maximum number of columns seen
  # in the table so far so:   # in the table so far so:
  if ($Apache::londefdef::table[-1]{'prior_columns'} > $Apache::londefdef::table[-1]{'counter_columns'}) {   if ($Apache::londefdef::table[-1]{'prior_columns'} > $Apache::londefdef::table[-1]{'counter_columns'}) {
     $Apache::londefdef::table[-1]{'counter_columns'} = $Apache::londefdef::table[-1]{'prior_columns'};      $Apache::londefdef::table[-1]{'counter_columns'} = $Apache::londefdef::table[-1]{'prior_columns'};
  }   }
       }
   
   
     }      }
Line 2548  sub start_td { Line 2345  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' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::TD_redirection = 1;   $Apache::londefdef::TD_redirection = 1;
  &tag_check('tr','td',$tagstack,$parstack,$parser,$safeeval);   &tag_check('tr','td',$tagstack,$parstack,$parser,$safeeval);
     }       }
     return $currentstring;      return $currentstring;
 }     }
       
 sub tag_check {  sub tag_check {
     my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
     my @ar=@$parstack;       my @ar=@$parstack;
     for (my $i=$#ar-1;$i>=0;$i--) {      for (my $i=$#ar-1;$i>=0;$i--) {
  if (lc($$tagstack[$i]) eq $good_tag) {   if (lc($$tagstack[$i]) eq $good_tag) {
     &start_td_tex($parstack,$parser,$safeeval);      &start_td_tex($parstack,$parser,$safeeval);
Line 2572  sub tag_check { Line 2369  sub tag_check {
     }      }
     return '';      return '';
 }  }
    
   #
   #  Factor out cell configuration hash generation:
   #
   
   sub cell_config_hash {
       my ($align, $rowspan, $colspan, $width) = @_;
       if ($rowspan ne '') {
           $rowspan =~ s/^\s+|\s+$//g;
       }
       if ($colspan ne '') {
           $colspan =~ s/^\s+|\s+$//g;
       }
       my %config;
       if ($align ne '') {
    $config{'halign'} = $align;
       }
       if (($colspan =~ /^\d+$/) && ($colspan > 0)) {
    $config{'colspan'} = $colspan;
       }
       if (($rowspan =~ /^\d+$/) && ($rowspan > 0)) {
    $config{'rowspan'} = $rowspan;
       }
       if ($width ne '') {
    $config{'width'} = $width;
       }
       return \%config;
   }
   
 sub start_td_tex {  sub start_td_tex {
     my ($parstack,$parser,$safeeval) = @_;      my ($parstack,$parser,$safeeval) = @_;
   
       # At this stage, an empty cell is created with the
       # appropriate rowspan/colspan and alignment
       # attributes, but empty of text.  end_td_tex will
       # fetch the contents from the recursive parse and
       # fill the cell with them:
       my $align   = &Apache::lonxml::get_param('align', $parstack, $safeeval);
       my $rowspan = &Apache::lonxml::get_param('rowspan', $parstack, $safeeval);
       my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval);
       my $width   = &Apache::lonxml::get_param('TeXwidth', $parstack, $safeeval);
       my $config = &cell_config_hash($align, $rowspan, $colspan, $width);
   
       my $table = $Apache::londefdef::table[-1];
       $table->add_cell('', $config);
   
   
       #------------------------------------------------
       #  Old table code.
       #------------------------------------------------
   
       if (0) {
   
     my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);      my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
     if ($alignchar eq '') {      if ($alignchar eq '') {
  $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];   $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
Line 2587  sub start_td_tex { Line 2434  sub start_td_tex {
  $current_length=~/(\d+\.?\d*)/;   $current_length=~/(\d+\.?\d*)/;
  push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
     }      }
       }
     &Apache::lonxml::startredirection();      &Apache::lonxml::startredirection();
     return '';      return '';
 }  }
   
 sub end_td_tex {  sub end_td_tex {
   
       my $text = &Apache::lonxml::endredirection();
       my $table = $Apache::londefdef::table[-1];
       $table->append_cell_text($text);
   
       #-------------------------------------------------
       # Old table code
       #-------------------------------------------------
   
       if (0) {
     my ($parstack,$parser,$safeeval) = @_;      my ($parstack,$parser,$safeeval) = @_;
     my $current_row    = $Apache::londefdef::table[-1]{'row_number'};      my $current_row    = $Apache::londefdef::table[-1]{'row_number'};
     my $current_column = $Apache::londefdef::table[-1]{'counter_columns'};       my $current_column = $Apache::londefdef::table[-1]{'counter_columns'};
     my $data = &Apache::lonxml::endredirection();      my $data = &Apache::lonxml::endredirection();
   
     #  The rowspan array of the table indicates which cells are part of a span.      #  The rowspan array of the table indicates which cells are part of a span.
Line 2604  sub end_td_tex { Line 2462  sub end_td_tex {
     #  If this and subsequent cells are part of a rowspan, we must      #  If this and subsequent cells are part of a rowspan, we must
     #  push along the row until we find one that is not.      #  push along the row until we find one that is not.
   
     while ((defined $Apache::londefdef::table[-1]{'rowspan'}[$current_row] [$current_column])       while ((defined $Apache::londefdef::table[-1]{'rowspan'}[$current_row] [$current_column])
    && ($Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column] =~ /[\^\_]/)) {     && ($Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column] =~ /[\^\_]/)) {
  # Part of a span.   # Part of a span.
  push @ {$Apache::londefdef::table[-1]{'content'}[-1]}, '';   push @ {$Apache::londefdef::table[-1]{'content'}[-1]}, '';
  $current_column++;   $current_column++;
     }      }
     $Apache::londefdef::table[-1]{'counter_columns'} = $current_column;      $Apache::londefdef::table[-1]{'counter_columns'} = $current_column;
      
   
     # Get the column and row spans.      # Get the column and row spans.
     # Colspan can be done via \multicolumn if I can figure out the data structs.      # Colspan can be done via \multicolumn if I can figure out the data structs.
Line 2687  sub end_td_tex { Line 2545  sub end_td_tex {
  push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
  push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     }      }
     $data=~s/\\\\\s*$//;       $data=~s/\\\\\s*$//;
  } else {     } else {
     $data=~s/^\s+(\S.*)/$1/;       $data=~s/^\s+(\S.*)/$1/;
     $data=~s/(.*\S)\s+$/$1/;      $data=~s/(.*\S)\s+$/$1/;
     $data=~s/(\s)+/$1/;      $data=~s/(\s)+/$1/;
     my ($current_length,$min_length)=(0,0);      my ($current_length,$min_length)=(0,0);
Line 2720  sub end_td_tex { Line 2578  sub end_td_tex {
  push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;   push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
  push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;   push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
     }      }
  }           }
     }      }
     # Substitute all of the tables nested in this cell in their appropriate places.      # Substitute all of the tables nested in this cell in their appropriate places.
   
   
     my $nested_count = $#{$Apache::londefdef::table[-1]{'include'}}; # This one is constant...      my $nested_count = $#{$Apache::londefdef::table[-1]{'include'}}; # This one is constant...
     for (my $in=0; $in<=$nested_count; $in++) {          for (my $in=0; $in<=$nested_count; $in++) {
  my $nested = shift @{$Apache::londefdef::table[-1]{'include'}};   my $nested = shift @{$Apache::londefdef::table[-1]{'include'}};
  $nested =~ s/\\end\{tabular\}\\strut\\\\/\\end\{tabular\}/;   $nested =~ s/\\end\{tabular\}\\strut\\\\/\\end\{tabular\}/;
  # $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;   # $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
Line 2756  sub end_td_tex { Line 2614  sub end_td_tex {
   
     }      }
   
       }
   
     return '';      return '';
 }  }
Line 2765  sub end_td { Line 2623  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' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
         $Apache::londefdef::TD_redirection =0;          $Apache::londefdef::TD_redirection =0;
  &end_td_tex($parstack,$parser,$safeeval);   &end_td_tex($parstack,$parser,$safeeval);
Line 2778  sub start_th { Line 2636  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' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $Apache::londefdef::TD_redirection = 1;   $Apache::londefdef::TD_redirection = 1;
  &tagg_check('tr','th',$tagstack,$parstack,$parser,$safeeval);   &tagg_check('tr','th',$tagstack,$parstack,$parser,$safeeval);
     }       }
     return $currentstring;      return $currentstring;
 }     }
       
 sub tagg_check {  sub tagg_check {
     my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
     my @ar=@$parstack;       my @ar=@$parstack;
     for (my $i=$#ar-1;$i>=0;$i--) {      for (my $i=$#ar-1;$i>=0;$i--) {
  if (lc($$tagstack[$i]) eq $good_tag) {   if (lc($$tagstack[$i]) eq $good_tag) {
     &start_th_tex($parstack,$parser,$safeeval);      &start_th_tex($parstack,$parser,$safeeval);
Line 2802  sub tagg_check { Line 2660  sub tagg_check {
     }      }
     return '';      return '';
 }  }
    
 sub start_th_tex {  sub start_th_tex {
     my ($parstack,$parser,$safeeval) = @_;      my ($parstack,$parser,$safeeval) = @_;
   
       my $alignment = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef,1);
       my $rowspan  =  &Apache::lonxml::get_param('rowspan', $parstack, $safeeval, undef, 1);
       my $colspan  =  &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 1);
   
       my $config   = cell_config_hash($alignment, $rowspan, $colspan);
       my $table    = $Apache::londefdef::table[-1];
       $table->add_cell('\textbf{', $config);
   
       #-------------------------------------------------------------------------------------
       #
       #  Old table code.
       #
       #--------------------------------------------------------------------------------------
   
       if (0) {
   
   
     my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);      my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
     if ($alignchar eq '') {      if ($alignchar eq '') {
  $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];   $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
Line 2817  sub start_th_tex { Line 2693  sub start_th_tex {
  $current_length=~/(\d+\.?\d*)/;   $current_length=~/(\d+\.?\d*)/;
  push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
     }      }
       }
   
       # Accept xml until the </th> tag.
   
     &Apache::lonxml::startredirection();      &Apache::lonxml::startredirection();
     return '';      return '';
 }  }
   
 sub end_th_tex {  sub end_th_tex {
     my ($parstack,$parser,$safeeval) = @_;      my ($parstack,$parser,$safeeval) = @_;
   
       my $table = $Apache::londefdef::table[-1];
       my $text  = &Apache::lonxml::endredirection();
       $table->append_cell_text($text.'}');
   
       #-----------------------------------------------------------------------------
       #  Old table code:
       #-----------------------------------------------------------------------------
   
       if (0) {
     my $current_row = $Apache::londefdef::table[-1]{'row_number'};      my $current_row = $Apache::londefdef::table[-1]{'row_number'};
     my $data=&Apache::lonxml::endredirection();      my $data=&Apache::lonxml::endredirection();
     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);      my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
Line 2849  sub end_th_tex { Line 2739  sub end_th_tex {
     push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;      push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
     push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
  } else {     } else {
     $data=~s/^\s+(\S.*)/$1/;       $data=~s/^\s+(\S.*)/$1/;
     $data=~s/(.*\S)\s+$/$1/;      $data=~s/(.*\S)\s+$/$1/;
     $data=~s/(\s)+/$1/;      $data=~s/(\s)+/$1/;
     my ($current_length,$min_length)=(0,0);      my ($current_length,$min_length)=(0,0);
Line 2879  sub end_th_tex { Line 2769  sub end_th_tex {
     push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;      push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
     push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;      push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
  }           }
     }      }
  for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {            for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {
     $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;      $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
  }   }
     #make data bold      #make data bold
     $data='\textbf{'.$data.'}';      $data='\textbf{'.$data.'}';
     push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;      push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
       }
     return'';      return'';
 }  }
   
Line 2894  sub end_th { Line 2785  sub end_th {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close any open <p> in the row.      my $currentstring = &end_p(); # Close any open <p> in the row.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];        $currentstring .= $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
         $Apache::londefdef::TD_redirection =0;          $Apache::londefdef::TD_redirection =0;
  &end_th_tex($parstack,$parser,$safeeval);   &end_th_tex($parstack,$parser,$safeeval);
     }      }
     return $currentstring;      return $currentstring;
 }  }
        
 #-- <img> tag (end tag forbidden)  #-- <img> tag (end tag forbidden)
 #  #
 #  Render the <IMG> tag.  #  Render the <IMG> tag.
 #     <IMG> has the following attributes (in addition to the   #     <IMG> has the following attributes (in addition to the
 #     standard HTML ones:  #     standard HTML ones:
 #      TeXwrap   - Governs how the tex target will try to wrap text around  #      TeXwrap   - Governs how the tex target will try to wrap text around
 #                  horizontally aligned images.  #                  horizontally aligned images.
 #      TeXwidth  - The width of the image when rendered for print (mm).  #      TeXwidth  - The width of the image when rendered for print (mm).
 #      TeXheight - The height of the image when rendered for print (mm)  #      TeXheight - The height of the image when rendered for print (mm)
 #         (Note there seems to also be support for this as a % of page size)  #         (Note there seems to also be support for this as a % of page size)
 #        #
 sub start_img {  sub start_img {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,      my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,
  undef,1);   undef,1);
     if (! $src &&       if (! $src &&
  ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex')   ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex')
  ) {    ) {
  my $inside = &Apache::lonxml::get_all_text("/img",$parser,$style);   my $inside = &Apache::lonxml::get_all_text("/img",$parser,$style);
  return '';   return '';
     }      }
     &Apache::lonxml::extlink($src);      unless ($src =~ m{^data\:image/gif;base64,}) {
           &Apache::lonxml::extlink($src);
       }
     my $currentstring = '';      my $currentstring = '';
     my $scaling = .3;      my $scaling = .3;
   
    # Render unto browsers that which are the browser's...     # Render unto browsers that which are the browser's...
   
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  if ($env{'browser.imagesuppress'} ne 'on') {          my $enc = ('yes' eq
     my $enc = ('yes' eq                      lc(&Apache::lonxml::get_param('encrypturl',$parstack,
        lc(&Apache::lonxml::get_param('encrypturl',$parstack,                        $safeeval)));
      $safeeval)));          unless ($src =~ m{^data\:image/gif;base64,}) {
     $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src},              $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src},
  $enc);                              $enc);
  } else {          }
     my $alttag = &Apache::lonxml::get_param('alt',$parstack,$safeeval,  
     undef,1);  
     if (!$alttag) {  
  $alttag = &Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],  
    $src);  
     }  
     $currentstring.='[IMAGE: '.$alttag.']';  
  }  
   
  # and render unto TeX that which is LaTeX  
   
       # and render unto TeX that which is LaTeX
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  #   #
  #  The alignment will require some superstructure to be put around   #  The alignment will require some superstructure to be put around
Line 2955  sub start_img { Line 2839  sub start_img {
  #  simulate the alignments offered by html.   #  simulate the alignments offered by html.
  #   #
  #   #
  my $align = lc(&Apache::lonxml::get_param('align',    my $align = lc(&Apache::lonxml::get_param('align',
   $parstack,    $parstack,
   $safeeval,    $safeeval,
   undef,1));    undef,1));
Line 2965  sub start_img { Line 2849  sub start_img {
  #   #
  &Apache::lonxml::debug("Alignemnt = $align");   &Apache::lonxml::debug("Alignemnt = $align");
  #  LaTeX's image/text wrapping is really bad since it wants to   #  LaTeX's image/text wrapping is really bad since it wants to
  #  make figures float.     #  make figures float.
         #   The user has the optional parameter (applicable only to l/r          #   The user has the optional parameter (applicable only to l/r
  # alignment to use the picins/parpic directive to get wrapped text   # alignment to use the picins/parpic directive to get wrapped text
  # this is also imperfect.. that's why we give them a choice...   # this is also imperfect.. that's why we give them a choice...
Line 2988  sub start_img { Line 2872  sub start_img {
   
  # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src");   # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src");
   
  #if original gif/jpg/png file exist do following:   #if original bmp/gif/jpg/png/svg file exist do following:
  my $origsrc=$src;   my $origsrc=$src;
  my ($path,$file) = &get_eps_image($src);   my ($path,$file) = &get_eps_image($src);
  # &Apache::lonnet::logthis("Image source: $src result: $path $file");   # &Apache::lonnet::logthis("Image source: $src result: $path $file");
Line 3002  sub start_img { Line 2886  sub start_img {
     if ($width_param)  { $size.='width='.$width_param.' mm,'; }      if ($width_param)  { $size.='width='.$width_param.' mm,'; }
     if ($height_param) { $size.='height='.$height_param.' mm]'; }      if ($height_param) { $size.='height='.$height_param.' mm]'; }
     # Default size if not able to extract that (e.g. eps image).      # Default size if not able to extract that (e.g. eps image).
       
     # &Apache::lonnet::logthis("Size = $size");      # &Apache::lonnet::logthis("Size = $size");
       
     $size='['.$size;      $size='['.$size;
     $size=~s/,$/]/;       $size=~s/,$/]/;
     $currentstring .= '\graphicspath{{'.$path.'}}'      $currentstring .= '\graphicspath{{'.$path.'}}'
  .'\includegraphics'.$size.'{'.$file.'} ';   .'\includegraphics'.$size.'{'.$file.'} ';
     my $closure;      my $closure;
     ($currentstring, $closure) = &align_latex_image($align,       ($currentstring, $closure) = &align_latex_image($align,
     $latex_rendering,       $latex_rendering,
     $currentstring,       $currentstring,
     $width_param,       $width_param,
     $height_param);      $height_param);
     $currentstring .= $closure;      $currentstring .= $closure;
   
  } else {   } else {
     &Apache::lonxml::debug("$src does not exist");      &Apache::lonxml::debug("$src does not exist");
     #original image file doesn't exist so check the alt attribute      #original image file doesn't exist so check the alt attribute
     my $alt =       my $alt =
  &Apache::lonxml::get_param('alt',$parstack,$safeeval,undef,1);   &Apache::lonxml::get_param('alt',$parstack,$safeeval,undef,1);
     unless ($alt) {      unless ($alt) {
  $alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);   $alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);
Line 3035  sub start_img { Line 2919  sub start_img {
         my $only = join(',',&Apache::loncommon::filecategorytypes('Pictures'));          my $only = join(',',&Apache::loncommon::filecategorytypes('Pictures'));
  $currentstring .=&Apache::edit::tag_start($target,$token);   $currentstring .=&Apache::edit::tag_start($target,$token);
  $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).   $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).
     &Apache::edit::browse('src',undef,'alt',$only).' '.                           &Apache::edit::browse_or_search('src',undef,'alt',$only,undef,1).
     &Apache::edit::search('src',undef,'alt').'<br />';                           '<br />';
  $currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />';   $currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />';
  $currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5);   $currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5);
  $currentstring .=&Apache::edit::text_arg('height (pixel):','height',$token,5).'<br />';   $currentstring .=&Apache::edit::text_arg('height (pixel):','height',$token,5).'<br />';
Line 3046  sub start_img { Line 2930  sub start_img {
    ['','bottom','middle','top','left','right'],$token,5);     ['','bottom','middle','top','left','right'],$token,5);
  $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',   $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',
    ['', 'none','parbox', 'parpic', 'wrapfigure'], $token, 2);     ['', 'none','parbox', 'parpic', 'wrapfigure'], $token, 2);
           my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);
           my $enc=    &Apache::lonxml::get_param('encrypturl',$parstack,$safeeval);
   
  $currentstring .=&Apache::edit::select_arg('Encrypt URL:','encrypturl',   $currentstring .=&Apache::edit::select_arg('Encrypt URL:','encrypturl',
    ['no','yes'], $token, 2);     ['no','yes'], $token, 2);
           if (($alt=~/\S/) && (lc($enc) eq 'yes')) {
              $currentstring.='<br /><span class="LC_warning">'.&mt('Warning: the description "[_1]" will be available, even for encrypted URL',$alt).'</span><br />';
           }
  $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();   $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
  my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);   my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);
  my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);  
  my $width=  &Apache::lonxml::get_param('width',$parstack,$safeeval);   my $width=  &Apache::lonxml::get_param('width',$parstack,$safeeval);
  my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);   my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);
           my $element = &Apache::edit::get_element('src');
           my $text;
  $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';          if ($token->[2]{'src'}=~/\$/) {
  if ($width) { $currentstring.=' width="'.$width.'" '; }             $text = &mt('Variable image source');
  if ($height) { $currentstring.=' height="'.$height.'" '; }          } elsif ($token->[2]{'src'}=~/\S/) {
  $currentstring .= ' />';     $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';
      if ($width) { $currentstring.=' width="'.$width.'" '; }
      if ($height) { $currentstring.=' height="'.$height.'" '; }
      $currentstring .= ' id="previewimg_'.$element.'" />';
           } else {
              $text = &mt("No image source specified");
           }
           $currentstring .= ' <span id="showimg_'.$element.'">'.$text.'</span>';
     } elsif ($target eq 'modified') {      } elsif ($target eq 'modified') {
  my ($osrc,$owidth,$oheight)=   my ($osrc,$owidth,$oheight)=
     ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});      ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
Line 3079  sub start_img { Line 2975  sub start_img {
  }   }
  if ($osrc ne $nsrc || (!$nwidth && !$nheight)) {   if ($osrc ne $nsrc || (!$nwidth && !$nheight)) {
     # changed image or no size specified,      # changed image or no size specified,
             # if they didn't explicitly change the               # if they didn't explicitly change the
             # width or height use the ones from the image              # width or height use the ones from the image
     if ($iwidth && $iheight) {      if ($iwidth && $iheight) {
  if ($owidth == $nwidth || (!$nwidth && !$nheight)) {   if ($owidth == $nwidth || (!$nwidth && !$nheight)) {
Line 3118  sub end_img { Line 3014  sub end_img {
 #-- <applet> tag (end tag required)  #-- <applet> tag (end tag required)
 sub start_applet {  sub start_applet {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
       
     my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,undef,1);      my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,undef,1);
     &Apache::lonxml::extlink($code);      &Apache::lonxml::extlink($code);
     my $archive=&Apache::lonxml::get_param('archive',$parstack,$safeeval,      my $archive=&Apache::lonxml::get_param('archive',$parstack,$safeeval,
Line 3126  sub start_applet { Line 3022  sub start_applet {
     &Apache::lonxml::extlink($archive);      &Apache::lonxml::extlink($archive);
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  if ($env{'browser.appletsuppress'} ne 'on') {          $currentstring = $token->[4];
     $currentstring = &Apache::lonenc::encrypt_ref($token,  
   {'code'=>$code,  
    'archive'=>$archive}  
   );  
  } else {  
     my $alttag= &Apache::lonxml::get_param('alt',$parstack,  
    $safeeval,undef,1);  
     unless ($alttag) {  
  $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],  
  $code);  
     }  
     $currentstring='[APPLET: '.$alttag.']';  
  }  
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  # Turn off some stuff we can't be inside thank you LaTeX          # Turn off some stuff we can't be inside thank you LaTeX
   
   
  my $restart_sub = 0;   my $restart_sub = 0;
  my $restart_sup = 0;   my $restart_sup = 0;
Line 3153  sub start_applet { Line 3035  sub start_applet {
   
  if (&is_inside_of($tagstack, "sub")) {   if (&is_inside_of($tagstack, "sub")) {
     $restart_sub = 1;      $restart_sub = 1;
     $currentstring .= &end_sub($target, $token, $tagstack,       $currentstring .= &end_sub($target, $token, $tagstack,
        $parstack, $parser, $safeeval);         $parstack, $parser, $safeeval);
  }   }
  if (&is_inside_of($tagstack, "sup")) {   if (&is_inside_of($tagstack, "sup")) {
Line 3185  sub start_applet { Line 3067  sub start_applet {
     $currentstring .= &start_sup($target, $token, $tagstack,      $currentstring .= &start_sup($target, $token, $tagstack,
  $parstack, $parser, $safeeval);   $parstack, $parser, $safeeval);
  }   }
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3195  sub end_applet { Line 3077  sub end_applet {
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];   $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <embed> tag (end tag optional/required)  #-- <embed> tag (end tag optional/required)
 sub start_embed {      sub start_embed {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);      my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
     &Apache::lonxml::extlink($src);      &Apache::lonxml::extlink($src);
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  if ($env{'browser.embedsuppress'} ne 'on') {      $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});
     $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});  
  } else {  
     my $alttag=&Apache::lonxml::get_param  
  ('alt',$parstack,$safeeval,undef,1);  
     unless ($alttag) {  
  $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);  
     }  
     $currentstring='[EMBED: '.$alttag.']';  
  }  
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3225  sub end_embed { Line 3098  sub end_embed {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];               $currentstring = $token->[2];
     } elsif ($target eq 'tex') {        } elsif ($target eq 'tex') {
     }           # ./.
       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <param> tag (end tag forbidden)  #-- <param> tag (end tag forbidden)
 sub start_param {  sub start_param {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     if (&Apache::lonxml::get_param('name',$parstack,      my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval,
    $safeeval,undef,1)=~/^cabbase$/i) {                                            undef,1);
       if ($name =~/^cabbase$/i) {
  my $value=&Apache::lonxml::get_param('value',$parstack,   my $value=&Apache::lonxml::get_param('value',$parstack,
      $safeeval,undef,1);       $safeeval,undef,1);
  &Apache::lonxml::extlink($value);   &Apache::lonxml::extlink($value);
     }       } elsif ($name eq 'flashvars') {
             if (lc(&Apache::lonxml::get_param('type',$parstack,$safeeval,-2,1))
               eq 'application/x-shockwave-flash') {
               my $launcher =
                   &Apache::lonxml::get_param('data',$parstack,$safeeval,-2,1);
               if ($launcher) {
                   &Apache::lonxml::extlink($launcher);
               }
               my $flashvars=&Apache::lonxml::get_param('value',$parstack,
                                                        $safeeval,undef,1);
               if ($flashvars ne '') {
                   foreach my $item (split(/\&/,$flashvars)) {
                       my ($key,$value)=split(/=/,$item,2);
                       if ($key eq 'content') {
                           if ($value ne '') {
                               my ($dir) = ($launcher =~ m{(.+/)[^/]+$});
                               &Apache::lonxml::extlink($dir.$value);
                           }
                       } elsif ($key eq 'thumb') {
                           if ($value ne '') {
                               &Apache::lonxml::extlink($value);
                           }
                       }
                   }
               }
           }
       }
     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);      my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
     &Apache::lonxml::extlink($src);      if ($src ne '') {
           &Apache::lonxml::extlink($src);
       }
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  my %toconvert;   my %toconvert;
  my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);  
  if ($src) { $toconvert{'src'}= $src; }   if ($src) { $toconvert{'src'}= $src; }
  my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval,  
     undef,1);  
  if ($name=~/^cabbase$/i) {   if ($name=~/^cabbase$/i) {
     $toconvert{'value'}=&Apache::lonxml::get_param('value',$parstack,      $toconvert{'value'}=&Apache::lonxml::get_param('value',$parstack,
    $safeeval,undef,1);     $safeeval,undef,1);
  }   }
  $currentstring = &Apache::lonenc::encrypt_ref($token,\%toconvert);   $currentstring = &Apache::lonenc::encrypt_ref($token,\%toconvert);
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3264  sub end_param { Line 3163  sub end_param {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];        $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3301  sub end_allow { Line 3200  sub end_allow {
 sub start_frameset {  sub start_frameset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = ''; # Close any pending para.      my $currentstring = ''; # Close any pending para.
     if ($target eq 'web' || $target eq 'webgrade') {       if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring =    $currentstring =
     &Apache::loncommon::start_page($Apache::londefdef::title,      &Apache::loncommon::start_page($Apache::londefdef::title,
    $Apache::londefdef::head,     $Apache::londefdef::head,
    {'add_entries'    => $token->[2],     {'add_entries'    => $token->[2],
     'no_title'       => 1,  #    'no_title'       => 1,
     'force_register' => 1,      'force_register' => 1,
     'frameset'       => 1,});      'frameset'       => 1,});
   
Line 3331  sub start_xmp { Line 3230  sub start_xmp {
  $currentstring .= $token->[4];   $currentstring .= $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\begin{verbatim}';   $currentstring .= '\begin{verbatim}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3355  sub start_pre { Line 3254  sub start_pre {
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring .= '\begin{verbatim}';   $currentstring .= '\begin{verbatim}';
  &Apache::lonxml::disable_LaTeX_substitutions();   &Apache::lonxml::disable_LaTeX_substitutions();
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3411  sub end_externallink { Line 3310  sub end_externallink {
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <blankspace heigth="">  #-- <blankspace height="">
 sub start_blankspace {  sub start_blankspace {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # closes off any unclosed <p>      my $currentstring = &end_p(); # closes off any unclosed <p>
     if ($target eq 'tex') {      if ($target eq 'tex') {
  my $howmuch = &Apache::lonxml::get_param('heigth',$parstack,$safeeval,undef,1);   my $howmuch = &Apache::lonxml::get_param('height',$parstack,$safeeval,undef,1);
  $currentstring .= '\vskip '.$howmuch.' ';   $currentstring .= '\vskip '.$howmuch.' ';
     }      }
     return $currentstring;      return $currentstring;
Line 3436  sub start_abbr { Line 3335  sub start_abbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3445  sub end_abbr { Line 3344  sub end_abbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3455  sub start_acronym { Line 3354  sub start_acronym {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3464  sub end_acronym { Line 3363  sub end_acronym {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3474  sub start_area { Line 3373  sub start_area {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3483  sub end_area { Line 3382  sub end_area {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3493  sub start_base { Line 3392  sub start_base {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 3502  sub end_base { Line 3401  sub end_base {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3512  sub start_bdo { Line 3411  sub start_bdo {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3521  sub end_bdo { Line 3420  sub end_bdo {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3531  sub start_bgsound { Line 3430  sub start_bgsound {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3540  sub end_bgsound { Line 3439  sub end_bgsound {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3550  sub start_blink { Line 3449  sub start_blink {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3559  sub end_blink { Line 3458  sub end_blink {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3569  sub start_blockquote { Line 3468  sub start_blockquote {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # Close any unclosed <p>      my $currentstring = &end_p(); # Close any unclosed <p>
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     }       }
     if ($target eq 'tex') {      if ($target eq 'tex') {
  $currentstring .= '\begin{quote}';   $currentstring .= '\begin{quote}';
     }      }
Line 3581  sub end_blockquote { Line 3480  sub end_blockquote {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     if ($target eq 'tex') {      if ($target eq 'tex') {
  $currentstring = '\end{quote}';   $currentstring = '\end{quote}';
     }      }
Line 3594  sub start_button { Line 3493  sub start_button {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3603  sub end_button { Line 3502  sub end_button {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3613  sub start_caption { Line 3512  sub start_caption {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3622  sub end_caption { Line 3521  sub end_caption {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3632  sub start_col { Line 3531  sub start_col {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3641  sub end_col { Line 3540  sub end_col {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
 #-- <colgroup> tag (end tag optional)  #-- <colgroup tag (end tag optional)
 sub start_colgroup {  sub start_colgroup {
     my ($target,$token) = @_;      my ($target,$token,$tagstack, $parstack, $parser, $safeeval, $style) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
       if ($target eq 'tex') {
    # TODO: Ensure this tag is in a table:
   
    # Fetch the attributes and build the hash for the
    # call to define_colgroup.
   
    my $span    = &Apache::lonxml::get_param('span',   $parstack, $safeeval);
    my $halign  = &Apache::lonxml::get_param('halign', $parstack, $safeeval);
   
    my %colgroup_params;
    if ($span ne '') {
       $colgroup_params{'span'} = $span;
    }
    if ($halign ne '') {
       $colgroup_params{'halign'} = $halign;
    }
   
    my $table = $Apache::londefdef::table[-1];
    $table->define_colgroup(\%colgroup_params);
   
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3660  sub end_colgroup { Line 3580  sub end_colgroup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
   
 #-- <del> tag (end tag required)  #-- <del> tag (end tag required)
 sub start_del {  sub start_del {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       } elsif ($target eq 'tex') {
    &disable_para();
    $currentstring .= '\st{';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3679  sub end_del { Line 3603  sub end_del {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       } elsif ($target eq 'tex') {
    &enable_para();
    $currentstring = '}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3689  sub start_fieldset { Line 3616  sub start_fieldset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3698  sub end_fieldset { Line 3625  sub end_fieldset {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3708  sub start_frame { Line 3635  sub start_frame {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3717  sub end_frame { Line 3644  sub end_frame {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3727  sub start_iframe { Line 3654  sub start_iframe {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];               my ($src,$url,$query);
     }           if ($token->[2]->{'src'}) {
               $src = $token->[2]->{'src'};
           } elsif ($token->[2]->{'SRC'}) {
               $src = $token->[2]->{'SRC'};
           }
           if ($src) {
               ($url,$query) = ($src =~ /^([^?]+)\??([^?]*)$/);
               if ($query =~ /inhibitmenu=yes/) {
                   $currentstring = $token->[4];
               } else {
                   my $inhibit;
                   if ($url =~ m{^[^/.].*\.x?html?$}) {
                       $inhibit = 1;
                   } elsif ($url =~ m{^/(uploaded|res)/.*\.x?html?$}) {
                       $inhibit = 1;
                   }
                   if ($inhibit) {
                       $currentstring = '<iframe ';
                       foreach my $attrib (@{$token->[3]}) {
                           if (lc($attrib) eq 'src') {
                               if ($query) {
                                   $query.='&amp;inhibitmenu=yes';
                               } else {
                                   $query = 'inhibitmenu=yes';
                               }
                               $currentstring .= 'src="'.$url.'?'.$query.'" ';
                           } else {
                               $currentstring .= lc($attrib).'="'.$token->[2]->{$attrib}.'" ';
                           }
                       }
                       $currentstring =~ s/\s+$//;
                       if ($token->[4] =~ m{/>$}) {
                           $currentstring .= ' />';
                       } else {
                           $currentstring .= '>';
                       }
                   } else {
                       $currentstring = $token->[4];
                   }
               }
               if (($url !~ m{^https?://}) && ($env{'request.course.id'})) {
                   my $docuri = &Apache::lonnet::hreflocation('',$env{'request.filename'});
                   my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   if ($url =~ m{^([^/]|/uploaded/)}) {
                       my $cleanhref = &clean_docs_httpref($url,$docuri,$cdom,$cnum);
                       if ($cleanhref) {
                           &Apache::lonxml::extlink($cleanhref);
                       }
                   } elsif (($url =~ m{/res/$LONCAPA::domain_re/}) && ($docuri =~ m{^\Q/uploaded/$cdom/$cnum/docs/\E})) {
                       if (!&Apache::lonnet::allowed('bre',$url)) {
                           if (&Apache::lonnet::is_on_map($url)) {
                               &Apache::lonxml::extlink($url);
                           }
                       }
                   }
               }
           } else {
               $currentstring = $token->[4];
           }
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3736  sub end_iframe { Line 3723  sub end_iframe {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3746  sub start_ins { Line 3733  sub start_ins {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3755  sub end_ins { Line 3742  sub end_ins {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3765  sub start_isindex { Line 3752  sub start_isindex {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3774  sub end_isindex { Line 3761  sub end_isindex {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3784  sub start_keygen { Line 3771  sub start_keygen {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3793  sub end_keygen { Line 3780  sub end_keygen {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3803  sub start_label { Line 3790  sub start_label {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3812  sub end_label { Line 3799  sub end_label {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3822  sub start_layer { Line 3809  sub start_layer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3831  sub end_layer { Line 3818  sub end_layer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3841  sub start_legend { Line 3828  sub start_legend {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3850  sub end_legend { Line 3837  sub end_legend {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3863  sub start_link { Line 3850  sub start_link {
  my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,   my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
     undef,1);      undef,1);
  &Apache::lonxml::extlink($href);   &Apache::lonxml::extlink($href);
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3872  sub end_link { Line 3859  sub end_link {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3882  sub start_marquee { Line 3869  sub start_marquee {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3891  sub end_marquee { Line 3878  sub end_marquee {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3901  sub start_multicol { Line 3888  sub start_multicol {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # Close any pending <p>      my $currentstring = &end_p(); # Close any pending <p>
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3910  sub end_multicol { Line 3897  sub end_multicol {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3920  sub start_nobr { Line 3907  sub start_nobr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  $currentstring='\mbox{';   $currentstring='\mbox{';
     }      }
Line 3931  sub end_nobr { Line 3918  sub end_nobr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }   elsif ($target eq 'tex') {      }   elsif ($target eq 'tex') {
  $currentstring='}';   $currentstring='}';
     }      }
Line 3943  sub start_noembed { Line 3930  sub start_noembed {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3952  sub end_noembed { Line 3939  sub end_noembed {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3962  sub start_noframes { Line 3949  sub start_noframes {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3971  sub end_noframes { Line 3958  sub end_noframes {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3981  sub start_nolayer { Line 3968  sub start_nolayer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3990  sub end_nolayer { Line 3977  sub end_nolayer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4000  sub start_noscript { Line 3987  sub start_noscript {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4009  sub end_noscript { Line 3996  sub end_noscript {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4019  sub start_object { Line 4006  sub start_object {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4028  sub end_object { Line 4015  sub end_object {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4038  sub start_optgroup { Line 4025  sub start_optgroup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4047  sub end_optgroup { Line 4034  sub end_optgroup {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4057  sub start_samp { Line 4044  sub start_samp {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring='\texttt{';   $currentstring='\texttt{';
     }      }
Line 4068  sub end_samp { Line 4055  sub end_samp {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring='}';   $currentstring='}';
     }      }
Line 4080  sub start_server { Line 4067  sub start_server {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4089  sub end_server { Line 4076  sub end_server {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4099  sub start_spacer { Line 4086  sub start_spacer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = &end_p(); # Close off any open <p> tag.      my $currentstring = &end_p(); # Close off any open <p> tag.
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4108  sub end_spacer { Line 4095  sub end_spacer {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
   my @span_end_stack; # for span tex target
   
 #-- <span> tag (end tag required)  #-- <span> tag (end tag required)
 sub start_span {  sub start_span {
     my ($target,$token) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       } elsif ($target eq 'tex') {
           my $endstring = '';
           my $family = &get_css_property('font-family',$parstack,$safeeval);
           if ($family eq 'monospace') {
               $currentstring .= '\texttt{';
               $endstring .= '}';
           }
           my $weight = &get_css_property('font-weight',$parstack,$safeeval);
           if ($weight eq 'bold') {
               $currentstring .= '\textbf{';
               $endstring .= '}';
           }
           my $style = &get_css_property('font-style',$parstack,$safeeval);
           if ($style eq 'italic') {
               $currentstring .= '\textit{';
               $endstring .= '}';
           }
           push(@span_end_stack, $endstring);
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4127  sub end_span { Line 4134  sub end_span {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       } elsif ($target eq 'tex') {
           my $endstring = pop @span_end_stack;
           $currentstring .= $endstring;
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4137  sub start_tbody { Line 4147  sub start_tbody {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
       if ($target eq 'tex') {
    # TODO: Ensure this tag is within a table:
   
    my $table = $Apache::londefdef::table[-1];
    $table->start_body();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4146  sub end_tbody { Line 4162  sub end_tbody {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
       if($target eq 'tex') {
    # TODO: Ensure this tag is within a table:
   
    my $table = $Apache::londefdef::table[-1];
    $table->end_body();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4156  sub start_tfoot { Line 4178  sub start_tfoot {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
       if ($target eq 'tex') {
           # TODO: ensure this is within a table tag.
    my $table = $Apache::londefdef::table[-1];
    $table->start_foot();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4165  sub end_tfoot { Line 4192  sub end_tfoot {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
       if ($target eq 'tex') {
    #  TODO: Ensure this is in side a table
    my $table = $Apache::londefdef::table[-1];
    $table->end_foot();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4175  sub start_thead { Line 4207  sub start_thead {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
       if ($target eq 'tex') {
    # Assume we're in a table... TODO: Verify that and ignore tag if not.
    my $table = $Apache::londefdef::table[-1];
    $table->start_head();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4184  sub end_thead { Line 4221  sub end_thead {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
       if ($target eq 'tex') {
         # TODO: Verify we are in a table and ignore tag if not.
   
    my $table = $Apache::londefdef::table[-1];
    $table->end_head();
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4194  sub start_var { Line 4237  sub start_var {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\textit{';    $currentstring = '\textit{';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 4207  sub end_var { Line 4250  sub end_var {
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];   $currentstring = $token->[2];
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '}';    $currentstring = '}';
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4217  sub start_wbr { Line 4260  sub start_wbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[4];        $currentstring = $token->[4];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4226  sub end_wbr { Line 4269  sub end_wbr {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];
     }       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 4235  sub end_wbr { Line 4278  sub end_wbr {
 sub start_hideweboutput {  sub start_hideweboutput {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  &Apache::lonxml::startredirection();        &Apache::lonxml::startredirection();
     }       }
     return '';      return '';
 }  }
   
Line 4244  sub end_hideweboutput { Line 4287  sub end_hideweboutput {
     my ($target,$token) = @_;      my ($target,$token) = @_;
     my $currentstring = '';      my $currentstring = '';
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = &Apache::lonxml::endredirection();       $currentstring = &Apache::lonxml::endredirection();
     }       }
     return '';      return '';
 }  }
   
Line 4253  sub end_hideweboutput { Line 4296  sub end_hideweboutput {
 sub image_replication {  sub image_replication {
     my $src = shift;      my $src = shift;
     if (not -e $src) { &Apache::lonnet::repcopy($src); }      if (not -e $src) { &Apache::lonnet::repcopy($src); }
     #replicates eps or ps       #replicates eps or ps
     my $epssrc = my $pssrc = $src;      my $epssrc = my $pssrc = $src;
     $epssrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i;      $epssrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i;
     $pssrc  =~ s/\.(gif|jpg|jpeg|png)$/.ps/i;      $pssrc  =~ s/\.(gif|jpg|jpeg|png)$/.ps/i;
Line 4263  sub image_replication { Line 4306  sub image_replication {
     }      }
     return '';      return '';
 }  }
 #  
 #   Get correct sizing parameter for an image given  
 #   it's initial ht. and wid.  This allows sizing of  
 #   images that are generated on-the-fly (e.g. gnuplot)  
 #   as well as serving as a utility for image_size.  
 #   
 #  Parameter:  
 #        height_param  
 #        width_param    - Initial picture dimensions.  
 #        scaling        - A scale factor.  
 #        parstack,      - the current stack of tag attributes   
 #                         from the xml parser  
 #        safeeval,      - pointer to the safespace  
 #        depth,         - from what level in the stack to look for attributes  
 #                         (assumes -1 if unspecified)  
 #        cis            - look for attrubutes case insensitively  
 #                         (assumes false)  
 #  
 # Returns:  
 #   height, width   - new dimensions.  
 #  
 sub resize_image {  sub resize_image {
     my ($height_param, $width_param, $scaling,      my ($height_param, $width_param, $scaling,
  $parstack, $safeeval, $depth, $cis) = @_;   $parstack, $safeeval, $depth, $cis) = @_;
Line 4294  sub resize_image { Line 4319  sub resize_image {
     $width_param  = $width_param  * $scaling;      $width_param  = $width_param  * $scaling;
   
     #do we have any specified LaTeX size of the picture?      #do we have any specified LaTeX size of the picture?
     my $toget='TeXwidth';       my $toget='TeXwidth';
     if ($cis) {       if ($cis) {
  $toget=lc($toget);    $toget=lc($toget);
     }      }
     my $TeXwidth = &Apache::lonxml::get_param($toget,$parstack,      my $TeXwidth = &Apache::lonxml::get_param($toget,$parstack,
       $safeeval,$depth,$cis);        $safeeval,$depth,$cis);
Line 4306  sub resize_image { Line 4331  sub resize_image {
     #do we have any specified web size of the picture?      #do we have any specified web size of the picture?
     my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval,      my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval,
    $depth,1);     $depth,1);
     if ($TeXwidth) {       if ($TeXwidth) {
  my $old_width_param=$width_param;   my $old_width_param=$width_param;
  if ($TeXwidth=~/(\d+)\s*\%/) {   if ($TeXwidth=~/(\d+)\s*\%/) {
     $width_param = $1*$env{'form.textwidth'}/100;      $width_param = $1*$env{'form.textwidth'}/100;
  } else {    } else {
     $width_param = $TeXwidth;      $width_param = $TeXwidth;
  }   }
  if ($TeXheight) {   if ($TeXheight) {
Line 4319  sub resize_image { Line 4344  sub resize_image {
     $height_param=$TeXwidth/$old_width_param*$height_param;      $height_param=$TeXwidth/$old_width_param*$height_param;
  }   }
     } elsif ($TeXheight) {      } elsif ($TeXheight) {
  $height_param = $TeXheight;  
  if ($height_param) {   if ($height_param) {
     $width_param  = $TeXheight/$height_param*$width_param;      $width_param  = $TeXheight/$height_param*$width_param;
  }   }
    $height_param = $TeXheight;
     } elsif ($width) {      } elsif ($width) {
  my $old_width_param=$width_param;   my $old_width_param=$width_param;
  $width_param = $width*$scaling;   $width_param = $width*$scaling;
Line 4344  sub resize_image { Line 4369  sub resize_image {
 sub image_size {  sub image_size {
     my ($src,$scaling,$parstack,$safeeval,$depth,$cis)=@_;      my ($src,$scaling,$parstack,$safeeval,$depth,$cis)=@_;
   
     #size of image from gif/jpg/jpeg/png       #size of image from gif/jpg/jpeg/png
     my $ressrc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);      my $ressrc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
     if (-e $ressrc) {      if (-e $ressrc) {
  $src = $ressrc;   $src = $ressrc;
Line 4357  sub image_size { Line 4382  sub image_size {
     undef($image);      undef($image);
   
     ($height_param, $width_param) = &resize_image($height_param, $width_param,      ($height_param, $width_param) = &resize_image($height_param, $width_param,
   $scaling, $parstack, $safeeval,     $scaling, $parstack, $safeeval,
   $depth, $cis);    $depth, $cis);
   
     return ($height_param, $width_param);      return ($height_param, $width_param);
Line 4386  sub get_eps_image { Line 4411  sub get_eps_image {
  &Apache::lonnet::repcopy($orig_src); # Failure is not completely fatal.   &Apache::lonnet::repcopy($orig_src); # Failure is not completely fatal.
     }      }
     &Apache::lonxml::debug("get_eps_image: Original image: $orig_src");      &Apache::lonxml::debug("get_eps_image: Original image: $orig_src");
     my ($spath, $sname, $sext) = &fileparse($src, qr/\.(gif|png|jpg|jpeg)/i);      my ($spath, $sname, $sext) = &fileparse($src, qr/\.(bmp|gif|png|jpg|jpeg|svg)/i);
     $src=~s/\.(gif|png|jpg|jpeg)$/\.eps/i;      $src=~s/\.(bmp|gif|png|jpg|jpeg|svg)$/\.eps/i;
     $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);      $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
     &Apache::lonxml::debug("Filelocation gives: $src");      &Apache::lonxml::debug("Filelocation gives: $src");
     if (! -e $src) {      if (! -e $src) {
Line 4406  sub get_eps_image { Line 4431  sub get_eps_image {
   
  #if replication failed try to produce eps file dynamically   #if replication failed try to produce eps file dynamically
  $src=~s/\.ps$/\.eps/;   $src=~s/\.ps$/\.eps/;
  my $temp_file;   if (open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat")) {
  open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat");      my $newsrc=$orig_src;
  my $newsrc=$orig_src;      $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|;
  $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|;      &Apache::lonxml::debug("queueing $newsrc for dynamic eps production.");
  &Apache::lonxml::debug("queueing $newsrc for dynamic eps production.");      print FILE ("$newsrc\n");
  print FILE ("$newsrc\n");      close(FILE);
  close(FILE);                  }
  $src=~s|/home/httpd/html/res|/home/httpd/prtspool|;   $src=~s|/home/httpd/html/res|/home/httpd/prtspool|;
  $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;   $src=~s|/home/httpd/html/priv/[^/]+/([^/]*)/|/home/httpd/prtspool/$1/|;
  if ($sext ne "") { # Put the ext. back in to uniquify.   if ($sext ne "") { # Put the ext. back in to uniquify.
     $src =~ s/\.eps$/$sext.eps/;      $src =~ s/\.eps$/$sext.eps/;
  }   }
Line 4433  sub get_eps_image { Line 4458  sub get_eps_image {
  print FILE "$src\n";   print FILE "$src\n";
  close FILE;   close FILE;
  $src=~s|/home/httpd/html/res|/home/httpd/prtspool|;   $src=~s|/home/httpd/html/res|/home/httpd/prtspool|;
  $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;   $src=~s|/home/httpd/html/priv/[^/]+/([^/]*)/|/home/httpd/prtspool/$1/|;
     }      }
     my ($path,$file)=($src=~m|(.*)/([^/]*)$|);      my ($path,$file)=($src=~m|(.*)/([^/]*)$|);
     $path =~ s/ /\_/g;      $path =~ s/ /\_/g;
Line 4443  sub get_eps_image { Line 4468  sub get_eps_image {
 }  }
   
 sub eps_generation {  sub eps_generation {
     my ($src,$file,$width_param) = @_;           my ($src,$file,$width_param) = @_;
     my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";      my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
     my $temp_file = Apache::File->new('>>'.$filename);       if (open(my $tmpfile,">>$filename")) {
     print $temp_file "$src\n";          print $tmpfile "$src\n";
           close($tmpfile);
       }
     my $newsrc = $src;      my $newsrc = $src;
     $newsrc =~ s/(\.gif|\.jpg|\.jpeg)$/\.eps/i;      $newsrc =~ s/(\.bmp|\.gif|\.jpg|\.jpeg)$/\.eps/i;
     $newsrc=~s{/home/httpd/html/res}{};      $newsrc=~s{/home/httpd/html/res}{};
     $newsrc=~s{/home/($LONCAPA::username_re)/public_html/}{/$1/};      $newsrc=~s{/home/httpd/html/priv/[^/]+/($LONCAPA::username_re)/}{/$1/};
     $newsrc=~s{/\./}{/};      $newsrc=~s{/\./}{/};
     $newsrc=~s{/([^/]+)\.(ps|eps)}{/};      $newsrc=~s{/([^/]+)\.(ps|eps)}{/};
     if ($newsrc=~m{/home/httpd/lonUsers/}) {      if ($newsrc=~m{/home/httpd/lonUsers/}) {
Line 4464  sub eps_generation { Line 4491  sub eps_generation {
     }      }
 }  }
   
 sub file_path {       sub file_path {
     my $src=shift;      my $src=shift;
     my ($file,$path);       my ($file,$path);
     if ($src =~ m!(.*)/([^/]*)$!) {      if ($src =~ m!(.*)/([^/]*)$!) {
  $file = $2;    $file = $2;
  $path = $1.'/';    $path = $1.'/';
     }       }
     return $file,$path;      return $file,$path;
 }  }
 #  Converts a measurement in to mm from any of   
 #  the other valid LaTeX units of measure.  
 #  If the units of measure are missing from the   
 #  parameter, it is assumed to be in and returned  
 #  with mm units of measure  
 sub recalc {  sub recalc {
     my $argument = shift;      my $argument = shift;
     if (not $argument=~/(mm|cm|in|pc|pt)/) {return $argument.' mm';}      if (not $argument=~/(mm|cm|in|pc|pt)/) {return $argument.' mm';}
Line 4499  sub recalc { Line 4523  sub recalc {
 sub LATEX_length {  sub LATEX_length {
     my $garbage=shift;      my $garbage=shift;
     $garbage=~s/^\s+$//;      $garbage=~s/^\s+$//;
     $garbage=~s/^\s+(\S.*)/$1/;#space before       $garbage=~s/^\s+(\S.*)/$1/;#space before
     $garbage=~s/(.*\S)\s+$/$1/;#space after       $garbage=~s/(.*\S)\s+$/$1/;#space after
     $garbage=~s/(\s)+/$1/;#only one space      $garbage=~s/(\s)+/$1/;#only one space
     $garbage=~s/(\\begin{([^\}]+)}|\\end{([^\}]+)})//g;#remove LaTeX \begin{...} and \end{...}      $garbage=~s/(\\begin\{([^\}]+)}|\\end\{([^\}]+)})//g;#remove LaTeX \begin{...} and \end{...}
     $garbage=~s/(\$\_\{|\$\_|\$\^{|\$\^|\}\$)//g;#remove $_{,$_,$^{,$^,}$      $garbage=~s/(\$\_\{|\$\_|\$\^\{|\$\^|\}\$)//g;#remove $_{,$_,$^{,$^,}$
     $garbage=~s/([^\\])\$/$1/g;#$      $garbage=~s/([^\\])\$/$1/g;#$
     $garbage=~s/(\\ensuremath\{\_\{|\\ensuremath\{\_|\\ensuremath\{\^{|\\ensuremath\{\^|\})//g;#remove \ensuremath{...}      $garbage=~s/(\\ensuremath\{\_\{|\\ensuremath\{\_|\\ensuremath\{\^\{|\\ensuremath\{\^|\})//g;#remove \ensuremath{...}
    $garbage=~s/(\\alpha|\\beta|\\gamma|\\delta|\\epsilon|\\verepsilon|\\zeta|\\eta|\\theta|\\vartheta|\\iota|\\kappa|\\lambda|\\mu|\\nu|\\xi|\\pi|\\varpi|\\rho|\\varrho|\\sigma|\\varsigma|\\tau|\\upsilon|\\phi|\\varphi|\\chi|\\psi|\\omega|\\Gamma|\\Delta|\\Theta|\\Lambda|\\Xi|\\Pi|\\Sigma|\\Upsilon|\\Phi|\\Psi|\\Omega)/1/g;     $garbage=~s/(\\alpha|\\beta|\\gamma|\\delta|\\epsilon|\\verepsilon|\\zeta|\\eta|\\theta|\\vartheta|\\iota|\\kappa|\\lambda|\\mu|\\nu|\\xi|\\pi|\\varpi|\\rho|\\varrho|\\sigma|\\varsigma|\\tau|\\upsilon|\\phi|\\varphi|\\chi|\\psi|\\omega|\\Gamma|\\Delta|\\Theta|\\Lambda|\\Xi|\\Pi|\\Sigma|\\Upsilon|\\Phi|\\Psi|\\Omega)/1/g;
     $garbage=~s/(\\pm|\\mp|\\times|\\div|\\cdot|\\ast|\\star|\\dagger|\\ddagger|\\amalg|\\cap|\\cup|\\uplus|\\sqcap|\\sqcup|\\vee|\\wedge|\\oplus|\\ominus|\\otimes|\\circ|\\bullet|\\diamond|\\lhd|\\rhd|\\unlhd|\\unrhd|\\oslash|\\odot|\\bigcirc|\\Box|\\Diamond|\\bigtriangleup|\\bigtriangledown|\\triangleleft|\\triangleright|\\setminus|\\wr)/1/g;      $garbage=~s/(\\pm|\\mp|\\times|\\div|\\cdot|\\ast|\\star|\\dagger|\\ddagger|\\amalg|\\cap|\\cup|\\uplus|\\sqcap|\\sqcup|\\vee|\\wedge|\\oplus|\\ominus|\\otimes|\\circ|\\bullet|\\diamond|\\lhd|\\rhd|\\unlhd|\\unrhd|\\oslash|\\odot|\\bigcirc|\\Box|\\Diamond|\\bigtriangleup|\\bigtriangledown|\\triangleleft|\\triangleright|\\setminus|\\wr)/1/g;
     $garbage=~s/(\\le|\\ll|\\leq|\\ge|\\geq|\\gg|\\neq|\\doreq|\\sim|\\simeq|\\subset|\\subseteq|\\sqsubset|\\sqsubseteq|\\in|\\vdash|\\models|\\supset|\\supseteq|\\sqsupset|\\sqsupseteq|\\ni|\\dash|\\perp|\\approx|\\cong|\\equiv|\\propto|\\prec|\\preceq|\\parallel|\\asymp|\\smile|\\frown|\\bowtie|\\succ|\\succeq|\\mid)/1/g;      $garbage=~s/(\\le|\\ll|\\leq|\\ge|\\geq|\\gg|\\neq|\\doreq|\\sim|\\simeq|\\subset|\\subseteq|\\sqsubset|\\sqsubseteq|\\in|\\vdash|\\models|\\supset|\\supseteq|\\sqsupset|\\sqsupseteq|\\ni|\\dash|\\perp|\\approx|\\cong|\\equiv|\\propto|\\prec|\\preceq|\\parallel|\\asymp|\\smile|\\frown|\\bowtie|\\succ|\\succeq|\\mid)/1/g;
     $garbage=~s/(\\not<|\\\\not\\le|\\not\\prec|\\not\\preceq|\\not\\subset|\\not\\subseteq|\\not\\sqsubseteq|\\not\\in|\\not>|\\not\\ge|\\not\\succ|\\notsucceq|\\not\\supset|\\notsupseteq|\\not\\sqsupseteq|\\notin|\\not=|\\not\\equiv|\\not\\sim|\\not\\simeq|\\not\\approx|\\not\\cong|\\not\\asymp)/1/g;      $garbage=~s/(\\not<|\\\\not\\le|\\not\\prec|\\not\\preceq|\\not\\subset|\\not\\subseteq|\\not\\sqsubseteq|\\not\\in|\\not>|\\not\\ge|\\not\\succ|\\notsucceq|\\not\\supset|\\notsupseteq|\\not\\sqsupseteq|\\notin|\\not=|\\not\\equiv|\\not\\sim|\\not\\simeq|\\not\\approx|\\not\\cong|\\not\\asymp)/1/g;
     $garbage=~s/(\\leftarrow|\\gets|\\Leftarrow|\\rightarrow|\\to|\\Rightarrow|\\leftrightarrow|\\Leftrightarrow|\\mapsto|\\hookleftarrow|\\leftharpoonup|\\leftkarpoondown|\\rightleftharpoons|\\longleftarrow|\\Longleftarrow|\\longrightarrow|\\Longrightarrow|\\longleftrightarrow|\\Longleftrightarrow|\\longmapsto|\\hookrightarrow|\\rightharpoonup|\\rightharpoondown|\\uparrow|\\Uparrow|\\downarrow|\\Downarrow|\\updownarrow|\\Updownarrow|\\nearrow|\\searrow|\\swarrow|\\nwarrow)/11/g;      $garbage=~s/(\\leftarrow|\\gets|\\Leftarrow|\\rightarrow|\\to|\\Rightarrow|\\leftrightarrow|\\Leftrightarrow|\\mapsto|\\hookleftarrow|\\leftharpoonup|\\leftkarpoondown|\\rightleftharpoons|\\longleftarrow|\\Longleftarrow|\\longrightarrow|\\Longrightarrow|\\longleftrightarrow|\\Longleftrightarrow|\\longmapsto|\\hookrightarrow|\\rightharpoonup|\\rightharpoondown|\\uparrow|\\Uparrow|\\downarrow|\\Downarrow|\\updownarrow|\\Updownarrow|\\nearrow|\\searrow|\\swarrow|\\nwarrow)/11/g;
     $garbage=~s/(\\aleph|\\hbar|\\imath|\\jmath|\\ell|\\wp|\\Re|\\Im|\\mho|\\prime|\\emptyset|\\nabla|\\surd|\\partial|\\top|\\bot|\\vdash|\\dashv|\\forall|\\exists|\\neg|\\flat|\\natural|\\sharp|\\\||\\angle|\\backslash|\\Box|\\Diamond|\\triangle|\\clubsuit|\\diamondsuit|\\heartsuit|\\spadesuit|\\Join|\\infty)/11/g;      $garbage=~s/(\\aleph|\\hbar|\\imath|\\jmath|\\ell|\\wp|\\Re|\\Im|\\mho|\\prime|\\emptyset|\\nabla|\\surd|\\partial|\\top|\\bot|\\vdash|\\dashv|\\forall|\\exists|\\neg|\\flat|\\natural|\\sharp|\\\||\\angle|\\backslash|\\Box|\\Diamond|\\triangle|\\clubsuit|\\diamondsuit|\\heartsuit|\\spadesuit|\\Join|\\infty)/11/g;
     $garbage=~s/(\\hat{([^}]+)}|\\check{([^}]+)}|\\dot{([^}]+)}|\\breve{([^}]+)}|\\acute{([^}]+)}|\\ddot{([^}]+)}|\\grave{([^}]+)}|\\tilde{([^}]+)}|\\mathring{([^}]+)}|\\bar{([^}]+)}|\\vec{([^}]+)})/$1/g;      $garbage=~s/(\\hat\{([^}]+)}|\\check\{([^}]+)}|\\dot\{([^}]+)}|\\breve\{([^}]+)}|\\acute\{([^}]+)}|\\ddot\{([^}]+)}|\\grave\{([^}]+)}|\\tilde\{([^}]+)}|\\mathring\{([^}]+)}|\\bar\{([^}]+)}|\\vec\{([^}]+)})/$1/g;
     #remove some other LaTeX command      #remove some other LaTeX command
     $garbage=~s|\\(\w+)\\|\\|g;        $garbage=~s|\\(\w+)\\|\\|g;
     $garbage=~s|\\(\w+)(\s*)|$2|g;        $garbage=~s|\\(\w+)(\s*)|$2|g;
     $garbage=~s|\+|11|g;      $garbage=~s|\+|11|g;
     my  $value=length($garbage);      my  $value=length($garbage);
     return $value;      return $value;
 }  }
   
 #   Wrap image 'stuff' inside of the LaTeX required to implement   
 #   alignment:  
 #     align_tex_image(align, latex_rendering, image)  
 #   Where:  
 #     align   - The HTML alignment specification.  
 #     latex_rendering - rendering hint for latex.  
 #     image   - The LaTeX needed to insert the image itsef.  
 #     width,height - dimensions of the image.  
 # Returns:  
 #    The 1/2 wrapped image and the stuff required to close the  
 #    wrappage.  This allows e.g. randomlabel to insert more stuff  
 #    into the closure.  
 #  
 sub align_latex_image {  sub align_latex_image {
     my ($align, $latex_rendering, $image, $width, $height) = @_;      my ($align, $latex_rendering, $image, $width, $height) = @_;
     my $currentstring;        # The 1/2 wrapped image.      my $currentstring;        # The 1/2 wrapped image.
Line 4547  sub align_latex_image { Line 4559  sub align_latex_image {
     #    If there's an alignment specification we need to honor it here.      #    If there's an alignment specification we need to honor it here.
     #    For the horizontal alignments, we will also honor the      #    For the horizontal alignments, we will also honor the
     #    value of the latex specfication.  The default is parbox,      #    value of the latex specfication.  The default is parbox,
     #    and that's used for illegal values too.        #    and that's used for illegal values too.
     #          #
     #    Even though we set a default alignment value, the user      #    Even though we set a default alignment value, the user
     #    could have given us an illegal value.  In that case we      #    could have given us an illegal value.  In that case we
     #    just use the default alignment of bottom..      #    just use the default alignment of bottom..
     $currentstring = "\n% figurewrapping \n";      $currentstring = '';
     if      ($align eq "top")    {      if      ($align eq "top")    {
  $currentstring .= '\raisebox{-'.$height.'mm}{'.$image;   $currentstring .= '\raisebox{-'.$height.'mm}{'.$image;
  $closure = '}';   $closure = '}';
Line 4560  sub align_latex_image { Line 4572  sub align_latex_image {
  my $offset = $height/2;   my $offset = $height/2;
  $currentstring .= '\raisebox{-'.$offset.'mm}{'.$image;   $currentstring .= '\raisebox{-'.$offset.'mm}{'.$image;
  $closure       = '}';   $closure       = '}';
     } elsif ($align eq "left")   {       } elsif ($align eq "left")   {
  if ($latex_rendering eq "parpic") {    if ($latex_rendering eq "parpic") {
     $currentstring .= '\parpic[l]{'.$image;      $currentstring .= '\parpic[l]{'.$image;
     $closure       = '}';      $closure       = '}';
  } elsif ($latex_rendering eq "parbox") {   } elsif ($latex_rendering eq "parbox") {
Line 4570  sub align_latex_image { Line 4582  sub align_latex_image {
     $closure = '\end{minipage}';      $closure = '\end{minipage}';
  } elsif ($latex_rendering eq "wrapfigure"   } elsif ($latex_rendering eq "wrapfigure"
  || $latex_rendering ne 'none') {  # wrapfig render   || $latex_rendering ne 'none') {  # wrapfig render
     $currentstring .=       $currentstring .=
  '\begin{wrapfigure}{l}{'.$width.'mm}'   '\begin{wrapfigure}{l}{'.$width.'mm}'
  .'\scalebox{1.0}{'.$image;   .'\scalebox{1.0}{'.$image;
     $closure = '}\end{wrapfigure}';      $closure = '}\end{wrapfigure}';
  }   }
     } elsif ($align eq "right")  {         } elsif ($align eq "right")  {
  if ($latex_rendering eq "parpic") {   if ($latex_rendering eq "parpic") {
     $currentstring .= '\parpic[r]{'.$image;      $currentstring .= '\parpic[r]{'.$image;
     $closure = '}';      $closure = '}';
Line 4585  sub align_latex_image { Line 4597  sub align_latex_image {
     $closure = '\end{minipage}';      $closure = '\end{minipage}';
  } elsif ($latex_rendering eq "wrapfigure"   } elsif ($latex_rendering eq "wrapfigure"
  || $latex_rendering ne 'none') {  # wrapfig render   || $latex_rendering ne 'none') {  # wrapfig render
     $currentstring .=       $currentstring .=
  '\begin{wrapfigure}{r}{'.$width.'mm}'   '\begin{wrapfigure}{r}{'.$width.'mm}'
  .'\scalebox{1.0}{'.$image;   .'\scalebox{1.0}{'.$image;
     $closure = '}\end{wrapfigure}';      $closure = '}\end{wrapfigure}';
Line 4595  sub align_latex_image { Line 4607  sub align_latex_image {
  $currentstring .= "{$image";   $currentstring .= "{$image";
  $closure       = '}';   $closure       = '}';
     }      }
     $currentstring .= "\n% end wrappage\n";  
     $closure        = "\n% Begin closure\n".$closure."\n% End closure\n";  
     return ($currentstring, $closure);      return ($currentstring, $closure);
 }  }
   
 # is_inside_of $tagstack $tag  
 #    This sub returns true if the current state of Xml processing  
 #    is inside of the tag.     
 # Parameters:  
 #     tagstack   - The tagstack from the parser.  
 #     tag        - The tag (without the <>'s.).  
 # Sample usage:  
 #     if (is_inside_of($tagstack "table")) {  
 #          # I'm in a table....  
 #      }  
 sub is_inside_of {  sub is_inside_of {
     my ($tagstack, $tag) = @_;      my ($tagstack, $tag) = @_;
     my @stack = @$tagstack;      my @stack = @$tagstack;
Line 4622  sub is_inside_of { Line 4623  sub is_inside_of {
 }  }
   
   
   #
   #   This sub provides the typical LaTeX prefix matter for tex output:
   #
   sub latex_header {
       my ($mode) = @_;
       my $currentstring = '';
   
       $currentstring .=
    "\n% &Apache::lonxml::londefdef \n" .
    '\documentclass[letterpaper,twoside]{article}\raggedbottom';
       if (($env{'form.latex_type'}=~'batchmode') ||
    (!$env{'request.role.adv'}) ||
    ($mode eq 'batchmode')) {$currentstring .='\batchmode';}
       $currentstring .= '\newcommand{\keephidden}[1]{}'.
    '\renewcommand{\deg}{$^{\circ}$}'.
    '\usepackage{multirow}'."\n".
    '\usepackage{longtable}'."\n".
    '\usepackage{textcomp}'."\n".
    '\usepackage{makeidx}'."\n".
    '\usepackage[dvips]{graphicx}'."\n".
    '\usepackage{wrapfig}'."\n".
    '\usepackage{picins}'."\n".
    '\usepackage[T1]{fontenc}'."\n".
    '\usepackage{lmodern}'."\n".
    '\usepackage[postscript]{ucs}'."\n".
    '\usepackage[utf8x]{inputenc}'."\n".
    '\usepackage{pifont}'."\n".
    '\usepackage{latexsym}'."\n".
    '\usepackage{epsfig}'."\n".
    '\usepackage{xtab}'."\n".
    '\usepackage{tabularx}'."\n".
    '\usepackage{booktabs}'."\n".
    '\usepackage{array}'."\n".
    '\usepackage{colortbl}'."\n".
    '\usepackage{xcolor}'."\n".
    '\usepackage{calc}'."\n".
    '\usepackage{amsmath}'."\n".
    '\usepackage{soul}'."\n".
    '\usepackage{amssymb}'."\n".
    '\usepackage{amsfonts}'."\n".
    '\usepackage{amsthm}'."\n".
    '\usepackage{amscd}'."\n".
    '\usepackage{actuarialangle}'."\n";
       if($env{'form.pdfFormFields'} eq 'yes') {
    $currentstring .= '\usepackage{hyperref}'.
       '\usepackage{eforms}'.
       '\usepackage{tabularx}';
       }
   
           $currentstring .= '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'.
                             '\renewenvironment{theindex}{\begin{list}{}{{\vskip 1mm \noindent \large\textbf{Index}} \newline \setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.01in}\setlength{\itemsep}{0.1in}\setlength{\parsep}{-0.02in}\setlength{\belowdisplayskip}{0.01in}\setlength{\abovedisplayskip}{0.01in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.01in}}}{\end{list}}';
       $currentstring .= '\begin{document}';
   
       return $currentstring;
   
   }
   
   sub clean_docs_httpref {
       my ($href,$docuri,$cdom,$cnum) = @_;
       if ($docuri eq '') {
           $docuri = &Apache::lonnet::hreflocation('',$env{'request.filename'});
       }
       if ($cdom eq '') {
           $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       }
       if ($cnum eq '') {
           $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       }
       my $cleanhref;
       if ($docuri =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/)(.+/)[^/]+$}) {
           my $prefix = $1;
           my $relpath = $2;
           my ($hrefpath,$fname);
           if ($href =~ m{^/}) {
               if ($href =~ m{^\Q$prefix\E(.+/)([^/]+)$}) {
                   $hrefpath = $1;
                   $fname = $2;
               } else {
                   return $cleanhref;
               }
           } else {
               if ($href =~ m{/}) {
                   (my $path,$fname) = ($href =~ m{^(.*)/([^/]*)$});
                   $hrefpath = $relpath.$path;
                   if ($path eq '') {
                       $hrefpath =~ s{/$}{};
                   }
               } else {
                   $fname = $href;
                   $hrefpath = $relpath;
                   $hrefpath =~ s{/$}{};
               }
           }
           if ($fname ne '') {
               my $cleanrelpath;
               foreach my $dir (split(/\//,$hrefpath)) {
                   next if ($dir eq '.');
                   if ($dir eq '..') {
                       $cleanrelpath =~ s{([^/]+/)$}{};
                   } else {
                       $cleanrelpath .= $dir.'/';
                   }
               }
               if ($cleanrelpath ne '') {
                   $cleanhref = $prefix.$cleanrelpath.$fname;
               } else {
                   $cleanhref = $prefix.$fname;
               }
           }
       }
       return $cleanhref;
   }
   
   # This is retrieving a CSS property from the style attribute of the current element.
   # It is not checking <style> elements or linked stylesheets yet.
   sub get_css_property {
       my ($property,$parstack,$safeeval) = @_;
       my $style=&Apache::lonxml::get_param('style',$parstack,$safeeval,undef,1);
       my @style_components=split(/;/,$style);
       foreach my $css_pair (@style_components) {
           my ($name, $value) = split(/:/, $css_pair);
           $name =~ s/^\s+|\s+$//g;
           $value =~ s/^\s+|\s+$//g;
           if ($name eq $property) {
               return $value;
           }
       }
       return undef;
   }
   
   =pod
   
   =head1 NAME
   
   Apache::londefdef.pm
   
   =head1 SYNOPSIS
   
   Tags Default Definition Module
   
   This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   
   =head1 NOTABLE SUBROUTINES
   
   =over
   
   =item start_hideweboutput()
   
   =item end_hideweboutput()
   
   =item image_replication()
   
   =item resize_image()
   
    Get correct sizing parameter for an image given
    it's initial ht. and wid.  This allows sizing of
    images that are generated on-the-fly (e.g. gnuplot)
    as well as serving as a utility for image_size.
   
    Parameter:
           height_param
           width_param    - Initial picture dimensions.
           scaling        - A scale factor.
           parstack,      - the current stack of tag attributes
                            from the xml parser
           safeeval,      - pointer to the safespace
           depth,         - from what level in the stack to look for attributes
                            (assumes -1 if unspecified)
           cis            - look for attrubutes case insensitively
                            (assumes false)
   
    Returns:
    height, width   - new dimensions.
   
   =item image_size()
   
   =item image_width()
   
   =item image_height()
   
   =item get_eps_image()
   
   =item eps_generation()
   
   =item file_path()
   
   =item recalc()
   
    Converts a measurement in to mm from any of
    the other valid LaTeX units of measure.
    If the units of measure are missing from the
    parameter, it is assumed to be in and returned
    with mm units of measure
   
   =item LATEX_length()
   
   =item align_latex_image()
   
     Wrap image 'stuff' inside of the LaTeX required to implement
       alignment:
         align_tex_image(align, latex_rendering, image)
       Where:
         align   - The HTML alignment specification.
         latex_rendering - rendering hint for latex.
         image   - The LaTeX needed to insert the image itsef.
         width,height - dimensions of the image.
     Returns:
       The 1/2 wrapped image and the stuff required to close the
       wrappage.  This allows e.g. randomlabel to insert more stuff
       into the closure.
   
   
   =item is_inside_of($tagstack, $tag)
       This sub returns true if the current state of Xml processing is inside of the tag.
    Parameters:
       tagstack   - The tagstack from the parser.
       tag        - The tag (without the <>'s.).
    Sample usage:
       if (is_inside_of($tagstack "table")) {
           I'm in a table....
         }
   
   =item clean_docs_httpref($href,$docuri,$cdom,$cnum)
           HTML pages uploaded to a course which contain dependencies either from iframes,
           javascript files or objects (FlashPlayerSwf, MediaSrc, XMPSrc, ConfigurationSrc,
           and PosterImageSrc) for which dependency is another file uploaded to the same
           course.
   
           Required input:
           href - dependency (either a relative URL, or an absolute URL)
           Optional inputs:
           docuri - URL of HTML page containing the dependency
           cdom - Course domain
           cnum - CourseID
   
           Output:
           returns an absolute URL constructed from the href provided, and the calling context.
           (this will be null, if the URL does not begin: /uploaded/$cdom/$cnum/docs/ or
           /uploaded/$cdom/$cnum/supplemental/).
   
   =back
   
   =cut
   
   
 1;  1;
 __END__  __END__

Removed from v.1.375.2.1  
changed lines
  Added in v.1.475


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