Diff for /loncom/xml/londefdef.pm between versions 1.330 and 1.431

version 1.330, 2006/07/19 20:32:23 version 1.431, 2011/07/21 03:31:16
Line 1 Line 1
   
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # Tags Default Definition Module   # Tags Default Definition Module 
 #  #
Line 42  package Apache::londefdef; Line 43  package Apache::londefdef;
 use Apache::lonnet;  use Apache::lonnet;
 use strict;  use strict;
 use Apache::lonxml;  use Apache::lonxml;
 use Apache::File();  use Apache::lontable;
 use Image::Magick;  use Image::Magick;
 use Apache::lonmenu();  use Apache::lonmenu();
 use Apache::lonmeta();  use Apache::lonmeta();
   use Apache::lonlocal;
   use Apache::loncommon();
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use File::Basename;  use File::Basename;
   use LONCAPA();
 # use Data::Dumper;  # use Data::Dumper;
   
 BEGIN {  BEGIN {
Line 56  BEGIN { Line 60  BEGIN {
   
 }  }
   
 #  
 #   Dumps all elements of the table structure.  
 #   Need this 'cause evidently when given an array, Data::Dumper only seems  
 #   to dump element 0.  
 #  
 #sub debug_dump_table {  
 #    my $lastrow = $#Apache::londefdef::table;  
 #    &Apache::lonnet::logthis("Dumping table:  Last row index: $lastrow");  
 #    my $row;  
 #    for ($row =0; $row <= $lastrow; $row++ ) {  
 # my $text = Dumper($Apache::londefdef::table[$row]);  
 # &Apache::lonnet::logthis("table [ $row ]".$text);  
 #    }  
 #}  
 sub initialize_londefdef {  sub initialize_londefdef {
     $Apache::londefdef::TD_redirection=0;      $Apache::londefdef::TD_redirection=0;
     @Apache::londefdef::table = ();      @Apache::londefdef::table = ();
Line 105  sub start_m { Line 96  sub start_m {
  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 127  sub start_m { Line 118  sub start_m {
  #&Apache::lonxml::debug("M is ends with:$currentstring:");   #&Apache::lonxml::debug("M is ends with:$currentstring:");
  $Apache::lonxml::post_evaluate=0;   $Apache::lonxml::post_evaluate=0;
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
   
  $currentstring = $inside;   $currentstring = $inside;
  my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);   my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
  if ($eval eq 'on') {   if ($eval eq 'on') {
Line 134  sub start_m { Line 126  sub start_m {
  }   }
  if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';}   if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';}
  # detect simple math mode entry exits, and convert them   # detect simple math mode entry exits, and convert them
         # to use \ensuremath          # to use \ensuremath ... unless there's a \verb inside.
  if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) {   if (! ($currentstring=~/\\verb/)) {
     $currentstring=~s/^(\s*)\$/$1/;      if ($currentstring=~/^\s*\$[^\$].*\$\s*$/) {
     $currentstring=~s/\$(\s*)$/$1/;   $currentstring=~s/^(\s*)\$/$1/;
     $currentstring='\ensuremath{'.$currentstring.'}';   $currentstring=~s/\$(\s*)$/$1/;
    $currentstring='\ensuremath{'.$currentstring.'}';
       }
  }   }
  $Apache::lonxml::post_evaluate=0;   $Apache::lonxml::post_evaluate=0;
     }      }
Line 183  sub start_html { Line 177  sub start_html {
     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}';  
  if (($env{'form.latex_type'}=~'batchmode') ||   $currentstring .= &latex_header();
             (!$env{'request.role.adv'})) {$currentstring .='\batchmode';}   
  $currentstring .= '\newcommand{\keephidden}[1]{}'.  
                           '\renewcommand{\deg}{$^{\circ}$}'.  
   '\usepackage{multirow}'.  
                           '\usepackage{longtable}'.  
                           '\usepackage{textcomp}'.  
                           '\usepackage{makeidx}'.  
                           '\usepackage[dvips]{graphicx}'.  
   '\usepackage{wrapfig}'.  
   '\usepackage{picins}'.  
                           '\usepackage{epsfig}'.  
                           '\usepackage{calc}'.  
                           '\usepackage{amsmath}'.  
                           '\usepackage{amssymb}'.  
                           '\usepackage{amsfonts}'.  
                           '\usepackage{amsthm}'.  
                           '\usepackage{amscd}'.  
                           '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'.  
                           '\renewenvironment{theindex}{\begin{list}{}{{\vskip 1mm \noindent \large\textbf{Index}} \newline \setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.01in}\setlength{\itemsep}{0.1in}\setlength{\parsep}{-0.02in}\setlength{\belowdisplayskip}{0.01in}\setlength{\abovedisplayskip}{0.01in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.01in}}}{\end{list}}';  
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 409  sub start_meta { Line 384  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 443  sub start_meta { Line 421  sub start_meta {
  if ((not defined $content) && (not defined $name)) {   if ((not defined $content) && (not defined $name)) {
     &Apache::lonxml::startredirection();      &Apache::lonxml::startredirection();
  }   }
       } elsif ($target eq 'edit') {
    $currentstring .= &Apache::edit::tag_start($target,$token);
    $currentstring .= &Apache::edit::text_arg('Name:','name',$token,30);
    $currentstring .= &Apache::edit::text_arg('Content:','content',$token,70);
    $currentstring .= &Apache::edit::end_row();
       } elsif ($target eq 'modified') {
    my $constructtag =
       &Apache::edit::get_new_args($token,$parstack,$safeeval,
    'name','content');
    if ($constructtag) { $currentstring = &Apache::edit::rebuild_tag($token); }
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 466  sub end_meta { Line 454  sub end_meta {
     return $currentstring;      return $currentstring;
 }  }
   
   sub insert_meta {
       return '
       <meta />';
   }
   
 # accessrule  # accessrule
 sub start_accessrule {  sub start_accessrule {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
     my $currentstring = '';      my $currentstring = '';
     my $eff=&Apache::lonxml::get_param      my $eff  =&Apache::lonxml::get_param('effect',$parstack,$safeeval,undef,1);
  ('effect',$parstack,$safeeval,undef,1);      my $realm=&Apache::lonxml::get_param('realm', $parstack,$safeeval,undef,1);
     my $realm=&Apache::lonxml::get_param      my $role =&Apache::lonxml::get_param('role',  $parstack,$safeeval,undef,1);
  ('realm',$parstack,$safeeval,undef,1);      my $type =&Apache::lonxml::get_param('type',  $parstack,$safeeval,undef,1);
     my $role=&Apache::lonxml::get_param  
  ('role',$parstack,$safeeval,undef,1);      my ($dom,$crs,$sec,$separator);
     $realm=~s/\s+//g;      if ($type eq 'user') {
     $realm=~s/\//\_/g;   ($dom,$crs,$sec)=split(m{/},$realm);
     $realm=~s/^\_//;   $crs = &LONCAPA::clean_username($crs);
     $realm=~s/\W/\;/g;   $separator = '/';
     $role=~s/\s+//g;      } else {
     $role=~s/\//\_/g;   ($dom,$crs,$sec)=split(/\_/,$realm);
     $role=~s/\W/\;/g;   $crs = &LONCAPA::clean_courseid($crs);
    $separator = '_';
       }
       $dom = &LONCAPA::clean_domain($dom);
   
       $sec =~s/\W//;
       $realm = $dom;
       if ($crs =~ /\S/) { $realm .= $separator.$crs; }
       if ($sec =~ /\S/) { $realm .= $separator.$sec; }
       $role=~s/\W//g;
   
     if ($target eq 'web') {      if ($target eq 'web') {
  my $args='';   my $args='';
  if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }   if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
Line 493  sub start_accessrule { Line 496  sub start_accessrule {
  }   }
     }      }
     if ($target eq 'meta') {      if ($target eq 'meta') {
  $currentstring='<rule>'.$eff.':'.$realm.':'.$role.'</rule>';   $currentstring='<rule>'.$eff.':'.$realm.':'.$role.':'.$type.'</rule>';
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 511  sub end_accessrule { Line 514  sub end_accessrule {
     return $currentstring;      return $currentstring;
 }  }
   
   sub generate_css_links {
       my $links;
       my $css_href = &Apache::lonnet::EXT('resource.0.cssfile');
       if ($css_href =~ /\S/) {
    &Apache::lonxml::extlink($css_href);
    $links .= 
       '<link rel="stylesheet" type="text/css" href="'.$css_href.'" />';
       }
       return $links;
   }
   
 #-- <body> tag (end tag required)  #-- <body> tag (end tag required)
 sub start_body {  sub start_body {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
Line 525  sub start_body { Line 539  sub start_body {
  if (&is_inside_of($tagstack, "head")) {   if (&is_inside_of($tagstack, "head")) {
     &end_head(@_);      &end_head(@_);
  }   }
   
    my $extra_head = &generate_css_links();
   
       # Breadcrumbs
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       if ($env{'request.state'} eq 'construct') {
           &Apache::lonhtmlcommon::add_breadcrumb({
               'text'  => 'Construction Space',
               'href'  => &Apache::loncommon::authorspace(),
           });
           &Apache::lonhtmlcommon::add_breadcrumb({
               'text'  => 'HTML Editor',
               'href'  => '',
           });
           # breadcrumbs (and tools) will be created 
           # in start_page->bodytag->innerregister
       } else {
           # FIXME Where are we?
       }
   
  $currentstring =    $currentstring = 
     &Apache::loncommon::start_page($Apache::londefdef::title,      &Apache::loncommon::start_page($Apache::londefdef::title,
    $Apache::londefdef::head,     $Apache::londefdef::head
         .$extra_head,
    {'add_entries'    => $token->[2],     {'add_entries'    => $token->[2],
     'no_title'       => 1,  #    'no_title'       => 1,
     'force_register' => 1});      'force_register' => 1});
   
  if ($env{'request.state'} ne 'published') {          my $header = '';
     $currentstring.=&Apache::lonmenu::constspaceform();          if ($env{'request.state'} ne 'published' &&
     $currentstring.=(<<EDITBUTTON);              $env{'request.state'} ne 'construct') {
 <form method="post">              $header=&Apache::lonmenu::constspaceform();
 <input type="submit" name="editmode" accesskey="e" value="Edit" />          }
 </form>          if ($env{'request.state'} ne 'published') {
 <br />              $header.=&Apache::londefdef::edit_controls();
 EDITBUTTON          }
  }          if ($env{'request.state'} eq 'construct') {
  $currentstring.=&Apache::lonxml::message_location();              $currentstring.=&Apache::loncommon::head_subbox(
                                   &Apache::loncommon::CSTR_pageheader()
                                  .$header);
           } elsif ($env{'request.state'} eq 'edit') {
               $currentstring.=&Apache::loncommon::head_subbox($header);
           }
           $currentstring.=&Apache::lonxml::message_location();
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\begin{document}';            $currentstring = '';   #  '\begin{document}' is in header.
     }       }
   
     return $currentstring;      return $currentstring;
 }  }
   
   sub edit_controls {
       my ($nochgview) = @_;
       my $result .= '
   <form method="post" action="">
   <div class="LC_edit_problem_header">';
       unless ($nochgview) {
           $result .= '
   <div class="LC_edit_problem_header_row1">'.
   &Apache::lonxml::renderingoptions().'
   <input type="submit" name="changeproblemmode" value="'.&mt('Change View').'" />
   </div>';
       }
       $result .= '
   <div><input type="submit" name="editmode" accesskey="e" value="'.&mt('Edit').'" />';
       if (($env{'request.course.id'}) && ($env{'form.forceedit'})) {
           my $viewtext = &mt('Course View');
           if (&Apache::loncommon::course_type() eq 'Community') {
               $viewtext = &mt('Community View');
           }
           $result .= ('&nbsp;' x 3).'<input type="button" value="'.
                      $viewtext.'" onclick="javascript:location.href=currentURL" />';
       }
       $result .= '</div>
   </div>
   </form>
   ';
       return $result;
   }
   
 sub end_body {  sub end_body {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p(); # Close off unclosed <p>      my $currentstring = &end_p(); # Close off unclosed <p>
Line 560  sub end_body { Line 631  sub end_body {
 }  }
   
 # \begin{center} causes a new paragprah spacing that looks odd inside   # \begin{center} causes a new paragprah spacing that looks odd inside 
 # of a table cell  # of a table cell.  Same at the end of a \center but with a slightly
 sub center_correction { return '\vspace*{-6 mm}'; }  # larger space .. hence center_correction and center_end_correction.
   #
   sub center_correction { return '\vspace*{-6 mm}'; } 
   sub center_end_correction { return '\vspace*{-7 mm}'; }
   
 #-- <center> tag (end tag required)  #-- <center> tag (end tag required)
 sub start_center {  sub start_center {
     my ($target,$token,$tagstack) = @_;      my ($target,$token,$tagstack) = @_;
Line 584  sub end_center { Line 659  sub end_center {
  $currentstring = $token->[2];        $currentstring = $token->[2];     
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
  $currentstring = '\end{center}';     $currentstring = '\end{center}';  
    if (&is_inside_of($tagstack, "table")) {
       $currentstring .= &center_end_correction();
    }
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1153  sub start_p { Line 1231  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 ($align eq 'center') {   if ($align eq 'center') {
     $currentstring .='\begin{center}\par';      $currentstring .='\begin{center}\par ';
     $closing_string = '\end{center}';      $closing_string = '\end{center}';
     if (&is_inside_of($tagstack, "table")) {      if (&is_inside_of($tagstack, "table")) {
  $currentstring = &center_correction().$currentstring;   $currentstring = &center_correction().$currentstring;
Line 1209  sub start_br { Line 1287  sub start_br {
  #   #
  for (my $i=$#tempo;$i>=0;$i--) {   for (my $i=$#tempo;$i>=0;$i--) {
     if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') ||      if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') ||
                 ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul') ||                  ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul'))  {
                 ($tempo[$i] eq 'td') || ($tempo[$i] eq 'th'))  {  
  $signal=1;   $signal=1;
  last;      }
       if (($tempo[$i] eq 'td') || ($tempo[$i] eq 'th')) {
    $signal = 1;
     }      }
  }   }
  if ($signal) {   if ($signal != 1) {
     $currentstring .= ' \vskip 0 mm ';  
  } elsif ($$tagstack[-2] ne 'sub' && $$tagstack[-2] ne 'sup') {  
     $currentstring .= '\strut \\\\ \strut ';      $currentstring .= '\strut \\\\ \strut ';
  }   }
       
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1314  sub start_font { Line 1392  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) {  
     if (($env{'browser.fontenhance'} eq 'on') ||   
  ($env{'browser.blackwhite'} eq 'on')) { return ''; }  
  }  
  $currentstring = $token->[4];        $currentstring = $token->[4];     
     }  elsif ($target eq 'tex') {      }  elsif ($target eq 'tex') {
  my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);   my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
Line 1401  sub start_sub { Line 1475  sub start_sub {
     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 .= '\ensuremath{_{';   $currentstring .= '\raisebox{-\smallskipamount}{\scriptsize{';
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 1424  sub start_sup { Line 1498  sub start_sup {
     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 .= '\ensuremath{^{';   $currentstring .= '\raisebox{\smallskipamount}{\scriptsize{';
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 1447  sub start_hr { Line 1521  sub start_hr {
     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') {
   
    # <hr /> can't be inside of <sup><sub> thank you LaTeX.
    # 
    my $restart_sub = 0;
    my $restart_sup = 0;
   
    # Since <sub> and <sup> are simple tags it's ok to turn off/on
    # using the start_ stop_ functions.. those tags only care about
    # $target.
   
    if (&is_inside_of($tagstack, "sub")) {
       $restart_sub = 1;
       $currentstring .= &end_sub($target, $token, $tagstack, 
          $parstack, $parser, $safeeval);
    }
    if (&is_inside_of($tagstack, "sup")) {
       $restart_sup = 1;
       $currentstring .= &end_sup($target, $token, $tagstack,
          $parstack, $parser, $safeeval);
    }
   
  my $LaTeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);   my $LaTeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
  if (defined $LaTeXwidth) {   if (defined $LaTeXwidth) {
     if ($LaTeXwidth=~/^%/) {      if ($LaTeXwidth=~/^%/) {
Line 1467  sub start_hr { Line 1562  sub start_hr {
  }   }
  $currentstring .= ' \vskip 0 mm \noindent\makebox['.$LaTeXwidth.']{'.$pre.'\makebox['.   $currentstring .= ' \vskip 0 mm \noindent\makebox['.$LaTeXwidth.']{'.$pre.'\makebox['.
                                     $LaTeXwidth.'][b]{\hrulefill}'.$post.'}\vskip 0 mm ';                                      $LaTeXwidth.'][b]{\hrulefill}'.$post.'}\vskip 0 mm ';
    # Turn stuff back on that we can't be inside of.
   
    if ($restart_sub) {
       $currentstring .= &start_sub($target, $token, $tagstack,
    $parstack, $parser, $safeeval);
    }
    if ($restart_sup) {
       $currentstring .= &start_sup($target, $token, $tagstack,
    $parstack, $parser, $safeeval);
    }
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 1497  sub start_div { Line 1602  sub start_div {
     }       } 
     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 1507  sub start_div { Line 1615  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 1547  sub start_a { Line 1656  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});
     } elsif ($target eq 'tex') {          if ($href =~ /\S/) {
  my $a=&Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);              if ($href !~ m{^https?://}) {
  my $b=&Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1);                  my $url=&Apache::lonnet::hreflocation('',$env{'request.filename'});
  if ($a=~/\S/) {                  my $linkurl;
     $a=~s/([^\\])%/$1\\\%/g;                  if ($href =~ m{^/uploaded/}) {
     $currentstring .= '\ref{URI: '.$a.'}';                      $linkurl = $href;
  } elsif ($b=~/\S/) {                  } elsif ($href =~ m{^[^/]}) {
     $currentstring .= '\ref{Anchor: '.$b.'}';                      my $path = $url;
  } else {                      $path  =~ s{[^/]*$}{};
     $currentstring.='';                      $linkurl = $path.$href;
  }                  }
                   if ($linkurl =~ m{^/uploaded/}) {
                       if (!&Apache::lonnet::allowed('bre',$linkurl)) {
                           if (&Apache::lonnet::is_on_map($url)) {
                               &Apache::lonxml::extlink($linkurl);
                           }
                       }
                   }
               }
           }
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 1568  sub end_a { Line 1686  sub end_a {
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[2];   $currentstring .= $token->[2];
     }      }
       if ($target eq 'tex') {
    my $href =
       &Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);
    my $name =
       &Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1);
           my $uriprint =
               &Apache::lonxml::get_param('uriprint',$parstack,$safeeval,undef,1);
           my $anchorprint =
               &Apache::lonxml::get_param('anchorprint',$parstack,$safeeval,undef,1);
    if (($href =~ /\S/) && ($uriprint=~/^on|uriprint|yes|1$/i)) {
       $href =~ s/([^\\])%/$1\\\%/g;
       # Substitute special symbols... and allow line breaks at each /
       #
       $href = &Apache::lonxml::latex_special_symbols($href);
       $href =~ s/\//\/\\-/g;              # Map / to /\- to allow hyphenation.
       $currentstring .= ' ({\tt URI:'.$href.'})';
    } elsif (($name =~ /\S/) && ($anchorprint=~/^on|anchorprint|yes|1$/i)) {
       $currentstring .= ' ({\tt Anchor:'.&Apache::lonxml::latex_special_symbols($name).'})';
    } else {
       $currentstring.='';
    }
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 1897  sub end_dd { Line 2037  sub end_dd {
 #               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 = '';
Line 1905  sub start_table { Line 2046  sub start_table {
     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 $aa = {};   &disable_para(); # Can't have paras in a table.
  push @Apache::londefdef::table, $aa;   
  $Apache::londefdef::table[-1]{'row_number'} = -1;  
         #maximum table's width (default coincides with text line length)   #  New table code:
  if ($#Apache::londefdef::table==0) {  
     $textwidth=&recalc($env{'form.textwidth'}); #result is always in mm   #  Get the parameters that we can do something about:
     $textwidth=~/(\d+\.?\d*)/;  
     $textwidth=0.95*$1; #accounts "internal" LaTeX space for table frame   my $border = &Apache::lonxml::get_param('border', $parstack, $safeeval, undef, 0);
  } else {   my $width  = &Apache::lonxml::get_param('TeXwidth', $parstack, $safeeval, undef, 0);
     if ($Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]=~/\d/) {   my $theme  = &Apache::lonxml::get_param('TeXtheme', $parstack, $safeeval, undef, 0);
  #the maximum width of nested table is determined by LATeX width of parent cell   my $align  = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef, 0);
  $textwidth=$Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}];    my $cell_border = &Apache::lonxml::get_param('rules', $parstack, $safeeval, undef, 0);
     } else {  
               #try to use all space not used before (minus 5% for LaTeX table internal) - rather silly   # The only thing that needs any figuring out is the width.. and then only if it is
  $textwidth=$Apache::londefdef::table[-2]{'width'};   # a percent. If not it's assumed to be some valid TeX measurement unit e.g. 3.0cm
  for (my $i=0;$i<$Apache::londefdef::table[-2]{'counter_columns'};$i++) {   #
     $textwidth=$textwidth-$Apache::londefdef::table[-2]{'TeXlen'}[0][$i];  
  }   my $table = new Apache::lontable();
    if ((defined $border) && ($border > 0)) {
    #    &Apache::lonnet::logthis("Turning on table borders: $border");
       $table->table_border(1);
       if (!defined $cell_border) {
    $table->cell_border(1); # Default for rules is all if rules not defined.
     }      }
  }   }
    # Only all or nothing for cell borders for now:
   
  # width either comes forced from the TeXwidth or the width parameters.   if ((defined $cell_border)) {
  # in either case it can be a percentage or absolute width.      if ($cell_border eq 'all') {
  # in the width case we ignore absolute width    $table->cell_border(1);
  my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);      } elsif ($cell_border eq 'rows') {
  if (!defined($TeXwidth)) {   $table->cell_border(2);
     my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,      } elsif ($cell_border eq 'cols') {
        $safeeval,undef,1);   $table->cell_border(3);
     if ($htmlwidth =~ /%/) {      } elsif($cell_border eq 'groups') {
  $TeXwidth = $htmlwidth;   $table->cell_border(4);
     } else {       } else {
  $TeXwidth = $textwidth;   $table->cell_border(0);
     }      }
  } else {  
     $Apache::londefdef::table[-1]{'forcedtablewidth'} = 1;  
  }   }
  if ($TeXwidth=~/%/) {   if (defined $theme) {
     $Apache::londefdef::table[-1]{'percent'}=1;      $table->theme($theme);
     $TeXwidth=~/(\d+)/;  
             $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;  
  } else {  
     $Apache::londefdef::table[-1]{'width'}=$TeXwidth;  
  }   }
         #  In the end, however the table width cannot be wider than $textwidth...   if (defined $align) {
       $table->alignment($align);
  if ($Apache::londefdef::table[-1]{'width'} > $textwidth) {  
     $Apache::londefdef::table[-1]{'width'} = $textwidth;  
  }   }
   
         #table's border   # Missing width is most of page width
  my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval);   
         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);   if (!(defined $width)) {
  unless (defined $border) { $border = 0; }      $width = '70%';
  if ($border) {    }
     $Apache::londefdef::table[-1]{'hinc'} = '\hline ';   
     $Apache::londefdef::table[-1]{'vinc'} = '&';   
     $Apache::londefdef::table[-1]{'vvinc'} = '|';  
  } else {  
     $Apache::londefdef::table[-1]{'hinc'} = '';   
     $Apache::londefdef::table[-1]{'vinc'} = '&';   
     $Apache::londefdef::table[-1]{'vvinc'} = '';  
  }  
  if ($#Apache::londefdef::table==0) {  
     #    Note that \newline seems to destroy the alignment envs.  
     # $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}';  
   
    # If a percentage, need to calculate what this means in terms of
    # page width:
   
    if ($width =~ /%$/) {
       my $textwidth = &recalc($env{'form.textwidth'});  # Page width in mm.
       $width =~ s/%//;
       $width = $width * $textwidth / 100.0;
       $width .= " mm";
       $table->width($width);
    }
   
    push(@Apache::londefdef::table, $table);
           $currentstring.=' \keephidden{NEW TABLE ENTRY}';
   
     }      }
     return $currentstring;      return $currentstring;
Line 1993  sub end_table { Line 2123  sub end_table {
     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 $inmemory = '';  
  my $output = '';  
  my $WARNING='';   my $table = pop(@Apache::londefdef::table);
         #width of columns from TeXwidth attributes   my $t     = $table->generate();
    # &Apache::lonnet::logthis("Generating string");
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {   $currentstring = $t->generate_string();
     for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {   # &Apache::lonnet::logthis("Generated: $currentstring");
  if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]<$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]) {   &enable_para();
     $Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]=$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn];  
  }  
     }  
  }  
         #free space and number of empty columns  
  my ($available_space,$empty_columns)=($Apache::londefdef::table[-1]{'width'},0);  
  if ($#Apache::londefdef::table ne 0) {$available_space=0.9*$available_space;}   
  for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {  
     if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]==0) {  
  $empty_columns++;  
     } else {  
  $available_space=$available_space-$Apache::londefdef::table[-1]{'TeXlen'}[0][$jn];  
     }  
  }  
         #boundaries for contents columns  
  my @min_len=();#columns can not be narrower   
  my @max_len=();#maximum length of column  
  for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {  
  my ($localmin,$localmax)=(0,0);  
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
     if ($localmin<$Apache::londefdef::table[-1]{'minlen'}[$in][$jn]) {  
  $localmin=$Apache::londefdef::table[-1]{'minlen'}[$in][$jn];  
     }  
     if ($localmax<$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn]) {  
  $localmax=$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn];  
     }  
  }  
  push @min_len, $localmin;  
  push @max_len, $localmax;  
  }  
  for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {  
     my $localmin=0,;  
     for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
  if ($localmin<$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn]) {  
     $localmin=$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn];  
  }  
     }  
     if ($max_len[$jn]<$localmin) {  
  $max_len[$jn]=$localmin;  
      $Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;  
     }#object size is bigger  
     if ($min_len[$jn]<$localmin) {  
  $min_len[$jn]=$localmin;  
  $Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;  
     }#object size is bigger  
     if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]!=0) {  
  $min_len[$jn]=0;  
  $max_len[$jn]=0;  
     }  
  }  
        #final adjustment of column width  
  my @fwidth=@{$Apache::londefdef::table[-1]{'TeXlen'}[0]};#final width array  
  my @adjust=();  
         #step 1. adjustment by maximum value  
  my $space_neeeded=0;  
  for (my $jn=0;$jn<=$#max_len;$jn++) {  
     $space_neeeded=$space_neeeded+$max_len[$jn];  
  }  
  if ($space_neeeded<=$available_space) {  
     for (my $jn=0;$jn<=$#max_len;$jn++) {  
  if ($fwidth[$jn]==0) {  
     $fwidth[$jn]=$max_len[$jn];  
  }  
     }  
  } else {  
         #step 2. adjustment by minimum value (estimation)  
     $space_neeeded=0;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  $space_neeeded+=$min_len[$jn];  
     }  
     if ($space_neeeded>$available_space) {  
  $WARNING=' \textbf{NOT ENOUGH SPACE FOR TABLE} ';  
  for (my $jn=0;$jn<=$#max_len;$jn++) {  
     if ($fwidth[$jn]==0) {  
  $fwidth[$jn]=$min_len[$jn];  
     }  
  }  
  #check if we have objects which can be scaled  
  my $how_many_to_scale=0;  
  my @to_scale=();  
  for (my $jn=0;$jn<=$#max_len;$jn++) {  
     if ($Apache::londefdef::table[-1]{'objectsignal'}[$jn] eq '1') {  
  $how_many_to_scale++;  
  push @to_scale, $jn;  
     }  
  }  
  if ($how_many_to_scale>0) {  
     my $space_to_adjust=($space_neeeded-$available_space)/$how_many_to_scale;  
     foreach my $jn (@to_scale) {  
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
     $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/;  
     if ($1 ne '') {  
  my $current_length=&recalc($1);  
  $current_length=~/(\d+\.?\d*)/;  
  $current_length=$current_length-$space_to_adjust;  
  $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/width=$current_length mm/;  
     }  
     $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/\[(\d+\.?\d*)\s*mm\]/;  
     if ($1 ne '') {  
  my $current_length=$1;  
  $current_length=$current_length-$space_to_adjust;  
  $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/\[(\d+\.?\d*)\s*mm\]/\[$current_length mm\]/;  
     }  
  }  
  $fwidth[$jn]=$fwidth[$jn]-$space_to_adjust;  
     }  
  }  
     } else {  
       #step 3. adjustment over minimal + corrections  
  my $enlarge_coef=$available_space/$space_neeeded;  
  my $acsessive=0;  
  for (my $jn=0;$jn<=$#min_len;$jn++) {  
     $adjust[$jn]=$min_len[$jn]*$enlarge_coef;  
     if ($adjust[$jn]>$max_len[$jn]) {  
  $fwidth[$jn]=$max_len[$jn];  
  $acsessive=$acsessive+$adjust[$jn]-$max_len[$jn];  
  $adjust[$jn]=0;  
     }  
  }  
  if ($acsessive>0) {  
  #we have an excess of space and can redistribute it  
     my $notempty_columns=0;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  if ($adjust[$jn]!=0) {  
     $notempty_columns++;  
  }  
     }  
     my $per_column=$acsessive/$notempty_columns;  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  if ($adjust[$jn]!=0) {  
     $adjust[$jn]+=$per_column;  
     $fwidth[$jn]=$adjust[$jn];  
  }  
     }  
  } else {  
     for (my $jn=0;$jn<=$#min_len;$jn++) {  
  $fwidth[$jn]=$adjust[$jn];  
     }  
  }  
     }  
  }  
         #use all available width if it is defined in % or as TeXwidth  
         if (($Apache::londefdef::table[-1]{'percent'}==1) || ($Apache::londefdef::table[-1]{'forcetablewidth'}==1)) {  
     my $current=0;   
     for (my $i=0;$i<=$#fwidth;$i++) {    
  $current+=$fwidth[$i];  
     }  
     my $coef=$Apache::londefdef::table[-1]{'width'}/$current;  
     for (my $i=0;$i<=$#fwidth;$i++) {    
  $fwidth[$i]*=$coef;  
     }  
  }  
         #removing of empty columns if allowed  
         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);  
  if ($permission eq 'yes') {  
     my @cleaned_table=();  
             my @cleaned_header=();  
     my $colind=0;  
     for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {  
  if ($fwidth[$jn]!=0) {  
     #we need to copy column  
     for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
  $cleaned_table[$in][$colind]=$Apache::londefdef::table[-1]{'content'}[$in][$jn];  
  $cleaned_header[$colind]=$fwidth[$jn];  
     }  
     $colind++;  
  }  
     }  
     $Apache::londefdef::table[-1]{'content'}=\@cleaned_table;  
     @fwidth=@cleaned_header;  
  }  
  #construct header of the table  
  my $header_of_table = '{'.$Apache::londefdef::table[-1]{'vvinc'};  
  for (my $in=0;$in<=$#fwidth;$in++) {  
     $header_of_table.='p{'.$fwidth[$in].' mm}'.$Apache::londefdef::table[-1]{'vvinc'};  
  }  
  $header_of_table .= '}';  
  #fill the table  
  for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {  
     my $have_rowspan = 0;  
     for (my $jn=0;$jn<=$#fwidth;$jn++) {  
   
  #-----------------------------------------------------------  
                 #   I think this order of doing things will ensure that  
  #   single rowspan, columspan and combined row/colspans will  
                 #   work correctly.  LaTeX is delicate here.  
  #    RF.  
   
  # Start a rowspan if necessary:  
   
  my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];  
  my $colspan = $Apache::londefdef::table[-1]{'colspan'}[$in][$jn];  
  #  
  #  Do the appropriate magic if this has a colspan  
  #   
   
  if ($colspan > 1) {  
     $output .= '\multicolumn{'.  
  $colspan  
  .'}{|l|}{';  
  }  
   
  if ($rowspan > 1) {  
     $have_rowspan++;  
     $output .= '\multirow{'.$rowspan.'}[0]{'.$fwidth[$jn].'mm}{';  
  }  
  if (($rowspan eq '^') || ($rowspan eq '_')) {  
     $have_rowspan++;  
  }  
  #--------------------------------------------------------------  
   
  if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {  
     $output.=&center_correction().'\begin{center}';  
  } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {  
     $output.=' \hfill \llap{'  
  }  
  $output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn];  
  if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {  
     $output.='\end{center}';  
  } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {  
     $output.='} ';  
  }  
  # Close off any open multirow:  
   
  if ($rowspan > 1) {  
     $output .= '}';  
  }  
  #  Close off the colspan...  
  #  
  if ($colspan > 1)  {  
     $output .= '}';  
     $jn += $colspan-1; # Adjust for number of rows really left.  
  }  
                 if ($jn!=$#fwidth) {$output.=' '.$Apache::londefdef::table[-1]{'vinc'};}  
     }  
     #  If have_rowspan > 0, and borders are on, then   
     #  we need to do more than put an \hline at the bottom of row.  
     #  we need to do the appropriate \cline to ensure that  
     #  the spanned rows don't have \hlines through them.  
   
     if (($Apache::londefdef::table[-1]{'hinc'} =~ /\\hline/) && $have_rowspan) {  
  $output .= ' \\\\ ';  
  for (my $jn=0; $jn<=$#fwidth;$jn++) {  
     my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];  
     if ($rowspan ne "^") {  
  if (($rowspan <= 1) || ($rowspan eq '_')) {  
     my $column = $jn+1;  
     $output .= '\cline{'.$column.'-'.$column.'} ';  
  }  
     }  
  }  
   
     } else {  
  $output.=' \\\\ '.$Apache::londefdef::table[-1]{'hinc'}.' ';  
     }  
  }  
  # Note that \newline destroys alignment env's produced  by e.g. <div>  
  # $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut\newline\strut ';  
  $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut'.'\\\\'."\n".'\strut ';  
  if ($#Apache::londefdef::table > 0) {      
     my $inmemory = $Apache::londefdef::table[-1]{'output'};  
     # Figure out max/and min width  by summing us and then  
     # apply that to the current column of the table we nest in  
     # if it's larger than the current width or the current width  
     # is undefined.  
     #  
     my $min_nested_width = 0;  
     my $max_nested_width = 0;  
     for (my $col = 0; $col <= $Apache::londefdef::table[-1]{'counter_columns'}; $col++) {  
  $min_nested_width +=  $min_len[$col];  
  $max_nested_width +=  $max_len[$col];  
   
     }  
     # Fudge in an extra 5 mm for borders etc:  
       
     $min_nested_width += 5;  
     $max_nested_width += 5;  
   
     my $outer_column = $Apache::londefdef::table[-2]{'counter_columns'};  
     my $outer_row    = $Apache::londefdef::table[-2]{'row_number'};  
     if ($min_nested_width > $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column]) {  
  $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column] = $min_nested_width;  
     }  
     if ($max_nested_width > $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column]) {  
  $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column] = $max_nested_width;  
     }  
   
     pop @Apache::londefdef::table;  
     push @{$Apache::londefdef::table[-1]{'include'}}, $inmemory;  
  } else {  
     $currentstring .= $Apache::londefdef::table[-1]{'output'};  
     pop @Apache::londefdef::table;  
     undef @Apache::londefdef::table;  
  }  
     }      }
     return $currentstring;      return $currentstring;
 }  }
Line 2306  sub start_tr { Line 2143  sub start_tr {
     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 2324  sub start_tr { Line 2174  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;
 }  }
Line 2334  sub end_tr { Line 2185  sub end_tr {
     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) {
       &end_td_tex($parstack,$parser,$safeeval);    
    }
    $Apache::londefdef::table[-1]->end_row();
   
    #-----------------------------------------------
    # Old table code
    #-----------------------------------------------
   
    if (0) {
  if ($Apache::londefdef::TD_redirection) {   if ($Apache::londefdef::TD_redirection) {
     &end_td_tex($parstack,$parser,$safeeval);          &end_td_tex($parstack,$parser,$safeeval);    
  }   }
Line 2342  sub end_tr { Line 2206  sub end_tr {
  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 2378  sub tag_check { Line 2242  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 2393  sub start_td_tex { Line 2307  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'}; 
Line 2446  sub end_td_tex { Line 2371  sub end_td_tex {
   
     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);      my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
     if (defined $TeXwidth) {      if (defined $TeXwidth) {
  push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   for (my $c = 0; $c < $colspan; $c++) {
  push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
  push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    }
     } else {      } else {
  if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {   if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {
     my $garbage_data=$data;      my $garbage_data=$data;
Line 2464  sub end_td_tex { Line 2391  sub end_td_tex {
  if ($fwidth<$current_length) {$fwidth=$current_length;}   if ($fwidth<$current_length) {$fwidth=$current_length;}
  $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;   $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;
     }      }
     push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      for (my $c = 0; $c < $colspan; $c++) {
     push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
     push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
       }
  } elsif ($data=~/\\parbox\{\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*\s*\}/ or $data=~/\\epsfxsize\s*=\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*/) {   } elsif ($data=~/\\parbox\{\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*\s*\}/ or $data=~/\\epsfxsize\s*=\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*/) {
     my $garbage_data=$data;      my $garbage_data=$data;
     my $fwidth=0;      my $fwidth=0;
Line 2483  sub end_td_tex { Line 2412  sub end_td_tex {
  if ($fwidth<$1) {$fwidth=$1;}   if ($fwidth<$1) {$fwidth=$1;}
  $garbage_data=~s/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;   $garbage_data=~s/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
     }      }
     push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      for (my $c = 0; $c < $colspan; $c++) {
     push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
     push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
    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/; 
Line 2514  sub end_td_tex { Line 2445  sub end_td_tex {
  if ($min_length<$lengthword) {$min_length=$lengthword;}   if ($min_length<$lengthword) {$min_length=$lengthword;}
     }      }
     }      }
     push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';      for (my $c = 0; $c < $colspan; $c++) {
     push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';   push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;   push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
     push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;   push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
       }
  }           }        
     }      }
     # Substitute all of the tables nested in this cell in their appropriate places.      # Substitute all of the tables nested in this cell in their appropriate places.
Line 2554  sub end_td_tex { Line 2487  sub end_td_tex {
   
     }      }
   
       }
   
     return '';      return '';
 }  }
Line 2603  sub tagg_check { Line 2536  sub tagg_check {
     
 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 2615  sub start_th_tex { Line 2566  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 2685  sub end_th_tex { Line 2650  sub end_th_tex {
     #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 2728  sub start_img { Line 2694  sub start_img {
    # 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)));          $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 2786  sub start_img { Line 2741  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 file exist do following:
  my $origsrc=$src;   my $origsrc=$src;
  my ($path,$file) = &get_eps_image($src);   my ($path,$file) = &get_eps_image($src);
    # &Apache::lonnet::logthis("Image source: $src result: $path $file");
  $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);   $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
  &Apache::lonxml::debug("path = $path file = $file src = $src");   &Apache::lonxml::debug("path = $path file = $file src = $src");
  if (-e $src) {   if (-e $src) {
     &Apache::lonxml::debug("$src exists");      &Apache::lonxml::debug("$src exists");
     my ($height_param,$width_param)=      my ($height_param,$width_param)=
  &image_size($origsrc,0.3,$parstack,$safeeval);   &image_size($origsrc,0.3,$parstack,$safeeval);
     my $destpath = $path;  
     $destpath    =~ s/ /\_/g; # Spaces in path cause LaTex to vomit.  
     my $destfile = $file;  
     $destfile    =~ s/ /\_/g;  
     my $size;      my $size;
     if ($width_param)  { $size.='width='.$width_param.' mm,'; }      if ($width_param)  { $size.='width='.$width_param.' mm,'; }
     if ($height_param) { $size.='height='.$height_param.' mm]'; }      if ($height_param) { $size.='height='.$height_param.' mm]'; }
       # Default size if not able to extract that (e.g. eps image).
       
       # &Apache::lonnet::logthis("Size = $size");
       
     $size='['.$size;      $size='['.$size;
     $size=~s/,$/]/;       $size=~s/,$/]/; 
     $currentstring .= '\graphicspath{{'.$destpath.'}}'      $currentstring .= '\graphicspath{{'.$path.'}}'
  .'\includegraphics'.$size.'{'.$destfile.'} ';   .'\includegraphics'.$size.'{'.$file.'} ';
       my $closure;
     #    If there's an alignment specification we need to honor it here.      ($currentstring, $closure) = &align_latex_image($align, 
     #    For the horizontal alignments, we will also honor the      $latex_rendering, 
     #    value of the latex specfication.  The default is parbox,      $currentstring, 
     #    and that's used for illegal values too.        $width_param, 
     #          $height_param);
     #    Even though we set a default alignment value, the user      $currentstring .= $closure;
     #    could have given us an illegal value.  In that case we  
     #    just use the default alignment of bottom..  
     if      ($align eq "top")    {  
  $currentstring = '\raisebox{-'.$height_param.'mm}{'.$currentstring.'}';  
     } elsif (($align eq "center") || ($align eq "middle")) { # Being kind  
  my $offset = $height_param/2;  
  $currentstring = '\raisebox{-'.$offset.'mm}{'.$currentstring.'}';  
     } elsif ($align eq "left")   {   
  if ($latex_rendering eq "parpic") {   
     $currentstring = '\parpic[l]{'.$currentstring.'}';  
  } else {                                     # wrapfig render  
     $currentstring = '\begin{wrapfigure}{l}{'.$width_param.'mm}'  
  .'\scalebox{1.0}{'.$currentstring.'}\end{wrapfigure}';  
  }  
     } elsif ($align eq "right")  {     
  if ($latex_rendering eq "parpic") {  
     $currentstring = '\parpic[r]{'.$currentstring.'}';  
  } else {                                 # wrapfig rendering  
     $currentstring = '\begin{wrapfigure}{r}{'.$width_param.'mm}'  
  .'\scalebox{1.0}{'.$currentstring.'}\end{wrapfigure}';  
   
  }  
     } else { # Bottom is also default.  
  # $currentstring = '\raisebox{'.$height_param.'mm}{'.$currentstring.'}';  
     }  
  } else {   } else {
     &Apache::lonxml::debug("$src does not exist");      &Apache::lonxml::debug("$src does not exist");
     #original image file doesn't exist so check the alt attribute      #original image file doesn't exist so check the alt attribute
Line 2853  sub start_img { Line 2785  sub start_img {
  # And here's where the semi-quote breaks down: allow the user   # And here's where the semi-quote breaks down: allow the user
         # to edit the beast as well by rendering the problem for edit:          # to edit the beast as well by rendering the problem for edit:
     } elsif ($target eq 'edit') {      } elsif ($target eq 'edit') {
           my $only = join(',',&Apache::loncommon::filecategorytypes('Pictures'));
  $currentstring .=&Apache::edit::tag_start($target,$token);   $currentstring .=&Apache::edit::tag_start($target,$token);
  $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).   $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).
     &Apache::edit::browse('src',undef,'alt').' '.      &Apache::edit::browse('src',undef,'alt',$only).' '.
     &Apache::edit::search('src',undef,'alt').'<br />';      &Apache::edit::search('src',undef,'alt').'<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);
Line 2865  sub start_img { Line 2798  sub start_img {
  $currentstring .=&Apache::edit::select_arg('Alignment:','align',   $currentstring .=&Apache::edit::select_arg('Alignment:','align',
    ['','bottom','middle','top','left','right'],$token,5);     ['','bottom','middle','top','left','right'],$token,5);
  $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',   $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',
    ['', 'parbox', 'parpic'], $token, 2);     ['', 'none','parbox', 'parpic', 'wrapfigure'], $token, 2);
  $currentstring .=&Apache::edit::select_arg('Encyrpt URL:','encrypturl',          my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);
           my $enc=    &Apache::lonxml::get_param('encrypturl',$parstack,$safeeval);
    
    $currentstring .=&Apache::edit::select_arg('Encrypt URL:','encrypturl',
    ['no','yes'], $token, 2);     ['no','yes'], $token, 2);
           if (($alt=~/\S/) && (lc($enc) eq 'yes')) {
              $currentstring.='<br /><span class="LC_warning">'.&mt('Warning: the description "[_1]" will be available, even for encrypted URL',$alt).'</span><br />';
           }
  $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();   $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
  my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);   my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);
  my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);  
  my $width=  &Apache::lonxml::get_param('width',$parstack,$safeeval);   my $width=  &Apache::lonxml::get_param('width',$parstack,$safeeval);
  my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);   my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);
   
           if ($token->[2]{'src'}=~/\$/) {
  $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';             $currentstring.=&mt('Variable image source');
  if ($width) { $currentstring.=' width="'.$width.'" '; }          } elsif ($token->[2]{'src'}=~/\S/) {
  if ($height) { $currentstring.=' height="'.$height.'" '; }     $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';
  $currentstring .= ' />';     if ($width) { $currentstring.=' width="'.$width.'" '; }
      if ($height) { $currentstring.=' height="'.$height.'" '; }
      $currentstring .= ' />';
           } else {
              $currentstring.=&mt("No image source specified");
           }
     } 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 2946  sub start_applet { Line 2889  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 = &Apache::lonenc::encrypt_ref($token,
     $currentstring = &Apache::lonenc::encrypt_ref($token,                                                        {'code'=>$code,
   {'code'=>$code,                                                         'archive'=>$archive}
    'archive'=>$archive}                                                       );
   );  
  } else {  
     my $alttag= &Apache::lonxml::get_param('alt',$parstack,  
    $safeeval,undef,1);  
     unless ($alttag) {  
  $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],  
  $code);  
     }  
     $currentstring='[APPLET: '.$alttag.']';  
  }  
     } elsif ($target eq 'tex') {      } elsif ($target eq 'tex') {
           # Turn off some stuff we can't be inside thank you LaTeX
   
    my $restart_sub = 0;
    my $restart_sup = 0;
   
    # Since <sub> and <sup> are simple tags it's ok to turn off/on
    # using the start_ stop_ functions.. those tags only care about
    # $target.
   
    if (&is_inside_of($tagstack, "sub")) {
       $restart_sub = 1;
       $currentstring .= &end_sub($target, $token, $tagstack, 
          $parstack, $parser, $safeeval);
    }
    if (&is_inside_of($tagstack, "sup")) {
       $restart_sup = 1;
       $currentstring .= &end_sup($target, $token, $tagstack,
          $parstack, $parser, $safeeval);
    }
   
    # Now process the applet; just replace it with its alt attribute.
   
  my $alttag= &Apache::lonxml::get_param('alt',$parstack,   my $alttag= &Apache::lonxml::get_param('alt',$parstack,
        $safeeval,undef,1);         $safeeval,undef,1);
  unless ($alttag) {   unless ($alttag) {
Line 2971  sub start_applet { Line 2926  sub start_applet {
  }   }
  $currentstring.='\begin{center} \fbox{Java Applet: '.$alttag.   $currentstring.='\begin{center} \fbox{Java Applet: '.$alttag.
     '.}\end{center}';      '.}\end{center}';
   
    # Turn stuff back on that we can't be inside of.
   
    if ($restart_sub) {
       $currentstring .= &start_sub($target, $token, $tagstack,
    $parstack, $parser, $safeeval);
    }
    if ($restart_sup) {
       $currentstring .= &start_sup($target, $token, $tagstack,
    $parstack, $parser, $safeeval);
    }
     }       } 
     return $currentstring;      return $currentstring;
 }  }
Line 2992  sub start_embed { Line 2958  sub start_embed {
     &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 3011  sub end_embed { Line 2968  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;
 }  }
   
Line 3092  sub start_frameset { Line 3050  sub start_frameset {
     &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 3357  sub start_blockquote { Line 3315  sub start_blockquote {
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring .= $token->[4];        $currentstring .= $token->[4];     
     }       } 
       if ($target eq 'tex') {
    $currentstring .= '\begin{quote}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3366  sub end_blockquote { Line 3327  sub end_blockquote {
     if ($target eq 'web' || $target eq 'webgrade') {      if ($target eq 'web' || $target eq 'webgrade') {
  $currentstring = $token->[2];       $currentstring = $token->[2];    
     }       } 
       if ($target eq 'tex') {
    $currentstring = '\end{quote}';
       }
     return $currentstring;      return $currentstring;
 }  }
   
Line 3426  sub end_col { Line 3390  sub end_col {
     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 3445  sub end_colgroup { Line 3430  sub end_colgroup {
     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 3459  sub end_del { Line 3448  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 3919  sub start_tbody { Line 3911  sub start_tbody {
     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 3928  sub end_tbody { Line 3926  sub end_tbody {
     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 3938  sub start_tfoot { Line 3942  sub start_tfoot {
     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 3947  sub end_tfoot { Line 3956  sub end_tfoot {
     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 3957  sub start_thead { Line 3971  sub start_thead {
     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 3966  sub end_thead { Line 3985  sub end_thead {
     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 4043  sub image_replication { Line 4068  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 4166  sub get_eps_image { Line 4173  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)/i);
     $src=~s/\.(gif|png|jpg|jpeg)$/\.eps/i;      $src=~s/\.(bmp|gif|png|jpg|jpeg)$/\.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 4186  sub get_eps_image { Line 4193  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/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;
  if ($sext ne "") { # Put the ext. back in to uniquify.   if ($sext ne "") { # Put the ext. back in to uniquify.
     $src =~ s/\.eps$/$sext.eps/;      $src =~ s/\.eps$/$sext.eps/;
  }   }
   
     }      }
   
  }   }
       } else {
    # If the postscript file has spaces in its name,
    # LaTeX will gratuitiously vomit.  Therefore
    # queue such files for copy with " " replaced by "_".
    # printout.pm will know them by their .ps  or .eps extensions.
    my $newsrc = $orig_src;
    $newsrc    =~  s|(.*)/res/|/home/httpd/html/res/|;
    open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat");
    print FILE "$src\n";
    close FILE;
    $src=~s|/home/httpd/html/res|/home/httpd/prtspool|;
    $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;
     }      }
     my ($path,$file)=($src=~m|(.*)/([^/]*)$|);      my ($path,$file)=($src=~m|(.*)/([^/]*)$|);
       $path =~ s/ /\_/g;
       $file =~ s/ /\_/g;
     &Apache::lonxml::debug("get_eps_image returning: $path / $file<BR />");      &Apache::lonxml::debug("get_eps_image returning: $path / $file<BR />");
     return ($path.'/',$file);      return ($path.'/',$file);
 }  }
Line 4209  sub get_eps_image { Line 4232  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\/([^\/]*)\/public_html\//\/$1\//;      $newsrc=~s{/home/($LONCAPA::username_re)/public_html/}{/$1/};
     $newsrc=~s/\/\.\//\//;      $newsrc=~s{/\./}{/};
     $newsrc=~s/\/([^\/]+)\.(ps|eps)/\//;      $newsrc=~s{/([^/]+)\.(ps|eps)}{/};
     if ($newsrc=~/\/home\/httpd\/lonUsers\//) {      if ($newsrc=~m{/home/httpd/lonUsers/}) {
  $newsrc=~s/\/home\/httpd\/lonUsers//;   $newsrc=~s{/home/httpd/lonUsers}{};
  $newsrc=~s/\/([^\/]+)\/(\w)\/(\w)\/(\w)\//\/$1\//;   $newsrc=~s{/($LONCAPA::domain_re)/./././}{/$1/};
     }      }
     if ($newsrc=~/\/userfiles\//) {      if ($newsrc=~m{/userfiles/}) {
  return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';   return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
     } else {      } else {
  return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';   return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
Line 4237  sub file_path { Line 4262  sub file_path {
     }       } 
     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 4286  sub LATEX_length { Line 4308  sub LATEX_length {
 }  }
   
   
 # is_inside_of $tagstack $tag  sub align_latex_image {
 #    This sub returns true if the current state of Xml processing      my ($align, $latex_rendering, $image, $width, $height) = @_;
 #    is inside of the tag.         my $currentstring;        # The 1/2 wrapped image.
 # Parameters:      my $closure;              # The closure of the wrappage.
 #     tagstack   - The tagstack from the parser.  
 #     tag        - The tag (without the <>'s.).      # if it's none just return it back
 # Sample usage:      if ($latex_rendering eq 'none') {
 #     if (is_inside_of($tagstack "table")) {   return ($image,'');
 #          # I'm in a table....      }
 #      }  
       #    If there's an alignment specification we need to honor it here.
       #    For the horizontal alignments, we will also honor the
       #    value of the latex specfication.  The default is parbox,
       #    and that's used for illegal values too.  
       #    
       #    Even though we set a default alignment value, the user
       #    could have given us an illegal value.  In that case we
       #    just use the default alignment of bottom..
       $currentstring = '';
       if      ($align eq "top")    {
    $currentstring .= '\raisebox{-'.$height.'mm}{'.$image;
    $closure = '}';
       } elsif (($align eq "center") || ($align eq "middle")) { # Being kind
    my $offset = $height/2;
    $currentstring .= '\raisebox{-'.$offset.'mm}{'.$image;
    $closure       = '}';
       } elsif ($align eq "left")   { 
    if ($latex_rendering eq "parpic") { 
       $currentstring .= '\parpic[l]{'.$image;
       $closure       = '}';
    } elsif ($latex_rendering eq "parbox") {
       $currentstring .= '\begin{minipage}[l]{'.$width.'mm}'
    .$image;
       $closure = '\end{minipage}';
    } elsif ($latex_rendering eq "wrapfigure"
    || $latex_rendering ne 'none') {  # wrapfig render
       $currentstring .= 
    '\begin{wrapfigure}{l}{'.$width.'mm}'
    .'\scalebox{1.0}{'.$image;
       $closure = '}\end{wrapfigure}';
    }
       } elsif ($align eq "right")  {   
    if ($latex_rendering eq "parpic") {
       $currentstring .= '\parpic[r]{'.$image;
       $closure = '}';
    } elsif ($latex_rendering eq "parbox") {
       $currentstring .=  '\begin{minipage}[r]{'.$width.'mm}'
    .$image;
       $closure = '\end{minipage}';
    } elsif ($latex_rendering eq "wrapfigure"
    || $latex_rendering ne 'none') {  # wrapfig render
       $currentstring .= 
    '\begin{wrapfigure}{r}{'.$width.'mm}'
    .'\scalebox{1.0}{'.$image;
       $closure = '}\end{wrapfigure}';
    }
       } else { # Bottom is also default.
    # $currentstring = '\raisebox{'.$height.'mm}{'.$image.'}';
    $currentstring .= "{$image";
    $closure       = '}';
       }
       return ($currentstring, $closure);
   }
   
   
 sub is_inside_of {  sub is_inside_of {
     my ($tagstack, $tag) = @_;      my ($tagstack, $tag) = @_;
     my @stack = @$tagstack;      my @stack = @$tagstack;
Line 4308  sub is_inside_of { Line 4385  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}'.
    '\usepackage{longtable}'.
    '\usepackage{textcomp}'.
    '\usepackage{makeidx}'.
    '\usepackage[dvips]{graphicx}'.
    '\usepackage{wrapfig}'.
    '\usepackage{picins}'.
    '\usepackage[T1]{fontenc}'."\n".
    '\usepackage{lmodern}'."\n".
    '\usepackage[postscript]{ucs}'."\n".
    '\usepackage[utf8x]{inputenc}'."\n".
    '\usepackage{pifont}' ."\n".
    '\usepackage{latexsym}'."\n".
    '\usepackage{epsfig}'.
    "\\usepackage{xtab}\n".
    "\\usepackage{tabularx}\n".
    "\\usepackage{booktabs}\n".
    "\\usepackage{array}\n".
    "\\usepackage{colortbl}\n".
    "\\usepackage{xcolor}\n".
    '\usepackage{calc}'.
    '\usepackage{amsmath}'.
       '\usepackage{soul}',
    '\usepackage{amssymb}'.
    '\usepackage{amsfonts}'.
    '\usepackage{amsthm}'.
    '\usepackage{amscd}'
           .'\usepackage{picins}\usepackage{calc}'."\n". # From lonprintout.pm
    '\usepackage[T1]{fontenc}'."\n".
    '\usepackage{lmodern}'."\n".
    '\usepackage[postscript]{ucs}'."\n".
    '\usepackage[utf8x]{inputenc}'."\n".
    '\usepackage{pifont}'  . "\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;
   
   }
   
   =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....
         }
   
   
   
   =back
   
   =cut
   
   
 1;  1;
 __END__  __END__

Removed from v.1.330  
changed lines
  Added in v.1.431


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