File:  [LON-CAPA] / loncom / xml / londefdef.pm
Revision 1.260: download - view: text, annotated - select for diffs
Wed Mar 2 22:26:36 2005 UTC (19 years, 2 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
lonnet::repcopy() and lonnet::repcopy_userfile() now return strings rather than constants defined in Apache::Constants.  This allows lonnet::repcopy() to be used for cloning in batch course creation run from a command line script.  If Apache::Constants are to be returned by PerlHandlers these should be set in the appropriate handler rather than in subroutines in lonnet called by the handler, based on the string response from lonnet::repcopy().

    1: # The LearningOnline Network with CAPA
    2: # Tags Default Definition Module 
    3: #
    4: # $Id: londefdef.pm,v 1.260 2005/03/02 22:26:36 raeburn Exp $
    5: # 
    6: #
    7: # Copyright Michigan State University Board of Trustees
    8: #
    9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   10: #
   11: # LON-CAPA is free software; you can redistribute it and/or modify
   12: # it under the terms of the GNU General Public License as published by
   13: # the Free Software Foundation; either version 2 of the License, or
   14: # (at your option) any later version.
   15: #
   16: # LON-CAPA is distributed in the hope that it will be useful,
   17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19: # GNU General Public License for more details.
   20: #
   21: # You should have received a copy of the GNU General Public License
   22: # along with LON-CAPA; if not, write to the Free Software
   23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24: #
   25: # /home/httpd/html/adm/gpl.txt
   26: #
   27: # http://www.lon-capa.org/
   28: ## Copyright for TtHfunc and TtMfunc by Ian Hutchinson. 
   29: # TtHfunc and TtMfunc (the "Code") may be compiled and linked into 
   30: # binary executable programs or libraries distributed by the 
   31: # Michigan State University (the "Licensee"), but any binaries so 
   32: # distributed are hereby licensed only for use in the context
   33: # of a program or computational system for which the Licensee is the 
   34: # primary author or distributor, and which performs substantial 
   35: # additional tasks beyond the translation of (La)TeX into HTML.
   36: # The C source of the Code may not be distributed by the Licensee
   37: # to any other parties under any circumstances.
   38: #
   39: 
   40: package Apache::londefdef; 
   41: 
   42: use Apache::lonnet();
   43: use strict;
   44: use Apache::lonxml;
   45: use Apache::File();
   46: use Image::Magick;
   47: use Apache::lonmenu();
   48: use Apache::lonmeta();
   49: use Apache::Constants qw(:common);
   50: 
   51: 
   52: BEGIN {
   53: 
   54:     &Apache::lonxml::register('Apache::londefdef',('a','abbr','acronym','accessrule','address','allow','applet','area','b','base','basefont','bgo','bgsound','big','blink','blockquote','blankspace','body','br','button','caption','center','cite','code','col','colgroup','dd','del','dfn','dir','div','dl','dt','em','embed','externallink','fieldset','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','i','iframe','img','input','ins','insert','isindex','kbd','keygen','label','layer','legend','li','link','m','map','marquee','menu','meta','multicol','nobr','noembed','noframes','nolayer','noscript','object','ol','optgroup','option','output','p','param','pre','q','s','samp','select','server','small','spacer','span','strike','strong','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','tthoption','u','ul','var','wbr','hideweboutput'));
   55: 
   56: }
   57: 
   58: sub initialize_londefdef {
   59:     $Apache::londefdef::TD_redirection=0;
   60:     @Apache::londefdef::table = ();
   61:     $Apache::londefdef::select=0;
   62:     undef(@Apache::londefdef::description);
   63:     @Apache::londefdef::DD=(0);
   64:     @Apache::londefdef::DT=(0);
   65:     @Apache::londefdef::seenDT=(0);
   66:     $Apache::londefdef::list_index=0;
   67: }
   68: 
   69: #======================= TAG SUBROUTINES =====================
   70: #-- <output>
   71: sub start_output {
   72:     my ($target) = @_;
   73:     if ($target eq 'meta') { $Apache::lonxml::metamode--; }
   74:     return '';
   75: }
   76: sub end_output {
   77:     my ($target) = @_;
   78:     if ($target eq 'meta') { $Apache::lonxml::metamode++; }
   79:     return '';
   80: }
   81: #-- <m> tag
   82: sub start_m {
   83:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
   84:     my $currentstring = '';
   85:     my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);
   86:     if ($target eq 'web' || $target eq 'analyze') {
   87: 	&Apache::lonxml::debug("M is starting with:$inside:");
   88: 	my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
   89: 	if ($eval eq 'on') {
   90: 	    $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
   91: 	    #&Apache::lonxml::debug("M is evaulated to:$inside:");
   92: 	}
   93: 	$currentstring = &Apache::lontexconvert::converted(\$inside);
   94: 	if ($Apache::lontexconvert::errorstring) {
   95: 	    &Apache::lonxml::warning("tth error: ".
   96: 				     $Apache::lontexconvert::errorstring);
   97: 	    $Apache::lontexconvert::errorstring='';
   98: 	}
   99: 	#&Apache::lonxml::debug("M is ends with:$currentstring:");
  100: 	$Apache::lonxml::post_evaluate=0;
  101:     } elsif ($target eq 'tex') {
  102: 	$currentstring = $inside;
  103: 	my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
  104: 	if ($eval eq 'on') {
  105: 	    $currentstring=&Apache::run::evaluate($currentstring,$safeeval,$$parstack[-1]);
  106: 	}
  107: 	if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';}
  108: 	# detect simple math mode entry exits, and convert them
  109:         # to use \ensuremath
  110: 	if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) {
  111: 	    $currentstring=~s/^\$//;
  112: 	    $currentstring=~s/\$$//;
  113: 	    $currentstring='\ensuremath{'.$currentstring.'}';
  114: 	}
  115: 	$Apache::lonxml::post_evaluate=0;
  116:     }
  117:     return $currentstring;
  118: }
  119: 
  120: sub end_m {
  121:     my ($target,$token) = @_;
  122:     my $currentstring = '';
  123:     if ($target eq 'tex') {
  124: 	$currentstring = "";
  125:     }
  126:     return $currentstring;
  127: }
  128: 
  129: sub start_tthoption {
  130:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  131:     my $result;
  132:     if ($target eq 'web') {
  133: 	my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser);
  134: 	$inside=~s/^\s*//;
  135: 	if ($ENV{'browser.mathml'}) {
  136: 	    &tth::ttmoptions($inside);
  137: 	} else {
  138: 	    &tth::tthoptions($inside);
  139: 	}
  140:     }
  141:     return $result;
  142: }
  143: 
  144: sub end_tthoption {
  145:     my ($target,$token) = @_;
  146:     my $result;
  147:     return $result;
  148: }
  149: 
  150: #-- <html> tag (end tag optional)
  151: sub start_html {
  152:     my ($target,$token) = @_;
  153:     my $currentstring = '';
  154:     my $options=$ENV{'course.'.$ENV{'request.course.id'}.'.tthoptions'};
  155:     &Apache::lontexconvert::init_tth();
  156:     if ($target eq 'web' || $target eq 'edit') {
  157: 	$currentstring = &Apache::lonxml::xmlbegin();
  158:     } elsif ($target eq 'tex') {
  159: 	@Apache::londefdef::table = ();
  160: 	$currentstring .= '\documentclass[letterpaper]{article}';
  161: 	if (($ENV{'form.latex_type'}=~'batchmode') ||
  162:             (!$ENV{'request.role.adv'})) {$currentstring .='\batchmode';} 
  163: 	$currentstring .= '\newcommand{\keephidden}[1]{}'.
  164:                           '\renewcommand{\deg}{$^{\circ}$}'.
  165:                           '\usepackage{longtable}'.
  166:                           '\usepackage{textcomp}'.
  167:                           '\usepackage{makeidx}'.
  168:                           '\usepackage[dvips]{graphicx}'.
  169: 			  '\usepackage{picins}'.
  170:                           '\usepackage{epsfig}'.
  171:                           '\usepackage{calc}'.
  172:                           '\usepackage{amsmath}'.
  173:                           '\usepackage{amssymb}'.
  174:                           '\usepackage{amsfonts}'.
  175:                           '\usepackage{amsthm}'.
  176:                           '\usepackage{amscd}'.
  177:                           '\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}}'.
  178:                           '\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}}';
  179:     }
  180:     return $currentstring;
  181: }
  182: 
  183: sub end_html {
  184:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  185:     my $currentstring = '';
  186:     if ($target eq 'web') {
  187: 	$currentstring = '</html>';
  188:     }
  189:     return $currentstring;
  190: }
  191: 
  192: #-- <head> tag (end tag optional)
  193: sub start_head {
  194:     my ($target,$token) = @_;
  195:     my $currentstring = '';
  196:     if ($target eq 'web') {
  197: 	$currentstring = $token->[4].&Apache::lonxml::fontsettings();
  198:     } 
  199:     return $currentstring;
  200: }
  201: 
  202: sub end_head {
  203:     my ($target,$token) = @_;
  204:     my $currentstring = '';
  205:     if ($target eq 'web' && $ENV{'request.state'} eq 'published') {
  206: 	$currentstring = &Apache::lonmenu::registerurl(undef,$target).
  207: 	    $token->[2];    
  208:     } 
  209:     return $currentstring;
  210: }
  211: 
  212: #-- <map> tag (end tag required)
  213: sub start_map {
  214:     my ($target,$token) = @_;
  215:     my $currentstring = '';
  216:     if ($target eq 'web') {
  217: 	$currentstring = $token->[4];     
  218:     } 
  219:     return $currentstring;
  220: }
  221: 
  222: sub end_map {
  223:     my ($target,$token) = @_;
  224:     my $currentstring = '';
  225:     if ($target eq 'web') {
  226: 	$currentstring = $token->[2];    
  227:     } 
  228:     return $currentstring;
  229: }
  230: 
  231: #-- <select> tag (end tag required)
  232: sub start_select {
  233:     my ($target,$token) = @_;
  234:     my $currentstring = '';
  235:     if ($target eq 'web') {
  236: 	$currentstring = $token->[4];     
  237:     }  elsif ($target eq 'tex') {
  238: 	$Apache::londefdef::select=0;
  239:     }
  240:     return $currentstring;
  241: }
  242: 
  243: sub end_select {
  244:     my ($target,$token) = @_;
  245:     my $currentstring = '';
  246:     if ($target eq 'web') {
  247: 	$currentstring = $token->[2];    
  248:     } 
  249:     return $currentstring;
  250: }
  251: 
  252: #-- <option> tag (end tag optional)
  253: sub start_option {
  254:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  255:     my $currentstring = '';
  256:     if ($target eq 'web') {
  257: 	$currentstring = $token->[4];     
  258:     } elsif ($target eq 'tex') {
  259: 	$Apache::londefdef::select++;
  260: 	if ($Apache::londefdef::select == 1) {
  261: 	    $currentstring='\noindent\fbox{'.&Apache::lonxml::get_param('value',$parstack,$safeeval).'}\keephidden{';
  262: 	} else {
  263: 	    $currentstring='\keephidden{';
  264: 	}
  265:     }
  266:     return $currentstring;
  267: }
  268: 
  269: sub end_option {
  270:     my ($target,$token) = @_;
  271:     my $currentstring = '';
  272:     if ($target eq 'web') {
  273: 	$currentstring = $token->[2];    
  274:     }  elsif ($target eq 'tex') {
  275: 	$currentstring='}';
  276:     }
  277:     return $currentstring;
  278: }
  279: 
  280: #-- <input> tag (end tag forbidden)
  281: sub start_input {
  282:     my ($target,$token) = @_;
  283:     my $currentstring = '';
  284:     if ($target eq 'web') {
  285: 	$currentstring = $token->[4];     
  286:     } 
  287:     return $currentstring;
  288: }
  289: 
  290: sub end_input {
  291:     my ($target,$token) = @_;
  292:     my $currentstring = '';
  293:     if ($target eq 'web') {
  294: 	$currentstring = $token->[2];    
  295:     } 
  296:     return $currentstring;
  297: }
  298: 
  299: #-- <textarea> tag (end tag required)
  300: sub start_textarea {
  301:     my ($target,$token) = @_;
  302:     my $currentstring = '';
  303:     if ($target eq 'web') {
  304: 	$currentstring = $token->[4];     
  305:     } 
  306:     return $currentstring;
  307: }
  308: 
  309: sub end_textarea {
  310:     my ($target,$token) = @_;
  311:     my $currentstring = '';
  312:     if ($target eq 'web') {
  313: 	$currentstring = $token->[2];    
  314:     } 
  315:     return $currentstring;
  316: }
  317: 
  318: #-- <form> tag (end tag required)
  319: sub start_form {
  320:     my ($target,$token) = @_;
  321:     my $currentstring = '';
  322:     if ($target eq 'web') {
  323: 	$currentstring = $token->[4];     
  324:     } 
  325:     return $currentstring;
  326: }
  327: 
  328: sub end_form {
  329:     my ($target,$token) = @_;
  330:     my $currentstring = '';
  331:     if ($target eq 'web') {
  332: 	$currentstring = $token->[2];    
  333:     } 
  334:     return $currentstring;
  335: }
  336: 
  337: #-- <title> tag (end tag required)
  338: sub start_title {
  339:     my ($target,$token) = @_;
  340:     my $currentstring = '';
  341:     if ($target eq 'web') {
  342: 	$currentstring = $token->[4];     
  343:     } elsif ($target eq 'tex') {
  344: 	$currentstring .= '\keephidden{Title of the document:  ' 
  345:     }
  346:     if ($target eq 'meta') {
  347: 	$currentstring='<title>';
  348: 	&start_output($target);
  349:     }
  350:     return $currentstring;
  351: }
  352: 
  353: sub end_title {
  354:     my ($target,$token) = @_;
  355:     my $currentstring = '';
  356:     if ($target eq 'web') {
  357: 	$currentstring = $token->[2];    
  358:     } elsif ($target eq 'tex') {
  359: 	$currentstring .= '}';
  360:     }  
  361:     if ($target eq 'meta') {
  362: 	&end_output($target);
  363: 	$currentstring='</title>';
  364:     } 
  365:     return $currentstring;
  366: }
  367: 
  368: #-- <meta> tag (end tag forbidden)
  369: sub start_meta {
  370:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  371:     my $currentstring = '';
  372:     if ($target eq 'web') {
  373: 	my $args='';
  374: 	if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
  375: 	if ($args eq '') {
  376: 	    &Apache::lonxml::get_all_text("/meta",$parser);
  377: 	} else {
  378: 	    $currentstring = $token->[4];
  379: 	}
  380:     } elsif ($target eq 'meta') {
  381: 	unless (&Apache::lonxml::get_param
  382: 		('http-equiv',$parstack,$safeeval,undef,1)) {
  383: 	    my $name=$token->[2]->{'name'};
  384: 	    $name=~tr/A-Z/a-z/;
  385: 	    $name=~s/\s/\_/gs;
  386: 	    $name=~s/\W//gs;
  387: 	    if ($name) {
  388: 		$currentstring='<'.$name;
  389:                  my $display=&Apache::lonxml::get_param
  390: 		('display',$parstack,$safeeval,undef,1);
  391:                 if ($display) {
  392:                     $display=~s/\"/\'/g;
  393: 		    $currentstring.=' display="'.$display.'"';
  394:                 }
  395: 		$currentstring.='>'.
  396: 		    &Apache::lonxml::get_param
  397: 			('content',$parstack,$safeeval,undef,1).
  398: 			'</'.$name.'>';
  399: 	    }
  400:             my $display=&Apache::lonxml::get_param
  401: 		('display',$parstack,$safeeval,undef,1);
  402:             if ($display) {
  403: 		$display=&HTML::Entities::encode($display,'<>&"');
  404: 		$currentstring.='<'.$name.'.display>'.$display.
  405:                                '</'.$name.'.display>';
  406:             }
  407: 	}
  408:     } elsif ($target eq 'tex') {
  409: 	my $content=&Apache::lonxml::get_param('content',$parstack,$safeeval);
  410: 	my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval);
  411: 	if ((not defined $content) && (not defined $name)) {
  412: 	    &Apache::lonxml::startredirection();
  413: 	}
  414:     }
  415:     return $currentstring;
  416: }
  417: 
  418: sub end_meta {
  419:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  420:     my $currentstring = '';
  421:     if ($target eq 'web') {
  422: 	my $args='';
  423: 	if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
  424: 	if ($args ne '') {
  425: 	    $currentstring = $token->[4];
  426: 	}
  427:     } elsif ($target eq 'tex') {
  428: 	my $content=&Apache::lonxml::get_param('content',$parstack,$safeeval);
  429: 	my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval);
  430: 	if ((not defined $content) && (not defined $name)) {
  431: 	    &Apache::lonxml::endredirection();
  432: 	}
  433:     }
  434:     return $currentstring;
  435: }
  436: 
  437: # accessrule
  438: sub start_accessrule {
  439:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  440:     my $currentstring = '';
  441:     my $eff=&Apache::lonxml::get_param
  442: 	('effect',$parstack,$safeeval,undef,1);
  443:     my $realm=&Apache::lonxml::get_param
  444: 	('realm',$parstack,$safeeval,undef,1);
  445:     my $role=&Apache::lonxml::get_param
  446: 	('role',$parstack,$safeeval,undef,1);
  447:     $realm=~s/\s+//g;
  448:     $realm=~s/\//\_/g;
  449:     $realm=~s/^\_//;
  450:     $realm=~s/\W/\;/g;
  451:     $role=~s/\s+//g;
  452:     $role=~s/\//\_/g;
  453:     $role=~s/\W/\;/g;
  454:     if ($target eq 'web') {
  455: 	my $args='';
  456: 	if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
  457: 	if ($args eq '') {
  458: 	    &Apache::lonxml::get_all_text("/accessrule",$parser);
  459: 	} else {
  460: 	    $currentstring = $token->[4];
  461: 	}
  462:     }
  463:     if ($target eq 'meta') {
  464: 	$currentstring='<rule>'.$eff.':'.$realm.':'.$role.'</rule>';
  465:     }
  466:     return $currentstring;
  467: }
  468: 
  469: sub end_accessrule {
  470:     my ($target,$token,$tagstack,$parstack,$parser) = @_;
  471:     my $currentstring = '';
  472:     if ($target eq 'web') {
  473: 	my $args='';
  474: 	if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
  475: 	if ($args ne '') {
  476: 	    $currentstring = $token->[4];
  477: 	}
  478:     } 
  479:     return $currentstring;
  480: }
  481: 
  482: #-- <body> tag (end tag required)
  483: sub start_body {
  484:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  485:     my $currentstring = '';
  486: 
  487:     if ($target eq 'web') {
  488: 	if ($Apache::lonhomework::parsing_a_problem) {
  489: 	    &Apache::lonxml::warning("<body> tag found inside of <problem> tag this can cause problems.");
  490: 	    return '';
  491: 	}
  492: 	if (!$Apache::lonxml::registered && 
  493: 	    $ENV{'request.state'} eq 'published') {
  494: 	    $currentstring.='<head>'.
  495: 		&Apache::lonmenu::registerurl(undef,$target).'</head>';
  496: 	}
  497: # Accessibility
  498: 	if ($ENV{'browser.imagesuppress'} eq 'on') {
  499: 	    delete($token->[2]->{'background'});
  500: 	}
  501: 	if ($ENV{'browser.fontenhance'} eq 'on') {
  502: 	    my $style='';
  503: 	    foreach my $key (keys(%{$token->[2]})) {
  504: 		if ($key =~ /^style$/i) {
  505: 		    $style.=$token->[2]->{$key}.';';
  506: 		    delete($token->[2]->{$key});
  507: 		}
  508: 	    }
  509: 	    $token->[2]->{'style'}=$style.'; font-size: x-large;';
  510: 	}
  511: 	if ($ENV{'browser.blackwhite'} eq 'on') {
  512: 	    delete($token->[2]->{'font'});
  513: 	    delete($token->[2]->{'link'});
  514: 	    delete($token->[2]->{'alink'});
  515: 	    delete($token->[2]->{'vlink'});
  516: 	    delete($token->[2]->{'bgcolor'});
  517: 	    delete($token->[2]->{'background'});
  518: 	}
  519: # Overload loads
  520: 	my $onLoad='';
  521: 	foreach my $key (keys(%{$token->[2]})) {
  522: 	    if ($key =~ /^onload$/i) {
  523: 		$onLoad.=$token->[2]->{$key}.';';
  524: 		delete($token->[2]->{$key});
  525: 	    }
  526: 	}
  527: 	$token->[2]->{'onload'}=&Apache::lonmenu::loadevents().';'.$onLoad;
  528: 	my $onUnload='';
  529: 	foreach my $key (keys(%{$token->[2]})) {
  530: 	    if ($key =~ /^onunload$/i) {
  531: 		$onUnload.=$token->[2]->{$key}.';';
  532: 		delete($token->[2]->{$key});
  533: 	    }
  534: 	}
  535: 	$token->[2]->{'onunload'}=&Apache::lonmenu::unloadevents().
  536: 	    ';'.$onUnload;
  537: 	
  538: 	if ($ENV{'request.state'} ne 'construct') {
  539: 	    $currentstring .= '<'.$token->[1];
  540: 	}
  541: 	foreach (keys %{$token->[2]}) {
  542: 	    $currentstring.=' '.$_.'="'.$token->[2]->{$_}.'"';
  543: 	}
  544: 	if ($ENV{'request.state'} ne 'construct') {
  545: 	    $currentstring.='>';
  546: 	}
  547: 	if ($ENV{'request.state'} ne 'published') {
  548: 	    my $remote=($ENV{'environment.remote'} ne 'off');
  549: 	    $currentstring=&Apache::loncommon::bodytag(undef,undef,
  550: 						       $currentstring,$remote);
  551: 	    $currentstring.=(<<EDITBUTTON);
  552: 		<form method="post">
  553: 		<input type="submit" name="editmode" accesskey="e" value="Edit" />
  554: 		</form>
  555: EDITBUTTON
  556: 	} else {
  557: 	    $currentstring.=&Apache::lonmenu::menubuttons(undef,$target,1);
  558: 	}
  559: 	$currentstring.=&Apache::lonxml::message_location();
  560:     } elsif ($target eq 'tex') {
  561: 	$currentstring = '\begin{document}';  
  562:     } 
  563:     return $currentstring;
  564: }
  565: 
  566: sub end_body {
  567:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  568:     my $currentstring = '';
  569:     if ($target eq 'web') {
  570: 	$currentstring = &Apache::lonxml::xmlend($target,$parser);
  571:     } elsif ($target eq 'tex') {
  572: 	$currentstring = '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}';  
  573:     } 
  574:     return $currentstring;
  575: }
  576: 
  577: #-- <center> tag (end tag required)
  578: sub start_center {
  579:     my ($target,$token) = @_;
  580:     my $currentstring = '';
  581:     if ($target eq 'web') {
  582: 	$currentstring = $token->[4];     
  583:     } elsif ($target eq 'tex') {
  584: 	$currentstring = '\begin{center}';  
  585:     }
  586:     return $currentstring;
  587: }
  588: 
  589: sub end_center {
  590:     my ($target,$token) = @_;
  591:     my $currentstring = '';
  592:     if ($target eq 'web') {
  593: 	$currentstring = $token->[2];     
  594:     } elsif ($target eq 'tex') {
  595: 	$currentstring = '\end{center}';  
  596:     }
  597:     return $currentstring;
  598: }
  599: 
  600: #-- <b> tag (end tag required)
  601: sub start_b {
  602:     my ($target,$token) = @_;
  603:     my $currentstring = '';
  604:     if ($target eq 'web') {
  605: 	$currentstring = $token->[4];     
  606:     } elsif ($target eq 'tex') {
  607: 	$currentstring = '\textbf{';  
  608:     } 
  609:     return $currentstring;
  610: }
  611: 
  612: sub end_b {
  613:     my ($target,$token) = @_;
  614:     my $currentstring = '';
  615:     if ($target eq 'web') {
  616: 	$currentstring = $token->[2];     
  617:     } elsif ($target eq 'tex') {
  618: 	$currentstring = '}';  
  619:     } 
  620:     return $currentstring;
  621: }
  622: 
  623: #-- <strong> tag (end tag required)
  624: sub start_strong {
  625:     my ($target,$token) = @_;
  626:     my $currentstring = '';
  627:     if ($target eq 'web') {
  628: 	$currentstring = $token->[4];     
  629:     } elsif ($target eq 'tex') {
  630: 	$currentstring = '\textbf{';  
  631:     } 
  632:     return $currentstring;
  633: }
  634: 
  635: sub end_strong {
  636:     my ($target,$token) = @_;
  637:     my $currentstring = '';
  638:     if ($target eq 'web') {	
  639: 	$currentstring = $token->[2];     
  640:     } elsif ($target eq 'tex') {
  641: 	$currentstring = '}';  
  642:     }
  643:     return $currentstring;
  644: }
  645: 
  646: #-- <h1> tag (end tag required)
  647: sub start_h1 {
  648:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  649:     my $currentstring = '';
  650:     if ($target eq 'web') {
  651: 	$currentstring .= $token->[4];
  652:     } elsif ($target eq 'tex') {
  653: 	my $pre;
  654: 	my $align=lc(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1));
  655: 	if ($align eq 'center') {
  656: 	    $pre='\begin{center}';
  657: 	} elsif ($align eq 'left') {
  658: 	    $pre='\rlap{';
  659: 	} elsif ($align eq 'right') {
  660: 	    $pre=' \hfill \llap{';
  661: 	}
  662: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  663: 	if (not defined $TeXsize) {$TeXsize="large";}
  664: 	$currentstring .= $pre.'{\\'.$TeXsize.' \textbf{'; 
  665:     } elsif ($target eq 'meta') {
  666: 	$currentstring='<subject>';
  667: 	&start_output($target);
  668:     }
  669:     return $currentstring;
  670: }
  671: 
  672: sub end_h1 {
  673:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  674:     my $currentstring = '';
  675:     if ($target eq 'web') {
  676: 	$currentstring .= $token->[2];
  677:     } elsif ($target eq 'tex') {
  678: 	my $post='\vskip 0 mm ';
  679: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  680: 	if ($align eq 'center') {
  681: 	    $post='\end{center}';
  682: 	} elsif ($align eq 'left') {
  683: 	    $post='} \hfill'.'\vskip 0 mm ';
  684: 	} elsif ($align eq 'right') {
  685: 	    $post='}'.'\vskip 0 mm ';
  686: 	}
  687: 	$currentstring .= '}}'.$post;
  688:     } elsif ($target eq 'meta') {
  689: 	&end_output($target);
  690: 	$currentstring='</subject>';
  691:     } 
  692:     return $currentstring;
  693: }
  694: 
  695: #-- <h2> tag
  696: sub start_h2 {
  697:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  698:     my $currentstring = '';
  699:     if ($target eq 'web') {
  700: 	$currentstring .= $token->[4];
  701:     } elsif ($target eq 'tex') {
  702: 	my $pre;
  703: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  704: 	if ($align eq 'center') {
  705: 	    $pre='\begin{center}';
  706: 	} elsif ($align eq 'left') {
  707: 	    $pre='\rlap{';
  708: 	} elsif ($align eq 'right') {
  709: 	    $pre=' \hfill \llap{';
  710: 	}
  711: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  712: 	if (not defined $TeXsize) {$TeXsize="large";}
  713: 	$currentstring .= $pre.'{\\'.$TeXsize.' \textbf{'; 
  714:     } 
  715:     return $currentstring;
  716: }
  717: 
  718: sub end_h2 {
  719:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  720:     my $currentstring = '';
  721:     if ($target eq 'web') {
  722: 	$currentstring .= $token->[2];
  723:     } elsif ($target eq 'tex') {
  724: 	my $post='\vskip 0 mm ';
  725: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  726: 	if ($align eq 'center') {
  727: 	    $post='\end{center}';
  728: 	} elsif ($align eq 'left') {
  729: 	    $post='} \hfill'.'\vskip 0 mm ';
  730: 	} elsif ($align eq 'right') {
  731: 	    $post='}'.'\vskip 0 mm ';
  732: 	}
  733: 	$currentstring .= '}}'.$post;
  734:     } 
  735:     return $currentstring;
  736: }
  737: 
  738: #-- <h3> tag
  739: sub start_h3 {
  740:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  741:     my $currentstring = '';
  742:     if ($target eq 'web') {
  743: 	$currentstring .= $token->[4];
  744:     } elsif ($target eq 'tex') {
  745: 	my $pre;
  746: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  747: 	if ($align eq 'center') {
  748: 	    $pre='\begin{center}';
  749: 	} elsif ($align eq 'left') {
  750: 	    $pre='\rlap{';
  751: 	} elsif ($align eq 'right') {
  752: 	    $pre=' \hfill \llap{';
  753: 	}
  754: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  755: 	if (not defined $TeXsize) {$TeXsize="large";}
  756: 	$currentstring .= $pre.'{\\'.$TeXsize.' \textbf{'; 
  757:     } 
  758:     return $currentstring;
  759: }
  760: 
  761: sub end_h3 {
  762:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  763:     my $currentstring = '';
  764:     if ($target eq 'web') {
  765: 	$currentstring .= $token->[2];
  766:     } elsif ($target eq 'tex') {
  767: 	my $post='\vskip 0 mm ';
  768: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  769: 	if ($align eq 'center') {
  770: 	    $post='\end{center}';
  771: 	} elsif ($align eq 'left') {
  772: 	    $post='} \hfill'.'\vskip 0 mm ';
  773: 	} elsif ($align eq 'right') {
  774: 	    $post='}'.'\vskip 0 mm ';
  775: 	}
  776: 	$currentstring .= '}}'.$post;
  777:     } 
  778:     return $currentstring;
  779: }
  780: 
  781: #-- <h4> tag
  782: sub start_h4 {
  783:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  784:     my $currentstring = '';
  785:     if ($target eq 'web') {
  786: 	$currentstring .= $token->[4];
  787:     } elsif ($target eq 'tex') {
  788: 	my $pre;
  789: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  790: 	if ($align eq 'center') {
  791: 	    $pre='\begin{center}';
  792: 	} elsif ($align eq 'left') {
  793: 	    $pre='\rlap{';
  794: 	} elsif ($align eq 'right') {
  795: 	    $pre=' \hfill \llap{';
  796: 	}
  797: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  798: 	if (not defined $TeXsize) {$TeXsize="large";}
  799: 	$currentstring .= $pre.'{\\'.$TeXsize.' \textbf{'; 
  800:     } 
  801:     return $currentstring;
  802: }
  803: 
  804: sub end_h4 {
  805:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  806:     my $currentstring = '';
  807:     if ($target eq 'web') {
  808: 	$currentstring .= $token->[2];
  809:     } elsif ($target eq 'tex') {
  810: 	my $post='\vskip 0 mm ';
  811: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  812: 	if ($align eq 'center') {
  813: 	    $post='\end{center}';
  814: 	} elsif ($align eq 'left') {
  815: 	    $post='} \hfill'.'\vskip 0 mm ';
  816: 	} elsif ($align eq 'right') {
  817: 	    $post='}'.'\vskip 0 mm ';
  818: 	}
  819: 	$currentstring .= '}}'.$post;
  820:     } 
  821:     return $currentstring;
  822: }
  823: 
  824: #-- <h5> tag
  825: sub start_h5 {
  826:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  827:     my $currentstring = '';
  828:     if ($target eq 'web') {
  829: 	$currentstring .= $token->[4];
  830:     } elsif ($target eq 'tex') {
  831: 	my $pre;
  832: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  833: 	if ($align eq 'center') {
  834: 	    $pre='\begin{center}';
  835: 	} elsif ($align eq 'left') {
  836: 	    $pre='\rlap{';
  837: 	} elsif ($align eq 'right') {
  838: 	    $pre=' \hfill \llap{';
  839: 	}
  840: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  841: 	if (not defined $TeXsize) {$TeXsize="large";}
  842: 	$currentstring .= $pre.'{\\'.$TeXsize.' \textbf{'; 
  843:     } 
  844:     return $currentstring;
  845: }
  846: 
  847: sub end_h5 {
  848:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  849:     my $currentstring = '';
  850:     if ($target eq 'web') {
  851: 	$currentstring .= $token->[2];
  852:     } elsif ($target eq 'tex') {
  853: 	my $post='\vskip 0 mm ';
  854: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  855: 	if ($align eq 'center') {
  856: 	    $post='\end{center}';
  857: 	} elsif ($align eq 'left') {
  858: 	    $post='} \hfill'.'\vskip 0 mm ';
  859: 	} elsif ($align eq 'right') {
  860: 	    $post='}'.'\vskip 0 mm ';
  861: 	}
  862: 	$currentstring .= '}}'.$post;
  863:     } 
  864:     return $currentstring;
  865: }
  866: 
  867: #-- <h6> tag
  868: sub start_h6 {
  869:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  870:     my $currentstring = '';
  871:     if ($target eq 'web') {
  872: 	$currentstring .= $token->[4];
  873:     } elsif ($target eq 'tex') {
  874: 	my $pre;
  875: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  876: 	if ($align eq 'center') {
  877: 	    $pre='\begin{center}';
  878: 	} elsif ($align eq 'left') {
  879: 	    $pre='\rlap{';
  880: 	} elsif ($align eq 'right') {
  881: 	    $pre=' \hfill \llap{';
  882: 	}
  883: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
  884: 	if (not defined $TeXsize) {$TeXsize="large";}
  885: 	$currentstring .= $pre.'{\\'.$TeXsize.' \textbf{'; 
  886:     } 
  887:     return $currentstring;
  888: }
  889: 
  890: sub end_h6 {
  891:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
  892:     my $currentstring = '';
  893:     if ($target eq 'web') {
  894: 	$currentstring .= $token->[2];
  895:     } elsif ($target eq 'tex') {
  896: 	my $post='\vskip 0 mm ';
  897: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
  898: 	if ($align eq 'center') {
  899: 	    $post='\end{center}';
  900: 	} elsif ($align eq 'left') {
  901: 	    $post='} \hfill'.'\vskip 0 mm ';
  902: 	} elsif ($align eq 'right') {
  903: 	    $post='}'.'\vskip 0 mm ';
  904: 	}
  905: 	$currentstring .= '}}'.$post;
  906:     } 
  907:     return $currentstring;
  908: }
  909: 
  910: #--- <cite> tag (end tag required)
  911: sub start_cite {
  912:     my ($target,$token) = @_;
  913:     my $currentstring = '';
  914:     if ($target eq 'web') {
  915: 	$currentstring .= $token->[4];
  916:     } elsif ($target eq 'tex') {
  917: 	$currentstring .= '\textit{';
  918:     }
  919:     return $currentstring;
  920: }
  921: 
  922: sub end_cite {
  923:     my ($target,$token) = @_;
  924:     my $currentstring = '';
  925:     if ($target eq 'web') {
  926: 	$currentstring .= $token->[2];
  927:     } elsif ($target eq 'tex') {
  928: 	$currentstring .= '}';
  929:     }
  930:     return $currentstring;
  931: }
  932: 
  933: #-- <i> tag (end tag required)
  934: sub start_i {
  935:     my ($target,$token) = @_;
  936:     my $currentstring = '';
  937:     if ($target eq 'web') {
  938: 	$currentstring .= $token->[4];
  939:     } elsif ($target eq 'tex') {
  940: 	$currentstring .= '\textit{';
  941:     }
  942:     return $currentstring;
  943: }
  944: 
  945: sub end_i {
  946:     my ($target,$token) = @_;
  947:     my $currentstring = '';
  948:     if ($target eq 'web') {
  949: 	$currentstring .= $token->[2];
  950:     } elsif ($target eq 'tex') {
  951: 	$currentstring .= '}';
  952:     } 
  953:     return $currentstring;
  954: }
  955: 
  956: #-- <address> tag (end tag required)
  957: sub start_address {
  958:     my ($target,$token) = @_;
  959:     my $currentstring = '';
  960:     if ($target eq 'web') {
  961: 	$currentstring .= $token->[4];
  962:     } elsif ($target eq 'tex') {
  963: 	$currentstring .= '\textit{';
  964:     }
  965:     return $currentstring;
  966: }
  967: 
  968: sub end_address {
  969:     my ($target,$token) = @_;
  970:     my $currentstring = '';
  971:     if ($target eq 'web') {
  972: 	$currentstring .= $token->[2];
  973:     } elsif ($target eq 'tex') {
  974: 	$currentstring .= '}';
  975:     }
  976:     return $currentstring;
  977: }
  978: 
  979: #-- <dfn> tag (end tag required)
  980: sub start_dfn {
  981:     my ($target,$token) = @_;
  982:     my $currentstring = '';
  983:     if ($target eq 'web') {
  984: 	$currentstring .= $token->[4];
  985:     } elsif ($target eq 'tex') {
  986: 	$currentstring .= '\textit{';
  987:     } 
  988:     return $currentstring;
  989: }
  990: 
  991: sub end_dfn {
  992:     my ($target,$token) = @_;
  993:     my $currentstring = '';
  994:     if ($target eq 'web') {
  995: 	$currentstring .= $token->[2];
  996:     } elsif ($target eq 'tex') {
  997: 	$currentstring .= '}';
  998:     }
  999:     return $currentstring;
 1000: }
 1001: 
 1002: #-- <tt> tag (end tag required)
 1003: sub start_tt {
 1004:     my ($target,$token) = @_;
 1005:     my $currentstring = '';
 1006:     if ($target eq 'web') {
 1007: 	$currentstring .= $token->[4];
 1008:     } elsif ($target eq 'tex') {
 1009: 	$currentstring .= '\texttt{';
 1010:     }
 1011:     return $currentstring;
 1012: }
 1013: 
 1014: sub end_tt {
 1015:     my ($target,$token) = @_;
 1016:     my $currentstring = '';
 1017:     if ($target eq 'web') {
 1018: 	$currentstring .= $token->[2];
 1019:     } elsif ($target eq 'tex') {
 1020: 	$currentstring .= '}';
 1021:     }
 1022:     return $currentstring;
 1023: }
 1024: 
 1025: #-- <kbd> tag (end tag required)
 1026: sub start_kbd {
 1027:     my ($target,$token) = @_;
 1028:     my $currentstring = '';
 1029:     if ($target eq 'web') {
 1030: 	$currentstring .= $token->[4];
 1031:     } elsif ($target eq 'tex') {
 1032: 	$currentstring .= '\texttt{';
 1033:     }
 1034:     return $currentstring;
 1035: }
 1036: 
 1037: sub end_kbd {
 1038:     my ($target,$token) = @_;
 1039:     my $currentstring = '';
 1040:     if ($target eq 'web') {
 1041: 	$currentstring .= $token->[2];
 1042:     } elsif ($target eq 'tex') {
 1043: 	$currentstring .= '}';
 1044:     }
 1045:     return $currentstring;
 1046: }
 1047: 
 1048: #-- <code> tag (end tag required)
 1049: sub start_code {
 1050:     my ($target,$token) = @_;
 1051:     my $currentstring = '';
 1052:     if ($target eq 'web') {
 1053: 	$currentstring .= $token->[4];
 1054:     } elsif ($target eq 'tex') {
 1055: 	$currentstring .= '\texttt{';
 1056:     } 
 1057:     return $currentstring;
 1058: }
 1059: 
 1060: sub end_code {
 1061:     my ($target,$token) = @_;
 1062:     my $currentstring = '';
 1063:     if ($target eq 'web') {
 1064: 	$currentstring .= $token->[2];
 1065:     } elsif ($target eq 'tex') {
 1066: 	$currentstring .= '}';
 1067:     } 
 1068:     return $currentstring;
 1069: }
 1070: 
 1071: #-- <em> tag (end tag required)
 1072: sub start_em {
 1073:     my ($target,$token) = @_;
 1074:     my $currentstring = '';
 1075:     if ($target eq 'web') {
 1076: 	$currentstring .= $token->[4];
 1077:     } elsif ($target eq 'tex') {
 1078: 	$currentstring .= '\emph{';
 1079:     }
 1080:     return $currentstring;
 1081: }
 1082: 
 1083: sub end_em {
 1084:     my ($target,$token) = @_;
 1085:     my $currentstring = '';
 1086:     if ($target eq 'web') {
 1087: 	$currentstring .= $token->[2];
 1088:     } elsif ($target eq 'tex') {
 1089: 	$currentstring .= '}';
 1090:     } 
 1091:     return $currentstring;
 1092: }
 1093: 
 1094: #-- <q> tag (end tag required)
 1095: sub start_q {
 1096:     my ($target,$token) = @_;
 1097:     my $currentstring = '';
 1098:     if ($target eq 'web') {
 1099: 	$currentstring .= $token->[4];
 1100:     } elsif ($target eq 'tex') {
 1101: 	$currentstring .= '\emph{';
 1102:     }
 1103:     return $currentstring;
 1104: }
 1105: 
 1106: sub end_q {
 1107:     my ($target,$token) = @_;
 1108:     my $currentstring = '';
 1109:     if ($target eq 'web') {
 1110: 	$currentstring .= $token->[2];
 1111:     } elsif ($target eq 'tex') {
 1112: 	$currentstring .= '}';
 1113:     } 
 1114:     return $currentstring;
 1115: }
 1116: 
 1117: #-- <p> tag (end tag optional)
 1118: #optional attribute - align="center|left|right"
 1119: sub start_p {
 1120:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1121:     my $currentstring = '';
 1122:     if ($target eq 'web') {
 1123: 	$currentstring .= $token->[4];
 1124:     } elsif ($target eq 'tex') {
 1125: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
 1126: 	if ($align eq 'center') {
 1127: 	    $currentstring='\begin{center}\par';
 1128: 	} elsif ($align eq 'right') {
 1129: 	    $currentstring='\makebox['.$ENV{'form.textwidth'}.']{\hfill\llap{';
 1130: 	} elsif ($align eq 'left') {
 1131: 	    $currentstring='\noindent\makebox['.$ENV{'form.textwidth'}.']{\rlap{';
 1132: 	} else {
 1133:             $currentstring='\par ';
 1134:         }
 1135: 	my $signal=1;#<p> does not work inside <b>...</b> 
 1136: 	foreach my $tag (@$tagstack) {if (lc($tag) eq 'b') {$signal=0;}
 1137: 	if (!$signal) {$currentstring = '';}
 1138: 	}
 1139:     }
 1140:     return $currentstring;
 1141: }
 1142: 
 1143: sub end_p {
 1144:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1145:     my $currentstring = '';
 1146:     if ($target eq 'web') {
 1147: 	$currentstring .= $token->[2];
 1148:     } elsif ($target eq 'tex') {
 1149: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
 1150: 	if (not defined $align) {
 1151: 	    $currentstring.='\strut\\\\\strut ';
 1152: 	} elsif ($align eq 'center') {		
 1153: 	    $currentstring .= '\end{center}';
 1154: 	} elsif ($align eq 'right') {
 1155: 	    $currentstring .= '}}';
 1156: 	} elsif ($align eq 'left') {
 1157: 	    $currentstring .= '}\hfill}';
 1158: 	} 
 1159:     }
 1160:     return $currentstring;
 1161: }
 1162: 
 1163: #-- <br> tag (end tag forbidden)
 1164: sub start_br {
 1165:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
 1166:     my $currentstring = '';
 1167:     if ($target eq 'web') {
 1168: 	$currentstring .= $token->[4];
 1169:     } elsif ($target eq 'tex') {
 1170: 	my @tempo=@$tagstack;
 1171: 	my $signal=0;
 1172: 	for (my $i=$#tempo;$i>=0;$i--) {
 1173: 	    if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') ||
 1174:                 ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul') ||
 1175:                 ($tempo[$i] eq 'td') || ($tempo[$i] eq 'th'))  {
 1176: 		$signal=1;
 1177: 		last;
 1178: 	    }
 1179: 	}
 1180: 	if ($signal) {
 1181: 	    $currentstring .= ' \vskip 0 mm ';
 1182: 	} elsif ($$tagstack[-2] ne 'sub' && $$tagstack[-2] ne 'sup') {
 1183: 	    $currentstring .= '\strut \\\\ \strut ';
 1184: 	}
 1185:     }
 1186:     return $currentstring;
 1187: }
 1188: 
 1189: sub end_br {
 1190:     my ($target,$token) = @_;
 1191:     my $currentstring = '';
 1192:     if ($target eq 'web') {
 1193: 	$currentstring .= $token->[2];
 1194:     }
 1195:     return $currentstring;
 1196: }
 1197: 
 1198: #-- <big> tag (end tag required)
 1199: sub start_big {
 1200:     my ($target,$token) = @_;
 1201:     my $currentstring = '';
 1202:     if ($target eq 'web') {
 1203: 	$currentstring .= $token->[4];
 1204:     } elsif ($target eq 'tex') {
 1205: 	$currentstring .= '{\large ';
 1206:     } 
 1207:     return $currentstring;
 1208: }
 1209: 
 1210: sub end_big {
 1211:     my ($target,$token) = @_;
 1212:     my $currentstring = '';
 1213:     if ($target eq 'web') {
 1214: 	$currentstring .= $token->[2];
 1215:     } elsif ($target eq 'tex') {
 1216: 	$currentstring .= '}';
 1217:     }
 1218:     return $currentstring;
 1219: }
 1220: 
 1221: #-- <small> tag (end tag required)
 1222: sub start_small {
 1223:     my ($target,$token) = @_;
 1224:     my $currentstring = '';
 1225:     if ($target eq 'web') {
 1226: 	$currentstring .= $token->[4];
 1227:     } elsif ($target eq 'tex') {
 1228: 	$currentstring .= '{\footnotesize ';
 1229:     }
 1230:     return $currentstring;
 1231: }
 1232: 
 1233: sub end_small {
 1234:     my ($target,$token) = @_;
 1235:     my $currentstring = '';
 1236:     if ($target eq 'web') {
 1237: 	$currentstring .= $token->[2];
 1238:     } elsif ($target eq 'tex') {
 1239: 	$currentstring .= '}';
 1240:     }
 1241:     return $currentstring;
 1242: }
 1243: 
 1244: #-- <basefont> tag (end tag forbidden)
 1245: sub start_basefont {
 1246:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
 1247:     my $currentstring = '';
 1248:     if ($target eq 'web') {
 1249: 	$currentstring = $token->[4];     
 1250:     } elsif ($target eq 'tex') {
 1251: 	my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
 1252: 	if (defined $basesize) {
 1253: 	    $currentstring = '{\\'.$basesize.' ';
 1254: 	}
 1255:     }
 1256:     return $currentstring;
 1257: }
 1258: 
 1259: sub end_basefont {
 1260:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1261:     my $currentstring = '';
 1262:     if ($target eq 'web') {
 1263: 	$currentstring = $token->[4];     
 1264:     } elsif ($target eq 'tex') {
 1265: 	my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
 1266: 	if (defined $basesize) {
 1267: 	    $currentstring = '}';
 1268: 	}
 1269:     }
 1270:     return $currentstring;
 1271: }
 1272: 
 1273: #-- <font> tag (end tag required)
 1274: sub start_font {
 1275:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
 1276:     my $currentstring = '';
 1277:     if ($target eq 'web') {
 1278: 	my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);
 1279: 	if ($face!~/symbol/i) {
 1280: 	    if (($ENV{'browser.fontenhance'} eq 'on') || 
 1281: 		($ENV{'browser.blackwhite'} eq 'on')) { return ''; }
 1282: 	}
 1283: 	$currentstring = $token->[4];     
 1284:     }  elsif ($target eq 'tex') {
 1285: 	my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
 1286: 	if (defined $fontsize) {
 1287: 	    $currentstring = '{\\'.$fontsize.' ';
 1288: 	}
 1289:     }
 1290:     return $currentstring;
 1291: }
 1292: 
 1293: sub end_font {
 1294:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
 1295:     my $currentstring = '';
 1296:     if ($target eq 'web') {
 1297: 	$currentstring = $token->[2];    
 1298:     }  elsif ($target eq 'tex') {
 1299: 	my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
 1300: 	if (defined $fontsize) {
 1301: 	    $currentstring = '}';
 1302: 	}
 1303:     }
 1304:     return $currentstring;
 1305: }
 1306:  
 1307: #-- <strike> tag (end tag required)
 1308: sub start_strike {
 1309:     my ($target,$token) = @_;
 1310:     my $currentstring = '';
 1311:     if ($target eq 'web') {
 1312: 	$currentstring .= $token->[4];
 1313:     } elsif ($target eq 'tex') {
 1314: 	&Apache::lonxml::startredirection();
 1315:     } 
 1316:     return $currentstring;
 1317: }
 1318: 
 1319: sub end_strike {
 1320:     my ($target,$token) = @_;
 1321:     my $currentstring = '';
 1322:     if ($target eq 'web') {
 1323: 	$currentstring .= $token->[2];
 1324:     } elsif ($target eq 'tex') {
 1325: 	$currentstring=&Apache::lonxml::endredirection();
 1326: 	$currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g; 
 1327: 	$currentstring=~s/^\s*(\S)/\\underline\{$1/; 
 1328: 	$currentstring=~s/(\S)\s*$/$1\}/;
 1329:     }
 1330:     return $currentstring;
 1331: }
 1332: 
 1333: #-- <s> tag (end tag required)
 1334: sub start_s {
 1335:     my ($target,$token) = @_;
 1336:     my $currentstring = '';
 1337:     if ($target eq 'web') {
 1338: 	$currentstring .= $token->[4];
 1339:     } elsif ($target eq 'tex') {
 1340: 	&Apache::lonxml::startredirection();
 1341:     } 
 1342:     return $currentstring;
 1343: }
 1344: 
 1345: sub end_s {
 1346:     my ($target,$token) = @_;
 1347:     my $currentstring = '';
 1348:     if ($target eq 'web') {
 1349: 	$currentstring .= $token->[2];
 1350:     } elsif ($target eq 'tex') {
 1351: 	$currentstring=&Apache::lonxml::endredirection();
 1352: 	$currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g;
 1353: 	$currentstring=~s/^\s*(\S)/\\underline\{$1/;
 1354: 	$currentstring=~s/(\S)\s*$/$1\}/;	
 1355:     }
 1356:     return $currentstring;
 1357: }
 1358: 
 1359: #-- <sub> tag (end tag required)
 1360: sub start_sub {
 1361:     my ($target,$token) = @_;
 1362:     my $currentstring = '';
 1363:     if ($target eq 'web') {
 1364: 	$currentstring .= $token->[4];
 1365:     } elsif ($target eq 'tex') {
 1366: 	$currentstring .= '\ensuremath{_{';
 1367:     } 
 1368:     return $currentstring;
 1369: }
 1370: 
 1371: sub end_sub {
 1372:     my ($target,$token) = @_;
 1373:     my $currentstring = '';
 1374:     if ($target eq 'web') {
 1375: 	$currentstring .= $token->[2];
 1376:     } elsif ($target eq 'tex') {
 1377: 	$currentstring .= '}}';
 1378:     }
 1379:     return $currentstring;
 1380: }
 1381: 
 1382: #-- <sup> tag (end tag required)
 1383: sub start_sup {
 1384:     my ($target,$token) = @_;
 1385:     my $currentstring = '';
 1386:     if ($target eq 'web') {
 1387: 	$currentstring .= $token->[4];
 1388:     } elsif ($target eq 'tex') {
 1389: 	$currentstring .= '\ensuremath{^{';
 1390:     } 
 1391:     return $currentstring;
 1392: }
 1393: 
 1394: sub end_sup {
 1395:     my ($target,$token) = @_;
 1396:     my $currentstring = '';
 1397:     if ($target eq 'web') {
 1398: 	$currentstring .= $token->[2];
 1399:     } elsif ($target eq 'tex') {
 1400: 	$currentstring .= '}}';
 1401:     }
 1402:     return $currentstring;
 1403: }
 1404: 
 1405: #-- <hr> tag (end tag forbidden)
 1406: sub start_hr {
 1407:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1408:     my $currentstring = '';
 1409:     if ($target eq 'web') {
 1410: 	$currentstring .= $token->[4];
 1411:     } elsif ($target eq 'tex') {
 1412: 	my $LaTeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
 1413: 	if (defined $LaTeXwidth) {
 1414: 	    if ($LaTeXwidth=~/^%/) {
 1415: 		substr($LaTeXwidth,0,1)='';
 1416: 		$LaTeXwidth=($LaTeXwidth/100).'\textwidth';
 1417: 	    }
 1418: 	} else {
 1419: 	    $LaTeXwidth ='0.9\textwidth';
 1420: 	}
 1421: 	my ($pre,$post);
 1422: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
 1423: 	if (($align eq 'center') || (not defined $align)) {
 1424: 	    $pre=''; $post='';
 1425: 	} elsif ($align eq 'left') {
 1426: 	    $pre='\rlap{'; $post='} \hfill';
 1427: 	} elsif ($align eq 'right') {
 1428: 	    $pre=' \hfill \llap{'; $post='}';
 1429: 	}
 1430: 	$currentstring .= ' \vskip 0 mm \noindent\makebox['.$LaTeXwidth.']{'.$pre.'\makebox['.
 1431:                                     $LaTeXwidth.'][b]{\hrulefill}'.$post.'}\vskip 0 mm ';
 1432:     } 
 1433:     return $currentstring;
 1434: }
 1435: 
 1436: sub end_hr {
 1437:     my ($target,$token) = @_;
 1438:     my $currentstring = '';
 1439:     if ($target eq 'web') {
 1440: 	$currentstring .= $token->[2];
 1441:     }
 1442:     return $currentstring;
 1443: }
 1444: 
 1445: #-- <div> tag (end tag required)
 1446: sub start_div {
 1447:     my ($target,$token) = @_;
 1448:     my $currentstring = '';
 1449:     if ($target eq 'web') {
 1450: 	$currentstring .= $token->[4];
 1451:     } 
 1452:     return $currentstring;
 1453: }
 1454: 
 1455: sub end_div {
 1456:     my ($target,$token) = @_;
 1457:     my $currentstring = '';
 1458:     if ($target eq 'web') {
 1459: 	$currentstring .= $token->[2];
 1460:     } 
 1461:     return $currentstring;
 1462: }
 1463: 
 1464: #-- <a> tag (end tag required)
 1465: sub start_a {
 1466:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1467:     my $currentstring = '';
 1468:     if ($target eq 'web') {
 1469: 	my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
 1470: 					    undef,1);
 1471: 	$currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href});
 1472:     } elsif ($target eq 'tex') {
 1473: 	my $a=&Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);
 1474: 	my $b=&Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1);
 1475: 	if ($a=~/\S/) {
 1476: 	    $a=~s/([^\\])%/$1\\\%/g;
 1477: 	    $currentstring .= '\ref{URI: '.$a.'}';
 1478: 	} elsif ($b=~/\S/) {
 1479: 	    $currentstring .= '\ref{Anchor: '.$b.'}';
 1480: 	} else {
 1481: 	    $currentstring.='';
 1482: 	}
 1483:     }
 1484:     return $currentstring;
 1485: }
 1486: 
 1487: sub end_a {
 1488:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1489:     my $currentstring = '';
 1490:     if ($target eq 'web') {
 1491: 	$currentstring .= $token->[2];
 1492:     }
 1493:     return $currentstring;
 1494: }
 1495: 
 1496: #-- <li> tag (end tag optional)
 1497: sub start_li {
 1498:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1499:     my $currentstring = '';
 1500:     if ($target eq 'web') {
 1501: 	$currentstring = $token->[4];     
 1502:     } elsif ($target eq 'tex') {
 1503: 	my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
 1504: 	my $value=&Apache::lonxml::get_param('value',$parstack,$safeeval,undef,0);
 1505: 	#FIXME need to support types i and I 
 1506: 	if ($type=~/disc/) {
 1507: 	    $currentstring .= ' \item[$\bullet$] ';
 1508: 	} elsif ($type=~/circle/) {
 1509: 	    $currentstring .= ' \item[$\circ$] ';
 1510: 	} elsif ($type=~/square/) {
 1511: 	    $currentstring .= ' \item[$\diamond$] ';
 1512: 	} elsif ($type eq '1') {
 1513: 	    $currentstring .= ' \item['.($Apache::londefdef::list_index+1).'.]';
 1514: 	} elsif ($type eq 'A') {
 1515: 	    $currentstring .= ' \item['.('A'..'Z')[$Apache::londefdef::list_index].'.]';
 1516: 	} elsif ($type eq 'a') {
 1517: 	    $currentstring .= ' \item['.('a'..'z')[$Apache::londefdef::list_index].'.]';
 1518: 	} elsif ($value ne '') {
 1519: 	    $currentstring .= ' \item['.$value.'] ';
 1520: 	} else {
 1521: 	    $currentstring .= ' \item ';
 1522: 	}  
 1523: 	$Apache::londefdef::list_index++;
 1524:     }
 1525:     return $currentstring;
 1526: }
 1527: 
 1528: sub end_li {
 1529:     my ($target,$token) = @_;
 1530:     my $currentstring = '';
 1531:     if ($target eq 'web') {
 1532: 	$currentstring = $token->[2];     
 1533:     } 
 1534:     return $currentstring;
 1535: }
 1536: 
 1537: #-- <u> tag (end tag required)
 1538: sub start_u {
 1539:     my ($target,$token) = @_;
 1540:     my $currentstring = '';
 1541:     if ($target eq 'web') {
 1542: 	$currentstring .= $token->[4];
 1543:     } elsif ($target eq 'tex') {
 1544: 	&Apache::lonxml::startredirection();
 1545:     } 
 1546:     return $currentstring;
 1547: }
 1548: 
 1549: sub end_u {
 1550:     my ($target,$token) = @_;
 1551:     my $currentstring = '';
 1552:     if ($target eq 'web') {
 1553: 	$currentstring .= $token->[2];
 1554:     } elsif ($target eq 'tex') {
 1555: 	$currentstring=&Apache::lonxml::endredirection();
 1556: 	$currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g;
 1557: 	$currentstring=~s/^\s*(\S)/\\underline\{$1/;
 1558: 	$currentstring=~s/(\S)\s*$/$1\}/;		
 1559:     }
 1560:     return $currentstring;
 1561: }
 1562: 
 1563: #-- <ul> tag (end tag required)
 1564: sub start_ul {
 1565:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1566:     my $currentstring = '';
 1567:     if ($target eq 'web') {
 1568: 	$currentstring = $token->[4];     
 1569:     } elsif ($target eq 'tex') {
 1570: 	my $TeXtype=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
 1571: 	$Apache::londefdef::list_index=0;
 1572: 	if ($TeXtype eq 'disc') {
 1573: 	    $currentstring .= '\renewcommand{\labelitemi}{$\bullet$}'.
 1574:                               '\renewcommand{\labelitemii}{$\bullet$}'. 
 1575:                               '\renewcommand{\labelitemiii}{$\bullet$}'.
 1576:                               '\renewcommand{\labelitemiv}{$\bullet$}';
 1577: 	} elsif ($TeXtype eq 'circle') {
 1578: 	    $currentstring .= '\renewcommand{\labelitemi}{$\circ$}'.
 1579:                               '\renewcommand{\labelitemii}{$\circ$}'. 
 1580:                               '\renewcommand{\labelitemiii}{$\circ$}'.
 1581:                               '\renewcommand{\labelitemiv}{$\circ$}';
 1582: 	} elsif ($TeXtype eq 'square') {
 1583: 	    $currentstring .= '\renewcommand{\labelitemi}{$\diamond$}'.
 1584:                               '\renewcommand{\labelitemii}{$\diamond$}'. 
 1585:                               '\renewcommand{\labelitemiii}{$\diamond$}'.
 1586:                               '\renewcommand{\labelitemiv}{$\diamond$}';
 1587: 	}
 1588: 	$currentstring .= '\strut \begin{itemize}';  
 1589:     } 
 1590:     return $currentstring;
 1591: }
 1592: 
 1593: sub end_ul {
 1594:     my ($target,$token) = @_;
 1595:     my $currentstring = '';
 1596:     if ($target eq 'web') {
 1597: 	$currentstring = $token->[2];     
 1598:     } elsif ($target eq 'tex') {
 1599: 	$currentstring = '\end{itemize} \renewcommand{\labelitemi}{$\bullet$}'.
 1600:                                '\renewcommand{\labelitemii}{$\bullet$}'. 
 1601:                                '\renewcommand{\labelitemiii}{$\bullet$}'.
 1602:                                '\renewcommand{\labelitemiv}{$\bullet$}\strut ';  
 1603:     } 
 1604:     return $currentstring;
 1605: }
 1606: 
 1607: #-- <menu> tag (end tag required)
 1608: sub start_menu {
 1609:     my ($target,$token) = @_;
 1610:     my $currentstring = '';
 1611:     if ($target eq 'web') {
 1612: 	$currentstring = $token->[4];     
 1613:     } elsif ($target eq 'tex') {
 1614: 	$currentstring = " \\begin{itemize} ";  
 1615:     } 
 1616:     return $currentstring;
 1617: }
 1618: 
 1619: sub end_menu {
 1620:     my ($target,$token) = @_;
 1621:     my $currentstring = '';
 1622:     if ($target eq 'web') {
 1623: 	$currentstring = $token->[2];     
 1624:     } elsif ($target eq 'tex') {
 1625: 	$currentstring = " \\end{itemize}";  
 1626:     } 
 1627:     return $currentstring;
 1628: }
 1629: 
 1630: #-- <dir> tag (end tag required)
 1631: sub start_dir {
 1632:     my ($target,$token) = @_;
 1633:     my $currentstring = '';
 1634:     if ($target eq 'web') {
 1635: 	$currentstring = $token->[4];     
 1636:     } elsif ($target eq 'tex') {
 1637: 	$currentstring = " \\begin{itemize} ";  
 1638:     } 
 1639:     return $currentstring;
 1640: }
 1641: 
 1642: sub end_dir {
 1643:     my ($target,$token) = @_;
 1644:     my $currentstring = '';
 1645:     if ($target eq 'web') {
 1646: 	$currentstring = $token->[2];     
 1647:     } elsif ($target eq 'tex') {
 1648: 	$currentstring = " \\end{itemize}";  
 1649:     } 
 1650:     return $currentstring;
 1651: }
 1652: 
 1653: #-- <ol> tag (end tag required)
 1654: sub start_ol {
 1655:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1656:     my $currentstring = '';
 1657:     if ($target eq 'web') {
 1658: 	$currentstring = $token->[4];     
 1659:     } elsif ($target eq 'tex') {
 1660: 	$Apache::londefdef::list_index=0;
 1661: 	my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
 1662: 	if ($type eq '1') {
 1663: 	    $currentstring .= '\renewcommand{\labelenumi}{\arabic{enumi}.}'.
 1664:                               '\renewcommand{\labelenumii}{\arabic{enumii}.}'. 
 1665:                               '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.
 1666:                               '\renewcommand{\labelenumiv}{\arabic{enumiv}.}';
 1667: 	} elsif ($type eq 'A') {
 1668: 	    $currentstring .= '\renewcommand{\labelenumi}{\Alph{enumi}.}'.
 1669:                               '\renewcommand{\labelenumii}{\Alph{enumii}.}'. 
 1670:                               '\renewcommand{\labelenumiii}{\Alph{enumiii}.}'.
 1671:                               '\renewcommand{\labelenumiv}{\Alph{enumiv}.}';
 1672: 	} elsif ($type eq 'a') {
 1673: 	    $currentstring .= '\renewcommand{\labelenumi}{\alph{enumi}.}'.
 1674:                               '\renewcommand{\labelenumii}{\alph{enumii}.}'.
 1675:                               '\renewcommand{\labelenumiii}{\alph{enumiii}.}'.
 1676:                               '\renewcommand{\labelenumiv}{\alph{enumiv}.}';
 1677: 	} elsif ($type eq 'i') {
 1678: 	    $currentstring .= '\renewcommand{\labelenumi}{\roman{enumi}.}'.
 1679:                               '\renewcommand{\labelenumii}{\roman{enumii}.}'.
 1680:                               '\renewcommand{\labelenumiii}{\roman{enumiii}.}'.
 1681:                               '\renewcommand{\labelenumiv}{\roman{enumiv}.}';
 1682: 	} elsif ($type eq 'I') {
 1683: 	    $currentstring .= '\renewcommand{\labelenumi}{\Roman{enumi}.}'.
 1684:                               '\renewcommand{\labelenumii}{\Roman{enumii}.}'.
 1685:                               '\renewcommand{\labelenumiii}{\Roman{enumiii}.}'.
 1686:                               '\renewcommand{\labelenumiv}{\Roman{enumiv}.}';
 1687: 	}
 1688: 	$currentstring .= '\strut \begin{enumerate}';  
 1689:     } 
 1690:     return $currentstring;
 1691: }
 1692: 
 1693: sub end_ol {
 1694:     my ($target,$token) = @_;
 1695:     my $currentstring = '';
 1696:     if ($target eq 'web') {
 1697: 	$currentstring = $token->[2];     
 1698:     } elsif ($target eq 'tex') {
 1699: 	$currentstring = '\end{enumerate}\renewcommand{\labelenumi}{\arabic{enumi}.}'.
 1700:                                         '\renewcommand{\labelenumii}{\arabic{enumii}.}'.
 1701:                                         '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.
 1702:                                         '\renewcommand{\labelenumiv}{\arabic{enumiv}.}\strut ';  
 1703:     } 
 1704:     return $currentstring;
 1705: }
 1706: 
 1707: #-- <dl> tag (end tag required)
 1708: sub start_dl {
 1709:     my ($target,$token) = @_;
 1710:     my $currentstring = '';
 1711:     if ($target eq 'web') {
 1712: 	$currentstring = $token->[4];     
 1713:     } elsif ($target eq 'tex') {
 1714: 	$currentstring = '\begin{description}';
 1715: 	$Apache::londefdef::DL++;
 1716: 	push(@Apache::londefdef::description,[]);
 1717: 	$Apache::londefdef::DD[$Apache::londefdef::DL]=0;
 1718: 	$Apache::londefdef::DT[$Apache::londefdef::DL]=0;
 1719: 	$Apache::londefdef::seenDT[$Apache::londefdef::DL]=0;
 1720:     } 
 1721:     return $currentstring;
 1722: }
 1723: 
 1724: sub end_dl {
 1725:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1726:     my $currentstring = '';
 1727:     if ($target eq 'web') {
 1728: 	$currentstring = $token->[2];     
 1729:     } elsif ($target eq 'tex') {
 1730: 	if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
 1731: 	if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
 1732: 	foreach my $element (@{$Apache::londefdef::description[-1]}) {
 1733: 	    $currentstring.=' '.$element.' ';
 1734: 	}
 1735: 	pop(@Apache::londefdef::description);
 1736: 	$currentstring.='\end{description}';  
 1737: 	delete($Apache::londefdef::DD[$Apache::londefdef::DL]);
 1738: 	delete($Apache::londefdef::DT[$Apache::londefdef::DL]);
 1739: 	delete($Apache::londefdef::seenDT[$Apache::londefdef::DL]);
 1740: 	$Apache::londefdef::DL--;
 1741:     } 
 1742:     return $currentstring;
 1743: }
 1744: 
 1745: #-- <dt> tag (end tag optional)
 1746: sub start_dt {
 1747:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1748:     my $currentstring='';
 1749:     if ($target eq 'web') {
 1750: 	$currentstring = $token->[4];     
 1751:     } elsif ($target eq 'tex') {
 1752: 	if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
 1753: 	if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
 1754: 	&Apache::lonxml::startredirection();
 1755: 	$Apache::londefdef::DT[-1]++;
 1756: 	$Apache::londefdef::seenDT[-1]=1;
 1757:     } 
 1758:     return $currentstring;
 1759: }
 1760: 
 1761: sub end_dt {
 1762:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1763:     my $currentstring = '';
 1764:     if ($target eq 'web') {
 1765: 	$currentstring = $token->[2];    
 1766:     } elsif ($target eq 'tex') {
 1767: 	if ($Apache::londefdef::DT[-1]) {
 1768: 	    my $data=&item_cleanup();
 1769: 	    push(@{$Apache::londefdef::description[-1]},'\item['.$data.'] \strut \vskip 0mm');
 1770: 	    $Apache::londefdef::DT[-1]--;
 1771: 	}
 1772:     } 
 1773:     return $currentstring;
 1774: }
 1775: 
 1776: sub item_cleanup {
 1777:     my $item=&Apache::lonxml::endredirection();
 1778:     $item=~s/\\begin{center}//g;
 1779:     $item=~s/\\end{center}//g;
 1780:     return $item;
 1781: }
 1782: 
 1783: #-- <dd> tag (end tag optional)
 1784: sub start_dd {
 1785:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1786:     my $currentstring = '';
 1787:     if ($target eq 'web') {
 1788: 	$currentstring = $token->[4];     
 1789:     } elsif ($target eq 'tex') {
 1790: 	if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
 1791: 	if ($Apache::londefdef::DD[-1]) { &end_dd(@_);}
 1792: 	if (!$Apache::londefdef::seenDT[-1]) {
 1793: 	    push(@{$Apache::londefdef::description[-1]},'\item[\strut] \strut \vskip 0mm ');
 1794: 	}
 1795: 	push(@{$Apache::londefdef::description[-1]},'');
 1796: 	$Apache::londefdef::description[-1]->[-1].=' \strut ';
 1797: 	$Apache::londefdef::DD[-1]++;
 1798: 	&Apache::lonxml::startredirection();
 1799:     } 
 1800:     return $currentstring;
 1801: }
 1802: 
 1803: sub end_dd {
 1804:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1805:     my $currentstring = '';
 1806:     if ($target eq 'web') {
 1807: 	$currentstring = $token->[2];    
 1808:     }  elsif ($target eq 'tex') {
 1809: 	$Apache::londefdef::description[-1]->[-1].=
 1810: 	    &Apache::lonxml::endredirection().' \vskip 0mm ';
 1811: 	$Apache::londefdef::DD[-1]--;
 1812:     }
 1813:     return $currentstring;
 1814: }
 1815: 
 1816: #-- <table> tag (end tag required)
 1817: #list of supported attributes: border,width,TeXwidth
 1818: sub start_table {
 1819:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1820:     my ($textwidth,$currentstring)=('','');
 1821:     if ($target eq 'web') {
 1822: 	$currentstring = $token->[4];     
 1823:     } elsif ($target eq 'tex') {
 1824: 	my $aa = {};
 1825: 	push @Apache::londefdef::table, $aa; 
 1826: 	$Apache::londefdef::table[-1]{'row_number'} = -1;
 1827:         #maximum table's width (default coincides with text line length)
 1828: 	if ($#Apache::londefdef::table==0) {
 1829: 	    $textwidth=&recalc($ENV{'form.textwidth'}); #result is always in mm
 1830: 	    $textwidth=~/(\d+\.?\d*)/;
 1831: 	    $textwidth=0.95*$1; #accounts "internal" LaTeX space for table frame
 1832: 	} else {
 1833: 	    if ($Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]=~/\d/) {
 1834: 		#the maximum width of nested table is determined by LATeX width of parent cell
 1835: 		$textwidth=$Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]; 
 1836: 	    } else {
 1837:               #try to use all space not used before (minus 5% for LaTeX table internal) - rather silly
 1838: 		$textwidth=$Apache::londefdef::table[-2]{'width'};
 1839: 		for (my $i=0;$i<$Apache::londefdef::table[-2]{'counter_columns'};$i++) {
 1840: 		    $textwidth=$textwidth-$Apache::londefdef::table[-2]{'TeXlen'}[0][$i];
 1841: 		}
 1842: 	    }
 1843: 	}
 1844: 	my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
 1845: 	if (not defined $TeXwidth) {
 1846: 	    my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,$safeeval,undef,1);
 1847: 	    if ($htmlwidth=~/%/) {
 1848:                 $Apache::londefdef::table[-1]{'percent'}=1;
 1849: 		$htmlwidth=~/(\d+)/;
 1850: 		$Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;;
 1851: 	    } else {
 1852: 		$Apache::londefdef::table[-1]{'width'}=$textwidth;
 1853: 	    }
 1854: 	} elsif ($TeXwidth=~/%/) {
 1855: 	    $Apache::londefdef::table[-1]{'percent'}=1;
 1856: 	    $TeXwidth=~/(\d+)/;
 1857:             $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;
 1858: 	} else {
 1859: 	    $Apache::londefdef::table[-1]{'forcetablewidth'}=1;
 1860: 	    $Apache::londefdef::table[-1]{'width'}=$TeXwidth;
 1861: 	}        
 1862:         #table's border
 1863: 	my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval); 
 1864:         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);
 1865: 	unless (defined $border) { $border = 0; }
 1866: 	if ($border) { 
 1867: 	    $Apache::londefdef::table[-1]{'hinc'} = '\hline '; 
 1868: 	    $Apache::londefdef::table[-1]{'vinc'} = '&'; 
 1869: 	    $Apache::londefdef::table[-1]{'vvinc'} = '|';
 1870: 	} else {
 1871: 	    $Apache::londefdef::table[-1]{'hinc'} = ''; 
 1872: 	    $Apache::londefdef::table[-1]{'vinc'} = '&'; 
 1873: 	    $Apache::londefdef::table[-1]{'vvinc'} = '';
 1874: 	}
 1875: 	if ($#Apache::londefdef::table==0) {
 1876: 	    $Apache::londefdef::table[-1]{'output'}='\strut\newline\strut\setlength{\tabcolsep}{1 mm}';
 1877: 	}
 1878: 	$Apache::londefdef::table[-1]{'output'}.=' \noindent \begin{tabular} ';
 1879:         $Apache::londefdef::table[-1]{'TeXlen'}=[];
 1880:         $Apache::londefdef::table[-1]{'objectlen'}=[];
 1881:         $Apache::londefdef::table[-1]{'objectsignal'}=[];
 1882:         $Apache::londefdef::table[-1]{'maxlen'}=[];
 1883:         $Apache::londefdef::table[-1]{'minlen'}=[];
 1884:         $Apache::londefdef::table[-1]{'content'}=[];
 1885:         $Apache::londefdef::table[-1]{'align'}=[];
 1886:         $currentstring='\keephidden{NEW TABLE ENTRY}';
 1887:    }
 1888:     return $currentstring;
 1889: }
 1890:  
 1891: sub end_table {
 1892:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 1893:     my $currentstring = '';
 1894:     if ($target eq 'web') {
 1895: 	$currentstring = $token->[2];     
 1896:     } elsif ($target eq 'tex') {
 1897: 	my $inmemory = '';
 1898: 	my $output = '';
 1899: 	my $WARNING='';
 1900:         #width of columns from TeXwidth attributes
 1901: 	for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
 1902: 	    for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
 1903: 		if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]<$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]) {
 1904: 		    $Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]=$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn];
 1905: 		}	
 1906: 	    }
 1907: 	}
 1908:         #free space and number of empty columns
 1909: 	my ($available_space,$empty_columns)=($Apache::londefdef::table[-1]{'width'},0);
 1910: 	if ($#Apache::londefdef::table ne 0) {$available_space=0.9*$available_space;} 
 1911: 	for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
 1912: 	    if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]==0) {
 1913: 		$empty_columns++;
 1914: 	    } else {
 1915: 		$available_space=$available_space-$Apache::londefdef::table[-1]{'TeXlen'}[0][$jn];
 1916: 	    }
 1917: 	}
 1918:         #boundaries for contents columns
 1919: 	my @min_len=();#columns can not be narrower 
 1920: 	my @max_len=();#maximum length of column
 1921: 	for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
 1922: 		my ($localmin,$localmax)=(0,0);
 1923: 		for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
 1924: 		    if ($localmin<$Apache::londefdef::table[-1]{'minlen'}[$in][$jn]) {
 1925: 			$localmin=$Apache::londefdef::table[-1]{'minlen'}[$in][$jn];
 1926: 		    }
 1927: 		    if ($localmax<$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn]) {
 1928: 			$localmax=$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn];
 1929: 		    }
 1930: 		}
 1931: 		push @min_len, $localmin;
 1932: 		push @max_len, $localmax;
 1933: 	}
 1934: 	for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
 1935: 	    my $localmin=0,;
 1936: 	    for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
 1937: 		if ($localmin<$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn]) {
 1938: 		    $localmin=$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn];
 1939: 		}
 1940: 	    }
 1941: 	    if ($max_len[$jn]<$localmin) {
 1942: 		$max_len[$jn]=$localmin;
 1943: 	    	$Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;
 1944: 	    }#object size is bigger
 1945: 	    if ($min_len[$jn]<$localmin) {
 1946: 		$min_len[$jn]=$localmin;
 1947: 		$Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;
 1948: 	    }#object size is bigger
 1949: 	    if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]!=0) {
 1950: 		$min_len[$jn]=0;
 1951: 		$max_len[$jn]=0;
 1952: 	    }
 1953: 	}
 1954:        #final adjustment of column width
 1955: 	my @fwidth=@{$Apache::londefdef::table[-1]{'TeXlen'}[0]};#final width array
 1956: 	my @adjust=();
 1957:         #step 1. adjustment by maximum value
 1958: 	my $space_neeeded=0;
 1959: 	for (my $jn=0;$jn<=$#max_len;$jn++) {
 1960: 	    $space_neeeded=$space_neeeded+$max_len[$jn];
 1961: 	}
 1962: 	if ($space_neeeded<=$available_space) {
 1963: 	    for (my $jn=0;$jn<=$#max_len;$jn++) {
 1964: 		if ($fwidth[$jn]==0) {
 1965: 		    $fwidth[$jn]=$max_len[$jn];
 1966: 		}
 1967: 	    }
 1968: 	} else {
 1969:         #step 2. adjustment by minimum value (estimation)
 1970: 	    $space_neeeded=0;
 1971: 	    for (my $jn=0;$jn<=$#min_len;$jn++) {
 1972: 		$space_neeeded+=$min_len[$jn];
 1973: 	    }
 1974: 	    if ($space_neeeded>$available_space) {
 1975: 		$WARNING=' \textbf{NOT ENOUGH SPACE FOR TABLE} ';
 1976: 		for (my $jn=0;$jn<=$#max_len;$jn++) {
 1977: 		    if ($fwidth[$jn]==0) {
 1978: 			$fwidth[$jn]=$min_len[$jn];
 1979: 		    }
 1980: 		}
 1981: 		#check if we have objects which can be scaled
 1982: 		my $how_many_to_scale=0;
 1983: 		my @to_scale=();
 1984: 		for (my $jn=0;$jn<=$#max_len;$jn++) {
 1985: 		    if ($Apache::londefdef::table[-1]{'objectsignal'}[$jn] eq '1') {
 1986: 			$how_many_to_scale++;
 1987: 			push @to_scale, $jn;
 1988: 		    }
 1989: 		}
 1990: 		if ($how_many_to_scale>0) {
 1991: 		    my $space_to_adjust=($space_neeeded-$available_space)/$how_many_to_scale;
 1992: 		    foreach my $jn (@to_scale) {
 1993: 			for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
 1994: 			    $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/;
 1995: 			    if ($1 ne '') {
 1996: 				my $current_length=&recalc($1);
 1997: 				$current_length=~/(\d+\.?\d*)/;
 1998: 				$current_length=$current_length-$space_to_adjust;
 1999: 				$Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/width=$current_length mm/;
 2000: 			    }
 2001: 			    $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/\[(\d+\.?\d*)\s*mm\]/;
 2002: 			    if ($1 ne '') {
 2003: 				my $current_length=$1;
 2004: 				$current_length=$current_length-$space_to_adjust;
 2005: 				$Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/\[(\d+\.?\d*)\s*mm\]/\[$current_length mm\]/;
 2006: 			    }				
 2007: 			}
 2008: 			$fwidth[$jn]=$fwidth[$jn]-$space_to_adjust;
 2009: 		    }
 2010: 		}
 2011: 	    } else {
 2012: 	      #step 3. adjustment over minimal + corrections
 2013: 		my $enlarge_coef=$available_space/$space_neeeded;
 2014: 		my $acsessive=0;
 2015: 		for (my $jn=0;$jn<=$#min_len;$jn++) {
 2016: 		    $adjust[$jn]=$min_len[$jn]*$enlarge_coef;
 2017: 		    if ($adjust[$jn]>$max_len[$jn]) {
 2018: 			$fwidth[$jn]=$max_len[$jn];
 2019: 			$acsessive=$acsessive+$adjust[$jn]-$max_len[$jn];
 2020: 			$adjust[$jn]=0;
 2021: 		    }
 2022: 		}
 2023: 		if ($acsessive>0) {
 2024: 		#we have an excess of space and can redistribute it
 2025: 		    my $notempty_columns=0;
 2026: 		    for (my $jn=0;$jn<=$#min_len;$jn++) {
 2027: 			if ($adjust[$jn]!=0) {
 2028: 			    $notempty_columns++;
 2029: 			}
 2030: 		    }
 2031: 		    my $per_column=$acsessive/$notempty_columns;
 2032: 		    for (my $jn=0;$jn<=$#min_len;$jn++) {
 2033: 			if ($adjust[$jn]!=0) {
 2034: 			    $adjust[$jn]+=$per_column;
 2035: 			    $fwidth[$jn]=$adjust[$jn];
 2036: 			}
 2037: 		    }
 2038: 		} else {
 2039: 		    for (my $jn=0;$jn<=$#min_len;$jn++) {
 2040: 			$fwidth[$jn]=$adjust[$jn];
 2041: 		    }
 2042: 		}
 2043: 	    }
 2044: 	}
 2045:         #use all available width if it is defined in % or as TeXwidth
 2046:         if (($Apache::londefdef::table[-1]{'percent'}==1) || ($Apache::londefdef::table[-1]{'forcetablewidth'}==1)) {
 2047: 	    my $current=0; 
 2048: 	    for (my $i=0;$i<=$#fwidth;$i++) {  
 2049: 		$current+=$fwidth[$i];
 2050: 	    }
 2051: 	    my $coef=$Apache::londefdef::table[-1]{'width'}/$current;
 2052: 	    for (my $i=0;$i<=$#fwidth;$i++) {  
 2053: 		$fwidth[$i]*=$coef;
 2054: 	    }
 2055: 	}
 2056:         #removing of empty columns if allowed
 2057:         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);
 2058: 	if ($permission eq 'yes') {
 2059: 	    my @cleaned_table=();
 2060:             my @cleaned_header=();
 2061: 	    my $colind=0;
 2062: 	    for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
 2063: 		if ($fwidth[$jn]!=0) {
 2064: 		    #we need to copy column
 2065: 		    for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
 2066: 			$cleaned_table[$in][$colind]=$Apache::londefdef::table[-1]{'content'}[$in][$jn];
 2067: 			$cleaned_header[$colind]=$fwidth[$jn];
 2068: 		    }
 2069: 		    $colind++;
 2070: 		}
 2071: 	    }
 2072: 	    $Apache::londefdef::table[-1]{'content'}=\@cleaned_table;
 2073: 	    @fwidth=@cleaned_header;
 2074: 	}
 2075: 	#construct header of the table
 2076: 	my $header_of_table = '{'.$Apache::londefdef::table[-1]{'vvinc'};
 2077: 	for (my $in=0;$in<=$#fwidth;$in++) {
 2078: 	    $header_of_table.='p{'.$fwidth[$in].' mm}'.$Apache::londefdef::table[-1]{'vvinc'};
 2079: 	}
 2080: 	$header_of_table .= '}';
 2081: 	#fill the table
 2082: 	for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
 2083: 	    for (my $jn=0;$jn<=$#fwidth;$jn++) {
 2084: 		if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
 2085: 		    $output.='\vspace*{-6 mm}\begin{center}';
 2086: 		} elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {
 2087: 		    $output.=' \hfill \llap{'
 2088: 		}
 2089: 		$output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn];
 2090: 		if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
 2091: 		    $output.='\end{center}\vspace*{-6 mm}';
 2092: 		} elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {
 2093: 		    $output.='} ';
 2094: 		}
 2095:                 if ($jn!=$#fwidth) {$output.=' '.$Apache::londefdef::table[-1]{'vinc'};}
 2096: 	    }
 2097: 	    $output.=' \\\\ '.$Apache::londefdef::table[-1]{'hinc'}.' ';
 2098: 	}
 2099: 	$Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut\newline\strut ';
 2100: 	if ($#Apache::londefdef::table > 0) {	    
 2101: 	    my $inmemory = $Apache::londefdef::table[-1]{'output'};
 2102: 	    pop @Apache::londefdef::table;
 2103: 	    push @{$Apache::londefdef::table[-1]{'include'}}, $inmemory;
 2104: 	} else {
 2105: 	    $currentstring .= $Apache::londefdef::table[-1]{'output'};
 2106: 	    pop @Apache::londefdef::table;
 2107: 	    undef @Apache::londefdef::table;
 2108: 	}
 2109:     }
 2110:     return $currentstring;
 2111: }
 2112: 
 2113: #-- <tr> tag (end tag optional)
 2114: sub start_tr {
 2115:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2116:     my $currentstring = '';
 2117:     if ($target eq 'web') {
 2118: 	$currentstring = $token->[4];     
 2119:     } elsif ($target eq 'tex') {
 2120: 	$Apache::londefdef::table[-1]{'row_number'}++;
 2121: 	my $alignchar=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
 2122: 	if ($alignchar ne '') {
 2123: 	    push @ {$Apache::londefdef::table[-1]{'rows'} },substr($alignchar,0,1);
 2124: 	} else {
 2125: 	    push @ {$Apache::londefdef::table[-1]{'rows'} }, 'l';
 2126: 	}
 2127: 	push ( @{ $Apache::londefdef::table[-1]{'rowdata'} }, $Apache::londefdef::table[-1]{'hinc'});
 2128: 	$Apache::londefdef::table[-1]{'counter_columns'} = -1;
 2129: 	push @ {$Apache::londefdef::table[-1]{'TeXlen'}}, [];
 2130: 	push @ {$Apache::londefdef::table[-1]{'objectlen'}}, [];
 2131: 	push @ {$Apache::londefdef::table[-1]{'minlen'}}, [];
 2132: 	push @ {$Apache::londefdef::table[-1]{'maxlen'}}, [];
 2133: 	push @ {$Apache::londefdef::table[-1]{'content'}}, [];
 2134:     } 
 2135:     return $currentstring;
 2136: }
 2137:         
 2138: sub end_tr {
 2139:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2140:     my $currentstring = '';
 2141:     if ($target eq 'web') {
 2142: 	$currentstring = $token->[2];     
 2143:     } elsif ($target eq 'tex') {
 2144: 	if ($Apache::londefdef::TD_redirection) {
 2145: 	    &end_td_tex($parstack,$parser,$safeeval);    
 2146: 	}
 2147:     }
 2148:     return $currentstring;
 2149: }
 2150: 
 2151: #-- <td> tag (end tag optional)
 2152: sub start_td {
 2153:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2154:     my $currentstring = '';
 2155:     if ($target eq 'web') {
 2156: 	$currentstring = $token->[4];     
 2157:     } elsif ($target eq 'tex') {
 2158: 	$Apache::londefdef::TD_redirection = 1;
 2159: 	&tag_check('tr','td',$tagstack,$parstack,$parser,$safeeval);
 2160:     } 
 2161:     return $currentstring;
 2162: }   
 2163:     
 2164: sub tag_check {
 2165:     my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
 2166:     my @ar=@$parstack; 
 2167:     for (my $i=$#ar-1;$i>=0;$i--) {
 2168: 	if (lc($$tagstack[$i]) eq $good_tag) {
 2169: 	    &start_td_tex($parstack,$parser,$safeeval);
 2170: 	    last;
 2171: 	} elsif (lc($$tagstack[$i]) eq $bad_tag) {
 2172: 	    splice @ar, $i+1;
 2173: 	    &end_td_tex(\@ar,$parser,$safeeval);
 2174: 	    &start_td_tex($parstack,$parser,$safeeval);
 2175: 	    last;
 2176: 	}
 2177:     }
 2178:     return '';
 2179: }
 2180:  
 2181: sub start_td_tex {
 2182:     my ($parstack,$parser,$safeeval) = @_;
 2183:     my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
 2184:     if ($alignchar eq '') {
 2185: 	$alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
 2186:     }
 2187:     push @{ $Apache::londefdef::table[-1]{'align'}[$Apache::londefdef::table[-1]{'row_number'}] }, $alignchar;
 2188:     $Apache::londefdef::table[-1]{'counter_columns'}++;
 2189:     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
 2190:     if (defined $TeXwidth) {		
 2191: 	my $current_length=&recalc($TeXwidth);
 2192: 	$current_length=~/(\d+\.?\d*)/;
 2193: 	push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
 2194:     }
 2195:     &Apache::lonxml::startredirection();
 2196:     return '';
 2197: }
 2198: 
 2199: sub end_td_tex {
 2200:     my ($parstack,$parser,$safeeval) = @_;
 2201:     my $current_row = $Apache::londefdef::table[-1]{'row_number'};
 2202:     my $data=&Apache::lonxml::endredirection();
 2203:     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
 2204:     if (defined $TeXwidth) {		
 2205: 	push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2206: 	push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2207: 	push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2208:     } else {
 2209: 	if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {
 2210: 	    my $garbage_data=$data;
 2211: 	    my $fwidth=0;
 2212:             while ($garbage_data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
 2213: 		my $current_length=&recalc($1);
 2214: 		$current_length=~/(\d+\.?\d*)/;
 2215: 		if ($fwidth<$1) {$fwidth=$1;}
 2216: 		$garbage_data=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
 2217: 	    }
 2218:             while ($garbage_data=~m/\[(\d+\.?\d*)\s*mm\]/) {
 2219: 		my $current_length=$1;
 2220: 		if ($fwidth<$current_length) {$fwidth=$current_length;}
 2221: 		$garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;
 2222: 	    }
 2223: 	    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2224: 	    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
 2225: 	    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2226: 	    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2227: 	} 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)*/) {
 2228: 	    my $garbage_data=$data;
 2229: 	    my $fwidth=0;
 2230:             while ($garbage_data=~/\\parbox\{\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)\s*\}/) {
 2231: 		my $current_length=&recalc($1);
 2232: 		$current_length=~/(\d+\.?\d*)/;
 2233: 		if ($fwidth<$1) {$fwidth=$1;}
 2234: 		$garbage_data=~s/\\parbox\{\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
 2235: 	    }
 2236:             while ($garbage_data=~/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
 2237: 		my $current_length=&recalc($1);
 2238: 		$current_length=~/(\d+\.?\d*)/;
 2239: 		if ($fwidth<$1) {$fwidth=$1;}
 2240: 		$garbage_data=~s/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
 2241: 	    }
 2242: 	    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2243: 	    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
 2244: 	    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2245: 	    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2246: 	    $data=~s/\\\\\s*$//; 
 2247: 	} else {  
 2248: 	    $data=~s/^\s+(\S.*)/$1/; 
 2249: 	    $data=~s/(.*\S)\s+$/$1/;
 2250: 	    $data=~s/(\s)+/$1/;
 2251: 	    my ($current_length,$min_length)=(0,0);
 2252: 	    if ($data=~/\\vskip/) {
 2253:                 my $newdata=$data;
 2254: 		$newdata=~s/\\vskip \d*\.?\d*\s*mm/THISISJUSTTEMPORARYSEPARATOR/g;
 2255: 		my @newdata=split(/THISISJUSTTEMPORARYSEPARATOR/,$newdata);
 2256: 		foreach my $elementdata (@newdata) {
 2257: 		    my $lengthnewdata=2.5*&LATEX_length($elementdata);
 2258: 		    if ($lengthnewdata>$current_length) {$current_length=$lengthnewdata;}
 2259:                     my @words=split(/ /,$elementdata);
 2260: 		    foreach my $word (@words) {
 2261: 			my $lengthword=2.5*&LATEX_length($word);
 2262: 			if ($min_length<$lengthword) {$min_length=$lengthword;}
 2263: 		    }
 2264: 		}
 2265: 	    } else {
 2266: 		$current_length=2.5*&LATEX_length($data);
 2267:                     my @words=split(/ /,$data);
 2268: 		    foreach my $word (@words) {
 2269: 			my $lengthword=2*&LATEX_length($word);
 2270: 			if ($min_length<$lengthword) {$min_length=$lengthword;}
 2271: 		    }
 2272: 	    }
 2273: 	    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2274: 	    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2275: 	    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
 2276: 	    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
 2277: 	}        
 2278:     }
 2279: 	for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {         
 2280: 	    $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
 2281: 	}
 2282:     push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
 2283:     return'';
 2284: }
 2285: 
 2286: sub end_td {
 2287:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2288:     my $currentstring = '';
 2289:     if ($target eq 'web') {
 2290: 	$currentstring = $token->[2];     
 2291:     } elsif ($target eq 'tex') {
 2292:         $Apache::londefdef::TD_redirection =0;
 2293: 	&end_td_tex($parstack,$parser,$safeeval);
 2294:     }
 2295:     return $currentstring;
 2296: }
 2297: 
 2298: #-- <th> tag (end tag optional)
 2299: sub start_th {
 2300:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2301:     my $currentstring = '';
 2302:     if ($target eq 'web') {
 2303: 	$currentstring = $token->[4];     
 2304:     } elsif ($target eq 'tex') {
 2305: 	$Apache::londefdef::TD_redirection = 1;
 2306: 	&tagg_check('tr','th',$tagstack,$parstack,$parser,$safeeval);
 2307:     } 
 2308:     return $currentstring;
 2309: }   
 2310:     
 2311: sub tagg_check {
 2312:     my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
 2313:     my @ar=@$parstack; 
 2314:     for (my $i=$#ar-1;$i>=0;$i--) {
 2315: 	if (lc($$tagstack[$i]) eq $good_tag) {
 2316: 	    &start_th_tex($parstack,$parser,$safeeval);
 2317: 	    last;
 2318: 	} elsif (lc($$tagstack[$i]) eq $bad_tag) {
 2319: 	    splice @ar, $i+1;
 2320: 	    &end_th_tex(\@ar,$parser,$safeeval);
 2321: 	    &start_th_tex($parstack,$parser,$safeeval);
 2322: 	    last;
 2323: 	}
 2324:     }
 2325:     return '';
 2326: }
 2327:  
 2328: sub start_th_tex {
 2329:     my ($parstack,$parser,$safeeval) = @_;
 2330:     my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
 2331:     if ($alignchar eq '') {
 2332: 	$alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
 2333:     }
 2334:     push @{ $Apache::londefdef::table[-1]{'align'}[$Apache::londefdef::table[-1]{'row_number'}] }, $alignchar;
 2335:     $Apache::londefdef::table[-1]{'counter_columns'}++;
 2336:     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
 2337:     if (defined $TeXwidth) {		
 2338: 	my $current_length=&recalc($TeXwidth);
 2339: 	$current_length=~/(\d+\.?\d*)/;
 2340: 	push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
 2341:     }
 2342:     &Apache::lonxml::startredirection();
 2343:     return '';
 2344: }
 2345: 
 2346: sub end_th_tex {
 2347:     my ($parstack,$parser,$safeeval) = @_;
 2348:     my $current_row = $Apache::londefdef::table[-1]{'row_number'};
 2349:     my $data=&Apache::lonxml::endredirection();
 2350:     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
 2351:     if (defined $TeXwidth) {		
 2352: 	push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2353: 	push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2354: 	push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2355:     } else {
 2356: 	if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {
 2357: 	    my $garbage_data=$data;
 2358: 	    my $fwidth=0;
 2359:             while ($garbage_data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
 2360: 		my $current_length=&recalc($1);
 2361: 		$current_length=~/(\d+\.?\d*)/;
 2362: 		if ($fwidth<$1) {$fwidth=$1;}
 2363: 		$garbage_data=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
 2364: 	    }
 2365:             while ($garbage_data=~m/\[(\d+\.?\d*)\s*mm\]/) {
 2366: 		my $current_length=$1;
 2367: 		if ($fwidth<$current_length) {$fwidth=$current_length;}
 2368: 		$garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;
 2369: 	    }
 2370: 	    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2371: 	    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
 2372: 	    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2373: 	    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2374: 	} else {  
 2375: 	    $data=~s/^\s+(\S.*)/$1/; 
 2376: 	    $data=~s/(.*\S)\s+$/$1/;
 2377: 	    $data=~s/(\s)+/$1/;
 2378: 	    my ($current_length,$min_length)=(0,0);
 2379: 	    if ($data=~/\\vskip/) {
 2380:                 my $newdata=$data;
 2381: 		$newdata=~s/\\vskip \d*\.?\d*\s*mm/THISISJUSTTEMPORARYSEPARATOR/g;
 2382: 		my @newdata=split(/THISISJUSTTEMPORARYSEPARATOR/,$newdata);
 2383: 		foreach my $elementdata (@newdata) {
 2384: 		    my $lengthnewdata=2.5*&LATEX_length($elementdata);
 2385: 		    if ($lengthnewdata>$current_length) {$current_length=$lengthnewdata;}
 2386:                     my @words=split(/ /,$elementdata);
 2387: 		    foreach my $word (@words) {
 2388: 			my $lengthword=2.5*&LATEX_length($word);
 2389: 			if ($min_length<$lengthword) {$min_length=$lengthword;}
 2390: 		    }
 2391: 		}
 2392: 	    } else {
 2393: 		$current_length=2.5*&LATEX_length($data);
 2394:                     my @words=split(/ /,$data);
 2395: 		    foreach my $word (@words) {
 2396: 			my $lengthword=2*&LATEX_length($word);
 2397: 			if ($min_length<$lengthword) {$min_length=$lengthword;}
 2398: 		    }
 2399: 	    }
 2400: 	    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2401: 	    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
 2402: 	    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
 2403: 	    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
 2404: 	}        
 2405:     }
 2406: 	for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {         
 2407: 	    $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
 2408: 	}
 2409:     #make data bold
 2410:     $data='\textbf{'.$data.'}';
 2411:     push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
 2412:     return'';
 2413: }
 2414: 
 2415: sub end_th {
 2416:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2417:     my $currentstring = '';
 2418:     if ($target eq 'web') {
 2419: 	$currentstring = $token->[2];     
 2420:     } elsif ($target eq 'tex') {
 2421:         $Apache::londefdef::TD_redirection =0;
 2422: 	&end_th_tex($parstack,$parser,$safeeval);
 2423:     }
 2424:     return $currentstring;
 2425: }
 2426:      
 2427: #-- <img> tag (end tag forbidden)
 2428: #
 2429: #  Render the <IMG> tag.
 2430: #     <IMG> has the following attributes (in addition to the 
 2431: #     standard HTML ones:
 2432: #      TeXwrap   - Governs how the tex target will try to wrap text around
 2433: #                  horizontally aligned images.
 2434: #      TeXwidth  - The width of the image when rendered for print (mm).
 2435: #      TeXheight - The height of the image when rendered for print (mm)
 2436: #         (Note there seems to also be support for this as a % of page size)
 2437: #      
 2438: sub start_img {
 2439:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2440:     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,
 2441: 					 undef,1);
 2442:     if (not $src and ($target eq 'web' or $target eq 'tex')) { 
 2443: 	my $inside = &Apache::lonxml::get_all_text("/img",$parser);
 2444: 	return '';
 2445:     }
 2446:     $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$src;
 2447:     my $currentstring = '';
 2448:     my $scaling = .3;
 2449: 
 2450:    # Render unto browsers that which are the browser's...
 2451: 
 2452:     if ($target eq 'web') {
 2453: 	if ($ENV{'browser.imagesuppress'} ne 'on') {
 2454: 	    $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});
 2455: 	} else {
 2456: 	    my $alttag= &Apache::lonxml::get_param
 2457: 		('alt',$parstack,$safeeval,undef,1);
 2458: 	    unless ($alttag) {
 2459: 		$alttag=&Apache::lonmeta::alttag
 2460: 		    ($Apache::lonxml::pwd[-1],$src);
 2461: 	    }
 2462: 	    $currentstring.='[IMAGE: '.$alttag.']';
 2463: 	}
 2464: 
 2465: 	# and render unto TeX that which is LaTeX
 2466: 
 2467:     } elsif ($target eq 'tex') {
 2468: 	#
 2469: 	#  The alignment will require some superstructure to be put around
 2470: 	#  the \includegraphics stuff.  At present we can only partially
 2471: 	#  simulate the alignments offered by html.
 2472: 	#
 2473: 	#
 2474: 	my $align = lc(&Apache::lonxml::get_param('align', 
 2475: 						  $parstack,
 2476: 						  $safeeval,
 2477: 						  undef,1));
 2478: 	if(!$align) {
 2479: 	    $align = "bottom";	# This is html's default so it's ours too.
 2480: 	}
 2481: 	#
 2482: 	&Apache::lonxml::debug("Alignemnt = $align");
 2483: 	#  LaTeX's image/text wrapping is really bad since it wants to
 2484: 	#  make figures float.  
 2485:         #   The user has the optional parameter (applicable only to l/r
 2486: 	# alignment to use the picins/parpic directive to get wrapped text
 2487: 	# this is also imperfect.. that's why we give them a choice...
 2488: 	# so they can't yell at us for our choice.
 2489: 	#
 2490: 	my $latex_rendering = &Apache::lonxml::get_param('TeXwrap',
 2491: 							    $parstack,
 2492: 							    $safeeval,
 2493: 							    undef,0);
 2494: 	&Apache::lonxml::debug("LaTeX rendering = $latex_rendering");
 2495: 	if(!$latex_rendering) {
 2496: 	    $latex_rendering = "parbox";
 2497: 	}
 2498: 	&Apache::lonxml::debug("LaTeX rendering = $latex_rendering");
 2499: 
 2500: 	#if original gif/jpg/png file exist do following:
 2501: 	my ($path,$file) = &get_eps_image($src);
 2502: 	$src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
 2503: 	if (-e $src) {
 2504: 	    my ($height_param,$width_param)=
 2505: 		&image_size($src,0.3,$parstack,$safeeval);
 2506: 	    $currentstring .= '\graphicspath{{'.$path.'}}'
 2507: 		.'\includegraphics[width='.$width_param.' mm,height='.$height_param.'mm]{'.$file.'} ';
 2508: 
 2509: 	    #    If there's an alignment specification we need to honor it here.
 2510: 	    #    For the horizontal alignments, we will also honor the
 2511: 	    #    value of the latex specfication.  The default is parbox,
 2512: 	    #    and that's used for illegal values too.  
 2513: 	    #    
 2514: 	    #    Even though we set a default alignment value, the user
 2515: 	    #    could have given us an illegal value.  In that case we
 2516: 	    #    just use the default alignment of bottom..
 2517: 	    if      ($align eq "top")    {
 2518: 		$currentstring = '\raisebox{-'.$height_param.'mm}{'.$currentstring.'}';
 2519: 	    } elsif (($align eq "center") || ($align eq "middle")) { # Being kind
 2520: 		my $offset = $height_param/2;
 2521: 		$currentstring = '\raisebox{-'.$offset.'mm}{'.$currentstring.'}';
 2522: 	    } elsif ($align eq "left")   { 
 2523: 		if ($latex_rendering eq "parpic") { 
 2524: 		    $currentstring = '\parpic[l]{'.$currentstring.'}';
 2525: 		} else {    	                                 # parbox rendering
 2526: 		    $currentstring = "\\strut\\newline\n".
 2527: 			'\parbox{'.$width_param.'mm}{'.$currentstring.'}';
 2528: 		}
 2529: 	    } elsif ($align eq "right")  {   
 2530: 		if ($latex_rendering eq "parpic") {
 2531: 		    $currentstring = '\parpic[r]{'.$currentstring.'}';
 2532: 		} else {	                                 # parbox rendering. 
 2533: 		    $currentstring = '\parbox{'.$width_param.'mm}{\begin{flushright}'
 2534: 			             .$currentstring.'\end{flushright}} \newline'."\n";
 2535: 		}
 2536: 	    } else {		# Bottom is also default.
 2537: 		# $currentstring = '\raisebox{'.$height_param.'mm}{'.$currentstring.'}';
 2538: 	    }
 2539: 	} else {
 2540: 	    #original image file doesn't exist so check the alt attribute
 2541: 	    my $alt = 
 2542: 		&Apache::lonxml::get_param('alt',$parstack,$safeeval,undef,1);
 2543: 	    unless ($alt) {
 2544: 		$alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);
 2545: 	    }
 2546: 
 2547: 	    if ($alt) { $currentstring .= ' '.$alt.' '; }
 2548: 	}
 2549: 
 2550: 	# And here's where the semi-quote breaks down: allow the user
 2551:         # to edit the beast as well by rendering the problem for edit:
 2552:     } elsif ($target eq 'edit') {
 2553: 	$currentstring .=&Apache::edit::tag_start($target,$token);
 2554: 	$currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).
 2555: 	    &Apache::edit::browse('src',undef,'alt').' '.
 2556: 	    &Apache::edit::search('src',undef,'alt').'<br />';
 2557: 	$currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />';
 2558: 	$currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5);
 2559: 	$currentstring .=&Apache::edit::text_arg('height (pixel):','height',$token,5).'<br />';
 2560: 	$currentstring .=&Apache::edit::text_arg('TeXwidth (mm):','TeXwidth',$token,5);
 2561: 	$currentstring .=&Apache::edit::text_arg('TeXheight (mm):','TeXheight',$token,5);
 2562: 	$currentstring .=&Apache::edit::select_arg('Alignment:','align',
 2563: 						   ['','bottom','middle','top','left','right'],$token,5);
 2564: 	$currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',
 2565: 						   ['', 'parbox', 'parpic'], $token, 2);
 2566: 	$currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
 2567: 	my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);
 2568: 	my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);
 2569: 	my $width=  &Apache::lonxml::get_param('width',$parstack,$safeeval);
 2570: 	my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);
 2571: 
 2572: 
 2573: 	$currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';
 2574: 	if ($width) { $currentstring.=' width="'.$width.'" '; }
 2575: 	if ($height) { $currentstring.=' height="'.$height.'" '; }
 2576: 	$currentstring .= ' />';
 2577:     } elsif ($target eq 'modified') {
 2578: 	my ($osrc,$owidth,$oheight)=
 2579: 	    ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
 2580: 	my $ctag=&Apache::edit::get_new_args($token,$parstack,
 2581: 					     $safeeval,'src','alt','align',
 2582: 					     'TeXwidth','TeXheight', 'TeXwrap',
 2583: 					     'width','height');
 2584: 	my ($nsrc,$nwidth,$nheight)=
 2585: 	    ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
 2586: 	my $loc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$nsrc);
 2587: 	&image_replication($loc);
 2588: 	my ($iwidth,$iheight);
 2589: 	if (-e $loc) {
 2590: 	    my $image = Image::Magick->new;
 2591: 	    $image->Read($loc);
 2592: 	    ($iwidth, $iheight) = ($image->Get('width'),
 2593: 				   $image->Get('height'));
 2594: 	}
 2595: 	if ($osrc ne $nsrc || (!$nwidth && !$nheight)) {
 2596: 	    # changed image or no size specified,
 2597:             # if they didn't explicitly change the 
 2598:             # width or height use the ones from the image
 2599: 	    if ($iwidth && $iheight) {
 2600: 		if ($owidth == $nwidth || (!$nwidth && !$nheight)) {
 2601: 		    $token->[2]{'width'} = $iwidth;$ctag=1;
 2602: 		}
 2603: 		if ($oheight == $nheight || (!$nwidth && !$nheight)) {
 2604: 		    $token->[2]{'height'}=$iheight;$ctag=1;
 2605: 		}
 2606: 	    }
 2607: 	}
 2608: 	my ($cwidth,$cheight)=($token->[2]{'width'},$token->[2]{'height'});
 2609: 	# if we don't have a width or height
 2610: 	if ($iwidth && $cwidth && !$cheight) {
 2611: 	    $token->[2]{'height'}=int(($cwidth/$iwidth)*$iheight);$ctag=1;
 2612: 	}
 2613: 	if ($iheight && $cheight && !$cwidth) {
 2614: 	    $token->[2]{'width'}=int(($cheight/$iheight)*$iwidth);$ctag=1;
 2615: 	}
 2616: 	if ($ctag) {$currentstring=&Apache::edit::rebuild_tag($token);}
 2617:     }
 2618:     return $currentstring;
 2619: }
 2620: 
 2621: sub end_img {
 2622:     my ($target,$token) = @_;
 2623:     my $currentstring = '';
 2624:     if ($target eq 'web') {
 2625: 	$currentstring = $token->[2];
 2626:     } elsif ($target eq 'tex') {
 2627: 	$currentstring = '';
 2628:     }
 2629:     return $currentstring;
 2630: }
 2631: 
 2632: #-- <applet> tag (end tag required)
 2633: sub start_applet {
 2634:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2635:     
 2636:     my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,undef,1);
 2637:     $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$code;
 2638:     
 2639:     my $archive=&Apache::lonxml::get_param('archive',$parstack,$safeeval,
 2640: 					   undef,1);
 2641:     $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$archive;
 2642:     
 2643:     my $currentstring = '';
 2644:     if ($target eq 'web') {
 2645: 	if ($ENV{'browser.appletsuppress'} ne 'on') {
 2646: 	    $currentstring = &Apache::lonenc::encrypt_ref($token,
 2647: 							  {'code'=>$code,
 2648: 							   'archive'=>$archive}
 2649: 							  );
 2650: 	} else {
 2651: 	    my $alttag= &Apache::lonxml::get_param('alt',$parstack,
 2652: 						   $safeeval,undef,1);
 2653: 	    unless ($alttag) {
 2654: 		$alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],
 2655: 						 $code);
 2656: 	    }
 2657: 	    $currentstring='[APPLET: '.$alttag.']';
 2658: 	}
 2659:     } elsif ($target eq 'tex') {
 2660: 	my $alttag= &Apache::lonxml::get_param('alt',$parstack,
 2661: 					       $safeeval,undef,1);
 2662: 	unless ($alttag) {
 2663: 	    my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,
 2664: 						undef,1);
 2665: 	    $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],
 2666: 					     $code);
 2667: 	}
 2668: 	$currentstring.='\begin{center} \fbox{Java Applet: '.$alttag.
 2669: 	    '.}\end{center}';
 2670:     } 
 2671:     return $currentstring;
 2672: }
 2673: 
 2674: sub end_applet {
 2675:     my ($target,$token) = @_;
 2676:     my $currentstring = '';
 2677:     if ($target eq 'web') {
 2678: 	$currentstring = $token->[2];
 2679:     } elsif ($target eq 'tex') {
 2680:     } 
 2681:     return $currentstring;
 2682: }
 2683: 
 2684: #-- <embed> tag (end tag optional/required)
 2685: sub start_embed {    
 2686:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2687:     my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
 2688:     $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$src;
 2689:     my $currentstring = '';
 2690:     if ($target eq 'web') {
 2691: 	if ($ENV{'browser.embedsuppress'} ne 'on') {
 2692: 	    $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});
 2693: 	} else {
 2694: 	    my $alttag=&Apache::lonxml::get_param
 2695: 		('alt',$parstack,$safeeval,undef,1);
 2696: 	    unless ($alttag) {
 2697: 		$alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);
 2698: 	    }
 2699: 	    $currentstring='[EMBED: '.$alttag.']';
 2700: 	}
 2701:     } elsif ($target eq 'tex') {
 2702:     } 
 2703:     return $currentstring;
 2704: }
 2705: 
 2706: sub end_embed {
 2707:     my ($target,$token) = @_;
 2708:     my $currentstring = '';
 2709:     if ($target eq 'web') {
 2710: 	$currentstring = $token->[2];     
 2711:     } elsif ($target eq 'tex') {  
 2712:     } 
 2713:     return $currentstring;
 2714: }
 2715: 
 2716: #-- <param> tag (end tag forbidden)
 2717: sub start_param {
 2718:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2719:     if (&Apache::lonxml::get_param
 2720: 	('name',$parstack,$safeeval,undef,1)=~/^cabbase$/i) {
 2721: 	$Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=
 2722: 	    &Apache::lonxml::get_param('value',$parstack,$safeeval,undef,1);
 2723:     }   
 2724:     $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=   
 2725: 	&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
 2726:     my $currentstring = '';
 2727:     if ($target eq 'web') {
 2728: 	my %toconvert;
 2729: 	my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
 2730: 	if ($src) { $toconvert{'src'}= $src; }
 2731: 	my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval,
 2732: 					    undef,1);
 2733: 	if ($name=~/^cabbase$/i) {
 2734: 	    $toconvert{'value'}=&Apache::lonxml::get_param('value',$parstack,
 2735: 							   $safeeval,undef,1);
 2736: 	}
 2737: 	$currentstring = &Apache::lonenc::encrypt_ref($token,\%toconvert);
 2738:     } elsif ($target eq 'tex') {
 2739:     } 
 2740:     return $currentstring;
 2741: }
 2742: 
 2743: sub end_param {
 2744:     my ($target,$token) = @_;
 2745:     my $currentstring = '';
 2746:     if ($target eq 'web') {
 2747: 	$currentstring = $token->[2];     
 2748:     } elsif ($target eq 'tex') {
 2749:     } 
 2750:     return $currentstring;
 2751: }
 2752: 
 2753: #-- <allow> tag
 2754: sub start_allow {
 2755:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2756:     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
 2757:     $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
 2758:     $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=
 2759: 	&Apache::lonnet::clutter($src);
 2760:     if ($target eq 'tex') { &image_replication($src); }
 2761:     my $result;
 2762:     if ($target eq 'edit') {
 2763: 	$result .=&Apache::edit::tag_start($target,$token);
 2764: 	$result .=&Apache::edit::text_arg('File Spec:','src',$token,70);
 2765: 	$result .=&Apache::edit::end_row();#.&Apache::edit::start_spanning_row();
 2766:     } elsif ($target eq 'modified') {
 2767: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
 2768: 						     $safeeval,'src');
 2769: 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
 2770:     }
 2771:     return $result;
 2772: }
 2773: 
 2774: sub end_allow {
 2775:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2776:     if ( $target eq 'edit') { return (&Apache::edit::end_table()); }
 2777:     return '';
 2778: }
 2779: 
 2780: #-- Frames (end tag required)
 2781: #-- <frameset>
 2782: sub start_frameset {
 2783:     my ($target,$token) = @_;
 2784:     my $currentstring = '';
 2785:     if ($target eq 'web') { 
 2786: 	if (!$Apache::lonxml::registered &&
 2787: 	    $ENV{'request.state'} eq 'published') {
 2788: 	    $currentstring.='<head>'.
 2789: 		&Apache::lonmenu::registerurl(undef,$target).'</head>';
 2790: 	}
 2791: 	my $onLoad='';
 2792: 	foreach my $key (keys(%{$token->[2]})) {
 2793: 	    if ($key =~ /^onload$/i) {
 2794: 		$onLoad.=$token->[2]->{$key}.';';
 2795: 		delete($token->[2]->{$key});
 2796: 	    }
 2797: 	}
 2798: 	$token->[2]->{'onload'}=&Apache::lonmenu::loadevents().';'.$onLoad;
 2799: 	my $onUnload='';
 2800: 	foreach my $key (keys(%{$token->[2]})) {
 2801: 	    if ($key =~ /^onunload$/i) {
 2802: 		$onUnload.=$token->[2]->{$key}.';';
 2803: 		delete($token->[2]->{$key});
 2804: 	    }
 2805: 	}
 2806: 	$token->[2]->{'onunload'}=&Apache::lonmenu::unloadevents().
 2807: 	    ';'.$onUnload;
 2808: 	
 2809: 	$currentstring .= '<'.$token->[1];
 2810: 	foreach (keys %{$token->[2]}) {
 2811: 	    $currentstring.=' '.$_.'="'.$token->[2]->{$_}.'"';
 2812: 	}
 2813: 	$currentstring.='>';
 2814:     }
 2815:     return $currentstring;
 2816: }
 2817: 
 2818: sub end_frameset {
 2819:     my ($target,$token) = @_;
 2820:     my $currentstring = '';
 2821:     if ($target eq 'web') {
 2822: 	$currentstring = $token->[2];
 2823:     }
 2824:     return $currentstring;
 2825: }
 2826: 
 2827: #-- <xmp> (end tag required)
 2828: sub start_xmp {
 2829:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2830:     my $currentstring = '';
 2831:     if ($target eq 'web') {
 2832: 	$currentstring .= $token->[4];
 2833:     } elsif ($target eq 'tex') {
 2834: 	$currentstring .= '\begin{verbatim}';
 2835:     } 
 2836:     return $currentstring;
 2837: }
 2838: 
 2839: sub end_xmp {
 2840:     my ($target,$token) = @_;
 2841:     my $currentstring = '';
 2842:     if ($target eq 'web') {
 2843: 	$currentstring .= $token->[2];
 2844:     } elsif ($target eq 'tex') {
 2845: 	$currentstring .= '\end{verbatim}';
 2846:     }
 2847:     return $currentstring;
 2848: }
 2849: 
 2850: #-- <pre> (end tag required)
 2851: sub start_pre {
 2852:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2853:     my $currentstring = '';
 2854:     if ($target eq 'web') {
 2855: 	$currentstring .= $token->[4];
 2856:     } elsif ($target eq 'tex') {
 2857: 	$currentstring .= '\begin{verbatim}';
 2858:     } 
 2859:     return $currentstring;
 2860: }
 2861: 
 2862: sub end_pre {
 2863:     my ($target,$token) = @_;
 2864:     my $currentstring = '';
 2865:     if ($target eq 'web') {
 2866: 	$currentstring .= $token->[2];
 2867:     } elsif ($target eq 'tex') {
 2868: 	$currentstring .= '\end{verbatim}';
 2869:     }
 2870:     return $currentstring;
 2871: }
 2872: 
 2873: #-- <insert>
 2874: sub start_insert {
 2875:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2876:     my $currentstring = '';
 2877:     if ($target eq 'web') {
 2878: 	my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1);
 2879: 	$currentstring .= '<b>'.$display.'</b>';;
 2880:     }
 2881:     return $currentstring;
 2882: }
 2883: 
 2884: sub end_insert {
 2885:     my ($target,$token) = @_;
 2886:     my $currentstring = '';
 2887:     if ($target eq 'web') {
 2888: 	$currentstring .= '';
 2889:     }
 2890:     return $currentstring;
 2891: }
 2892: 
 2893: #-- <externallink>
 2894: sub start_externallink {
 2895:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2896:     my $currentstring = '';
 2897:     if ($target eq 'web') {
 2898: 	my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1);
 2899: 	$currentstring .= '<b>'.$display.'</b>';;
 2900:     }
 2901:     return $currentstring;
 2902: }
 2903: 
 2904: sub end_externallink {
 2905:     my ($target,$token) = @_;
 2906:     my $currentstring = '';
 2907:     if ($target eq 'web') {
 2908: 	$currentstring .= '';
 2909:     }
 2910:     return $currentstring;
 2911: }
 2912: 
 2913: #-- <blankspace heigth="">
 2914: sub start_blankspace {
 2915:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
 2916:     my $currentstring = '';
 2917:     if ($target eq 'tex') {
 2918: 	my $howmuch = &Apache::lonxml::get_param('heigth',$parstack,$safeeval,undef,1);
 2919: 	$currentstring .= '\vskip '.$howmuch.' ';
 2920:     }
 2921:     return $currentstring;
 2922: }
 2923: 
 2924: sub end_blankspace {
 2925:     my ($target,$token) = @_;
 2926:     my $currentstring = '';
 2927:     if ($target eq 'tex') {
 2928: 	$currentstring .= '';
 2929:     }
 2930:     return $currentstring;
 2931: }
 2932: 
 2933: #-- <abbr> tag (end tag required)
 2934: sub start_abbr {
 2935:     my ($target,$token) = @_;
 2936:     my $currentstring = '';
 2937:     if ($target eq 'web') {
 2938: 	$currentstring = $token->[4];     
 2939:     } 
 2940:     return $currentstring;
 2941: }
 2942: 
 2943: sub end_abbr {
 2944:     my ($target,$token) = @_;
 2945:     my $currentstring = '';
 2946:     if ($target eq 'web') {
 2947: 	$currentstring = $token->[2];    
 2948:     } 
 2949:     return $currentstring;
 2950: }
 2951: 
 2952: #-- <acronym> tag (end tag required)
 2953: sub start_acronym {
 2954:     my ($target,$token) = @_;
 2955:     my $currentstring = '';
 2956:     if ($target eq 'web') {
 2957: 	$currentstring = $token->[4];     
 2958:     } 
 2959:     return $currentstring;
 2960: }
 2961: 
 2962: sub end_acronym {
 2963:     my ($target,$token) = @_;
 2964:     my $currentstring = '';
 2965:     if ($target eq 'web') {
 2966: 	$currentstring = $token->[2];    
 2967:     } 
 2968:     return $currentstring;
 2969: }
 2970: 
 2971: #-- <area> tag (end tag forbidden)
 2972: sub start_area {
 2973:     my ($target,$token) = @_;
 2974:     my $currentstring = '';
 2975:     if ($target eq 'web') {
 2976: 	$currentstring = $token->[4];     
 2977:     } 
 2978:     return $currentstring;
 2979: }
 2980: 
 2981: sub end_area {
 2982:     my ($target,$token) = @_;
 2983:     my $currentstring = '';
 2984:     if ($target eq 'web') {
 2985: 	$currentstring = $token->[2];    
 2986:     } 
 2987:     return $currentstring;
 2988: }
 2989: 
 2990: #-- <base> tag (end tag forbidden)
 2991: sub start_base {
 2992:     my ($target,$token) = @_;
 2993:     my $currentstring = '';
 2994:     if ($target eq 'web') {
 2995: 	$currentstring = $token->[4];     
 2996:     }
 2997:     return $currentstring;
 2998: }
 2999: 
 3000: sub end_base {
 3001:     my ($target,$token) = @_;
 3002:     my $currentstring = '';
 3003:     if ($target eq 'web') {
 3004: 	$currentstring = $token->[2];    
 3005:     } 
 3006:     return $currentstring;
 3007: }
 3008: 
 3009: #-- <bdo> tag (end tag required)
 3010: sub start_bdo {
 3011:     my ($target,$token) = @_;
 3012:     my $currentstring = '';
 3013:     if ($target eq 'web') {
 3014: 	$currentstring = $token->[4];     
 3015:     } 
 3016:     return $currentstring;
 3017: }
 3018: 
 3019: sub end_bdo {
 3020:     my ($target,$token) = @_;
 3021:     my $currentstring = '';
 3022:     if ($target eq 'web') {
 3023: 	$currentstring = $token->[2];    
 3024:     } 
 3025:     return $currentstring;
 3026: }
 3027: 
 3028: #-- <bgsound> tag (end tag optional)
 3029: sub start_bgsound {
 3030:     my ($target,$token) = @_;
 3031:     my $currentstring = '';
 3032:     if ($target eq 'web') {
 3033: 	$currentstring = $token->[4];     
 3034:     } 
 3035:     return $currentstring;
 3036: }
 3037: 
 3038: sub end_bgsound {
 3039:     my ($target,$token) = @_;
 3040:     my $currentstring = '';
 3041:     if ($target eq 'web') {
 3042: 	$currentstring = $token->[2];    
 3043:     } 
 3044:     return $currentstring;
 3045: }
 3046: 
 3047: #-- <blink> tag (end tag required)
 3048: sub start_blink {
 3049:     my ($target,$token) = @_;
 3050:     my $currentstring = '';
 3051:     if ($target eq 'web') {
 3052: 	$currentstring = $token->[4];     
 3053:     } 
 3054:     return $currentstring;
 3055: }
 3056: 
 3057: sub end_blink {
 3058:     my ($target,$token) = @_;
 3059:     my $currentstring = '';
 3060:     if ($target eq 'web') {
 3061: 	$currentstring = $token->[2];    
 3062:     } 
 3063:     return $currentstring;
 3064: }
 3065: 
 3066: #-- <blockquote> tag (end tag required)
 3067: sub start_blockquote {
 3068:     my ($target,$token) = @_;
 3069:     my $currentstring = '';
 3070:     if ($target eq 'web') {
 3071: 	$currentstring = $token->[4];     
 3072:     } 
 3073:     return $currentstring;
 3074: }
 3075: 
 3076: sub end_blockquote {
 3077:     my ($target,$token) = @_;
 3078:     my $currentstring = '';
 3079:     if ($target eq 'web') {
 3080: 	$currentstring = $token->[2];    
 3081:     } 
 3082:     return $currentstring;
 3083: }
 3084: 
 3085: #-- <button> tag (end tag required)
 3086: sub start_button {
 3087:     my ($target,$token) = @_;
 3088:     my $currentstring = '';
 3089:     if ($target eq 'web') {
 3090: 	$currentstring = $token->[4];     
 3091:     } 
 3092:     return $currentstring;
 3093: }
 3094: 
 3095: sub end_button {
 3096:     my ($target,$token) = @_;
 3097:     my $currentstring = '';
 3098:     if ($target eq 'web') {
 3099: 	$currentstring = $token->[2];    
 3100:     } 
 3101:     return $currentstring;
 3102: }
 3103: 
 3104: #-- <caption> tag (end tag required)
 3105: sub start_caption {
 3106:     my ($target,$token) = @_;
 3107:     my $currentstring = '';
 3108:     if ($target eq 'web') {
 3109: 	$currentstring = $token->[4];     
 3110:     } 
 3111:     return $currentstring;
 3112: }
 3113: 
 3114: sub end_caption {
 3115:     my ($target,$token) = @_;
 3116:     my $currentstring = '';
 3117:     if ($target eq 'web') {
 3118: 	$currentstring = $token->[2];    
 3119:     } 
 3120:     return $currentstring;
 3121: }
 3122: 
 3123: #-- <col> tag (end tag forbdden)
 3124: sub start_col {
 3125:     my ($target,$token) = @_;
 3126:     my $currentstring = '';
 3127:     if ($target eq 'web') {
 3128: 	$currentstring = $token->[4];     
 3129:     } 
 3130:     return $currentstring;
 3131: }
 3132: 
 3133: sub end_col {
 3134:     my ($target,$token) = @_;
 3135:     my $currentstring = '';
 3136:     if ($target eq 'web') {
 3137: 	$currentstring = $token->[2];    
 3138:     } 
 3139:     return $currentstring;
 3140: }
 3141: 
 3142: #-- <colgroup> tag (end tag optional)
 3143: sub start_colgroup {
 3144:     my ($target,$token) = @_;
 3145:     my $currentstring = '';
 3146:     if ($target eq 'web') {
 3147: 	$currentstring = $token->[4];     
 3148:     } 
 3149:     return $currentstring;
 3150: }
 3151: 
 3152: sub end_colgroup {
 3153:     my ($target,$token) = @_;
 3154:     my $currentstring = '';
 3155:     if ($target eq 'web') {
 3156: 	$currentstring = $token->[2];    
 3157:     } 
 3158:     return $currentstring;
 3159: }
 3160: 
 3161: #-- <del> tag (end tag required)
 3162: sub start_del {
 3163:     my ($target,$token) = @_;
 3164:     my $currentstring = '';
 3165:     if ($target eq 'web') {
 3166: 	$currentstring = $token->[4];     
 3167:     } 
 3168:     return $currentstring;
 3169: }
 3170: 
 3171: sub end_del {
 3172:     my ($target,$token) = @_;
 3173:     my $currentstring = '';
 3174:     if ($target eq 'web') {
 3175: 	$currentstring = $token->[2];    
 3176:     } 
 3177:     return $currentstring;
 3178: }
 3179: 
 3180: #-- <fieldset> tag (end tag required)
 3181: sub start_fieldset {
 3182:     my ($target,$token) = @_;
 3183:     my $currentstring = '';
 3184:     if ($target eq 'web') {
 3185: 	$currentstring = $token->[4];     
 3186:     } 
 3187:     return $currentstring;
 3188: }
 3189: 
 3190: sub end_fieldset {
 3191:     my ($target,$token) = @_;
 3192:     my $currentstring = '';
 3193:     if ($target eq 'web') {
 3194: 	$currentstring = $token->[2];    
 3195:     } 
 3196:     return $currentstring;
 3197: }
 3198: 
 3199: #-- <frame> tag (end tag forbidden)
 3200: sub start_frame {
 3201:     my ($target,$token) = @_;
 3202:     my $currentstring = '';
 3203:     if ($target eq 'web') {
 3204: 	$currentstring = $token->[4];     
 3205:     } 
 3206:     return $currentstring;
 3207: }
 3208: 
 3209: sub end_frame {
 3210:     my ($target,$token) = @_;
 3211:     my $currentstring = '';
 3212:     if ($target eq 'web') {
 3213: 	$currentstring = $token->[2];    
 3214:     } 
 3215:     return $currentstring;
 3216: }
 3217: 
 3218: #-- <iframe> tag (end tag required)
 3219: sub start_iframe {
 3220:     my ($target,$token) = @_;
 3221:     my $currentstring = '';
 3222:     if ($target eq 'web') {
 3223: 	$currentstring = $token->[4];     
 3224:     } 
 3225:     return $currentstring;
 3226: }
 3227: 
 3228: sub end_iframe {
 3229:     my ($target,$token) = @_;
 3230:     my $currentstring = '';
 3231:     if ($target eq 'web') {
 3232: 	$currentstring = $token->[2];    
 3233:     } 
 3234:     return $currentstring;
 3235: }
 3236: 
 3237: #-- <ins> tag (end tag required)
 3238: sub start_ins {
 3239:     my ($target,$token) = @_;
 3240:     my $currentstring = '';
 3241:     if ($target eq 'web') {
 3242: 	$currentstring = $token->[4];     
 3243:     } 
 3244:     return $currentstring;
 3245: }
 3246: 
 3247: sub end_ins {
 3248:     my ($target,$token) = @_;
 3249:     my $currentstring = '';
 3250:     if ($target eq 'web') {
 3251: 	$currentstring = $token->[2];    
 3252:     } 
 3253:     return $currentstring;
 3254: }
 3255: 
 3256: #-- <isindex> tag (end tag forbidden)
 3257: sub start_isindex {
 3258:     my ($target,$token) = @_;
 3259:     my $currentstring = '';
 3260:     if ($target eq 'web') {
 3261: 	$currentstring = $token->[4];     
 3262:     } 
 3263:     return $currentstring;
 3264: }
 3265: 
 3266: sub end_isindex {
 3267:     my ($target,$token) = @_;
 3268:     my $currentstring = '';
 3269:     if ($target eq 'web') {
 3270: 	$currentstring = $token->[2];    
 3271:     } 
 3272:     return $currentstring;
 3273: }
 3274: 
 3275: #-- <keygen> tag (end tag forbidden)
 3276: sub start_keygen {
 3277:     my ($target,$token) = @_;
 3278:     my $currentstring = '';
 3279:     if ($target eq 'web') {
 3280: 	$currentstring = $token->[4];     
 3281:     } 
 3282:     return $currentstring;
 3283: }
 3284: 
 3285: sub end_keygen {
 3286:     my ($target,$token) = @_;
 3287:     my $currentstring = '';
 3288:     if ($target eq 'web') {
 3289: 	$currentstring = $token->[2];    
 3290:     } 
 3291:     return $currentstring;
 3292: }
 3293: 
 3294: #-- <label> tag
 3295: sub start_label {
 3296:     my ($target,$token) = @_;
 3297:     my $currentstring = '';
 3298:     if ($target eq 'web') {
 3299: 	$currentstring = $token->[4];     
 3300:     } 
 3301:     return $currentstring;
 3302: }
 3303: 
 3304: sub end_label {
 3305:     my ($target,$token) = @_;
 3306:     my $currentstring = '';
 3307:     if ($target eq 'web') {
 3308: 	$currentstring = $token->[2];    
 3309:     } 
 3310:     return $currentstring;
 3311: }
 3312: 
 3313: #-- <layer> tag (end tag required)
 3314: sub start_layer {
 3315:     my ($target,$token) = @_;
 3316:     my $currentstring = '';
 3317:     if ($target eq 'web') {
 3318: 	$currentstring = $token->[4];     
 3319:     } 
 3320:     return $currentstring;
 3321: }
 3322: 
 3323: sub end_layer {
 3324:     my ($target,$token) = @_;
 3325:     my $currentstring = '';
 3326:     if ($target eq 'web') {
 3327: 	$currentstring = $token->[2];    
 3328:     } 
 3329:     return $currentstring;
 3330: }
 3331: 
 3332: #-- <legend> tag (end tag required)
 3333: sub start_legend {
 3334:     my ($target,$token) = @_;
 3335:     my $currentstring = '';
 3336:     if ($target eq 'web') {
 3337: 	$currentstring = $token->[4];     
 3338:     } 
 3339:     return $currentstring;
 3340: }
 3341: 
 3342: sub end_legend {
 3343:     my ($target,$token) = @_;
 3344:     my $currentstring = '';
 3345:     if ($target eq 'web') {
 3346: 	$currentstring = $token->[2];    
 3347:     } 
 3348:     return $currentstring;
 3349: }
 3350: 
 3351: #-- <link> tag (end tag forbidden)
 3352: sub start_link {
 3353:     my ($target,$token) = @_;
 3354:     my $currentstring = '';
 3355:     if ($target eq 'web') {
 3356: 	$currentstring = $token->[4];     
 3357:     } 
 3358:     return $currentstring;
 3359: }
 3360: 
 3361: sub end_link {
 3362:     my ($target,$token) = @_;
 3363:     my $currentstring = '';
 3364:     if ($target eq 'web') {
 3365: 	$currentstring = $token->[2];    
 3366:     } 
 3367:     return $currentstring;
 3368: }
 3369: 
 3370: #-- <marquee> tag (end tag optional)
 3371: sub start_marquee {
 3372:     my ($target,$token) = @_;
 3373:     my $currentstring = '';
 3374:     if ($target eq 'web') {
 3375: 	$currentstring = $token->[4];     
 3376:     } 
 3377:     return $currentstring;
 3378: }
 3379: 
 3380: sub end_marquee {
 3381:     my ($target,$token) = @_;
 3382:     my $currentstring = '';
 3383:     if ($target eq 'web') {
 3384: 	$currentstring = $token->[2];    
 3385:     } 
 3386:     return $currentstring;
 3387: }
 3388: 
 3389: #-- <multicol> tag (end tag required)
 3390: sub start_multicol {
 3391:     my ($target,$token) = @_;
 3392:     my $currentstring = '';
 3393:     if ($target eq 'web') {
 3394: 	$currentstring = $token->[4];     
 3395:     } 
 3396:     return $currentstring;
 3397: }
 3398: 
 3399: sub end_multicol {
 3400:     my ($target,$token) = @_;
 3401:     my $currentstring = '';
 3402:     if ($target eq 'web') {
 3403: 	$currentstring = $token->[2];    
 3404:     } 
 3405:     return $currentstring;
 3406: }
 3407: 
 3408: #-- <nobr> tag (end tag required)
 3409: sub start_nobr {
 3410:     my ($target,$token) = @_;
 3411:     my $currentstring = '';
 3412:     if ($target eq 'web') {
 3413: 	$currentstring = $token->[4];     
 3414:     }  elsif ($target eq 'tex') {
 3415: 	$currentstring='\mbox{';
 3416:     }
 3417:     return $currentstring;
 3418: }
 3419: 
 3420: sub end_nobr {
 3421:     my ($target,$token) = @_;
 3422:     my $currentstring = '';
 3423:     if ($target eq 'web') {
 3424: 	$currentstring = $token->[2];    
 3425:     }   elsif ($target eq 'tex') {
 3426: 	$currentstring='}';
 3427:     }
 3428:     return $currentstring;
 3429: }
 3430: 
 3431: #-- <noembed> tag (end tag required)
 3432: sub start_noembed {
 3433:     my ($target,$token) = @_;
 3434:     my $currentstring = '';
 3435:     if ($target eq 'web') {
 3436: 	$currentstring = $token->[4];     
 3437:     } 
 3438:     return $currentstring;
 3439: }
 3440: 
 3441: sub end_noembed {
 3442:     my ($target,$token) = @_;
 3443:     my $currentstring = '';
 3444:     if ($target eq 'web') {
 3445: 	$currentstring = $token->[2];    
 3446:     } 
 3447:     return $currentstring;
 3448: }
 3449: 
 3450: #-- <noframes> tag (end tag required)
 3451: sub start_noframes {
 3452:     my ($target,$token) = @_;
 3453:     my $currentstring = '';
 3454:     if ($target eq 'web') {
 3455: 	$currentstring = $token->[4];     
 3456:     } 
 3457:     return $currentstring;
 3458: }
 3459: 
 3460: sub end_noframes {
 3461:     my ($target,$token) = @_;
 3462:     my $currentstring = '';
 3463:     if ($target eq 'web') {
 3464: 	$currentstring = $token->[2];    
 3465:     } 
 3466:     return $currentstring;
 3467: }
 3468: 
 3469: #-- <nolayer> tag (end tag required)
 3470: sub start_nolayer {
 3471:     my ($target,$token) = @_;
 3472:     my $currentstring = '';
 3473:     if ($target eq 'web') {
 3474: 	$currentstring = $token->[4];     
 3475:     } 
 3476:     return $currentstring;
 3477: }
 3478: 
 3479: sub end_nolayer {
 3480:     my ($target,$token) = @_;
 3481:     my $currentstring = '';
 3482:     if ($target eq 'web') {
 3483: 	$currentstring = $token->[2];    
 3484:     } 
 3485:     return $currentstring;
 3486: }
 3487: 
 3488: #-- <noscript> tag (end tag required)
 3489: sub start_noscript {
 3490:     my ($target,$token) = @_;
 3491:     my $currentstring = '';
 3492:     if ($target eq 'web') {
 3493: 	$currentstring = $token->[4];     
 3494:     } 
 3495:     return $currentstring;
 3496: }
 3497: 
 3498: sub end_noscript {
 3499:     my ($target,$token) = @_;
 3500:     my $currentstring = '';
 3501:     if ($target eq 'web') {
 3502: 	$currentstring = $token->[2];    
 3503:     } 
 3504:     return $currentstring;
 3505: }
 3506: 
 3507: #-- <object> tag (end tag required)
 3508: sub start_object {
 3509:     my ($target,$token) = @_;
 3510:     my $currentstring = '';
 3511:     if ($target eq 'web') {
 3512: 	$currentstring = $token->[4];     
 3513:     } 
 3514:     return $currentstring;
 3515: }
 3516: 
 3517: sub end_object {
 3518:     my ($target,$token) = @_;
 3519:     my $currentstring = '';
 3520:     if ($target eq 'web') {
 3521: 	$currentstring = $token->[2];    
 3522:     } 
 3523:     return $currentstring;
 3524: }
 3525: 
 3526: #-- <optgroup> tag (end tag required)
 3527: sub start_optgroup {
 3528:     my ($target,$token) = @_;
 3529:     my $currentstring = '';
 3530:     if ($target eq 'web') {
 3531: 	$currentstring = $token->[4];     
 3532:     } 
 3533:     return $currentstring;
 3534: }
 3535: 
 3536: sub end_optgroup {
 3537:     my ($target,$token) = @_;
 3538:     my $currentstring = '';
 3539:     if ($target eq 'web') {
 3540: 	$currentstring = $token->[2];    
 3541:     } 
 3542:     return $currentstring;
 3543: }
 3544: 
 3545: #-- <samp> tag (end tag required)
 3546: sub start_samp {
 3547:     my ($target,$token) = @_;
 3548:     my $currentstring = '';
 3549:     if ($target eq 'web') {
 3550: 	$currentstring = $token->[4];     
 3551:     } elsif ($target eq 'tex') {
 3552: 	$currentstring='\texttt{';
 3553:     }
 3554:     return $currentstring;
 3555: }
 3556: 
 3557: sub end_samp {
 3558:     my ($target,$token) = @_;
 3559:     my $currentstring = '';
 3560:     if ($target eq 'web') {
 3561: 	$currentstring = $token->[2];    
 3562:     } elsif ($target eq 'tex') {
 3563: 	$currentstring='}';
 3564:     }
 3565:     return $currentstring;
 3566: }
 3567: 
 3568: #-- <server> tag
 3569: sub start_server {
 3570:     my ($target,$token) = @_;
 3571:     my $currentstring = '';
 3572:     if ($target eq 'web') {
 3573: 	$currentstring = $token->[4];     
 3574:     } 
 3575:     return $currentstring;
 3576: }
 3577: 
 3578: sub end_server {
 3579:     my ($target,$token) = @_;
 3580:     my $currentstring = '';
 3581:     if ($target eq 'web') {
 3582: 	$currentstring = $token->[2];    
 3583:     } 
 3584:     return $currentstring;
 3585: }
 3586: 
 3587: #-- <spacer> tag (end tag forbidden)
 3588: sub start_spacer {
 3589:     my ($target,$token) = @_;
 3590:     my $currentstring = '';
 3591:     if ($target eq 'web') {
 3592: 	$currentstring = $token->[4];     
 3593:     } 
 3594:     return $currentstring;
 3595: }
 3596: 
 3597: sub end_spacer {
 3598:     my ($target,$token) = @_;
 3599:     my $currentstring = '';
 3600:     if ($target eq 'web') {
 3601: 	$currentstring = $token->[2];    
 3602:     } 
 3603:     return $currentstring;
 3604: }
 3605: 
 3606: #-- <span> tag (end tag required)
 3607: sub start_span {
 3608:     my ($target,$token) = @_;
 3609:     my $currentstring = '';
 3610:     if ($target eq 'web') {
 3611: 	$currentstring = $token->[4];     
 3612:     } 
 3613:     return $currentstring;
 3614: }
 3615: 
 3616: sub end_span {
 3617:     my ($target,$token) = @_;
 3618:     my $currentstring = '';
 3619:     if ($target eq 'web') {
 3620: 	$currentstring = $token->[2];    
 3621:     } 
 3622:     return $currentstring;
 3623: }
 3624: 
 3625: #-- <tbody> tag (end tag optional)
 3626: sub start_tbody {
 3627:     my ($target,$token) = @_;
 3628:     my $currentstring = '';
 3629:     if ($target eq 'web') {
 3630: 	$currentstring = $token->[4];     
 3631:     } 
 3632:     return $currentstring;
 3633: }
 3634: 
 3635: sub end_tbody {
 3636:     my ($target,$token) = @_;
 3637:     my $currentstring = '';
 3638:     if ($target eq 'web') {
 3639: 	$currentstring = $token->[2];    
 3640:     } 
 3641:     return $currentstring;
 3642: }
 3643: 
 3644: #-- <tfoot> tag (end tag optional)
 3645: sub start_tfoot {
 3646:     my ($target,$token) = @_;
 3647:     my $currentstring = '';
 3648:     if ($target eq 'web') {
 3649: 	$currentstring = $token->[4];     
 3650:     } 
 3651:     return $currentstring;
 3652: }
 3653: 
 3654: sub end_tfoot {
 3655:     my ($target,$token) = @_;
 3656:     my $currentstring = '';
 3657:     if ($target eq 'web') {
 3658: 	$currentstring = $token->[2];    
 3659:     } 
 3660:     return $currentstring;
 3661: }
 3662: 
 3663: #-- <thead> tag (end tag optional)
 3664: sub start_thead {
 3665:     my ($target,$token) = @_;
 3666:     my $currentstring = '';
 3667:     if ($target eq 'web') {
 3668: 	$currentstring = $token->[4];     
 3669:     } 
 3670:     return $currentstring;
 3671: }
 3672: 
 3673: sub end_thead {
 3674:     my ($target,$token) = @_;
 3675:     my $currentstring = '';
 3676:     if ($target eq 'web') {
 3677: 	$currentstring = $token->[2];    
 3678:     } 
 3679:     return $currentstring;
 3680: }
 3681: 
 3682: #-- <var> tag
 3683: sub start_var {
 3684:     my ($target,$token) = @_;
 3685:     my $currentstring = '';
 3686:     if ($target eq 'web') {
 3687: 	$currentstring = $token->[4];     
 3688:     } elsif ($target eq 'tex') {
 3689: 	$currentstring = '\textit{'; 
 3690:     }
 3691:     return $currentstring;
 3692: }
 3693: 
 3694: sub end_var {
 3695:     my ($target,$token) = @_;
 3696:     my $currentstring = '';
 3697:     if ($target eq 'web') {
 3698: 	$currentstring = $token->[2];
 3699:     } elsif ($target eq 'tex') {
 3700: 	$currentstring = '}'; 
 3701:     } 
 3702:     return $currentstring;
 3703: }
 3704: 
 3705: #-- <wbr> tag (end tag forbidden)
 3706: sub start_wbr {
 3707:     my ($target,$token) = @_;
 3708:     my $currentstring = '';
 3709:     if ($target eq 'web') {
 3710: 	$currentstring = $token->[4];     
 3711:     } 
 3712:     return $currentstring;
 3713: }
 3714: 
 3715: sub end_wbr {
 3716:     my ($target,$token) = @_;
 3717:     my $currentstring = '';
 3718:     if ($target eq 'web') {
 3719: 	$currentstring = $token->[2];    
 3720:     } 
 3721:     return $currentstring;
 3722: }
 3723: 
 3724: #-- <hideweboutput> tag
 3725: sub start_hideweboutput {
 3726:     my ($target,$token) = @_;
 3727:     if ($target eq 'web') {
 3728: 	&Apache::lonxml::startredirection();     
 3729:     } 
 3730:     return '';
 3731: }
 3732: 
 3733: sub end_hideweboutput {
 3734:     my ($target,$token) = @_;
 3735:     my $currentstring = '';
 3736:     if ($target eq 'web') {
 3737: 	$currentstring = &Apache::lonxml::endredirection();    
 3738:     } 
 3739:     return '';
 3740: }
 3741: 
 3742: 
 3743: sub image_replication {
 3744:     my $src = shift;
 3745:     if (not -e $src) { &Apache::lonnet::repcopy($src); }
 3746:     #replicates eps or ps 
 3747:     my $epssrc = my $pssrc = $src;
 3748:     $epssrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i;
 3749:     $pssrc  =~ s/\.(gif|jpg|jpeg|png)$/.ps/i;
 3750:     if (not -e $epssrc && not -e $pssrc) {
 3751: 	my $result=&Apache::lonnet::repcopy($epssrc);
 3752: 	if ($result ne 'OK') { &Apache::lonnet::repcopy($pssrc); }
 3753:     }
 3754:     return '';
 3755: }
 3756: 
 3757: sub image_size {
 3758:     my ($src,$scaling,$parstack,$safeeval,$depth,$cis)=@_;
 3759:     #size of image from gif/jpg/jpeg/png 
 3760:     $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
 3761:     my $image = Image::Magick->new;
 3762:     my $current_figure = $image->Read($src);
 3763:     my $width_param = $image->Get('width') * $scaling;;
 3764:     my $height_param = $image->Get('height') * $scaling;;
 3765:     undef($image);
 3766:     #do we have any specified LaTeX size of the picture?
 3767:     my $toget='TeXwidth'; if ($cis) { $toget=lc($toget); }
 3768:     my $TeXwidth = &Apache::lonxml::get_param($toget,$parstack,
 3769: 					      $safeeval,$depth,$cis);
 3770:     $toget='TeXheight'; if ($cis) { $toget=lc($toget); }
 3771:     my $TeXheight = &Apache::lonxml::get_param($toget,$parstack,
 3772: 					       $safeeval,$depth,$cis);
 3773:     #do we have any specified web size of the picture?
 3774:     my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval,
 3775: 					   $depth,1);
 3776:     if ($TeXwidth) { 
 3777: 	my $old_width_param=$width_param;
 3778: 	if ($TeXwidth=~/(\d+)\s*\%/) {
 3779: 	    $width_param = $1*$ENV{'form.textwidth'}/100;
 3780: 	} else { 
 3781: 	    $width_param = $TeXwidth;
 3782: 	}
 3783: 	$height_param=$TeXwidth/$old_width_param*$height_param;
 3784:     } elsif ($TeXheight) {
 3785: 	$height_param = $TeXheight;
 3786: 	$width_param  = $TeXheight/$height_param*$width_param;
 3787:     } elsif ($width) {
 3788: 	my $old_width_param=$width_param;
 3789: 	$width_param = $width*$scaling;
 3790:         $height_param=$width_param/$old_width_param*$height_param;
 3791:     }
 3792:     if ($width_param > $ENV{'form.textwidth'}) {
 3793:         my $old_width_param=$width_param;
 3794: 	$width_param =0.95*$ENV{'form.textwidth'};
 3795:         $height_param=$width_param/$old_width_param*$height_param;
 3796:     }
 3797:     return ($height_param, $width_param);
 3798: }
 3799: 
 3800: sub image_width {
 3801:     my ($height, $width) = &image_size(@_);
 3802:     return $width;
 3803: }
 3804: #  Not yet 100% sure this is correct in all circumstances..
 3805: #  due to my uncertainty about mods to image_size.
 3806: #
 3807: sub image_height {
 3808:     my ($height, $width) = &image_size(@_);
 3809:     return $height;
 3810: }
 3811: 
 3812: sub get_eps_image {
 3813:     my ($src)=@_;
 3814:     my $orig_src=$src;
 3815:     $src=~s/\.(gif|png|jpg|jpeg)$/\.eps/i;
 3816:     $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
 3817:     if (! -e $src) {
 3818: 	if (&Apache::lonnet::repcopy($src) ne 'OK' ) {
 3819: 	    #if replication failed try to find ps file
 3820: 	    $src=~s/\.eps$/\.ps/;
 3821: 	    #if no ps file try to replicate it
 3822: 	    if (not -e $src &&
 3823: 		&Apache::lonnet::repcopy($src) ne 'OK') {
 3824: 		#if replication failed try to produce eps file dynamically
 3825: 		$src=~s/\.ps$/\.eps/;
 3826: 		my $temp_file;
 3827: 		open(FILE,">>/home/httpd/prtspool/$ENV{'user.name'}_$ENV{'user.domain'}_printout.dat");
 3828: 		my $newsrc=$orig_src;
 3829: 		$newsrc =~ s|(.*)/res/|/home/httpd/html/res/|;
 3830: 		print FILE "$newsrc\n";
 3831: 		$src=~s|/home/httpd/html/res|/home/httpd/prtspool|;
 3832: 		$src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;
 3833: 	    }
 3834: 	}
 3835:     }
 3836:     my ($path,$file)=($src=~m|(.*)/([^/]*)$|);
 3837:     return ($path.'/',$file);
 3838: }
 3839: 
 3840: sub eps_generation {
 3841:     my ($src,$file,$width_param) = @_;	     
 3842:     my $filename = "/home/httpd/prtspool/$ENV{'user.name'}_$ENV{'user.domain'}_printout.dat";
 3843:     my $temp_file = Apache::File->new('>>'.$filename); 
 3844:     print $temp_file "$src\n";
 3845:     my $newsrc = $src;
 3846:     $newsrc =~ s/(\.gif|\.jpg|\.jpeg)$/\.eps/i;
 3847:     $newsrc=~s/\/home\/httpd\/html\/res//;
 3848:     $newsrc=~s/\/home\/([^\/]*)\/public_html\//\/$1\//;
 3849:     $newsrc=~s/\/\.\//\//;
 3850:     $newsrc=~s/\/([^\/]+)\.(ps|eps)/\//;
 3851:     if ($newsrc=~/\/home\/httpd\/lonUsers\//) {
 3852: 	$newsrc=~s/\/home\/httpd\/lonUsers//;
 3853: 	$newsrc=~s/\/([^\/]+)\/(\w)\/(\w)\/(\w)\//\/$1\//;
 3854:     }
 3855:     if ($newsrc=~/\/userfiles\//) {
 3856: 	return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
 3857:     } else {
 3858: 	return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
 3859:     }
 3860: }
 3861: 
 3862: sub file_path {     
 3863:     my $src=shift;
 3864:     my ($file,$path); 
 3865:     if ($src =~ m!(.*)/([^/]*)$!) {
 3866: 	$file = $2; 
 3867: 	$path = $1.'/'; 
 3868:     } 
 3869:     return $file,$path;
 3870: }
 3871: 
 3872: sub recalc {
 3873:     my $argument = shift;
 3874:     if (not $argument=~/(mm|cm|in|pc|pt)/) {return $argument.' mm';}
 3875:     $argument=~/\s*(\d+\.?\d*)\s*(mm|cm|in|pc|pt)/;
 3876:     my $value=$1;
 3877:     my $units=$2;
 3878:     if ($units eq 'cm') {
 3879: 	$value*=10;
 3880:     } elsif ($units eq 'in') {
 3881: 	$value*=25.4;
 3882:     } elsif ($units eq 'pc') {
 3883: 	$value*=(25.4*12/72.27);
 3884:     } elsif ($units eq 'pt') {
 3885: 	$value*=(25.4/72.27);
 3886:     }
 3887:     return $value.' mm';
 3888: }
 3889: 
 3890: sub LATEX_length {
 3891:     my $garbage=shift;
 3892:     $garbage=~s/^\s+$//;
 3893:     $garbage=~s/^\s+(\S.*)/$1/;#space before 
 3894:     $garbage=~s/(.*\S)\s+$/$1/;#space after 
 3895:     $garbage=~s/(\s)+/$1/;#only one space
 3896:     $garbage=~s/(\\begin{([^\}]+)}|\\end{([^\}]+)})//g;#remove LaTeX \begin{...} and \end{...}
 3897:     $garbage=~s/(\$\_\{|\$\_|\$\^{|\$\^|\}\$)//g;#remove $_{,$_,$^{,$^,}$
 3898:     $garbage=~s/([^\\])\$/$1/g;#$
 3899:     $garbage=~s/(\\ensuremath\{\_\{|\\ensuremath\{\_|\\ensuremath\{\^{|\\ensuremath\{\^|\})//g;#remove \ensuremath{...}
 3900:    $garbage=~s/(\\alpha|\\beta|\\gamma|\\delta|\\epsilon|\\verepsilon|\\zeta|\\eta|\\theta|\\vartheta|\\iota|\\kappa|\\lambda|\\mu|\\nu|\\xi|\\pi|\\varpi|\\rho|\\varrho|\\sigma|\\varsigma|\\tau|\\upsilon|\\phi|\\varphi|\\chi|\\psi|\\omega|\\Gamma|\\Delta|\\Theta|\\Lambda|\\Xi|\\Pi|\\Sigma|\\Upsilon|\\Phi|\\Psi|\\Omega)/1/g;
 3901:     $garbage=~s/(\\pm|\\mp|\\times|\\div|\\cdot|\\ast|\\star|\\dagger|\\ddagger|\\amalg|\\cap|\\cup|\\uplus|\\sqcap|\\sqcup|\\vee|\\wedge|\\oplus|\\ominus|\\otimes|\\circ|\\bullet|\\diamond|\\lhd|\\rhd|\\unlhd|\\unrhd|\\oslash|\\odot|\\bigcirc|\\Box|\\Diamond|\\bigtriangleup|\\bigtriangledown|\\triangleleft|\\triangleright|\\setminus|\\wr)/1/g;
 3902:     $garbage=~s/(\\le|\\ll|\\leq|\\ge|\\geq|\\gg|\\neq|\\doreq|\\sim|\\simeq|\\subset|\\subseteq|\\sqsubset|\\sqsubseteq|\\in|\\vdash|\\models|\\supset|\\supseteq|\\sqsupset|\\sqsupseteq|\\ni|\\dash|\\perp|\\approx|\\cong|\\equiv|\\propto|\\prec|\\preceq|\\parallel|\\asymp|\\smile|\\frown|\\bowtie|\\succ|\\succeq|\\mid)/1/g;
 3903:     $garbage=~s/(\\not<|\\\\not\\le|\\not\\prec|\\not\\preceq|\\not\\subset|\\not\\subseteq|\\not\\sqsubseteq|\\not\\in|\\not>|\\not\\ge|\\not\\succ|\\notsucceq|\\not\\supset|\\notsupseteq|\\not\\sqsupseteq|\\notin|\\not=|\\not\\equiv|\\not\\sim|\\not\\simeq|\\not\\approx|\\not\\cong|\\not\\asymp)/1/g;
 3904:     $garbage=~s/(\\leftarrow|\\gets|\\Leftarrow|\\rightarrow|\\to|\\Rightarrow|\\leftrightarrow|\\Leftrightarrow|\\mapsto|\\hookleftarrow|\\leftharpoonup|\\leftkarpoondown|\\rightleftharpoons|\\longleftarrow|\\Longleftarrow|\\longrightarrow|\\Longrightarrow|\\longleftrightarrow|\\Longleftrightarrow|\\longmapsto|\\hookrightarrow|\\rightharpoonup|\\rightharpoondown|\\uparrow|\\Uparrow|\\downarrow|\\Downarrow|\\updownarrow|\\Updownarrow|\\nearrow|\\searrow|\\swarrow|\\nwarrow)/11/g;
 3905:     $garbage=~s/(\\aleph|\\hbar|\\imath|\\jmath|\\ell|\\wp|\\Re|\\Im|\\mho|\\prime|\\emptyset|\\nabla|\\surd|\\partial|\\top|\\bot|\\vdash|\\dashv|\\forall|\\exists|\\neg|\\flat|\\natural|\\sharp|\\\||\\angle|\\backslash|\\Box|\\Diamond|\\triangle|\\clubsuit|\\diamondsuit|\\heartsuit|\\spadesuit|\\Join|\\infty)/11/g;
 3906:     $garbage=~s/(\\hat{([^}]+)}|\\check{([^}]+)}|\\dot{([^}]+)}|\\breve{([^}]+)}|\\acute{([^}]+)}|\\ddot{([^}]+)}|\\grave{([^}]+)}|\\tilde{([^}]+)}|\\mathring{([^}]+)}|\\bar{([^}]+)}|\\vec{([^}]+)})/$1/g;
 3907:     #remove some other LaTeX command
 3908:     $garbage=~s|\\(\w+)\\|\\|g;	 
 3909:     $garbage=~s|\\(\w+)(\s*)|$2|g;	 	 
 3910:     $garbage=~s|\+|11|g;
 3911:     my  $value=length($garbage);
 3912:     return $value;
 3913: }
 3914: 
 3915: 
 3916: 
 3917: 
 3918: 1;
 3919: __END__

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