Annotation of loncom/xml/londefdef.pm, revision 1.381

1.1       sakharuk    1: # The LearningOnline Network with CAPA
                      2: # Tags Default Definition Module 
                      3: #
1.381   ! www         4: # $Id: londefdef.pm,v 1.380 2007/12/06 11:22:37 foxr Exp $
1.41      sakharuk    5: # 
1.34      www         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/
1.156     sakharuk   28: ## Copyright for TtHfunc and TtMfunc by Ian Hutchinson. 
1.34      www        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: #
1.1       sakharuk   39: 
1.2       albertel   40: package Apache::londefdef; 
1.1       sakharuk   41: 
1.267     albertel   42: use Apache::lonnet;
1.1       sakharuk   43: use strict;
1.124     sakharuk   44: use Apache::lonxml;
1.57      sakharuk   45: use Apache::File();
1.70      sakharuk   46: use Image::Magick;
1.118     www        47: use Apache::lonmenu();
                     48: use Apache::lonmeta();
1.187     albertel   49: use Apache::Constants qw(:common);
1.282     foxr       50: use File::Basename;
1.345     albertel   51: use LONCAPA();
1.302     foxr       52: # use Data::Dumper;
1.160     sakharuk   53: 
1.38      harris41   54: BEGIN {
1.15      sakharuk   55: 
1.135     sakharuk   56:     &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'));
1.15      sakharuk   57: 
1.188     albertel   58: }
                     59: 
1.294     foxr       60: #
                     61: #   Dumps all elements of the table structure.
                     62: #   Need this 'cause evidently when given an array, Data::Dumper only seems
                     63: #   to dump element 0.
                     64: #
1.302     foxr       65: #sub debug_dump_table {
                     66: #    my $lastrow = $#Apache::londefdef::table;
                     67: #    &Apache::lonnet::logthis("Dumping table:  Last row index: $lastrow");
                     68: #    my $row;
                     69: #    for ($row =0; $row <= $lastrow; $row++ ) {
                     70: #	my $text = Dumper($Apache::londefdef::table[$row]);
                     71: #	&Apache::lonnet::logthis("table [ $row ]".$text);
                     72: #    }
                     73: #}
1.188     albertel   74: sub initialize_londefdef {
                     75:     $Apache::londefdef::TD_redirection=0;
                     76:     @Apache::londefdef::table = ();
                     77:     $Apache::londefdef::select=0;
1.243     albertel   78:     undef(@Apache::londefdef::description);
                     79:     @Apache::londefdef::DD=(0);
                     80:     @Apache::londefdef::DT=(0);
1.244     albertel   81:     @Apache::londefdef::seenDT=(0);
1.238     albertel   82:     $Apache::londefdef::list_index=0;
1.327     albertel   83:     undef($Apache::londefdef::head);
                     84:     undef($Apache::londefdef::title);
1.3       sakharuk   85: }
1.1       sakharuk   86: 
1.35      sakharuk   87: #======================= TAG SUBROUTINES =====================
1.8       sakharuk   88: #-- <output>
1.21      albertel   89: sub start_output {
1.122     albertel   90:     my ($target) = @_;
                     91:     if ($target eq 'meta') { $Apache::lonxml::metamode--; }
                     92:     return '';
1.21      albertel   93: }
                     94: sub end_output {
1.122     albertel   95:     my ($target) = @_;
                     96:     if ($target eq 'meta') { $Apache::lonxml::metamode++; }
                     97:     return '';
1.21      albertel   98: }
1.4       sakharuk   99: #-- <m> tag
1.33      albertel  100: sub start_m {
1.190     albertel  101:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
1.122     albertel  102:     my $currentstring = '';
1.193     albertel  103:     my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser);
1.191     albertel  104:     if ($target eq 'web' || $target eq 'analyze') {
1.122     albertel  105: 	&Apache::lonxml::debug("M is starting with:$inside:");
                    106: 	my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
                    107: 	if ($eval eq 'on') {
                    108: 	    $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
                    109: 	    #&Apache::lonxml::debug("M is evaulated to:$inside:");
                    110: 	}
1.317     albertel  111: 	my $tex = $inside;
1.276     albertel  112: 	my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval);
                    113: 	$currentstring = &Apache::lontexconvert::converted(\$inside,$display);
1.122     albertel  114: 	if ($Apache::lontexconvert::errorstring) {
1.317     albertel  115: 	    my $errormsg='<pre>'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'</pre> occured while attempting to convert this TeX: <pre>';
                    116: 	    $tex = &HTML::Entities::encode($tex,'<>&"');
                    117: 	    my ($linenumber) =
                    118: 		($Apache::lontexconvert::errorstring =~ /Line (\d+)/);
                    119: 	    if (defined($linenumber)) {
                    120: 		my @tex=split("\n",$tex);
                    121: 		$tex[$linenumber]='<b><font color="red">'.
                    122: 		    $tex[$linenumber].'</font></b>';
                    123: 		$tex=join("\n",@tex);
                    124: 	    }
                    125: 	    &Apache::lonxml::warning($errormsg.$tex.'</pre>');
1.122     albertel  126: 	    $Apache::lontexconvert::errorstring='';
                    127: 	}
                    128: 	#&Apache::lonxml::debug("M is ends with:$currentstring:");
1.178     albertel  129: 	$Apache::lonxml::post_evaluate=0;
1.122     albertel  130:     } elsif ($target eq 'tex') {
1.360     foxr      131: 
1.190     albertel  132: 	$currentstring = $inside;
1.178     albertel  133: 	my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval);
                    134: 	if ($eval eq 'on') {
                    135: 	    $currentstring=&Apache::run::evaluate($currentstring,$safeeval,$$parstack[-1]);
                    136: 	}
1.122     albertel  137: 	if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';}
1.257     albertel  138: 	# detect simple math mode entry exits, and convert them
1.360     foxr      139:         # to use \ensuremath ... unless there's a \verb inside.
                    140: 	if (! ($currentstring=~/\\verb/)) {
                    141: 	    if ($currentstring=~/^\s*\$[^\$].*[^\$]\$\s*$/) {
                    142: 		$currentstring=~s/^(\s*)\$/$1/;
                    143: 		$currentstring=~s/\$(\s*)$/$1/;
                    144: 		$currentstring='\ensuremath{'.$currentstring.'}';
                    145: 	    }
1.257     albertel  146: 	}
1.178     albertel  147: 	$Apache::lonxml::post_evaluate=0;
1.122     albertel  148:     }
                    149:     return $currentstring;
1.33      albertel  150: }
1.122     albertel  151: 
1.33      albertel  152: sub end_m {
1.122     albertel  153:     my ($target,$token) = @_;
                    154:     my $currentstring = '';
1.204     albertel  155:     if ($target eq 'tex') {
1.122     albertel  156: 	$currentstring = "";
                    157:     }
                    158:     return $currentstring;
1.33      albertel  159: }
1.110     albertel  160: 
                    161: sub start_tthoption {
1.299     albertel  162:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
1.122     albertel  163:     my $result;
1.325     albertel  164:     if ($target eq 'web' || $target eq 'webgrade') {
1.299     albertel  165: 	my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser,
                    166: 						   $style);
1.122     albertel  167: 	$inside=~s/^\s*//;
1.267     albertel  168: 	if ($env{'browser.mathml'}) {
1.122     albertel  169: 	    &tth::ttmoptions($inside);
                    170: 	} else {
                    171: 	    &tth::tthoptions($inside);
                    172: 	}
                    173:     }
                    174:     return $result;
1.110     albertel  175: }
                    176: 
                    177: sub end_tthoption {
1.122     albertel  178:     my ($target,$token) = @_;
                    179:     my $result;
                    180:     return $result;
1.110     albertel  181: }
                    182: 
1.181     sakharuk  183: #-- <html> tag (end tag optional)
1.100     albertel  184: sub start_html {
                    185:     my ($target,$token) = @_;
                    186:     my $currentstring = '';
1.269     albertel  187:     if ($target eq 'web' || $target eq 'edit' || $target eq 'webgrade' ) {
1.327     albertel  188: 	# start_body() takes care of emitting the <html> 
1.100     albertel  189:     } elsif ($target eq 'tex') {
1.331     albertel  190: 	$currentstring .= 
                    191: 	    '\documentclass[letterpaper,twoside]{article}\raggedbottom';
1.267     albertel  192: 	if (($env{'form.latex_type'}=~'batchmode') ||
                    193:             (!$env{'request.role.adv'})) {$currentstring .='\batchmode';} 
1.217     sakharuk  194: 	$currentstring .= '\newcommand{\keephidden}[1]{}'.
                    195:                           '\renewcommand{\deg}{$^{\circ}$}'.
1.306     foxr      196: 			  '\usepackage{multirow}'.
1.217     sakharuk  197:                           '\usepackage{longtable}'.
                    198:                           '\usepackage{textcomp}'.
                    199:                           '\usepackage{makeidx}'.
                    200:                           '\usepackage[dvips]{graphicx}'.
1.286     foxr      201: 			  '\usepackage{wrapfig}'.
1.248     foxr      202: 			  '\usepackage{picins}'.
1.217     sakharuk  203:                           '\usepackage{epsfig}'.
                    204:                           '\usepackage{calc}'.
                    205:                           '\usepackage{amsmath}'.
                    206:                           '\usepackage{amssymb}'.
                    207:                           '\usepackage{amsfonts}'.
                    208:                           '\usepackage{amsthm}'.
                    209:                           '\usepackage{amscd}'.
                    210:                           '\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}}'.
                    211:                           '\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}}';
1.100     albertel  212:     }
                    213:     return $currentstring;
                    214: }
1.122     albertel  215: 
                    216: sub end_html {
1.232     sakharuk  217:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  218:     my $currentstring = '';
1.324     albertel  219:     if ($target eq 'web' || $target eq 'webgrade') {
1.327     albertel  220: 	# end_body takes care of the </html>
1.122     albertel  221:     }
                    222:     return $currentstring;
                    223: }
                    224: 
1.181     sakharuk  225: #-- <head> tag (end tag optional)
1.122     albertel  226: sub start_head {
                    227:     my ($target,$token) = @_;
                    228:     my $currentstring = '';
1.324     albertel  229:     if ($target eq 'web' || $target eq 'webgrade') {
1.327     albertel  230: 	&Apache::lonxml::startredirection();
1.122     albertel  231:     } 
                    232:     return $currentstring;
                    233: }
                    234: 
                    235: sub end_head {
                    236:     my ($target,$token) = @_;
                    237:     my $currentstring = '';
1.324     albertel  238:     if (($target eq 'web'      && $env{'request.state'} eq 'published') ||
                    239: 	($target eq 'webgrade' && $env{'request.state'} eq 'published')) {
1.327     albertel  240: 	# in case there is a </head> but no <head>
                    241: 	if ($Apache::lonxml::redirection) {
                    242: 	    $Apache::londefdef::head = &Apache::lonxml::endredirection();
                    243: 	}
1.122     albertel  244:     } 
                    245:     return $currentstring;
                    246: }
                    247: 
1.181     sakharuk  248: #-- <map> tag (end tag required)
1.122     albertel  249: sub start_map {
                    250:     my ($target,$token) = @_;
                    251:     my $currentstring = '';
1.325     albertel  252:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  253: 	$currentstring = $token->[4];     
                    254:     } 
                    255:     return $currentstring;
                    256: }
                    257: 
                    258: sub end_map {
                    259:     my ($target,$token) = @_;
                    260:     my $currentstring = '';
1.325     albertel  261:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  262: 	$currentstring = $token->[2];    
                    263:     } 
                    264:     return $currentstring;
                    265: }
                    266: 
1.181     sakharuk  267: #-- <select> tag (end tag required)
1.122     albertel  268: sub start_select {
                    269:     my ($target,$token) = @_;
                    270:     my $currentstring = '';
1.325     albertel  271:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  272: 	$currentstring = $token->[4];     
1.181     sakharuk  273:     }  elsif ($target eq 'tex') {
                    274: 	$Apache::londefdef::select=0;
                    275:     }
1.122     albertel  276:     return $currentstring;
                    277: }
                    278: 
                    279: sub end_select {
                    280:     my ($target,$token) = @_;
                    281:     my $currentstring = '';
1.325     albertel  282:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  283: 	$currentstring = $token->[2];    
                    284:     } 
                    285:     return $currentstring;
                    286: }
                    287: 
1.181     sakharuk  288: #-- <option> tag (end tag optional)
1.122     albertel  289: sub start_option {
1.181     sakharuk  290:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  291:     my $currentstring = '';
1.325     albertel  292:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  293: 	$currentstring = $token->[4];     
1.181     sakharuk  294:     } elsif ($target eq 'tex') {
                    295: 	$Apache::londefdef::select++;
                    296: 	if ($Apache::londefdef::select == 1) {
                    297: 	    $currentstring='\noindent\fbox{'.&Apache::lonxml::get_param('value',$parstack,$safeeval).'}\keephidden{';
                    298: 	} else {
                    299: 	    $currentstring='\keephidden{';
                    300: 	}
                    301:     }
1.122     albertel  302:     return $currentstring;
                    303: }
                    304: 
                    305: sub end_option {
                    306:     my ($target,$token) = @_;
                    307:     my $currentstring = '';
1.325     albertel  308:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  309: 	$currentstring = $token->[2];    
1.181     sakharuk  310:     }  elsif ($target eq 'tex') {
                    311: 	$currentstring='}';
                    312:     }
1.122     albertel  313:     return $currentstring;
                    314: }
                    315: 
1.181     sakharuk  316: #-- <input> tag (end tag forbidden)
1.122     albertel  317: sub start_input {
                    318:     my ($target,$token) = @_;
                    319:     my $currentstring = '';
1.325     albertel  320:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  321: 	$currentstring = $token->[4];     
                    322:     } 
                    323:     return $currentstring;
                    324: }
                    325: 
                    326: sub end_input {
                    327:     my ($target,$token) = @_;
                    328:     my $currentstring = '';
1.325     albertel  329:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  330: 	$currentstring = $token->[2];    
                    331:     } 
                    332:     return $currentstring;
                    333: }
                    334: 
1.181     sakharuk  335: #-- <textarea> tag (end tag required)
1.122     albertel  336: sub start_textarea {
                    337:     my ($target,$token) = @_;
                    338:     my $currentstring = '';
1.325     albertel  339:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  340: 	$currentstring = $token->[4];     
                    341:     } 
                    342:     return $currentstring;
                    343: }
                    344: 
                    345: sub end_textarea {
                    346:     my ($target,$token) = @_;
                    347:     my $currentstring = '';
1.325     albertel  348:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  349: 	$currentstring = $token->[2];    
                    350:     } 
                    351:     return $currentstring;
                    352: }
                    353: 
1.181     sakharuk  354: #-- <form> tag (end tag required)
1.122     albertel  355: sub start_form {
                    356:     my ($target,$token) = @_;
                    357:     my $currentstring = '';
1.325     albertel  358:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  359: 	$currentstring = $token->[4];     
                    360:     } 
                    361:     return $currentstring;
                    362: }
                    363: 
                    364: sub end_form {
                    365:     my ($target,$token) = @_;
                    366:     my $currentstring = '';
1.325     albertel  367:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  368: 	$currentstring = $token->[2];    
                    369:     } 
                    370:     return $currentstring;
                    371: }
                    372: 
1.181     sakharuk  373: #-- <title> tag (end tag required)
1.122     albertel  374: sub start_title {
1.327     albertel  375:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
1.122     albertel  376:     my $currentstring = '';
1.324     albertel  377:     if ($target eq 'web' || $target eq 'webgrade') {
1.327     albertel  378: 	$Apache::londefdef::title = 
                    379: 	    &Apache::lonxml::get_all_text('/title',$parser,$style);
1.122     albertel  380:     } elsif ($target eq 'tex') {
1.166     sakharuk  381: 	$currentstring .= '\keephidden{Title of the document:  ' 
1.122     albertel  382:     }
                    383:     if ($target eq 'meta') {
                    384: 	$currentstring='<title>';
1.185     albertel  385: 	&start_output($target);
1.122     albertel  386:     }
                    387:     return $currentstring;
                    388: }
                    389: 
                    390: sub end_title {
                    391:     my ($target,$token) = @_;
                    392:     my $currentstring = '';
1.324     albertel  393:     if ($target eq 'web' || $target eq 'webgrade') {
1.327     albertel  394: 	# start_title takes care of swallowing the title
1.122     albertel  395:     } elsif ($target eq 'tex') {
                    396: 	$currentstring .= '}';
                    397:     }  
                    398:     if ($target eq 'meta') {
1.185     albertel  399: 	&end_output($target);
1.122     albertel  400: 	$currentstring='</title>';
                    401:     } 
                    402:     return $currentstring;
                    403: }
                    404: 
1.181     sakharuk  405: #-- <meta> tag (end tag forbidden)
1.122     albertel  406: sub start_meta {
1.299     albertel  407:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
1.122     albertel  408:     my $currentstring = '';
1.325     albertel  409:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  410: 	my $args='';
                    411: 	if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
                    412: 	if ($args eq '') {
1.299     albertel  413: 	    &Apache::lonxml::get_all_text("/meta",$parser,$style);
1.122     albertel  414: 	} else {
                    415: 	    $currentstring = $token->[4];
1.1       sakharuk  416: 	}
1.135     sakharuk  417:     } elsif ($target eq 'meta') {
1.122     albertel  418: 	unless (&Apache::lonxml::get_param
                    419: 		('http-equiv',$parstack,$safeeval,undef,1)) {
                    420: 	    my $name=$token->[2]->{'name'};
                    421: 	    $name=~tr/A-Z/a-z/;
                    422: 	    $name=~s/\s/\_/gs;
                    423: 	    $name=~s/\W//gs;
                    424: 	    if ($name) {
1.154     www       425: 		$currentstring='<'.$name;
                    426:                  my $display=&Apache::lonxml::get_param
                    427: 		('display',$parstack,$safeeval,undef,1);
                    428:                 if ($display) {
                    429:                     $display=~s/\"/\'/g;
                    430: 		    $currentstring.=' display="'.$display.'"';
                    431:                 }
                    432: 		$currentstring.='>'.
1.122     albertel  433: 		    &Apache::lonxml::get_param
                    434: 			('content',$parstack,$safeeval,undef,1).
1.135     sakharuk  435: 			'</'.$name.'>';
1.1       sakharuk  436: 	    }
1.154     www       437:             my $display=&Apache::lonxml::get_param
                    438: 		('display',$parstack,$safeeval,undef,1);
                    439:             if ($display) {
1.204     albertel  440: 		$display=&HTML::Entities::encode($display,'<>&"');
1.154     www       441: 		$currentstring.='<'.$name.'.display>'.$display.
                    442:                                '</'.$name.'.display>';
                    443:             }
1.1       sakharuk  444: 	}
1.135     sakharuk  445:     } elsif ($target eq 'tex') {
1.151     sakharuk  446: 	my $content=&Apache::lonxml::get_param('content',$parstack,$safeeval);
                    447: 	my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval);
                    448: 	if ((not defined $content) && (not defined $name)) {
                    449: 	    &Apache::lonxml::startredirection();
                    450: 	}
1.374     albertel  451:     } elsif ($target eq 'edit') {
                    452: 	$currentstring .= &Apache::edit::tag_start($target,$token);
                    453: 	$currentstring .= &Apache::edit::text_arg('Name:','name',$token,30);
                    454: 	$currentstring .= &Apache::edit::text_arg('Content:','content',$token,70);
                    455: 	$currentstring .= &Apache::edit::end_row();
                    456:     } elsif ($target eq 'modified') {
                    457: 	my $constructtag =
                    458: 	    &Apache::edit::get_new_args($token,$parstack,$safeeval,
                    459: 					'name','content');
                    460: 	if ($constructtag) { $currentstring = &Apache::edit::rebuild_tag($token); }
1.122     albertel  461:     }
                    462:     return $currentstring;
                    463: }
                    464: 
                    465: sub end_meta {
1.165     albertel  466:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  467:     my $currentstring = '';
1.325     albertel  468:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  469: 	my $args='';
                    470: 	if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
                    471: 	if ($args ne '') {
1.121     www       472: 	    $currentstring = $token->[4];
1.122     albertel  473: 	}
1.135     sakharuk  474:     } elsif ($target eq 'tex') {
1.165     albertel  475: 	my $content=&Apache::lonxml::get_param('content',$parstack,$safeeval);
                    476: 	my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval);
1.164     albertel  477: 	if ((not defined $content) && (not defined $name)) {
1.169     albertel  478: 	    &Apache::lonxml::endredirection();
1.164     albertel  479: 	}
1.135     sakharuk  480:     }
1.122     albertel  481:     return $currentstring;
                    482: }
                    483: 
1.374     albertel  484: sub insert_meta {
                    485:     return '
                    486:     <meta />';
                    487: }
                    488: 
1.121     www       489: # accessrule
1.122     albertel  490: sub start_accessrule {
1.299     albertel  491:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
1.122     albertel  492:     my $currentstring = '';
1.373     albertel  493:     my $eff  =&Apache::lonxml::get_param('effect',$parstack,$safeeval,undef,1);
                    494:     my $realm=&Apache::lonxml::get_param('realm', $parstack,$safeeval,undef,1);
                    495:     my $role =&Apache::lonxml::get_param('role',  $parstack,$safeeval,undef,1);
                    496:     my $type =&Apache::lonxml::get_param('type',  $parstack,$safeeval,undef,1);
                    497: 
                    498:     my ($dom,$crs,$sec,$separator);
1.369     albertel  499:     if ($type eq 'user') {
1.373     albertel  500: 	($dom,$crs,$sec)=split(m{/},$realm);
1.369     albertel  501: 	$crs = &LONCAPA::clean_username($crs);
1.373     albertel  502: 	$separator = '/';
1.369     albertel  503:     } else {
1.373     albertel  504: 	($dom,$crs,$sec)=split(/\_/,$realm);
1.369     albertel  505: 	$crs = &LONCAPA::clean_courseid($crs);
1.373     albertel  506: 	$separator = '_';
1.369     albertel  507:     }
1.373     albertel  508:     $dom = &LONCAPA::clean_domain($dom);
                    509: 
1.369     albertel  510:     $sec =~s/\W//;
                    511:     $realm = $dom;
1.373     albertel  512:     if ($crs =~ /\S/) { $realm .= $separator.$crs; }
                    513:     if ($sec =~ /\S/) { $realm .= $separator.$sec; }
1.369     albertel  514:     $role=~s/\W//g;
                    515: 
1.122     albertel  516:     if ($target eq 'web') {
                    517: 	my $args='';
                    518: 	if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
                    519: 	if ($args eq '') {
1.299     albertel  520: 	    &Apache::lonxml::get_all_text("/accessrule",$parser,$style);
1.122     albertel  521: 	} else {
                    522: 	    $currentstring = $token->[4];
                    523: 	}
                    524:     }
                    525:     if ($target eq 'meta') {
1.369     albertel  526: 	$currentstring='<rule>'.$eff.':'.$realm.':'.$role.':'.$type.'</rule>';
1.122     albertel  527:     }
                    528:     return $currentstring;
                    529: }
                    530: 
                    531: sub end_accessrule {
                    532:     my ($target,$token,$tagstack,$parstack,$parser) = @_;
                    533:     my $currentstring = '';
                    534:     if ($target eq 'web') {
                    535: 	my $args='';
                    536: 	if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; }
                    537: 	if ($args ne '') {
                    538: 	    $currentstring = $token->[4];
                    539: 	}
                    540:     } 
                    541:     return $currentstring;
                    542: }
                    543: 
1.366     albertel  544: sub generate_css_links {
                    545:     my $links;
                    546:     my $css_href = &Apache::lonnet::EXT('resource.0.cssfile');
                    547:     if ($css_href =~ /\S/) {
                    548: 	&Apache::lonxml::extlink($css_href);
                    549: 	$links .= 
                    550: 	    '<link rel="stylesheet" type="text/css" href="'.$css_href.'" />';
                    551:     }
                    552:     return $links;
                    553: }
                    554: 
1.181     sakharuk  555: #-- <body> tag (end tag required)
1.122     albertel  556: sub start_body {
                    557:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                    558:     my $currentstring = '';
1.244     albertel  559: 
1.324     albertel  560:     if ($target eq 'web' || $target eq 'webgrade') {
1.170     albertel  561: 	if ($Apache::lonhomework::parsing_a_problem) {
                    562: 	    &Apache::lonxml::warning("<body> tag found inside of <problem> tag this can cause problems.");
                    563: 	    return '';
                    564: 	}
1.122     albertel  565: 	
1.327     albertel  566: 	if (&is_inside_of($tagstack, "head")) {
                    567: 	    &end_head(@_);
1.122     albertel  568: 	}
1.366     albertel  569: 	
                    570: 	my $extra_head = &generate_css_links();
                    571: 
1.327     albertel  572: 	$currentstring = 
                    573: 	    &Apache::loncommon::start_page($Apache::londefdef::title,
1.366     albertel  574: 					   $Apache::londefdef::head
                    575: 					      .$extra_head,
1.327     albertel  576: 					   {'add_entries'    => $token->[2],
                    577: 					    'no_title'       => 1,
                    578: 					    'force_register' => 1});
                    579: 
1.267     albertel  580: 	if ($env{'request.state'} ne 'published') {
1.378     albertel  581: 	    $currentstring.=&Apache::lonmenu::constspaceform();
                    582: 	    $currentstring.=&Apache::londefdef::edit_controls();
1.1       sakharuk  583: 	}
1.201     albertel  584: 	$currentstring.=&Apache::lonxml::message_location();
1.122     albertel  585:     } elsif ($target eq 'tex') {
                    586: 	$currentstring = '\begin{document}';  
                    587:     } 
                    588:     return $currentstring;
                    589: }
                    590: 
1.376     albertel  591: sub edit_controls {
1.377     albertel  592:     my $result .= (<<EDITBUTTON);
1.376     albertel  593: <form method="post">
                    594: <input type="submit" name="editmode" accesskey="e" value="Edit" />
                    595: </form>
                    596: <br />
                    597: EDITBUTTON
                    598:     return $result;
                    599: }
                    600: 
1.122     albertel  601: sub end_body {
1.259     albertel  602:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr      603:     my $currentstring = &end_p();	# Close off unclosed <p>
1.324     albertel  604:     if ($target eq 'web' || $target eq 'webgrade') {
1.327     albertel  605: 	$currentstring .= &Apache::loncommon::end_page({'discussion' => 1});
1.122     albertel  606:     } elsif ($target eq 'tex') {
1.277     foxr      607: 	$currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}';  
1.122     albertel  608:     } 
                    609:     return $currentstring;
                    610: }
                    611: 
1.309     albertel  612: # \begin{center} causes a new paragprah spacing that looks odd inside 
1.337     foxr      613: # of a table cell.  Same at the end of a \center but with a slightly
                    614: # larger space .. hence center_correction and center_end_correction.
                    615: #
                    616: sub center_correction { return '\vspace*{-6 mm}'; } 
                    617: sub center_end_correction { return '\vspace*{-7 mm}'; }
                    618: 
1.181     sakharuk  619: #-- <center> tag (end tag required)
1.122     albertel  620: sub start_center {
1.309     albertel  621:     my ($target,$token,$tagstack) = @_;
1.279     foxr      622:     my $currentstring = &end_p();	# Close off any prior para.
1.325     albertel  623:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr      624: 	$currentstring .= $token->[4];     
1.122     albertel  625:     } elsif ($target eq 'tex') {
1.309     albertel  626: 	if (&is_inside_of($tagstack, "table")) {
                    627: 	    $currentstring .= &center_correction();
                    628: 	}
1.277     foxr      629: 	$currentstring .= '\begin{center}';  
1.144     sakharuk  630:     }
1.122     albertel  631:     return $currentstring;
                    632: }
                    633: 
                    634: sub end_center {
1.309     albertel  635:     my ($target,$token,$tagstack) = @_;
1.122     albertel  636:     my $currentstring = '';
1.325     albertel  637:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  638: 	$currentstring = $token->[2];     
                    639:     } elsif ($target eq 'tex') {
                    640: 	$currentstring = '\end{center}';  
1.337     foxr      641: 	if (&is_inside_of($tagstack, "table")) {
                    642: 	    $currentstring .= &center_end_correction();
                    643: 	}
1.144     sakharuk  644:     }
1.122     albertel  645:     return $currentstring;
                    646: }
                    647: 
1.181     sakharuk  648: #-- <b> tag (end tag required)
1.279     foxr      649: #      NOTE: In TeX mode disables internal <p>
1.122     albertel  650: sub start_b {
                    651:     my ($target,$token) = @_;
                    652:     my $currentstring = '';
1.325     albertel  653:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  654: 	$currentstring = $token->[4];     
                    655:     } elsif ($target eq 'tex') {
1.279     foxr      656: 	&disable_para();
                    657: 	$currentstring .= '\textbf{';  
1.122     albertel  658:     } 
                    659:     return $currentstring;
                    660: }
                    661: 
                    662: sub end_b {
                    663:     my ($target,$token) = @_;
                    664:     my $currentstring = '';
1.325     albertel  665:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  666: 	$currentstring = $token->[2];     
                    667:     } elsif ($target eq 'tex') {
1.279     foxr      668: 	&enable_para();
                    669: 	$currentstring = '}';
1.122     albertel  670:     } 
                    671:     return $currentstring;
                    672: }
1.35      sakharuk  673: 
1.181     sakharuk  674: #-- <strong> tag (end tag required)
1.279     foxr      675: #    NOTE: in TeX mode disables internal <p>
1.122     albertel  676: sub start_strong {
                    677:     my ($target,$token) = @_;
                    678:     my $currentstring = '';
1.325     albertel  679:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  680: 	$currentstring = $token->[4];     
                    681:     } elsif ($target eq 'tex') {
1.279     foxr      682: 	&disable_para();
1.122     albertel  683: 	$currentstring = '\textbf{';  
                    684:     } 
                    685:     return $currentstring;
                    686: }
                    687: 
                    688: sub end_strong {
                    689:     my ($target,$token) = @_;
                    690:     my $currentstring = '';
1.325     albertel  691:     if ($target eq 'web' || $target eq 'webgrade') {	
1.122     albertel  692: 	$currentstring = $token->[2];     
                    693:     } elsif ($target eq 'tex') {
1.279     foxr      694: 	&enable_para();
1.122     albertel  695: 	$currentstring = '}';  
1.144     sakharuk  696:     }
1.122     albertel  697:     return $currentstring;
                    698: }
                    699: 
1.181     sakharuk  700: #-- <h1> tag (end tag required)
1.122     albertel  701: sub start_h1 {
1.125     sakharuk  702:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr      703:     my $currentstring = &end_p();	# Close off any prior para.
1.325     albertel  704:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  705: 	$currentstring .= $token->[4];
                    706:     } elsif ($target eq 'tex') {
1.125     sakharuk  707: 	my $pre;
1.199     albertel  708: 	my $align=lc(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1));
1.212     sakharuk  709: 	if ($align eq 'center') {
1.125     sakharuk  710: 	    $pre='\begin{center}';
                    711: 	} elsif ($align eq 'left') {
                    712: 	    $pre='\rlap{';
                    713: 	} elsif ($align eq 'right') {
                    714: 	    $pre=' \hfill \llap{';
                    715: 	}
                    716: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
                    717: 	if (not defined $TeXsize) {$TeXsize="large";}
1.275     foxr      718: 	$currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
1.122     albertel  719:     } elsif ($target eq 'meta') {
1.277     foxr      720: 	$currentstring.='<subject>';
1.185     albertel  721: 	&start_output($target);
1.122     albertel  722:     }
                    723:     return $currentstring;
                    724: }
                    725: 
                    726: sub end_h1 {
1.125     sakharuk  727:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  728:     my $currentstring = '';
1.325     albertel  729:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  730: 	$currentstring .= $token->[2];
                    731:     } elsif ($target eq 'tex') {
1.212     sakharuk  732: 	my $post='\vskip 0 mm ';
1.125     sakharuk  733: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  734: 	if ($align eq 'center') {
1.125     sakharuk  735: 	    $post='\end{center}';
                    736: 	} elsif ($align eq 'left') {
                    737: 	    $post='} \hfill'.'\vskip 0 mm ';
                    738: 	} elsif ($align eq 'right') {
                    739: 	    $post='}'.'\vskip 0 mm ';
                    740: 	}
                    741: 	$currentstring .= '}}'.$post;
1.122     albertel  742:     } elsif ($target eq 'meta') {
1.185     albertel  743: 	&end_output($target);
1.122     albertel  744: 	$currentstring='</subject>';
                    745:     } 
                    746:     return $currentstring;
                    747: }
                    748: 
1.35      sakharuk  749: #-- <h2> tag
1.122     albertel  750: sub start_h2 {
1.125     sakharuk  751:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr      752:     my $currentstring = &end_p();	# Close off any prior para.
1.325     albertel  753:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  754: 	$currentstring .= $token->[4];
                    755:     } elsif ($target eq 'tex') {
1.125     sakharuk  756: 	my $pre;
                    757: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  758: 	if ($align eq 'center') {
1.125     sakharuk  759: 	    $pre='\begin{center}';
                    760: 	} elsif ($align eq 'left') {
                    761: 	    $pre='\rlap{';
                    762: 	} elsif ($align eq 'right') {
                    763: 	    $pre=' \hfill \llap{';
                    764: 	}
                    765: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
                    766: 	if (not defined $TeXsize) {$TeXsize="large";}
1.275     foxr      767: 	$currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
1.122     albertel  768:     } 
                    769:     return $currentstring;
                    770: }
                    771: 
                    772: sub end_h2 {
1.125     sakharuk  773:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  774:     my $currentstring = '';
1.325     albertel  775:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  776: 	$currentstring .= $token->[2];
                    777:     } elsif ($target eq 'tex') {
1.212     sakharuk  778: 	my $post='\vskip 0 mm ';
1.125     sakharuk  779: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  780: 	if ($align eq 'center') {
1.125     sakharuk  781: 	    $post='\end{center}';
                    782: 	} elsif ($align eq 'left') {
                    783: 	    $post='} \hfill'.'\vskip 0 mm ';
                    784: 	} elsif ($align eq 'right') {
                    785: 	    $post='}'.'\vskip 0 mm ';
                    786: 	}
                    787: 	$currentstring .= '}}'.$post;
1.122     albertel  788:     } 
                    789:     return $currentstring;
                    790: }
                    791: 
1.35      sakharuk  792: #-- <h3> tag
1.122     albertel  793: sub start_h3 {
1.125     sakharuk  794:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr      795:     my $currentstring = &end_p();	# Close off any prior para.
1.325     albertel  796:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  797: 	$currentstring .= $token->[4];
                    798:     } elsif ($target eq 'tex') {
1.125     sakharuk  799: 	my $pre;
                    800: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  801: 	if ($align eq 'center') {
1.125     sakharuk  802: 	    $pre='\begin{center}';
                    803: 	} elsif ($align eq 'left') {
                    804: 	    $pre='\rlap{';
                    805: 	} elsif ($align eq 'right') {
                    806: 	    $pre=' \hfill \llap{';
                    807: 	}
                    808: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
                    809: 	if (not defined $TeXsize) {$TeXsize="large";}
1.275     foxr      810: 	$currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
1.122     albertel  811:     } 
                    812:     return $currentstring;
                    813: }
                    814: 
                    815: sub end_h3 {
1.125     sakharuk  816:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  817:     my $currentstring = '';
1.325     albertel  818:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  819: 	$currentstring .= $token->[2];
                    820:     } elsif ($target eq 'tex') {
1.212     sakharuk  821: 	my $post='\vskip 0 mm ';
1.125     sakharuk  822: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  823: 	if ($align eq 'center') {
1.125     sakharuk  824: 	    $post='\end{center}';
                    825: 	} elsif ($align eq 'left') {
                    826: 	    $post='} \hfill'.'\vskip 0 mm ';
                    827: 	} elsif ($align eq 'right') {
                    828: 	    $post='}'.'\vskip 0 mm ';
                    829: 	}
                    830: 	$currentstring .= '}}'.$post;
1.122     albertel  831:     } 
                    832:     return $currentstring;
                    833: }
                    834: 
1.35      sakharuk  835: #-- <h4> tag
1.122     albertel  836: sub start_h4 {
1.125     sakharuk  837:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr      838:     my $currentstring = &end_p();	# Close off any prior para.
1.325     albertel  839:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  840: 	$currentstring .= $token->[4];
                    841:     } elsif ($target eq 'tex') {
1.125     sakharuk  842: 	my $pre;
                    843: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  844: 	if ($align eq 'center') {
1.125     sakharuk  845: 	    $pre='\begin{center}';
                    846: 	} elsif ($align eq 'left') {
                    847: 	    $pre='\rlap{';
                    848: 	} elsif ($align eq 'right') {
                    849: 	    $pre=' \hfill \llap{';
                    850: 	}
                    851: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
                    852: 	if (not defined $TeXsize) {$TeXsize="large";}
1.275     foxr      853: 	$currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
1.122     albertel  854:     } 
                    855:     return $currentstring;
                    856: }
                    857: 
                    858: sub end_h4 {
1.125     sakharuk  859:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  860:     my $currentstring = '';
1.325     albertel  861:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  862: 	$currentstring .= $token->[2];
                    863:     } elsif ($target eq 'tex') {
1.212     sakharuk  864: 	my $post='\vskip 0 mm ';
1.125     sakharuk  865: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  866: 	if ($align eq 'center') {
1.125     sakharuk  867: 	    $post='\end{center}';
                    868: 	} elsif ($align eq 'left') {
                    869: 	    $post='} \hfill'.'\vskip 0 mm ';
                    870: 	} elsif ($align eq 'right') {
                    871: 	    $post='}'.'\vskip 0 mm ';
                    872: 	}
                    873: 	$currentstring .= '}}'.$post;
1.122     albertel  874:     } 
                    875:     return $currentstring;
                    876: }
                    877: 
1.35      sakharuk  878: #-- <h5> tag
1.122     albertel  879: sub start_h5 {
1.125     sakharuk  880:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr      881:     my $currentstring = &end_p();	# Close off any prior paras.
1.325     albertel  882:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  883: 	$currentstring .= $token->[4];
                    884:     } elsif ($target eq 'tex') {
1.125     sakharuk  885: 	my $pre;
                    886: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  887: 	if ($align eq 'center') {
1.125     sakharuk  888: 	    $pre='\begin{center}';
                    889: 	} elsif ($align eq 'left') {
                    890: 	    $pre='\rlap{';
                    891: 	} elsif ($align eq 'right') {
                    892: 	    $pre=' \hfill \llap{';
                    893: 	}
                    894: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
                    895: 	if (not defined $TeXsize) {$TeXsize="large";}
1.275     foxr      896: 	$currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
1.122     albertel  897:     } 
                    898:     return $currentstring;
                    899: }
                    900: 
                    901: sub end_h5 {
1.125     sakharuk  902:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  903:     my $currentstring = '';
1.325     albertel  904:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  905: 	$currentstring .= $token->[2];
                    906:     } elsif ($target eq 'tex') {
1.212     sakharuk  907: 	my $post='\vskip 0 mm ';
1.125     sakharuk  908: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  909: 	if ($align eq 'center') {
1.125     sakharuk  910: 	    $post='\end{center}';
                    911: 	} elsif ($align eq 'left') {
                    912: 	    $post='} \hfill'.'\vskip 0 mm ';
                    913: 	} elsif ($align eq 'right') {
                    914: 	    $post='}'.'\vskip 0 mm ';
                    915: 	}
                    916: 	$currentstring .= '}}'.$post;
1.122     albertel  917:     } 
                    918:     return $currentstring;
                    919: }
                    920: 
1.35      sakharuk  921: #-- <h6> tag
1.122     albertel  922: sub start_h6 {
1.125     sakharuk  923:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr      924:     my $currentstring = &end_p();	# Close off any prior paras.
1.325     albertel  925:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  926: 	$currentstring .= $token->[4];
                    927:     } elsif ($target eq 'tex') {
1.125     sakharuk  928: 	my $pre;
                    929: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  930: 	if ($align eq 'center') {
1.125     sakharuk  931: 	    $pre='\begin{center}';
                    932: 	} elsif ($align eq 'left') {
                    933: 	    $pre='\rlap{';
                    934: 	} elsif ($align eq 'right') {
                    935: 	    $pre=' \hfill \llap{';
                    936: 	}
                    937: 	my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0);
                    938: 	if (not defined $TeXsize) {$TeXsize="large";}
1.275     foxr      939: 	$currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; 
1.122     albertel  940:     } 
                    941:     return $currentstring;
                    942: }
                    943: 
                    944: sub end_h6 {
1.125     sakharuk  945:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel  946:     my $currentstring = '';
1.325     albertel  947:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  948: 	$currentstring .= $token->[2];
                    949:     } elsif ($target eq 'tex') {
1.212     sakharuk  950: 	my $post='\vskip 0 mm ';
1.125     sakharuk  951: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.212     sakharuk  952: 	if ($align eq 'center') {
1.125     sakharuk  953: 	    $post='\end{center}';
                    954: 	} elsif ($align eq 'left') {
                    955: 	    $post='} \hfill'.'\vskip 0 mm ';
                    956: 	} elsif ($align eq 'right') {
                    957: 	    $post='}'.'\vskip 0 mm ';
                    958: 	}
                    959: 	$currentstring .= '}}'.$post;
1.122     albertel  960:     } 
                    961:     return $currentstring;
                    962: }
                    963: 
1.181     sakharuk  964: #--- <cite> tag (end tag required)
1.122     albertel  965: sub start_cite {
                    966:     my ($target,$token) = @_;
                    967:     my $currentstring = '';
1.325     albertel  968:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  969: 	$currentstring .= $token->[4];
                    970:     } elsif ($target eq 'tex') {
1.179     sakharuk  971: 	$currentstring .= '\textit{';
1.144     sakharuk  972:     }
1.122     albertel  973:     return $currentstring;
                    974: }
                    975: 
                    976: sub end_cite {
                    977:     my ($target,$token) = @_;
                    978:     my $currentstring = '';
1.325     albertel  979:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  980: 	$currentstring .= $token->[2];
                    981:     } elsif ($target eq 'tex') {
1.179     sakharuk  982: 	$currentstring .= '}';
1.144     sakharuk  983:     }
1.122     albertel  984:     return $currentstring;
                    985: }
                    986: 
1.181     sakharuk  987: #-- <i> tag (end tag required)
1.122     albertel  988: sub start_i {
                    989:     my ($target,$token) = @_;
                    990:     my $currentstring = '';
1.325     albertel  991:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel  992: 	$currentstring .= $token->[4];
                    993:     } elsif ($target eq 'tex') {
                    994: 	$currentstring .= '\textit{';
1.144     sakharuk  995:     }
1.122     albertel  996:     return $currentstring;
                    997: }
                    998: 
                    999: sub end_i {
                   1000:     my ($target,$token) = @_;
                   1001:     my $currentstring = '';
1.325     albertel 1002:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1003: 	$currentstring .= $token->[2];
                   1004:     } elsif ($target eq 'tex') {
                   1005: 	$currentstring .= '}';
                   1006:     } 
                   1007:     return $currentstring;
                   1008: }
                   1009: 
1.181     sakharuk 1010: #-- <address> tag (end tag required)
1.122     albertel 1011: sub start_address {
                   1012:     my ($target,$token) = @_;
                   1013:     my $currentstring = '';
1.325     albertel 1014:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1015: 	$currentstring .= $token->[4];
                   1016:     } elsif ($target eq 'tex') {
1.179     sakharuk 1017: 	$currentstring .= '\textit{';
1.144     sakharuk 1018:     }
1.122     albertel 1019:     return $currentstring;
                   1020: }
                   1021: 
                   1022: sub end_address {
                   1023:     my ($target,$token) = @_;
                   1024:     my $currentstring = '';
1.325     albertel 1025:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1026: 	$currentstring .= $token->[2];
                   1027:     } elsif ($target eq 'tex') {
1.179     sakharuk 1028: 	$currentstring .= '}';
1.122     albertel 1029:     }
                   1030:     return $currentstring;
                   1031: }
                   1032: 
1.181     sakharuk 1033: #-- <dfn> tag (end tag required)
1.122     albertel 1034: sub start_dfn {
                   1035:     my ($target,$token) = @_;
                   1036:     my $currentstring = '';
1.325     albertel 1037:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1038: 	$currentstring .= $token->[4];
                   1039:     } elsif ($target eq 'tex') {
1.179     sakharuk 1040: 	$currentstring .= '\textit{';
1.122     albertel 1041:     } 
                   1042:     return $currentstring;
                   1043: }
                   1044: 
                   1045: sub end_dfn {
                   1046:     my ($target,$token) = @_;
                   1047:     my $currentstring = '';
1.325     albertel 1048:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1049: 	$currentstring .= $token->[2];
                   1050:     } elsif ($target eq 'tex') {
1.179     sakharuk 1051: 	$currentstring .= '}';
1.144     sakharuk 1052:     }
1.122     albertel 1053:     return $currentstring;
                   1054: }
                   1055: 
1.181     sakharuk 1056: #-- <tt> tag (end tag required)
1.122     albertel 1057: sub start_tt {
                   1058:     my ($target,$token) = @_;
                   1059:     my $currentstring = '';
1.325     albertel 1060:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1061: 	$currentstring .= $token->[4];
                   1062:     } elsif ($target eq 'tex') {
                   1063: 	$currentstring .= '\texttt{';
1.144     sakharuk 1064:     }
1.122     albertel 1065:     return $currentstring;
                   1066: }
                   1067: 
                   1068: sub end_tt {
                   1069:     my ($target,$token) = @_;
                   1070:     my $currentstring = '';
1.325     albertel 1071:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1072: 	$currentstring .= $token->[2];
                   1073:     } elsif ($target eq 'tex') {
                   1074: 	$currentstring .= '}';
                   1075:     }
                   1076:     return $currentstring;
                   1077: }
                   1078: 
1.181     sakharuk 1079: #-- <kbd> tag (end tag required)
1.122     albertel 1080: sub start_kbd {
                   1081:     my ($target,$token) = @_;
                   1082:     my $currentstring = '';
1.325     albertel 1083:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1084: 	$currentstring .= $token->[4];
                   1085:     } elsif ($target eq 'tex') {
1.179     sakharuk 1086: 	$currentstring .= '\texttt{';
1.144     sakharuk 1087:     }
1.122     albertel 1088:     return $currentstring;
                   1089: }
                   1090: 
                   1091: sub end_kbd {
                   1092:     my ($target,$token) = @_;
                   1093:     my $currentstring = '';
1.325     albertel 1094:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1095: 	$currentstring .= $token->[2];
                   1096:     } elsif ($target eq 'tex') {
1.179     sakharuk 1097: 	$currentstring .= '}';
1.144     sakharuk 1098:     }
1.122     albertel 1099:     return $currentstring;
                   1100: }
                   1101: 
1.181     sakharuk 1102: #-- <code> tag (end tag required)
1.122     albertel 1103: sub start_code {
                   1104:     my ($target,$token) = @_;
                   1105:     my $currentstring = '';
1.325     albertel 1106:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1107: 	$currentstring .= $token->[4];
                   1108:     } elsif ($target eq 'tex') {
                   1109: 	$currentstring .= '\texttt{';
                   1110:     } 
                   1111:     return $currentstring;
                   1112: }
                   1113: 
                   1114: sub end_code {
                   1115:     my ($target,$token) = @_;
                   1116:     my $currentstring = '';
1.325     albertel 1117:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1118: 	$currentstring .= $token->[2];
                   1119:     } elsif ($target eq 'tex') {
                   1120: 	$currentstring .= '}';
                   1121:     } 
                   1122:     return $currentstring;
                   1123: }
                   1124: 
1.181     sakharuk 1125: #-- <em> tag (end tag required)
1.122     albertel 1126: sub start_em {
                   1127:     my ($target,$token) = @_;
                   1128:     my $currentstring = '';
1.325     albertel 1129:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1130: 	$currentstring .= $token->[4];
                   1131:     } elsif ($target eq 'tex') {
                   1132: 	$currentstring .= '\emph{';
1.144     sakharuk 1133:     }
1.122     albertel 1134:     return $currentstring;
                   1135: }
                   1136: 
                   1137: sub end_em {
                   1138:     my ($target,$token) = @_;
                   1139:     my $currentstring = '';
1.325     albertel 1140:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1141: 	$currentstring .= $token->[2];
                   1142:     } elsif ($target eq 'tex') {
                   1143: 	$currentstring .= '}';
1.144     sakharuk 1144:     } 
1.122     albertel 1145:     return $currentstring;
                   1146: }
                   1147: 
1.181     sakharuk 1148: #-- <q> tag (end tag required)
1.122     albertel 1149: sub start_q {
                   1150:     my ($target,$token) = @_;
                   1151:     my $currentstring = '';
1.325     albertel 1152:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1153: 	$currentstring .= $token->[4];
                   1154:     } elsif ($target eq 'tex') {
1.179     sakharuk 1155: 	$currentstring .= '\emph{';
1.122     albertel 1156:     }
                   1157:     return $currentstring;
                   1158: }
                   1159: 
                   1160: sub end_q {
                   1161:     my ($target,$token) = @_;
                   1162:     my $currentstring = '';
1.325     albertel 1163:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1164: 	$currentstring .= $token->[2];
                   1165:     } elsif ($target eq 'tex') {
1.179     sakharuk 1166: 	$currentstring .= '}';
1.144     sakharuk 1167:     } 
1.122     albertel 1168:     return $currentstring;
                   1169: }
                   1170: 
1.277     foxr     1171: #  <p> is a bit strange since it does not require a closing </p>
                   1172: #  However in latex, we must often output closing stuff to end
                   1173: #  environments and {}'s etc.  Therefore we do all the work
                   1174: #  of figuring out the ending strings in the start tag processing,
                   1175: #  and provide a mechanism to output the stop text external
                   1176: #  to tag processing.
                   1177: #
                   1178: {
                   1179: 
                   1180:     my $closing_string = '';		# String required to close <p>
                   1181: 
1.279     foxr     1182: #   Some tags are <p> fragile meaning that <p> inside of them
                   1183: #   does not work within TeX mode.  This is managed via the 
                   1184: #   counter below:
                   1185: #
                   1186: 
                   1187:     my $para_disabled = 0;
                   1188: 
                   1189: sub disable_para {
                   1190:     $para_disabled++;
                   1191: }
                   1192: sub enable_para {
                   1193:     $para_disabled--;
                   1194: }
                   1195: 
                   1196: 
1.181     sakharuk 1197: #-- <p> tag (end tag optional)
1.198     sakharuk 1198: #optional attribute - align="center|left|right"
1.122     albertel 1199: sub start_p {
1.157     sakharuk 1200:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr     1201:     my $currentstring = '';
1.325     albertel 1202:     if ($target eq 'web' || $target eq 'webgrade') {
1.279     foxr     1203: 	$currentstring .= &end_p();	# close off prior para if in progress.
1.122     albertel 1204: 	$currentstring .= $token->[4];
1.279     foxr     1205: 	if (! ($currentstring =~ /\//)) {
                   1206: 	    $closing_string = '</p>'; # Deal correctly with <p /> e.g.
                   1207: 	}
                   1208:     } elsif ($target eq 'tex' && !$para_disabled) {
1.313     foxr     1209: 
1.279     foxr     1210: 	$currentstring .= &end_p();	# close off prior para if in progress.
1.198     sakharuk 1211: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
                   1212: 	if ($align eq 'center') {
1.333     albertel 1213: 	    $currentstring .='\begin{center}\par ';
1.277     foxr     1214: 	    $closing_string = '\end{center}';
1.309     albertel 1215: 	    if (&is_inside_of($tagstack, "table")) {
                   1216: 		$currentstring = &center_correction().$currentstring;
                   1217: 	    }
1.198     sakharuk 1218: 	} elsif ($align eq 'right') {
1.323     foxr     1219: 	    $currentstring.="\n".'{\flushright ';
                   1220: #	    $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';
                   1221: 	    $closing_string= "}\n";
1.198     sakharuk 1222: 	} elsif ($align eq 'left') {
1.323     foxr     1223: 	    $currentstring.= "\n".'{\flushleft ';
                   1224: #	    $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{{';
                   1225: 	    $closing_string = "}\n";
1.216     matthew  1226: 	} else {
1.277     foxr     1227:             $currentstring.='\par ';
1.313     foxr     1228: 	    if (&is_inside_of($tagstack, 'table')) {
1.315     foxr     1229: 		$closing_string = '\vskip 0pt'; # Seems to be consistent with <p> in tables.
1.313     foxr     1230: 	    } else {
                   1231: 		$closing_string = '\strut\\\\\strut ';
                   1232: 	    }
1.216     matthew  1233:         }
1.277     foxr     1234: 
1.144     sakharuk 1235:     }
1.122     albertel 1236:     return $currentstring;
                   1237: }
1.277     foxr     1238: #
                   1239: #  End paragraph processing just requires that we output the
                   1240: #  closing string that was saved and blank it.
                   1241: sub end_p {
1.279     foxr     1242:     #  Note only 'tex' mode uses disable_para and enable_para
                   1243:     #  so we don't need to know the target in the check below:
                   1244: 
                   1245:     if (!$para_disabled) {
                   1246: 	my $current_string = $closing_string;
                   1247: 	$closing_string = '';	# Not in a para anymore.
                   1248: 	return $current_string;
                   1249:     } else {
                   1250: 	return '';
                   1251:     }
1.122     albertel 1252: 
                   1253: }
1.277     foxr     1254: }
1.181     sakharuk 1255: #-- <br> tag (end tag forbidden)
1.122     albertel 1256: sub start_br {
                   1257:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   1258:     my $currentstring = '';
1.325     albertel 1259:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1260: 	$currentstring .= $token->[4];
                   1261:     } elsif ($target eq 'tex') {
1.227     sakharuk 1262: 	my @tempo=@$tagstack;
1.229     sakharuk 1263: 	my $signal=0;
1.287     foxr     1264: 	#  Not going to factor this to is_inside_of since that would require
                   1265:         #  multiple stack traversals.
                   1266: 	#
1.227     sakharuk 1267: 	for (my $i=$#tempo;$i>=0;$i--) {
                   1268: 	    if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') ||
1.334     albertel 1269:                 ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul'))  {
1.229     sakharuk 1270: 		$signal=1;
1.334     albertel 1271: 	    }
                   1272: 	    if (($tempo[$i] eq 'td') || ($tempo[$i] eq 'th')) {
1.336     foxr     1273: 		$signal = 1;
1.227     sakharuk 1274: 	    }
                   1275: 	}
1.375     foxr     1276: 	if ($signal != 1) {
1.219     sakharuk 1277: 	    $currentstring .= '\strut \\\\ \strut ';
1.1       sakharuk 1278: 	}
1.355     foxr     1279:     
1.144     sakharuk 1280:     }
1.122     albertel 1281:     return $currentstring;
                   1282: }
                   1283: 
                   1284: sub end_br {
                   1285:     my ($target,$token) = @_;
                   1286:     my $currentstring = '';
1.325     albertel 1287:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1288: 	$currentstring .= $token->[2];
                   1289:     }
                   1290:     return $currentstring;
                   1291: }
                   1292: 
1.181     sakharuk 1293: #-- <big> tag (end tag required)
1.122     albertel 1294: sub start_big {
                   1295:     my ($target,$token) = @_;
                   1296:     my $currentstring = '';
1.325     albertel 1297:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1298: 	$currentstring .= $token->[4];
                   1299:     } elsif ($target eq 'tex') {
1.137     sakharuk 1300: 	$currentstring .= '{\large ';
1.144     sakharuk 1301:     } 
1.122     albertel 1302:     return $currentstring;
                   1303: }
                   1304: 
                   1305: sub end_big {
                   1306:     my ($target,$token) = @_;
                   1307:     my $currentstring = '';
1.325     albertel 1308:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1309: 	$currentstring .= $token->[2];
                   1310:     } elsif ($target eq 'tex') {
                   1311: 	$currentstring .= '}';
                   1312:     }
                   1313:     return $currentstring;
                   1314: }
                   1315: 
1.181     sakharuk 1316: #-- <small> tag (end tag required)
1.122     albertel 1317: sub start_small {
                   1318:     my ($target,$token) = @_;
                   1319:     my $currentstring = '';
1.325     albertel 1320:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1321: 	$currentstring .= $token->[4];
                   1322:     } elsif ($target eq 'tex') {
                   1323: 	$currentstring .= '{\footnotesize ';
1.144     sakharuk 1324:     }
1.122     albertel 1325:     return $currentstring;
                   1326: }
                   1327: 
                   1328: sub end_small {
                   1329:     my ($target,$token) = @_;
                   1330:     my $currentstring = '';
1.325     albertel 1331:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1332: 	$currentstring .= $token->[2];
                   1333:     } elsif ($target eq 'tex') {
                   1334: 	$currentstring .= '}';
                   1335:     }
                   1336:     return $currentstring;
                   1337: }
                   1338: 
1.181     sakharuk 1339: #-- <basefont> tag (end tag forbidden)
1.122     albertel 1340: sub start_basefont {
1.126     sakharuk 1341:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.122     albertel 1342:     my $currentstring = '';
1.325     albertel 1343:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1344: 	$currentstring = $token->[4];     
1.126     sakharuk 1345:     } elsif ($target eq 'tex') {
                   1346: 	my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
                   1347: 	if (defined $basesize) {
                   1348: 	    $currentstring = '{\\'.$basesize.' ';
                   1349: 	}
                   1350:     }
1.122     albertel 1351:     return $currentstring;
                   1352: }
                   1353: 
                   1354: sub end_basefont {
1.126     sakharuk 1355:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 1356:     my $currentstring = '';
1.325     albertel 1357:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1358: 	$currentstring = $token->[4];     
1.126     sakharuk 1359:     } elsif ($target eq 'tex') {
                   1360: 	my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
                   1361: 	if (defined $basesize) {
                   1362: 	    $currentstring = '}';
                   1363: 	}
                   1364:     }
1.122     albertel 1365:     return $currentstring;
                   1366: }
                   1367: 
1.181     sakharuk 1368: #-- <font> tag (end tag required)
1.122     albertel 1369: sub start_font {
                   1370:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   1371:     my $currentstring = '';
1.325     albertel 1372:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1373: 	my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval);
1.204     albertel 1374: 	if ($face!~/symbol/i) {
1.267     albertel 1375: 	    if (($env{'browser.fontenhance'} eq 'on') || 
                   1376: 		($env{'browser.blackwhite'} eq 'on')) { return ''; }
1.155     www      1377: 	}
1.122     albertel 1378: 	$currentstring = $token->[4];     
1.126     sakharuk 1379:     }  elsif ($target eq 'tex') {
                   1380: 	my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
                   1381: 	if (defined $fontsize) {
                   1382: 	    $currentstring = '{\\'.$fontsize.' ';
                   1383: 	}
                   1384:     }
1.122     albertel 1385:     return $currentstring;
                   1386: }
                   1387: 
                   1388: sub end_font {
                   1389:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   1390:     my $currentstring = '';
1.325     albertel 1391:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1392: 	$currentstring = $token->[2];    
1.126     sakharuk 1393:     }  elsif ($target eq 'tex') {
                   1394: 	my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval);
                   1395: 	if (defined $fontsize) {
                   1396: 	    $currentstring = '}';
                   1397: 	}
                   1398:     }
1.122     albertel 1399:     return $currentstring;
                   1400: }
                   1401:  
1.181     sakharuk 1402: #-- <strike> tag (end tag required)
1.122     albertel 1403: sub start_strike {
                   1404:     my ($target,$token) = @_;
                   1405:     my $currentstring = '';
1.325     albertel 1406:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1407: 	$currentstring .= $token->[4];
                   1408:     } elsif ($target eq 'tex') {
                   1409: 	&Apache::lonxml::startredirection();
                   1410:     } 
                   1411:     return $currentstring;
                   1412: }
                   1413: 
                   1414: sub end_strike {
                   1415:     my ($target,$token) = @_;
                   1416:     my $currentstring = '';
1.325     albertel 1417:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1418: 	$currentstring .= $token->[2];
                   1419:     } elsif ($target eq 'tex') {
                   1420: 	$currentstring=&Apache::lonxml::endredirection();
                   1421: 	$currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g; 
                   1422: 	$currentstring=~s/^\s*(\S)/\\underline\{$1/; 
                   1423: 	$currentstring=~s/(\S)\s*$/$1\}/;
                   1424:     }
                   1425:     return $currentstring;
                   1426: }
                   1427: 
1.181     sakharuk 1428: #-- <s> tag (end tag required)
1.122     albertel 1429: sub start_s {
                   1430:     my ($target,$token) = @_;
                   1431:     my $currentstring = '';
1.325     albertel 1432:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1433: 	$currentstring .= $token->[4];
                   1434:     } elsif ($target eq 'tex') {
                   1435: 	&Apache::lonxml::startredirection();
                   1436:     } 
                   1437:     return $currentstring;
                   1438: }
                   1439: 
                   1440: sub end_s {
                   1441:     my ($target,$token) = @_;
                   1442:     my $currentstring = '';
1.325     albertel 1443:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1444: 	$currentstring .= $token->[2];
                   1445:     } elsif ($target eq 'tex') {
                   1446: 	$currentstring=&Apache::lonxml::endredirection();
                   1447: 	$currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g;
                   1448: 	$currentstring=~s/^\s*(\S)/\\underline\{$1/;
                   1449: 	$currentstring=~s/(\S)\s*$/$1\}/;	
                   1450:     }
                   1451:     return $currentstring;
                   1452: }
                   1453: 
1.181     sakharuk 1454: #-- <sub> tag (end tag required)
1.122     albertel 1455: sub start_sub {
                   1456:     my ($target,$token) = @_;
                   1457:     my $currentstring = '';
1.325     albertel 1458:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1459: 	$currentstring .= $token->[4];
                   1460:     } elsif ($target eq 'tex') {
1.355     foxr     1461: 	$currentstring .= '\raisebox{-\smallskipamount}{\scriptsize{';
1.122     albertel 1462:     } 
                   1463:     return $currentstring;
                   1464: }
                   1465: 
                   1466: sub end_sub {
                   1467:     my ($target,$token) = @_;
                   1468:     my $currentstring = '';
1.325     albertel 1469:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1470: 	$currentstring .= $token->[2];
                   1471:     } elsif ($target eq 'tex') {
1.202     sakharuk 1472: 	$currentstring .= '}}';
1.122     albertel 1473:     }
                   1474:     return $currentstring;
                   1475: }
                   1476: 
1.181     sakharuk 1477: #-- <sup> tag (end tag required)
1.122     albertel 1478: sub start_sup {
                   1479:     my ($target,$token) = @_;
                   1480:     my $currentstring = '';
1.325     albertel 1481:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1482: 	$currentstring .= $token->[4];
                   1483:     } elsif ($target eq 'tex') {
1.355     foxr     1484: 	$currentstring .= '\raisebox{\smallskipamount}{\scriptsize{';
1.122     albertel 1485:     } 
                   1486:     return $currentstring;
                   1487: }
                   1488: 
                   1489: sub end_sup {
                   1490:     my ($target,$token) = @_;
                   1491:     my $currentstring = '';
1.325     albertel 1492:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1493: 	$currentstring .= $token->[2];
                   1494:     } elsif ($target eq 'tex') {
1.202     sakharuk 1495: 	$currentstring .= '}}';
1.122     albertel 1496:     }
                   1497:     return $currentstring;
                   1498: }
                   1499: 
1.181     sakharuk 1500: #-- <hr> tag (end tag forbidden)
1.122     albertel 1501: sub start_hr {
1.124     sakharuk 1502:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr     1503:     my $currentstring = &end_p();	# End enclosing para.
1.325     albertel 1504:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1505: 	$currentstring .= $token->[4];
                   1506:     } elsif ($target eq 'tex') {
1.361     foxr     1507: 
                   1508: 	# <hr /> can't be inside of <sup><sub> thank you LaTeX.
                   1509: 	# 
                   1510: 	my $restart_sub = 0;
                   1511: 	my $restart_sup = 0;
                   1512: 
                   1513: 	# Since <sub> and <sup> are simple tags it's ok to turn off/on
                   1514: 	# using the start_ stop_ functions.. those tags only care about
                   1515: 	# $target.
                   1516: 
                   1517: 	if (&is_inside_of($tagstack, "sub")) {
                   1518: 	    $restart_sub = 1;
                   1519: 	    $currentstring .= &end_sub($target, $token, $tagstack, 
                   1520: 				       $parstack, $parser, $safeeval);
                   1521: 	}
                   1522: 	if (&is_inside_of($tagstack, "sup")) {
                   1523: 	    $restart_sup = 1;
                   1524: 	    $currentstring .= &end_sup($target, $token, $tagstack,
                   1525: 				       $parstack, $parser, $safeeval);
                   1526: 	}	
                   1527: 
1.149     sakharuk 1528: 	my $LaTeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
1.124     sakharuk 1529: 	if (defined $LaTeXwidth) {
                   1530: 	    if ($LaTeXwidth=~/^%/) {
                   1531: 		substr($LaTeXwidth,0,1)='';
                   1532: 		$LaTeXwidth=($LaTeXwidth/100).'\textwidth';
                   1533: 	    }
                   1534: 	} else {
1.148     sakharuk 1535: 	    $LaTeXwidth ='0.9\textwidth';
1.124     sakharuk 1536: 	}
                   1537: 	my ($pre,$post);
                   1538: 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
                   1539: 	if (($align eq 'center') || (not defined $align)) {
                   1540: 	    $pre=''; $post='';
                   1541: 	} elsif ($align eq 'left') {
                   1542: 	    $pre='\rlap{'; $post='} \hfill';
                   1543: 	} elsif ($align eq 'right') {
                   1544: 	    $pre=' \hfill \llap{'; $post='}';
                   1545: 	}
1.148     sakharuk 1546: 	$currentstring .= ' \vskip 0 mm \noindent\makebox['.$LaTeXwidth.']{'.$pre.'\makebox['.
1.124     sakharuk 1547:                                     $LaTeXwidth.'][b]{\hrulefill}'.$post.'}\vskip 0 mm ';
1.361     foxr     1548: 	# Turn stuff back on that we can't be inside of.
                   1549: 
                   1550: 	if ($restart_sub) {
                   1551: 	    $currentstring .= &start_sub($target, $token, $tagstack,
                   1552: 					$parstack, $parser, $safeeval);
                   1553: 	}
                   1554: 	if ($restart_sup) {
                   1555: 	    $currentstring .= &start_sup($target, $token, $tagstack,
                   1556: 					 $parstack, $parser, $safeeval);
                   1557: 	}	
1.122     albertel 1558:     } 
                   1559:     return $currentstring;
                   1560: }
                   1561: 
                   1562: sub end_hr {
                   1563:     my ($target,$token) = @_;
                   1564:     my $currentstring = '';
1.325     albertel 1565:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1566: 	$currentstring .= $token->[2];
1.148     sakharuk 1567:     }
1.122     albertel 1568:     return $currentstring;
                   1569: }
                   1570: 
1.181     sakharuk 1571: #-- <div> tag (end tag required)
1.280     foxr     1572: {
                   1573: 
                   1574: #  Since div can be nested, the stack below is used
                   1575: #  in 'tex' mode to store the ending strings
                   1576: #  for the div stack.
                   1577: 
                   1578:     my @div_end_stack;
                   1579: 
1.122     albertel 1580: sub start_div {
1.280     foxr     1581:     my ($target,$token, $tagstack, $parstack, $parser, $safeeval) = @_;
1.279     foxr     1582:     my $currentstring = &end_p();	# Close enclosing para.
1.325     albertel 1583:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1584: 	$currentstring .= $token->[4];
                   1585:     } 
1.280     foxr     1586:     if ($target eq 'tex') {
                   1587: 	# 4 possible alignments: left, right, center, and -missing-.
1.380     foxr     1588:         # If inside a table row, we must let the table logic
                   1589: 	# do the alignment, however.
                   1590: 	# 
1.280     foxr     1591: 
                   1592: 	my $endstring = '';
                   1593: 
                   1594: 	my $align = lc(&Apache::lonxml::get_param('align', $parstack,
                   1595: 						  $safeeval, undef, 1));
                   1596: 	if ($align eq 'center') {
                   1597: 	    $currentstring .= '\begin{center}';
                   1598: 	    $endstring      = '\end{center}';
1.309     albertel 1599: 	    if (&is_inside_of($tagstack, "table")) {
                   1600: 		$currentstring = &center_correction().$currentstring;
1.380     foxr     1601: 		$endstring    .= &center_end_correction(); 
1.309     albertel 1602: 	    }
1.280     foxr     1603: 	}
                   1604: 	elsif ($align eq 'right') {
                   1605: 	    $currentstring .= '\begin{flushright}';
                   1606: 	    $endstring     .= '\end{flushright}';
                   1607: 	} elsif ($align eq 'left') {
                   1608: 	    $currentstring .= '\begin{flushleft}';
                   1609: 	    $endstring     = '\end{flushleft}';
                   1610: 	} else {
                   1611: 	
                   1612: 	}
                   1613: 	$currentstring .= "\n";   # For human readability.
                   1614: 	$endstring       = "\n$endstring\n"; # For human readability
                   1615: 	push(@div_end_stack, $endstring);
                   1616:     }
1.122     albertel 1617:     return $currentstring;
                   1618: }
                   1619: 
                   1620: sub end_div {
                   1621:     my ($target,$token) = @_;
                   1622:     my $currentstring = '';
1.325     albertel 1623:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1624: 	$currentstring .= $token->[2];
1.280     foxr     1625:     }
                   1626:     if ($target eq 'tex') {
                   1627: 	my $endstring = pop @div_end_stack;
                   1628: 	$currentstring .= $endstring;
                   1629:     }
1.122     albertel 1630:     return $currentstring;
                   1631: }
1.280     foxr     1632: }
1.122     albertel 1633: 
1.181     sakharuk 1634: #-- <a> tag (end tag required)
1.122     albertel 1635: sub start_a {
1.149     sakharuk 1636:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 1637:     my $currentstring = '';
1.325     albertel 1638:     if ($target eq 'web' || $target eq 'webgrade') {
1.250     albertel 1639: 	my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
                   1640: 					    undef,1);
                   1641: 	$currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href});
1.122     albertel 1642:     }
                   1643:     return $currentstring;
                   1644: }
                   1645: 
                   1646: sub end_a {
1.168     albertel 1647:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 1648:     my $currentstring = '';
1.325     albertel 1649:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1650: 	$currentstring .= $token->[2];
                   1651:     }
1.351     foxr     1652:     if ($target eq 'tex') {
1.352     albertel 1653: 	my $href =
                   1654: 	    &Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1);
                   1655: 	my $name =
                   1656: 	    &Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1);
                   1657: 	if ($href =~ /\S/) {
                   1658: 	    $href =~ s/([^\\])%/$1\\\%/g;
1.365     foxr     1659: 	    # Substitute special symbols... and allow line breaks at each /
                   1660: 	    #
                   1661: 	    $href = &Apache::lonxml::latex_special_symbols($href);
                   1662: 	    $href =~ s/\//\/\\-/g;              # Map / to /\- to allow hyphenation.
                   1663: 	    $currentstring .= ' ({\tt URI:'.$href.'})';
1.352     albertel 1664: 	} elsif ($name =~ /\S/) {
                   1665: 	    $currentstring .= ' ({\tt Anchor:'.&Apache::lonxml::latex_special_symbols($name).'})';
1.351     foxr     1666: 	} else {
                   1667: 	    $currentstring.='';
                   1668: 	}	
                   1669:     }
1.122     albertel 1670:     return $currentstring;
                   1671: }
                   1672: 
1.181     sakharuk 1673: #-- <li> tag (end tag optional)
1.122     albertel 1674: sub start_li {
1.168     albertel 1675:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 1676:     my $currentstring = '';
1.325     albertel 1677:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1678: 	$currentstring = $token->[4];     
                   1679:     } elsif ($target eq 'tex') {
1.237     sakharuk 1680: 	my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
                   1681: 	my $value=&Apache::lonxml::get_param('value',$parstack,$safeeval,undef,0);
1.238     albertel 1682: 	#FIXME need to support types i and I 
                   1683: 	if ($type=~/disc/) {
                   1684: 	    $currentstring .= ' \item[$\bullet$] ';
                   1685: 	} elsif ($type=~/circle/) {
                   1686: 	    $currentstring .= ' \item[$\circ$] ';
1.146     sakharuk 1687: 	} elsif ($type=~/square/) {
1.238     albertel 1688: 	    $currentstring .= ' \item[$\diamond$] ';
                   1689: 	} elsif ($type eq '1') {
                   1690: 	    $currentstring .= ' \item['.($Apache::londefdef::list_index+1).'.]';
1.237     sakharuk 1691: 	} elsif ($type eq 'A') {
1.238     albertel 1692: 	    $currentstring .= ' \item['.('A'..'Z')[$Apache::londefdef::list_index].'.]';
1.237     sakharuk 1693: 	} elsif ($type eq 'a') {
1.238     albertel 1694: 	    $currentstring .= ' \item['.('a'..'z')[$Apache::londefdef::list_index].'.]';
1.237     sakharuk 1695: 	} elsif ($value ne '') {
                   1696: 	    $currentstring .= ' \item['.$value.'] ';
1.122     albertel 1697: 	} else {
1.146     sakharuk 1698: 	    $currentstring .= ' \item ';
1.122     albertel 1699: 	}  
1.238     albertel 1700: 	$Apache::londefdef::list_index++;
                   1701:     }
1.122     albertel 1702:     return $currentstring;
                   1703: }
                   1704: 
                   1705: sub end_li {
                   1706:     my ($target,$token) = @_;
1.279     foxr     1707:     my $currentstring = &end_p();	# In case there's a <p> in the <li>
1.325     albertel 1708:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     1709: 	$currentstring .= $token->[2];     
1.122     albertel 1710:     } 
                   1711:     return $currentstring;
                   1712: }
                   1713: 
1.181     sakharuk 1714: #-- <u> tag (end tag required)
1.122     albertel 1715: sub start_u {
                   1716:     my ($target,$token) = @_;
                   1717:     my $currentstring = '';
1.325     albertel 1718:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1719: 	$currentstring .= $token->[4];
                   1720:     } elsif ($target eq 'tex') {
                   1721: 	&Apache::lonxml::startredirection();
                   1722:     } 
                   1723:     return $currentstring;
                   1724: }
                   1725: 
                   1726: sub end_u {
                   1727:     my ($target,$token) = @_;
                   1728:     my $currentstring = '';
1.325     albertel 1729:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1730: 	$currentstring .= $token->[2];
                   1731:     } elsif ($target eq 'tex') {
                   1732: 	$currentstring=&Apache::lonxml::endredirection();
                   1733: 	$currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g;
                   1734: 	$currentstring=~s/^\s*(\S)/\\underline\{$1/;
                   1735: 	$currentstring=~s/(\S)\s*$/$1\}/;		
                   1736:     }
                   1737:     return $currentstring;
                   1738: }
                   1739: 
1.181     sakharuk 1740: #-- <ul> tag (end tag required)
1.122     albertel 1741: sub start_ul {
1.125     sakharuk 1742:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr     1743:     my $currentstring = &end_p();	# Close off enclosing list.
1.325     albertel 1744:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     1745: 	$currentstring .= $token->[4];     
1.122     albertel 1746:     } elsif ($target eq 'tex') {
1.125     sakharuk 1747: 	my $TeXtype=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
1.238     albertel 1748: 	$Apache::londefdef::list_index=0;
1.125     sakharuk 1749: 	if ($TeXtype eq 'disc') {
1.222     sakharuk 1750: 	    $currentstring .= '\renewcommand{\labelitemi}{$\bullet$}'.
                   1751:                               '\renewcommand{\labelitemii}{$\bullet$}'. 
                   1752:                               '\renewcommand{\labelitemiii}{$\bullet$}'.
                   1753:                               '\renewcommand{\labelitemiv}{$\bullet$}';
1.125     sakharuk 1754: 	} elsif ($TeXtype eq 'circle') {
1.222     sakharuk 1755: 	    $currentstring .= '\renewcommand{\labelitemi}{$\circ$}'.
                   1756:                               '\renewcommand{\labelitemii}{$\circ$}'. 
                   1757:                               '\renewcommand{\labelitemiii}{$\circ$}'.
                   1758:                               '\renewcommand{\labelitemiv}{$\circ$}';
1.125     sakharuk 1759: 	} elsif ($TeXtype eq 'square') {
1.222     sakharuk 1760: 	    $currentstring .= '\renewcommand{\labelitemi}{$\diamond$}'.
                   1761:                               '\renewcommand{\labelitemii}{$\diamond$}'. 
                   1762:                               '\renewcommand{\labelitemiii}{$\diamond$}'.
                   1763:                               '\renewcommand{\labelitemiv}{$\diamond$}';
1.125     sakharuk 1764: 	}
1.222     sakharuk 1765: 	$currentstring .= '\strut \begin{itemize}';  
1.122     albertel 1766:     } 
                   1767:     return $currentstring;
                   1768: }
                   1769: 
                   1770: sub end_ul {
                   1771:     my ($target,$token) = @_;
                   1772:     my $currentstring = '';
1.325     albertel 1773:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1774: 	$currentstring = $token->[2];     
                   1775:     } elsif ($target eq 'tex') {
1.222     sakharuk 1776: 	$currentstring = '\end{itemize} \renewcommand{\labelitemi}{$\bullet$}'.
                   1777:                                '\renewcommand{\labelitemii}{$\bullet$}'. 
                   1778:                                '\renewcommand{\labelitemiii}{$\bullet$}'.
                   1779:                                '\renewcommand{\labelitemiv}{$\bullet$}\strut ';  
1.122     albertel 1780:     } 
                   1781:     return $currentstring;
                   1782: }
                   1783: 
1.181     sakharuk 1784: #-- <menu> tag (end tag required)
1.122     albertel 1785: sub start_menu {
                   1786:     my ($target,$token) = @_;
                   1787:     my $currentstring = '';
1.325     albertel 1788:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1789: 	$currentstring = $token->[4];     
                   1790:     } elsif ($target eq 'tex') {
                   1791: 	$currentstring = " \\begin{itemize} ";  
                   1792:     } 
                   1793:     return $currentstring;
                   1794: }
                   1795: 
                   1796: sub end_menu {
                   1797:     my ($target,$token) = @_;
                   1798:     my $currentstring = '';
1.325     albertel 1799:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1800: 	$currentstring = $token->[2];     
                   1801:     } elsif ($target eq 'tex') {
                   1802: 	$currentstring = " \\end{itemize}";  
                   1803:     } 
                   1804:     return $currentstring;
                   1805: }
                   1806: 
1.181     sakharuk 1807: #-- <dir> tag (end tag required)
1.122     albertel 1808: sub start_dir {
                   1809:     my ($target,$token) = @_;
1.279     foxr     1810:     my $currentstring = &end_p();	# In case there's a <p> prior to the list.
1.325     albertel 1811:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     1812: 	$currentstring .= $token->[4];     
1.122     albertel 1813:     } elsif ($target eq 'tex') {
1.277     foxr     1814: 	$currentstring .= " \\begin{itemize} ";  
1.122     albertel 1815:     } 
                   1816:     return $currentstring;
                   1817: }
                   1818: 
                   1819: sub end_dir {
                   1820:     my ($target,$token) = @_;
                   1821:     my $currentstring = '';
1.325     albertel 1822:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1823: 	$currentstring = $token->[2];     
                   1824:     } elsif ($target eq 'tex') {
                   1825: 	$currentstring = " \\end{itemize}";  
                   1826:     } 
                   1827:     return $currentstring;
                   1828: }
                   1829: 
1.181     sakharuk 1830: #-- <ol> tag (end tag required)
1.122     albertel 1831: sub start_ol {
1.125     sakharuk 1832:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr     1833:     my $currentstring = &end_p();	# In case there's a <p> prior to the list.
1.325     albertel 1834:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     1835: 	$currentstring .= $token->[4];     
1.122     albertel 1836:     } elsif ($target eq 'tex') {
1.238     albertel 1837: 	$Apache::londefdef::list_index=0;
1.125     sakharuk 1838: 	my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0);
                   1839: 	if ($type eq '1') {
1.222     sakharuk 1840: 	    $currentstring .= '\renewcommand{\labelenumi}{\arabic{enumi}.}'.
                   1841:                               '\renewcommand{\labelenumii}{\arabic{enumii}.}'. 
                   1842:                               '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.
                   1843:                               '\renewcommand{\labelenumiv}{\arabic{enumiv}.}';
1.125     sakharuk 1844: 	} elsif ($type eq 'A') {
1.222     sakharuk 1845: 	    $currentstring .= '\renewcommand{\labelenumi}{\Alph{enumi}.}'.
                   1846:                               '\renewcommand{\labelenumii}{\Alph{enumii}.}'. 
                   1847:                               '\renewcommand{\labelenumiii}{\Alph{enumiii}.}'.
                   1848:                               '\renewcommand{\labelenumiv}{\Alph{enumiv}.}';
1.125     sakharuk 1849: 	} elsif ($type eq 'a') {
1.222     sakharuk 1850: 	    $currentstring .= '\renewcommand{\labelenumi}{\alph{enumi}.}'.
                   1851:                               '\renewcommand{\labelenumii}{\alph{enumii}.}'.
                   1852:                               '\renewcommand{\labelenumiii}{\alph{enumiii}.}'.
                   1853:                               '\renewcommand{\labelenumiv}{\alph{enumiv}.}';
1.125     sakharuk 1854: 	} elsif ($type eq 'i') {
1.222     sakharuk 1855: 	    $currentstring .= '\renewcommand{\labelenumi}{\roman{enumi}.}'.
                   1856:                               '\renewcommand{\labelenumii}{\roman{enumii}.}'.
                   1857:                               '\renewcommand{\labelenumiii}{\roman{enumiii}.}'.
                   1858:                               '\renewcommand{\labelenumiv}{\roman{enumiv}.}';
1.125     sakharuk 1859: 	} elsif ($type eq 'I') {
1.222     sakharuk 1860: 	    $currentstring .= '\renewcommand{\labelenumi}{\Roman{enumi}.}'.
                   1861:                               '\renewcommand{\labelenumii}{\Roman{enumii}.}'.
                   1862:                               '\renewcommand{\labelenumiii}{\Roman{enumiii}.}'.
                   1863:                               '\renewcommand{\labelenumiv}{\Roman{enumiv}.}';
1.125     sakharuk 1864: 	}
1.222     sakharuk 1865: 	$currentstring .= '\strut \begin{enumerate}';  
1.122     albertel 1866:     } 
                   1867:     return $currentstring;
                   1868: }
                   1869: 
                   1870: sub end_ol {
                   1871:     my ($target,$token) = @_;
                   1872:     my $currentstring = '';
1.325     albertel 1873:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1874: 	$currentstring = $token->[2];     
                   1875:     } elsif ($target eq 'tex') {
1.222     sakharuk 1876: 	$currentstring = '\end{enumerate}\renewcommand{\labelenumi}{\arabic{enumi}.}'.
                   1877:                                         '\renewcommand{\labelenumii}{\arabic{enumii}.}'.
                   1878:                                         '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'.
                   1879:                                         '\renewcommand{\labelenumiv}{\arabic{enumiv}.}\strut ';  
1.122     albertel 1880:     } 
                   1881:     return $currentstring;
                   1882: }
                   1883: 
1.181     sakharuk 1884: #-- <dl> tag (end tag required)
1.122     albertel 1885: sub start_dl {
                   1886:     my ($target,$token) = @_;
1.279     foxr     1887:     my $currentstring = &end_p();	# In case there's a <p> unclosed prior to the list.
1.325     albertel 1888:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     1889: 	$currentstring .= $token->[4];     
1.122     albertel 1890:     } elsif ($target eq 'tex') {
1.277     foxr     1891: 	$currentstring .= '\begin{description}';
1.243     albertel 1892: 	$Apache::londefdef::DL++;
                   1893: 	push(@Apache::londefdef::description,[]);
                   1894: 	$Apache::londefdef::DD[$Apache::londefdef::DL]=0;
                   1895: 	$Apache::londefdef::DT[$Apache::londefdef::DL]=0;
1.244     albertel 1896: 	$Apache::londefdef::seenDT[$Apache::londefdef::DL]=0;
1.122     albertel 1897:     } 
                   1898:     return $currentstring;
                   1899: }
                   1900: 
                   1901: sub end_dl {
1.174     sakharuk 1902:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 1903:     my $currentstring = '';
1.325     albertel 1904:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1905: 	$currentstring = $token->[2];     
                   1906:     } elsif ($target eq 'tex') {
1.243     albertel 1907: 	if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
                   1908: 	if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
                   1909: 	foreach my $element (@{$Apache::londefdef::description[-1]}) {
1.174     sakharuk 1910: 	    $currentstring.=' '.$element.' ';
                   1911: 	}
1.243     albertel 1912: 	pop(@Apache::londefdef::description);
1.174     sakharuk 1913: 	$currentstring.='\end{description}';  
1.243     albertel 1914: 	delete($Apache::londefdef::DD[$Apache::londefdef::DL]);
                   1915: 	delete($Apache::londefdef::DT[$Apache::londefdef::DL]);
1.244     albertel 1916: 	delete($Apache::londefdef::seenDT[$Apache::londefdef::DL]);
1.243     albertel 1917: 	$Apache::londefdef::DL--;
1.122     albertel 1918:     } 
                   1919:     return $currentstring;
                   1920: }
                   1921: 
1.172     sakharuk 1922: #-- <dt> tag (end tag optional)
1.122     albertel 1923: sub start_dt {
1.172     sakharuk 1924:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   1925:     my $currentstring='';
1.325     albertel 1926:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1927: 	$currentstring = $token->[4];     
                   1928:     } elsif ($target eq 'tex') {
1.243     albertel 1929: 	if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
                   1930: 	if ($Apache::londefdef::DD[-1]) { &end_dd(@_); }
1.174     sakharuk 1931: 	&Apache::lonxml::startredirection();
1.243     albertel 1932: 	$Apache::londefdef::DT[-1]++;
1.244     albertel 1933: 	$Apache::londefdef::seenDT[-1]=1;
1.122     albertel 1934:     } 
                   1935:     return $currentstring;
                   1936: }
                   1937: 
                   1938: sub end_dt {
1.172     sakharuk 1939:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 1940:     my $currentstring = '';
1.325     albertel 1941:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1942: 	$currentstring = $token->[2];    
                   1943:     } elsif ($target eq 'tex') {
1.243     albertel 1944: 	if ($Apache::londefdef::DT[-1]) {
                   1945: 	    my $data=&item_cleanup();
1.244     albertel 1946: 	    push(@{$Apache::londefdef::description[-1]},'\item['.$data.'] \strut \vskip 0mm');
1.243     albertel 1947: 	    $Apache::londefdef::DT[-1]--;
                   1948: 	}
1.122     albertel 1949:     } 
                   1950:     return $currentstring;
                   1951: }
                   1952: 
1.173     sakharuk 1953: sub item_cleanup {
1.174     sakharuk 1954:     my $item=&Apache::lonxml::endredirection();
1.173     sakharuk 1955:     $item=~s/\\begin{center}//g;
                   1956:     $item=~s/\\end{center}//g;
                   1957:     return $item;
                   1958: }
                   1959: 
1.181     sakharuk 1960: #-- <dd> tag (end tag optional)
1.122     albertel 1961: sub start_dd {
1.147     sakharuk 1962:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 1963:     my $currentstring = '';
1.325     albertel 1964:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1965: 	$currentstring = $token->[4];     
1.147     sakharuk 1966:     } elsif ($target eq 'tex') {
1.243     albertel 1967: 	if ($Apache::londefdef::DT[-1]) { &end_dt(@_); }
                   1968: 	if ($Apache::londefdef::DD[-1]) { &end_dd(@_);}
1.244     albertel 1969: 	if (!$Apache::londefdef::seenDT[-1]) {
                   1970: 	    push(@{$Apache::londefdef::description[-1]},'\item[\strut] \strut \vskip 0mm ');
                   1971: 	}
1.243     albertel 1972: 	push(@{$Apache::londefdef::description[-1]},'');
                   1973: 	$Apache::londefdef::description[-1]->[-1].=' \strut ';
                   1974: 	$Apache::londefdef::DD[-1]++;
1.174     sakharuk 1975: 	&Apache::lonxml::startredirection();
1.122     albertel 1976:     } 
                   1977:     return $currentstring;
                   1978: }
                   1979: 
                   1980: sub end_dd {
1.174     sakharuk 1981:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 1982:     my $currentstring = '';
1.325     albertel 1983:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 1984: 	$currentstring = $token->[2];    
1.174     sakharuk 1985:     }  elsif ($target eq 'tex') {
1.243     albertel 1986: 	$Apache::londefdef::description[-1]->[-1].=
                   1987: 	    &Apache::lonxml::endredirection().' \vskip 0mm ';
                   1988: 	$Apache::londefdef::DD[-1]--;
1.174     sakharuk 1989:     }
1.122     albertel 1990:     return $currentstring;
                   1991: }
                   1992: 
1.181     sakharuk 1993: #-- <table> tag (end tag required)
1.277     foxr     1994: #       <table> also ends any prior <p> that is not closed.
                   1995: #               but, unless I allow <p>'s to nest, that's the
                   1996: #               only way I could think of to allow <p> in 
                   1997: #               <tr> <th> bodies
                   1998: #
1.206     sakharuk 1999: #list of supported attributes: border,width,TeXwidth
1.91      sakharuk 2000: sub start_table {
                   2001:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.277     foxr     2002:     my $textwidth = '';
1.279     foxr     2003:     my $currentstring = &end_p();
1.325     albertel 2004:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     2005: 	$currentstring .= $token->[4];     
1.91      sakharuk 2006:     } elsif ($target eq 'tex') {
1.344     albertel 2007: 	push(@Apache::londefdef::table, {}); 
1.91      sakharuk 2008: 	$Apache::londefdef::table[-1]{'row_number'} = -1;
1.222     sakharuk 2009:         #maximum table's width (default coincides with text line length)
1.206     sakharuk 2010: 	if ($#Apache::londefdef::table==0) {
1.267     albertel 2011: 	    $textwidth=&recalc($env{'form.textwidth'}); #result is always in mm
1.206     sakharuk 2012: 	    $textwidth=~/(\d+\.?\d*)/;
1.358     foxr     2013: 	    $textwidth=0.85*$1; #accounts "internal" LaTeX space for table frame
1.206     sakharuk 2014: 	} else {
                   2015: 	    if ($Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]=~/\d/) {
                   2016: 		#the maximum width of nested table is determined by LATeX width of parent cell
                   2017: 		$textwidth=$Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]; 
                   2018: 	    } else {
                   2019:               #try to use all space not used before (minus 5% for LaTeX table internal) - rather silly
1.228     sakharuk 2020: 		$textwidth=$Apache::londefdef::table[-2]{'width'};
1.206     sakharuk 2021: 		for (my $i=0;$i<$Apache::londefdef::table[-2]{'counter_columns'};$i++) {
                   2022: 		    $textwidth=$textwidth-$Apache::londefdef::table[-2]{'TeXlen'}[0][$i];
                   2023: 		}
                   2024: 	    }
                   2025: 	}
1.294     foxr     2026: 
                   2027: 	# width either comes forced from the TeXwidth or the width parameters.
                   2028: 	# in either case it can be a percentage or absolute width.
1.311     albertel 2029: 	# in the width case we ignore absolute width 
1.126     sakharuk 2030: 	my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
1.308     albertel 2031: 	if (!defined($TeXwidth)) {
1.311     albertel 2032: 	    my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,
                   2033: 						       $safeeval,undef,1);
                   2034: 	    if ($htmlwidth =~ /%/) {
                   2035: 		$TeXwidth = $htmlwidth;
                   2036: 	    } else { 
                   2037: 		$TeXwidth = $textwidth;
                   2038: 	    }
1.364     foxr     2039: 	}
                   2040: 	# if the width is specified as a % it is converted to an absolute width.
                   2041: 	# otherwise.. just plugged right in the hash
                   2042: 
1.294     foxr     2043: 	if ($TeXwidth=~/%/) {
1.126     sakharuk 2044: 	    $TeXwidth=~/(\d+)/;
1.206     sakharuk 2045:             $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;
1.126     sakharuk 2046: 	} else {
1.206     sakharuk 2047: 	    $Apache::londefdef::table[-1]{'width'}=$TeXwidth;
1.316     foxr     2048: 	}
                   2049:         #  In the end, however the table width cannot be wider than $textwidth...
                   2050: 	
                   2051: 	if ($Apache::londefdef::table[-1]{'width'} > $textwidth) {
                   2052: 	    $Apache::londefdef::table[-1]{'width'} = $textwidth;
                   2053: 	}
1.126     sakharuk 2054:         #table's border
1.206     sakharuk 2055: 	my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval); 
1.208     sakharuk 2056:         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);
1.91      sakharuk 2057: 	unless (defined $border) { $border = 0; }
                   2058: 	if ($border) { 
                   2059: 	    $Apache::londefdef::table[-1]{'hinc'} = '\hline '; 
                   2060: 	    $Apache::londefdef::table[-1]{'vinc'} = '&'; 
                   2061: 	    $Apache::londefdef::table[-1]{'vvinc'} = '|';
                   2062: 	} else {
                   2063: 	    $Apache::londefdef::table[-1]{'hinc'} = ''; 
                   2064: 	    $Apache::londefdef::table[-1]{'vinc'} = '&'; 
                   2065: 	    $Apache::londefdef::table[-1]{'vvinc'} = '';
                   2066: 	}
1.206     sakharuk 2067: 	if ($#Apache::londefdef::table==0) {
1.281     foxr     2068: 	    #    Note that \newline seems to destroy the alignment envs.
                   2069: 	    # $Apache::londefdef::table[-1]{'output'}='\strut\newline\strut\setlength{\tabcolsep}{1 mm}';
                   2070: 	    $Apache::londefdef::table[-1]{'output'}='\strut'.'\\\\'."\n".'\strut\setlength{\tabcolsep}{1 mm}';
1.206     sakharuk 2071: 	}
                   2072: 	$Apache::londefdef::table[-1]{'output'}.=' \noindent \begin{tabular} ';
                   2073:         $Apache::londefdef::table[-1]{'TeXlen'}=[];
                   2074:         $Apache::londefdef::table[-1]{'objectlen'}=[];
1.229     sakharuk 2075:         $Apache::londefdef::table[-1]{'objectsignal'}=[];
1.206     sakharuk 2076:         $Apache::londefdef::table[-1]{'maxlen'}=[];
                   2077:         $Apache::londefdef::table[-1]{'minlen'}=[];
                   2078:         $Apache::londefdef::table[-1]{'content'}=[];
                   2079:         $Apache::londefdef::table[-1]{'align'}=[];
1.340     foxr     2080:         $currentstring.=' \keephidden{NEW TABLE ENTRY}';
1.295     foxr     2081: 
1.294     foxr     2082: 
                   2083:     }
1.91      sakharuk 2084:     return $currentstring;
                   2085: }
1.122     albertel 2086:  
                   2087: sub end_table {
                   2088:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   2089:     my $currentstring = '';
1.325     albertel 2090:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 2091: 	$currentstring = $token->[2];     
                   2092:     } elsif ($target eq 'tex') {
1.372     foxr     2093: 	my $border =  &Apache::lonxml::get_param('border',$parstack,$safeeval);
1.122     albertel 2094: 	my $inmemory = '';
                   2095: 	my $output = '';
1.206     sakharuk 2096: 	my $WARNING='';
                   2097:         #width of columns from TeXwidth attributes
1.294     foxr     2098: 
1.206     sakharuk 2099: 	for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
                   2100: 	    for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
                   2101: 		if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]<$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]) {
                   2102: 		    $Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]=$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn];
                   2103: 		}	
                   2104: 	    }
                   2105: 	}
                   2106:         #free space and number of empty columns
                   2107: 	my ($available_space,$empty_columns)=($Apache::londefdef::table[-1]{'width'},0);
1.228     sakharuk 2108: 	if ($#Apache::londefdef::table ne 0) {$available_space=0.9*$available_space;} 
1.206     sakharuk 2109: 	for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
                   2110: 	    if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]==0) {
                   2111: 		$empty_columns++;
                   2112: 	    } else {
                   2113: 		$available_space=$available_space-$Apache::londefdef::table[-1]{'TeXlen'}[0][$jn];
                   2114: 	    }
                   2115: 	}
1.358     foxr     2116: 
1.206     sakharuk 2117:         #boundaries for contents columns
                   2118: 	my @min_len=();#columns can not be narrower 
                   2119: 	my @max_len=();#maximum length of column
1.357     foxr     2120: 	my $avg_max;
                   2121: 	my $avg_min;
                   2122: 	my $counter_cols = $Apache::londefdef::table[-1]{'counter_columns'};
                   2123: 	for (my $jn=0;$jn<=$counter_cols; $jn++) {
1.206     sakharuk 2124: 		my ($localmin,$localmax)=(0,0);
                   2125: 		for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
                   2126: 		    if ($localmin<$Apache::londefdef::table[-1]{'minlen'}[$in][$jn]) {
                   2127: 			$localmin=$Apache::londefdef::table[-1]{'minlen'}[$in][$jn];
                   2128: 		    }
                   2129: 		    if ($localmax<$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn]) {
                   2130: 			$localmax=$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn];
                   2131: 		    }
                   2132: 		}
                   2133: 		push @min_len, $localmin;
                   2134: 		push @max_len, $localmax;
1.357     foxr     2135: 		$avg_max = $localmax + $avg_max;
                   2136: 		$avg_min = $localmin + $avg_min;
                   2137: 	}
                   2138: 	# Does not really matter what the average max/min are if there are no cols.
                   2139: 	# and this prevents div 0 in that case.
                   2140: 
                   2141: 	if ($counter_cols != 0) {
                   2142: 	    $avg_max = $avg_max/$counter_cols;
                   2143: 	    $avg_min = $avg_min/$counter_cols;
                   2144: 	}
                   2145: 
                   2146: 
                   2147: 	#  I don't think the below is needed.. but just in case:
                   2148: 
                   2149: 	if ($avg_min > $avg_max) {
                   2150: 	    my $temp = $avg_min;
                   2151: 	    $avg_min = $avg_max;
                   2152: 	    $avg_max = $temp;
1.122     albertel 2153: 	}
1.357     foxr     2154: 
                   2155: 
                   2156: 	for (my $jn=0;$jn<=$counter_cols;$jn++) {
1.206     sakharuk 2157: 	    my $localmin=0,;
                   2158: 	    for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
                   2159: 		if ($localmin<$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn]) {
                   2160: 		    $localmin=$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn];
                   2161: 		}
                   2162: 	    }
1.229     sakharuk 2163: 	    if ($max_len[$jn]<$localmin) {
                   2164: 		$max_len[$jn]=$localmin;
                   2165: 	    	$Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;
                   2166: 	    }#object size is bigger
                   2167: 	    if ($min_len[$jn]<$localmin) {
                   2168: 		$min_len[$jn]=$localmin;
                   2169: 		$Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1;
                   2170: 	    }#object size is bigger
1.206     sakharuk 2171: 	    if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]!=0) {
                   2172: 		$min_len[$jn]=0;
                   2173: 		$max_len[$jn]=0;
                   2174: 	    }
1.357     foxr     2175: 	    #  Spans seem to be really bothered by max/min = 0.  So if we have one
                   2176: 	    #  make it an average joe max/min.
                   2177: 	    
                   2178: 	    if ($max_len[$jn] == 0) {
                   2179: 		$max_len[$jn] = $avg_max;
                   2180: 	    }
                   2181: 	    if ($min_len[$jn] == 0) {
                   2182: 		$min_len[$jn] = $avg_min;
                   2183: 	    }
                   2184: 
1.206     sakharuk 2185: 	}
                   2186:        #final adjustment of column width
                   2187: 	my @fwidth=@{$Apache::londefdef::table[-1]{'TeXlen'}[0]};#final width array
                   2188: 	my @adjust=();
                   2189:         #step 1. adjustment by maximum value
1.370     albertel 2190: 	my $space_needed=0;
1.206     sakharuk 2191: 	for (my $jn=0;$jn<=$#max_len;$jn++) {
1.370     albertel 2192: 	    $space_needed=$space_needed+$max_len[$jn];
1.206     sakharuk 2193: 	}
1.370     albertel 2194: 	if ($space_needed<=$available_space) {
1.362     foxr     2195: 
1.206     sakharuk 2196: 	    for (my $jn=0;$jn<=$#max_len;$jn++) {
                   2197: 		if ($fwidth[$jn]==0) {
                   2198: 		    $fwidth[$jn]=$max_len[$jn];
1.53      sakharuk 2199: 		}
1.51      sakharuk 2200: 	    }
1.206     sakharuk 2201: 	} else {
                   2202:         #step 2. adjustment by minimum value (estimation)
1.370     albertel 2203: 	    $space_needed=0;
1.206     sakharuk 2204: 	    for (my $jn=0;$jn<=$#min_len;$jn++) {
1.370     albertel 2205: 		$space_needed+=$min_len[$jn];
1.206     sakharuk 2206: 	    }
1.370     albertel 2207: 	    if ($space_needed>$available_space) {
1.206     sakharuk 2208: 		$WARNING=' \textbf{NOT ENOUGH SPACE FOR TABLE} ';
                   2209: 		for (my $jn=0;$jn<=$#max_len;$jn++) {
                   2210: 		    if ($fwidth[$jn]==0) {
                   2211: 			$fwidth[$jn]=$min_len[$jn];
                   2212: 		    }
                   2213: 		}
1.229     sakharuk 2214: 		#check if we have objects which can be scaled
                   2215: 		my $how_many_to_scale=0;
                   2216: 		my @to_scale=();
                   2217: 		for (my $jn=0;$jn<=$#max_len;$jn++) {
                   2218: 		    if ($Apache::londefdef::table[-1]{'objectsignal'}[$jn] eq '1') {
                   2219: 			$how_many_to_scale++;
                   2220: 			push @to_scale, $jn;
                   2221: 		    }
                   2222: 		}
                   2223: 		if ($how_many_to_scale>0) {
1.370     albertel 2224: 		    my $space_to_adjust=($space_needed-$available_space)/$how_many_to_scale;
1.229     sakharuk 2225: 		    foreach my $jn (@to_scale) {
                   2226: 			for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
                   2227: 			    $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/;
                   2228: 			    if ($1 ne '') {
                   2229: 				my $current_length=&recalc($1);
                   2230: 				$current_length=~/(\d+\.?\d*)/;
                   2231: 				$current_length=$current_length-$space_to_adjust;
                   2232: 				$Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/width=$current_length mm/;
                   2233: 			    }
                   2234: 			    $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/\[(\d+\.?\d*)\s*mm\]/;
                   2235: 			    if ($1 ne '') {
                   2236: 				my $current_length=$1;
                   2237: 				$current_length=$current_length-$space_to_adjust;
                   2238: 				$Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/\[(\d+\.?\d*)\s*mm\]/\[$current_length mm\]/;
                   2239: 			    }				
                   2240: 			}
                   2241: 			$fwidth[$jn]=$fwidth[$jn]-$space_to_adjust;
                   2242: 		    }
                   2243: 		}
1.206     sakharuk 2244: 	    } else {
                   2245: 	      #step 3. adjustment over minimal + corrections
1.370     albertel 2246: 		my $enlarge_coef=$available_space/$space_needed;
1.206     sakharuk 2247: 		my $acsessive=0;
                   2248: 		for (my $jn=0;$jn<=$#min_len;$jn++) {
                   2249: 		    $adjust[$jn]=$min_len[$jn]*$enlarge_coef;
                   2250: 		    if ($adjust[$jn]>$max_len[$jn]) {
                   2251: 			$fwidth[$jn]=$max_len[$jn];
                   2252: 			$acsessive=$acsessive+$adjust[$jn]-$max_len[$jn];
                   2253: 			$adjust[$jn]=0;
1.357     foxr     2254: 
1.206     sakharuk 2255: 		    }
                   2256: 		}
                   2257: 		if ($acsessive>0) {
                   2258: 		#we have an excess of space and can redistribute it
                   2259: 		    my $notempty_columns=0;
                   2260: 		    for (my $jn=0;$jn<=$#min_len;$jn++) {
                   2261: 			if ($adjust[$jn]!=0) {
                   2262: 			    $notempty_columns++;
                   2263: 			}
                   2264: 		    }
                   2265: 		    my $per_column=$acsessive/$notempty_columns;
                   2266: 		    for (my $jn=0;$jn<=$#min_len;$jn++) {
                   2267: 			if ($adjust[$jn]!=0) {
                   2268: 			    $adjust[$jn]+=$per_column;
                   2269: 			    $fwidth[$jn]=$adjust[$jn];
                   2270: 			}
1.223     sakharuk 2271: 		    }
                   2272: 		} else {
                   2273: 		    for (my $jn=0;$jn<=$#min_len;$jn++) {
                   2274: 			$fwidth[$jn]=$adjust[$jn];
1.206     sakharuk 2275: 		    }
                   2276: 		}
1.203     sakharuk 2277: 	    }
                   2278: 	}
1.364     foxr     2279:         # use all available width or specified width as if not specified,
                   2280: 	# the specified width gets defaulted to the available width.
                   2281: 
                   2282: 	my $current=0; 
                   2283: 	for (my $i=0;$i<=$#fwidth;$i++) {  
                   2284: 	    $current+=$fwidth[$i];
                   2285: 	}
1.371     albertel 2286: 	if ($current == 0) {
                   2287:             $current = $Apache::londefdef::table[-1]{'width'};
                   2288:         }
1.364     foxr     2289: 	my $coef=$Apache::londefdef::table[-1]{'width'}/$current;
                   2290: 	for (my $i=0;$i<=$#fwidth;$i++) {  
                   2291: 	    $fwidth[$i]*=$coef;
1.206     sakharuk 2292: 	}
                   2293:         #removing of empty columns if allowed
1.208     sakharuk 2294:         my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0);
1.206     sakharuk 2295: 	if ($permission eq 'yes') {
                   2296: 	    my @cleaned_table=();
                   2297:             my @cleaned_header=();
                   2298: 	    my $colind=0;
                   2299: 	    for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) {
                   2300: 		if ($fwidth[$jn]!=0) {
                   2301: 		    #we need to copy column
                   2302: 		    for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
                   2303: 			$cleaned_table[$in][$colind]=$Apache::londefdef::table[-1]{'content'}[$in][$jn];
                   2304: 			$cleaned_header[$colind]=$fwidth[$jn];
                   2305: 		    }
                   2306: 		    $colind++;
                   2307: 		}
1.122     albertel 2308: 	    }
1.206     sakharuk 2309: 	    $Apache::londefdef::table[-1]{'content'}=\@cleaned_table;
                   2310: 	    @fwidth=@cleaned_header;
1.122     albertel 2311: 	}
1.359     foxr     2312: 
1.358     foxr     2313: 
1.206     sakharuk 2314: 	#construct header of the table
                   2315: 	my $header_of_table = '{'.$Apache::londefdef::table[-1]{'vvinc'};
                   2316: 	for (my $in=0;$in<=$#fwidth;$in++) {
                   2317: 	    $header_of_table.='p{'.$fwidth[$in].' mm}'.$Apache::londefdef::table[-1]{'vvinc'};
                   2318: 	}
                   2319: 	$header_of_table .= '}';
1.357     foxr     2320: 
1.126     sakharuk 2321: 	#fill the table
                   2322: 	for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
1.306     foxr     2323: 	    my $have_rowspan = 0;
1.206     sakharuk 2324: 	    for (my $jn=0;$jn<=$#fwidth;$jn++) {
1.320     foxr     2325: 
                   2326: 		#-----------------------------------------------------------
                   2327:                 #   I think this order of doing things will ensure that
                   2328: 		#   single rowspan, columspan and combined row/colspans will
                   2329:                 #   work correctly.  LaTeX is delicate here.
                   2330: 		#    RF.
1.356     foxr     2331: 		
1.320     foxr     2332: 		# Start a rowspan if necessary:
1.356     foxr     2333: 		
                   2334: 		my $primary_col_width = $fwidth[$jn]; # Width of primary column.
1.320     foxr     2335: 		my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];
                   2336: 		my $colspan = $Apache::londefdef::table[-1]{'colspan'}[$in][$jn];
1.304     foxr     2337: 		#
                   2338: 		#  Do the appropriate magic if this has a colspan
                   2339: 		# 
1.356     foxr     2340: 		
1.372     foxr     2341: 		my $border_char = "";
                   2342: 		if ($border) {
                   2343: 		    $border_char = "|";
                   2344: 		}
1.356     foxr     2345: 		my $spanwidth = 0;
1.304     foxr     2346: 		if ($colspan > 1) {
1.336     foxr     2347: 		    for (my $spancol = $jn; $spancol < $jn + $colspan; $spancol++) {
                   2348: 			$spanwidth += $fwidth[$spancol];
                   2349: 		    }
1.304     foxr     2350: 		    $output .= '\multicolumn{'.
                   2351: 			$colspan
1.337     foxr     2352: 			."}";
                   2353: 		    if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
1.372     foxr     2354: 			$output .= '{'.$border_char.'c'.$border_char.'}{';
1.337     foxr     2355: 		    } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {
1.372     foxr     2356: 			$output .= '{'.$border_char.'r'.$border_char.'}{';
1.337     foxr     2357: 		    }
                   2358: 		    else {
1.372     foxr     2359: 			$output .= '{'.$border_char."p{$spanwidth mm}".$border_char.'}{';
1.337     foxr     2360: 		    }
1.356     foxr     2361: 		    
                   2362: 		} else {
                   2363: 		    $spanwidth = $primary_col_width; # If no span width will be just colwidth
1.304     foxr     2364: 		}
1.306     foxr     2365: 
1.337     foxr     2366: 		# Rowspan... if colspan is 1, and there's an alignment we'll need
                   2367: 		# to kick in a multicolumn in order to get the alignment spec.
                   2368: 		# this must precede the multirow or LaTex gets quite upset.
                   2369: 		# Naturally if colspan > 1 we've already done that above ^
                   2370: 		#
                   2371: 		my $multirow_aligned = 0;
1.306     foxr     2372: 		if ($rowspan > 1) {
1.337     foxr     2373: 		    if ($colspan == 1) {
                   2374: 			if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
1.372     foxr     2375: 			    $output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{';
1.337     foxr     2376: 			    $multirow_aligned = 1;
                   2377: 			} elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {
1.372     foxr     2378: 			    $output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{';
1.337     foxr     2379: 			    $multirow_aligned = 1;
                   2380: 			}
                   2381: 		    }
1.306     foxr     2382: 		    $have_rowspan++;
1.356     foxr     2383: 		    if ($multirow_aligned) {
                   2384: 			$output .= '\multirow{'.$rowspan.'}[0]{*}{';
                   2385: 		    } else {
                   2386: 			$output .= '\multirow{'.$rowspan."}[0]{$spanwidth mm}{";
                   2387: 		    }
1.350     albertel 2388: 		    
                   2389: 		    $Apache::londefdef::table[-1]{'content'}[$in][$jn] =~
                   2390: 			s{^\s*\\par\s*}{};
                   2391: 		    $Apache::londefdef::table[-1]{'content'}[$in][$jn] =~
                   2392: 			s{\s*\\vskip\s*0pt\s*$}{};
1.356     foxr     2393: 			  
1.337     foxr     2394: 		    #
                   2395: 		    # If we did not throw in a multicolumn to align, then add 
                   2396: 		    # an extra {
                   2397: 		    # so we close correctly without having to keep additional state
                   2398: 		    # around
                   2399: 		    #
                   2400: 		    if (!$multirow_aligned) {
                   2401: 			$output .= '{';
                   2402: 		    }
1.306     foxr     2403: 		}
                   2404: 		if (($rowspan eq '^') || ($rowspan eq '_')) {
                   2405: 		    $have_rowspan++;
                   2406: 		}
1.356     foxr     2407: 		    #--------------------------------------------------------------
1.306     foxr     2408: 
1.337     foxr     2409: 
                   2410: 		# For right and center alignment of single cells.
                   2411: 		# we are going to use a multicolumn with a span of 1 to specify alignment.
                   2412: 		#
                   2413: 		if ($colspan == 1  && $rowspan == 1) {
                   2414: 		    if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
1.372     foxr     2415: 			$output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{';
1.337     foxr     2416: 		    } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {
1.372     foxr     2417: 			$output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{';
1.337     foxr     2418: 		    }
1.206     sakharuk 2419: 		}
1.337     foxr     2420: 
1.206     sakharuk 2421: 		$output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn];
1.337     foxr     2422: 
                   2423: 		if (($colspan == 1 && $rowspan == 1)   &&
                   2424: 		    (($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') ||
                   2425: 		     ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r'))) {
                   2426: 		    $output .= '}';
1.206     sakharuk 2427: 		}
1.337     foxr     2428: 
1.306     foxr     2429: 		# Close off any open multirow:
                   2430: 		
                   2431: 		if ($rowspan > 1) {
1.337     foxr     2432: 		    $output .= '}}';
1.306     foxr     2433: 		}
1.304     foxr     2434: 		#  Close off the colspan...
                   2435: 		#
                   2436: 		if ($colspan > 1)  {
                   2437: 		    $output .= '}';
                   2438: 		    $jn += $colspan-1; # Adjust for number of rows really left.
                   2439: 		}
1.206     sakharuk 2440:                 if ($jn!=$#fwidth) {$output.=' '.$Apache::londefdef::table[-1]{'vinc'};}
                   2441: 	    }
1.306     foxr     2442: 	    #  If have_rowspan > 0, and borders are on, then 
                   2443: 	    #  we need to do more than put an \hline at the bottom of row.
                   2444: 	    #  we need to do the appropriate \cline to ensure that
                   2445: 	    #  the spanned rows don't have \hlines through them.
                   2446: 
                   2447: 	    if (($Apache::londefdef::table[-1]{'hinc'} =~ /\\hline/) && $have_rowspan) {
                   2448: 		$output .= ' \\\\ ';
                   2449: 		for (my $jn=0; $jn<=$#fwidth;$jn++) {
                   2450: 		    my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];
1.320     foxr     2451: 		    if ($rowspan ne "^") {
                   2452: 			if (($rowspan <= 1) || ($rowspan eq '_')) {
                   2453: 			    my $column = $jn+1;
                   2454: 			    $output .= '\cline{'.$column.'-'.$column.'} ';
                   2455: 			}
1.306     foxr     2456: 		    }
                   2457: 		}
                   2458: 
                   2459: 	    } else {
                   2460: 		$output.=' \\\\ '.$Apache::londefdef::table[-1]{'hinc'}.' ';
                   2461: 	    }
1.122     albertel 2462: 	}
1.281     foxr     2463: 	# Note that \newline destroys alignment env's produced  by e.g. <div>
                   2464: 	# $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut\newline\strut ';
                   2465: 	$Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut'.'\\\\'."\n".'\strut ';
1.127     sakharuk 2466: 	if ($#Apache::londefdef::table > 0) {	    
                   2467: 	    my $inmemory = $Apache::londefdef::table[-1]{'output'};
1.294     foxr     2468: 	    # Figure out max/and min width  by summing us and then
                   2469: 	    # apply that to the current column of the table we nest in
                   2470: 	    # if it's larger than the current width or the current width
                   2471: 	    # is undefined.
                   2472: 	    #
                   2473: 	    my $min_nested_width = 0;
                   2474: 	    my $max_nested_width = 0;
                   2475: 	    for (my $col = 0; $col <= $Apache::londefdef::table[-1]{'counter_columns'}; $col++) {
                   2476: 		$min_nested_width +=  $min_len[$col];
                   2477: 		$max_nested_width +=  $max_len[$col];
1.300     foxr     2478: 		
1.294     foxr     2479: 	    }
                   2480: 	    # Fudge in an extra 5 mm for borders etc:
                   2481: 	    
                   2482: 	    $min_nested_width += 5;
                   2483: 	    $max_nested_width += 5;
                   2484: 
                   2485: 	    my $outer_column = $Apache::londefdef::table[-2]{'counter_columns'};
                   2486: 	    my $outer_row    = $Apache::londefdef::table[-2]{'row_number'};
                   2487: 	    if ($min_nested_width > $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column]) {
                   2488: 		$Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column] = $min_nested_width;
                   2489: 	    }
                   2490: 	    if ($max_nested_width > $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column]) {
                   2491: 		$Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column] = $max_nested_width;
                   2492: 	    }
                   2493: 
1.127     sakharuk 2494: 	    pop @Apache::londefdef::table;
1.129     sakharuk 2495: 	    push @{$Apache::londefdef::table[-1]{'include'}}, $inmemory;
1.127     sakharuk 2496: 	} else {
                   2497: 	    $currentstring .= $Apache::londefdef::table[-1]{'output'};
                   2498: 	    pop @Apache::londefdef::table;
1.143     sakharuk 2499: 	    undef @Apache::londefdef::table;
1.127     sakharuk 2500: 	}
1.122     albertel 2501:     }
                   2502:     return $currentstring;
                   2503: }
                   2504: 
1.166     sakharuk 2505: #-- <tr> tag (end tag optional)
1.122     albertel 2506: sub start_tr {
                   2507:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   2508:     my $currentstring = '';
1.325     albertel 2509:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 2510: 	$currentstring = $token->[4];     
                   2511:     } elsif ($target eq 'tex') {
                   2512: 	$Apache::londefdef::table[-1]{'row_number'}++;
1.206     sakharuk 2513: 	my $alignchar=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
1.122     albertel 2514: 	if ($alignchar ne '') {
1.206     sakharuk 2515: 	    push @ {$Apache::londefdef::table[-1]{'rows'} },substr($alignchar,0,1);
1.122     albertel 2516: 	} else {
                   2517: 	    push @ {$Apache::londefdef::table[-1]{'rows'} }, 'l';
                   2518: 	}
                   2519: 	push ( @{ $Apache::londefdef::table[-1]{'rowdata'} }, $Apache::londefdef::table[-1]{'hinc'});
1.300     foxr     2520: 	#
                   2521: 	#  Need to save the number of table columns to preserve the max # columns.
                   2522: 	#
                   2523: 	$Apache::londefdef::table[-1]{'prior_columns'}   = $Apache::londefdef::table[-1]{'counter_columns'};
1.122     albertel 2524: 	$Apache::londefdef::table[-1]{'counter_columns'} = -1;
1.206     sakharuk 2525: 	push @ {$Apache::londefdef::table[-1]{'TeXlen'}}, [];
                   2526: 	push @ {$Apache::londefdef::table[-1]{'objectlen'}}, [];
                   2527: 	push @ {$Apache::londefdef::table[-1]{'minlen'}}, [];
                   2528: 	push @ {$Apache::londefdef::table[-1]{'maxlen'}}, [];
                   2529: 	push @ {$Apache::londefdef::table[-1]{'content'}}, [];
1.122     albertel 2530:     } 
                   2531:     return $currentstring;
                   2532: }
                   2533:         
                   2534: sub end_tr {
1.160     sakharuk 2535:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr     2536:     my $currentstring = &end_p();	# Close any pending <p> in the row.
1.325     albertel 2537:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     2538: 	$currentstring .= $token->[2];     
1.122     albertel 2539:     } elsif ($target eq 'tex') {
1.160     sakharuk 2540: 	if ($Apache::londefdef::TD_redirection) {
                   2541: 	    &end_td_tex($parstack,$parser,$safeeval);    
                   2542: 	}
1.300     foxr     2543: 	# Counter columns must be the maximum number of columns seen
                   2544: 	# in the table so far so:
                   2545: 	if ($Apache::londefdef::table[-1]{'prior_columns'} > $Apache::londefdef::table[-1]{'counter_columns'}) {
                   2546: 	    $Apache::londefdef::table[-1]{'counter_columns'} = $Apache::londefdef::table[-1]{'prior_columns'};
                   2547: 	}
1.295     foxr     2548: 
                   2549: 
1.294     foxr     2550: 	
1.122     albertel 2551:     }
                   2552:     return $currentstring;
                   2553: }
                   2554: 
1.166     sakharuk 2555: #-- <td> tag (end tag optional)
1.122     albertel 2556: sub start_td {
                   2557:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   2558:     my $currentstring = '';
1.325     albertel 2559:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 2560: 	$currentstring = $token->[4];     
                   2561:     } elsif ($target eq 'tex') {
1.160     sakharuk 2562: 	$Apache::londefdef::TD_redirection = 1;
1.159     sakharuk 2563: 	&tag_check('tr','td',$tagstack,$parstack,$parser,$safeeval);
1.122     albertel 2564:     } 
                   2565:     return $currentstring;
                   2566: }   
1.159     sakharuk 2567:     
                   2568: sub tag_check {
                   2569:     my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
1.160     sakharuk 2570:     my @ar=@$parstack; 
                   2571:     for (my $i=$#ar-1;$i>=0;$i--) {
                   2572: 	if (lc($$tagstack[$i]) eq $good_tag) {
                   2573: 	    &start_td_tex($parstack,$parser,$safeeval);
                   2574: 	    last;
                   2575: 	} elsif (lc($$tagstack[$i]) eq $bad_tag) {
                   2576: 	    splice @ar, $i+1;
                   2577: 	    &end_td_tex(\@ar,$parser,$safeeval);
                   2578: 	    &start_td_tex($parstack,$parser,$safeeval);
                   2579: 	    last;
1.159     sakharuk 2580: 	}
1.160     sakharuk 2581:     }
1.159     sakharuk 2582:     return '';
                   2583: }
                   2584:  
                   2585: sub start_td_tex {
                   2586:     my ($parstack,$parser,$safeeval) = @_;
1.206     sakharuk 2587:     my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
                   2588:     if ($alignchar eq '') {
                   2589: 	$alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
1.159     sakharuk 2590:     }
1.206     sakharuk 2591:     push @{ $Apache::londefdef::table[-1]{'align'}[$Apache::londefdef::table[-1]{'row_number'}] }, $alignchar;
1.159     sakharuk 2592:     $Apache::londefdef::table[-1]{'counter_columns'}++;
1.206     sakharuk 2593:     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
                   2594:     if (defined $TeXwidth) {		
                   2595: 	my $current_length=&recalc($TeXwidth);
                   2596: 	$current_length=~/(\d+\.?\d*)/;
                   2597: 	push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
                   2598:     }
1.159     sakharuk 2599:     &Apache::lonxml::startredirection();
                   2600:     return '';
                   2601: }
                   2602: 
                   2603: sub end_td_tex {
                   2604:     my ($parstack,$parser,$safeeval) = @_;
1.304     foxr     2605:     my $current_row    = $Apache::londefdef::table[-1]{'row_number'};
                   2606:     my $current_column = $Apache::londefdef::table[-1]{'counter_columns'}; 
1.303     foxr     2607:     my $data = &Apache::lonxml::endredirection();
                   2608: 
1.305     foxr     2609:     #  The rowspan array of the table indicates which cells are part of a span.
                   2610:     #  n indicates the start of a span set of n rows.
                   2611:     #  ^ indicates a cell that continues a span set.
1.306     foxr     2612:     #  _ indicates the cell is at the bottom of a span set.
1.305     foxr     2613:     #  If this and subsequent cells are part of a rowspan, we must
                   2614:     #  push along the row until we find one that is not.
                   2615: 
                   2616:     while ((defined $Apache::londefdef::table[-1]{'rowspan'}[$current_row] [$current_column]) 
1.306     foxr     2617: 	   && ($Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column] =~ /[\^\_]/)) {
1.305     foxr     2618: 	# Part of a span.
                   2619: 	push @ {$Apache::londefdef::table[-1]{'content'}[-1]}, '';
                   2620: 	$current_column++;
                   2621:     }
                   2622:     $Apache::londefdef::table[-1]{'counter_columns'} = $current_column;
                   2623:    
                   2624: 
1.320     foxr     2625:     # Get the column and row spans.
                   2626:     # Colspan can be done via \multicolumn if I can figure out the data structs.
                   2627: 
                   2628:     my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 0);
                   2629:     if (!$colspan) {
                   2630: 	$colspan = 1;
                   2631:     }
1.305     foxr     2632: 
                   2633:     my $rowspan = &Apache::lonxml::get_param('rowspan', $parstack, $safeeval, undef, 0);
                   2634:     if (!$rowspan) {
                   2635: 	$rowspan = 1;
                   2636:     }
                   2637: 
1.303     foxr     2638: 
1.305     foxr     2639: 
1.320     foxr     2640:     for (my $c = 0; $c < $colspan; $c++) {
                   2641: 	$Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column+$c] = $rowspan;
                   2642: 	for (my $i = 1; $i < $rowspan; $i++) {
                   2643: 	    $Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column+$c] = '^';
                   2644: 	    if ($i == ($rowspan-1)) {
                   2645: 		$Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column+$c] = '_';
                   2646: 	    }
1.306     foxr     2647: 	}
1.305     foxr     2648:     }
1.304     foxr     2649: 
1.159     sakharuk 2650:     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
                   2651:     if (defined $TeXwidth) {		
1.357     foxr     2652: 	for (my $c = 0; $c < $colspan; $c++) {
                   2653: 	    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2654: 	    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2655: 	    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2656: 	}
1.159     sakharuk 2657:     } else {
1.206     sakharuk 2658: 	if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {
                   2659: 	    my $garbage_data=$data;
                   2660: 	    my $fwidth=0;
                   2661:             while ($garbage_data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
                   2662: 		my $current_length=&recalc($1);
                   2663: 		$current_length=~/(\d+\.?\d*)/;
                   2664: 		if ($fwidth<$1) {$fwidth=$1;}
                   2665: 		$garbage_data=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
                   2666: 	    }
                   2667:             while ($garbage_data=~m/\[(\d+\.?\d*)\s*mm\]/) {
                   2668: 		my $current_length=$1;
                   2669: 		if ($fwidth<$current_length) {$fwidth=$current_length;}
                   2670: 		$garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;
                   2671: 	    }
1.357     foxr     2672: 	    for (my $c = 0; $c < $colspan; $c++) {
                   2673: 		push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2674: 		push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
                   2675: 		push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2676: 		push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2677: 	    }
1.231     sakharuk 2678: 	} 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)*/) {
                   2679: 	    my $garbage_data=$data;
                   2680: 	    my $fwidth=0;
                   2681:             while ($garbage_data=~/\\parbox\{\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)\s*\}/) {
                   2682: 		my $current_length=&recalc($1);
                   2683: 		$current_length=~/(\d+\.?\d*)/;
                   2684: 		if ($fwidth<$1) {$fwidth=$1;}
                   2685: 		$garbage_data=~s/\\parbox\{\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
                   2686: 	    }
                   2687:             while ($garbage_data=~/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
                   2688: 		my $current_length=&recalc($1);
                   2689: 		$current_length=~/(\d+\.?\d*)/;
                   2690: 		if ($fwidth<$1) {$fwidth=$1;}
                   2691: 		$garbage_data=~s/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
                   2692: 	    }
1.357     foxr     2693: 	    for (my $c = 0; $c < $colspan; $c++) {
                   2694: 		push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2695: 		push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
                   2696: 		push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2697: 		push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2698: 	    }
1.231     sakharuk 2699: 	    $data=~s/\\\\\s*$//; 
1.159     sakharuk 2700: 	} else {  
1.166     sakharuk 2701: 	    $data=~s/^\s+(\S.*)/$1/; 
1.159     sakharuk 2702: 	    $data=~s/(.*\S)\s+$/$1/;
1.166     sakharuk 2703: 	    $data=~s/(\s)+/$1/;
1.206     sakharuk 2704: 	    my ($current_length,$min_length)=(0,0);
1.166     sakharuk 2705: 	    if ($data=~/\\vskip/) {
                   2706:                 my $newdata=$data;
                   2707: 		$newdata=~s/\\vskip \d*\.?\d*\s*mm/THISISJUSTTEMPORARYSEPARATOR/g;
                   2708: 		my @newdata=split(/THISISJUSTTEMPORARYSEPARATOR/,$newdata);
                   2709: 		foreach my $elementdata (@newdata) {
1.206     sakharuk 2710: 		    my $lengthnewdata=2.5*&LATEX_length($elementdata);
1.166     sakharuk 2711: 		    if ($lengthnewdata>$current_length) {$current_length=$lengthnewdata;}
1.206     sakharuk 2712:                     my @words=split(/ /,$elementdata);
                   2713: 		    foreach my $word (@words) {
                   2714: 			my $lengthword=2.5*&LATEX_length($word);
                   2715: 			if ($min_length<$lengthword) {$min_length=$lengthword;}
                   2716: 		    }
1.166     sakharuk 2717: 		}
                   2718: 	    } else {
1.206     sakharuk 2719: 		$current_length=2.5*&LATEX_length($data);
                   2720:                     my @words=split(/ /,$data);
                   2721: 		    foreach my $word (@words) {
1.228     sakharuk 2722: 			my $lengthword=2*&LATEX_length($word);
1.206     sakharuk 2723: 			if ($min_length<$lengthword) {$min_length=$lengthword;}
                   2724: 		    }
1.166     sakharuk 2725: 	    }
1.357     foxr     2726: 	    for (my $c = 0; $c < $colspan; $c++) {
                   2727: 		push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2728: 		push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2729: 		push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
                   2730: 		push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
                   2731: 	    }
1.159     sakharuk 2732: 	}        
                   2733:     }
1.302     foxr     2734:     # Substitute all of the tables nested in this cell in their appropriate places.
                   2735: 
                   2736: 
                   2737:     my $nested_count = $#{$Apache::londefdef::table[-1]{'include'}}; # This one is constant...
                   2738:     for (my $in=0; $in<=$nested_count; $in++) {    
1.301     foxr     2739: 	my $nested = shift @{$Apache::londefdef::table[-1]{'include'}};
                   2740: 	$nested =~ s/\\end\{tabular\}\\strut\\\\/\\end\{tabular\}/;
                   2741: 	# $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
                   2742: 	$data =~ s/\\keephidden\{NEW TABLE ENTRY\}/$nested/;
                   2743: 
                   2744:     }
                   2745:     # Should be be killing off the 'include' elements as they're used up?
1.305     foxr     2746: 
1.206     sakharuk 2747:     push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
1.305     foxr     2748: 
1.304     foxr     2749: 
                   2750: 
                   2751: 
                   2752:     #  the colspan array will indicate how many columns will be spanned by this
                   2753:     #  cell..this requires that counter_columns also be adjusted accordingly
                   2754:     #  so that the next bunch of text goes in the right cell.  Note that since
                   2755:     #  counter_columns is incremented in the start_td_tex, we adjust by colspan-1.
                   2756:     #
                   2757: 
                   2758:     $Apache::londefdef::table[-1]{'counter_columns'} += $colspan -1;
                   2759:     for (my $i = 0; $i < ($colspan -1); $i++) {
                   2760: 	push @ {$Apache::londefdef::table[-1]{'content'}[-1] },'';
                   2761:     }
1.320     foxr     2762:     for (my $r = 0; $r < $rowspan; $r++) {
                   2763: 	$Apache::londefdef::table[-1]{'colspan'}[$current_row+$r][$current_column] = $colspan;
                   2764: 	# Put empty text in spanned cols.
                   2765: 	
                   2766:     }
                   2767: 
1.304     foxr     2768: 
                   2769: 
1.301     foxr     2770:     return '';
1.159     sakharuk 2771: }
                   2772: 
1.122     albertel 2773: sub end_td {
1.126     sakharuk 2774:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 2775:     my $currentstring = '';
1.325     albertel 2776:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 2777: 	$currentstring = $token->[2];     
                   2778:     } elsif ($target eq 'tex') {
1.160     sakharuk 2779:         $Apache::londefdef::TD_redirection =0;
1.159     sakharuk 2780: 	&end_td_tex($parstack,$parser,$safeeval);
1.122     albertel 2781:     }
                   2782:     return $currentstring;
                   2783: }
                   2784: 
1.166     sakharuk 2785: #-- <th> tag (end tag optional)
1.122     albertel 2786: sub start_th {
                   2787:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   2788:     my $currentstring = '';
1.325     albertel 2789:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 2790: 	$currentstring = $token->[4];     
                   2791:     } elsif ($target eq 'tex') {
1.230     sakharuk 2792: 	$Apache::londefdef::TD_redirection = 1;
                   2793: 	&tagg_check('tr','th',$tagstack,$parstack,$parser,$safeeval);
1.122     albertel 2794:     } 
                   2795:     return $currentstring;
1.130     sakharuk 2796: }   
1.230     sakharuk 2797:     
                   2798: sub tagg_check {
                   2799:     my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_;
                   2800:     my @ar=@$parstack; 
                   2801:     for (my $i=$#ar-1;$i>=0;$i--) {
                   2802: 	if (lc($$tagstack[$i]) eq $good_tag) {
                   2803: 	    &start_th_tex($parstack,$parser,$safeeval);
                   2804: 	    last;
                   2805: 	} elsif (lc($$tagstack[$i]) eq $bad_tag) {
                   2806: 	    splice @ar, $i+1;
                   2807: 	    &end_th_tex(\@ar,$parser,$safeeval);
                   2808: 	    &start_th_tex($parstack,$parser,$safeeval);
                   2809: 	    last;
                   2810: 	}
                   2811:     }
                   2812:     return '';
                   2813: }
                   2814:  
                   2815: sub start_th_tex {
                   2816:     my ($parstack,$parser,$safeeval) = @_;
                   2817:     my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1);
                   2818:     if ($alignchar eq '') {
                   2819: 	$alignchar = $Apache::londefdef::table[-1]{'rows'}[-1];
                   2820:     }
                   2821:     push @{ $Apache::londefdef::table[-1]{'align'}[$Apache::londefdef::table[-1]{'row_number'}] }, $alignchar;
                   2822:     $Apache::londefdef::table[-1]{'counter_columns'}++;
                   2823:     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
                   2824:     if (defined $TeXwidth) {		
                   2825: 	my $current_length=&recalc($TeXwidth);
                   2826: 	$current_length=~/(\d+\.?\d*)/;
                   2827: 	push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1;
                   2828:     }
                   2829:     &Apache::lonxml::startredirection();
                   2830:     return '';
                   2831: }
                   2832: 
                   2833: sub end_th_tex {
                   2834:     my ($parstack,$parser,$safeeval) = @_;
                   2835:     my $current_row = $Apache::londefdef::table[-1]{'row_number'};
                   2836:     my $data=&Apache::lonxml::endredirection();
                   2837:     my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
                   2838:     if (defined $TeXwidth) {		
                   2839: 	push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2840: 	push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2841: 	push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2842:     } else {
                   2843: 	if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) {
                   2844: 	    my $garbage_data=$data;
                   2845: 	    my $fwidth=0;
                   2846:             while ($garbage_data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) {
                   2847: 		my $current_length=&recalc($1);
                   2848: 		$current_length=~/(\d+\.?\d*)/;
                   2849: 		if ($fwidth<$1) {$fwidth=$1;}
                   2850: 		$garbage_data=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//;
                   2851: 	    }
                   2852:             while ($garbage_data=~m/\[(\d+\.?\d*)\s*mm\]/) {
                   2853: 		my $current_length=$1;
                   2854: 		if ($fwidth<$current_length) {$fwidth=$current_length;}
                   2855: 		$garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//;
                   2856: 	    }
                   2857: 	    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2858: 	    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth;
                   2859: 	    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2860: 	    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2861: 	} else {  
                   2862: 	    $data=~s/^\s+(\S.*)/$1/; 
                   2863: 	    $data=~s/(.*\S)\s+$/$1/;
                   2864: 	    $data=~s/(\s)+/$1/;
                   2865: 	    my ($current_length,$min_length)=(0,0);
                   2866: 	    if ($data=~/\\vskip/) {
                   2867:                 my $newdata=$data;
                   2868: 		$newdata=~s/\\vskip \d*\.?\d*\s*mm/THISISJUSTTEMPORARYSEPARATOR/g;
                   2869: 		my @newdata=split(/THISISJUSTTEMPORARYSEPARATOR/,$newdata);
                   2870: 		foreach my $elementdata (@newdata) {
                   2871: 		    my $lengthnewdata=2.5*&LATEX_length($elementdata);
                   2872: 		    if ($lengthnewdata>$current_length) {$current_length=$lengthnewdata;}
                   2873:                     my @words=split(/ /,$elementdata);
                   2874: 		    foreach my $word (@words) {
                   2875: 			my $lengthword=2.5*&LATEX_length($word);
                   2876: 			if ($min_length<$lengthword) {$min_length=$lengthword;}
                   2877: 		    }
                   2878: 		}
                   2879: 	    } else {
                   2880: 		$current_length=2.5*&LATEX_length($data);
                   2881:                     my @words=split(/ /,$data);
                   2882: 		    foreach my $word (@words) {
                   2883: 			my $lengthword=2*&LATEX_length($word);
                   2884: 			if ($min_length<$lengthword) {$min_length=$lengthword;}
                   2885: 		    }
                   2886: 	    }
                   2887: 	    push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2888: 	    push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0';
                   2889: 	    push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length;
                   2890: 	    push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length;
                   2891: 	}        
                   2892:     }
                   2893: 	for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) {         
                   2894: 	    $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/;
                   2895: 	}
                   2896:     #make data bold
                   2897:     $data='\textbf{'.$data.'}';
                   2898:     push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
                   2899:     return'';
                   2900: }
                   2901: 
1.122     albertel 2902: sub end_th {
1.130     sakharuk 2903:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr     2904:     my $currentstring = &end_p();	# Close any open <p> in the row.
1.325     albertel 2905:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     2906: 	$currentstring .= $token->[2];     
1.122     albertel 2907:     } elsif ($target eq 'tex') {
1.230     sakharuk 2908:         $Apache::londefdef::TD_redirection =0;
                   2909: 	&end_th_tex($parstack,$parser,$safeeval);
1.122     albertel 2910:     }
                   2911:     return $currentstring;
                   2912: }
1.230     sakharuk 2913:      
1.181     sakharuk 2914: #-- <img> tag (end tag forbidden)
1.249     foxr     2915: #
                   2916: #  Render the <IMG> tag.
                   2917: #     <IMG> has the following attributes (in addition to the 
                   2918: #     standard HTML ones:
                   2919: #      TeXwrap   - Governs how the tex target will try to wrap text around
                   2920: #                  horizontally aligned images.
                   2921: #      TeXwidth  - The width of the image when rendered for print (mm).
                   2922: #      TeXheight - The height of the image when rendered for print (mm)
                   2923: #         (Note there seems to also be support for this as a % of page size)
                   2924: #      
1.122     albertel 2925: sub start_img {
1.299     albertel 2926:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
1.122     albertel 2927:     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,
                   2928: 					 undef,1);
1.325     albertel 2929:     if (! $src && 
                   2930: 	($target eq 'web' || $target eq 'webgrade' || $target eq 'tex')
                   2931: 	) { 
1.299     albertel 2932: 	my $inside = &Apache::lonxml::get_all_text("/img",$parser,$style);
1.189     albertel 2933: 	return '';
                   2934:     }
1.290     albertel 2935:     &Apache::lonxml::extlink($src);
1.122     albertel 2936:     my $currentstring = '';
                   2937:     my $scaling = .3;
1.249     foxr     2938: 
                   2939:    # Render unto browsers that which are the browser's...
                   2940: 
1.325     albertel 2941:     if ($target eq 'web' || $target eq 'webgrade') {
1.267     albertel 2942: 	if ($env{'browser.imagesuppress'} ne 'on') {
1.322     albertel 2943: 	    my $enc = ('yes' eq 
                   2944: 		       lc(&Apache::lonxml::get_param('encrypturl',$parstack,
                   2945: 						     $safeeval)));
                   2946: 	    $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src},
                   2947: 							 $enc);
1.122     albertel 2948: 	} else {
1.322     albertel 2949: 	    my $alttag = &Apache::lonxml::get_param('alt',$parstack,$safeeval,
                   2950: 						    undef,1);
                   2951: 	    if (!$alttag) {
                   2952: 		$alttag = &Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],
                   2953: 						   $src);
1.51      sakharuk 2954: 	    }
1.158     sakharuk 2955: 	    $currentstring.='[IMAGE: '.$alttag.']';
1.1       sakharuk 2956: 	}
1.249     foxr     2957: 
                   2958: 	# and render unto TeX that which is LaTeX
                   2959: 
1.122     albertel 2960:     } elsif ($target eq 'tex') {
1.248     foxr     2961: 	#
                   2962: 	#  The alignment will require some superstructure to be put around
                   2963: 	#  the \includegraphics stuff.  At present we can only partially
                   2964: 	#  simulate the alignments offered by html.
                   2965: 	#
                   2966: 	#
                   2967: 	my $align = lc(&Apache::lonxml::get_param('align', 
                   2968: 						  $parstack,
                   2969: 						  $safeeval,
                   2970: 						  undef,1));
                   2971: 	if(!$align) {
1.287     foxr     2972: 		$align = "bottom";	# This is html's default so it's ours too.
1.248     foxr     2973: 	}
                   2974: 	#
                   2975: 	&Apache::lonxml::debug("Alignemnt = $align");
                   2976: 	#  LaTeX's image/text wrapping is really bad since it wants to
                   2977: 	#  make figures float.  
                   2978:         #   The user has the optional parameter (applicable only to l/r
                   2979: 	# alignment to use the picins/parpic directive to get wrapped text
                   2980: 	# this is also imperfect.. that's why we give them a choice...
                   2981: 	# so they can't yell at us for our choice.
                   2982: 	#
                   2983: 	my $latex_rendering = &Apache::lonxml::get_param('TeXwrap',
                   2984: 							    $parstack,
                   2985: 							    $safeeval,
                   2986: 							    undef,0);
1.312     foxr     2987: 	# &Apache::lonxml::debug("LaTeX rendering = $latex_rendering");
1.248     foxr     2988: 	if(!$latex_rendering) {
1.312     foxr     2989: 		$latex_rendering = "texwrap";
                   2990: 	}
                   2991: 	# using texwrap inside a table does not work. So, if after all of this,
                   2992: 	# texwrap is on, we turn it off if we detect we're in a table:
                   2993: 	#
                   2994: 	if (($latex_rendering eq 'texwrap') && &is_inside_of($tagstack, "table")) {
                   2995: 	    $latex_rendering = 'parpic';
1.248     foxr     2996: 	}
1.323     foxr     2997: 
1.312     foxr     2998: 	# &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src");
1.248     foxr     2999: 
1.256     albertel 3000: 	#if original gif/jpg/png file exist do following:
1.266     albertel 3001: 	my $origsrc=$src;
1.256     albertel 3002: 	my ($path,$file) = &get_eps_image($src);
1.341     foxr     3003: 	# &Apache::lonnet::logthis("Image source: $src result: $path $file");
1.122     albertel 3004: 	$src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
1.261     foxr     3005: 	&Apache::lonxml::debug("path = $path file = $file src = $src");
1.192     sakharuk 3006: 	if (-e $src) {
1.261     foxr     3007: 	    &Apache::lonxml::debug("$src exists");
1.256     albertel 3008: 	    my ($height_param,$width_param)=
1.266     albertel 3009: 		&image_size($origsrc,0.3,$parstack,$safeeval);
                   3010: 	    my $size;
                   3011: 	    if ($width_param)  { $size.='width='.$width_param.' mm,'; }
                   3012: 	    if ($height_param) { $size.='height='.$height_param.' mm]'; }
1.341     foxr     3013: 	    # Default size if not able to extract that (e.g. eps image).
                   3014: 	    
                   3015: 	    # &Apache::lonnet::logthis("Size = $size");
                   3016: 	    
1.266     albertel 3017: 	    $size='['.$size;
                   3018: 	    $size=~s/,$/]/; 
1.344     albertel 3019: 	    $currentstring .= '\graphicspath{{'.$path.'}}'
                   3020: 		.'\includegraphics'.$size.'{'.$file.'} ';
1.354     foxr     3021: 	    my $closure;
                   3022: 	    ($currentstring, $closure) = &align_latex_image($align, 
                   3023: 							    $latex_rendering, 
                   3024: 							    $currentstring, 
                   3025: 							    $width_param, 
                   3026: 							    $height_param);
                   3027: 	    $currentstring .= $closure;
1.353     foxr     3028: 						
1.122     albertel 3029: 	} else {
1.261     foxr     3030: 	    &Apache::lonxml::debug("$src does not exist");
1.122     albertel 3031: 	    #original image file doesn't exist so check the alt attribute
                   3032: 	    my $alt = 
                   3033: 		&Apache::lonxml::get_param('alt',$parstack,$safeeval,undef,1);
                   3034: 	    unless ($alt) {
                   3035: 		$alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);
                   3036: 	    }
                   3037: 
1.256     albertel 3038: 	    if ($alt) { $currentstring .= ' '.$alt.' '; }
1.59      sakharuk 3039: 	}
1.249     foxr     3040: 
                   3041: 	# And here's where the semi-quote breaks down: allow the user
                   3042:         # to edit the beast as well by rendering the problem for edit:
1.186     albertel 3043:     } elsif ($target eq 'edit') {
1.368     banghart 3044:         my $only = join(',',&Apache::loncommon::filecategorytypes('Pictures'));
1.186     albertel 3045: 	$currentstring .=&Apache::edit::tag_start($target,$token);
                   3046: 	$currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70).
1.368     banghart 3047: 	    &Apache::edit::browse('src',undef,'alt',$only).' '.
1.186     albertel 3048: 	    &Apache::edit::search('src',undef,'alt').'<br />';
                   3049: 	$currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />';
                   3050: 	$currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5);
                   3051: 	$currentstring .=&Apache::edit::text_arg('height (pixel):','height',$token,5).'<br />';
                   3052: 	$currentstring .=&Apache::edit::text_arg('TeXwidth (mm):','TeXwidth',$token,5);
                   3053: 	$currentstring .=&Apache::edit::text_arg('TeXheight (mm):','TeXheight',$token,5);
1.234     albertel 3054: 	$currentstring .=&Apache::edit::select_arg('Alignment:','align',
                   3055: 						   ['','bottom','middle','top','left','right'],$token,5);
1.249     foxr     3056: 	$currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',
1.348     albertel 3057: 						   ['', 'none','parbox', 'parpic', 'wrapfigure'], $token, 2);
1.332     www      3058: 	$currentstring .=&Apache::edit::select_arg('Encrypt URL:','encrypturl',
1.322     albertel 3059: 						   ['no','yes'], $token, 2);
1.186     albertel 3060: 	$currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
1.249     foxr     3061: 	my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);
                   3062: 	my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);
                   3063: 	my $width=  &Apache::lonxml::get_param('width',$parstack,$safeeval);
                   3064: 	my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);
                   3065: 
1.381   ! www      3066:         if ($token->[2]{'src'}=~/\$/) {
        !          3067:            $currentstring.='Variable image source';
        !          3068:         } else {
        !          3069: 	   $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" ';
        !          3070: 	   if ($width) { $currentstring.=' width="'.$width.'" '; }
        !          3071: 	   if ($height) { $currentstring.=' height="'.$height.'" '; }
        !          3072: 	   $currentstring .= ' />';
        !          3073:         }
1.186     albertel 3074:     } elsif ($target eq 'modified') {
1.210     albertel 3075: 	my ($osrc,$owidth,$oheight)=
                   3076: 	    ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
                   3077: 	my $ctag=&Apache::edit::get_new_args($token,$parstack,
1.234     albertel 3078: 					     $safeeval,'src','alt','align',
1.249     foxr     3079: 					     'TeXwidth','TeXheight', 'TeXwrap',
1.322     albertel 3080: 					     'width','height','encrypturl');
1.210     albertel 3081: 	my ($nsrc,$nwidth,$nheight)=
                   3082: 	    ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
                   3083: 	my $loc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$nsrc);
                   3084: 	&image_replication($loc);
                   3085: 	my ($iwidth,$iheight);
                   3086: 	if (-e $loc) {
                   3087: 	    my $image = Image::Magick->new;
                   3088: 	    $image->Read($loc);
                   3089: 	    ($iwidth, $iheight) = ($image->Get('width'),
                   3090: 				   $image->Get('height'));
                   3091: 	}
                   3092: 	if ($osrc ne $nsrc || (!$nwidth && !$nheight)) {
                   3093: 	    # changed image or no size specified,
                   3094:             # if they didn't explicitly change the 
                   3095:             # width or height use the ones from the image
                   3096: 	    if ($iwidth && $iheight) {
                   3097: 		if ($owidth == $nwidth || (!$nwidth && !$nheight)) {
                   3098: 		    $token->[2]{'width'} = $iwidth;$ctag=1;
                   3099: 		}
                   3100: 		if ($oheight == $nheight || (!$nwidth && !$nheight)) {
                   3101: 		    $token->[2]{'height'}=$iheight;$ctag=1;
1.186     albertel 3102: 		}
                   3103: 	    }
                   3104: 	}
1.210     albertel 3105: 	my ($cwidth,$cheight)=($token->[2]{'width'},$token->[2]{'height'});
                   3106: 	# if we don't have a width or height
                   3107: 	if ($iwidth && $cwidth && !$cheight) {
                   3108: 	    $token->[2]{'height'}=int(($cwidth/$iwidth)*$iheight);$ctag=1;
                   3109: 	}
                   3110: 	if ($iheight && $cheight && !$cwidth) {
                   3111: 	    $token->[2]{'width'}=int(($cheight/$iheight)*$iwidth);$ctag=1;
                   3112: 	}
                   3113: 	if ($ctag) {$currentstring=&Apache::edit::rebuild_tag($token);}
1.122     albertel 3114:     }
1.261     foxr     3115: 
1.122     albertel 3116:     return $currentstring;
                   3117: }
                   3118: 
                   3119: sub end_img {
                   3120:     my ($target,$token) = @_;
                   3121:     my $currentstring = '';
1.325     albertel 3122:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3123: 	$currentstring = $token->[2];
                   3124:     } elsif ($target eq 'tex') {
                   3125: 	$currentstring = '';
                   3126:     }
                   3127:     return $currentstring;
                   3128: }
                   3129: 
1.181     sakharuk 3130: #-- <applet> tag (end tag required)
1.122     albertel 3131: sub start_applet {
                   3132:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   3133:     
                   3134:     my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,undef,1);
1.290     albertel 3135:     &Apache::lonxml::extlink($code);
1.122     albertel 3136:     my $archive=&Apache::lonxml::get_param('archive',$parstack,$safeeval,
                   3137: 					   undef,1);
1.290     albertel 3138:     &Apache::lonxml::extlink($archive);
1.122     albertel 3139:     my $currentstring = '';
1.325     albertel 3140:     if ($target eq 'web' || $target eq 'webgrade') {
1.267     albertel 3141: 	if ($env{'browser.appletsuppress'} ne 'on') {
1.250     albertel 3142: 	    $currentstring = &Apache::lonenc::encrypt_ref($token,
                   3143: 							  {'code'=>$code,
                   3144: 							   'archive'=>$archive}
                   3145: 							  );
1.122     albertel 3146: 	} else {
                   3147: 	    my $alttag= &Apache::lonxml::get_param('alt',$parstack,
                   3148: 						   $safeeval,undef,1);
                   3149: 	    unless ($alttag) {
                   3150: 		$alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],
                   3151: 						 $code);
1.44      sakharuk 3152: 	    }
1.122     albertel 3153: 	    $currentstring='[APPLET: '.$alttag.']';
1.1       sakharuk 3154: 	}
1.122     albertel 3155:     } elsif ($target eq 'tex') {
1.361     foxr     3156: 	# Turn off some stuff we can't be inside thank you LaTeX
                   3157: 	
                   3158: 
                   3159: 	my $restart_sub = 0;
                   3160: 	my $restart_sup = 0;
                   3161: 
                   3162: 	# Since <sub> and <sup> are simple tags it's ok to turn off/on
                   3163: 	# using the start_ stop_ functions.. those tags only care about
                   3164: 	# $target.
                   3165: 
                   3166: 	if (&is_inside_of($tagstack, "sub")) {
                   3167: 	    $restart_sub = 1;
                   3168: 	    $currentstring .= &end_sub($target, $token, $tagstack, 
                   3169: 				       $parstack, $parser, $safeeval);
                   3170: 	}
                   3171: 	if (&is_inside_of($tagstack, "sup")) {
                   3172: 	    $restart_sup = 1;
                   3173: 	    $currentstring .= &end_sup($target, $token, $tagstack,
                   3174: 				       $parstack, $parser, $safeeval);
                   3175: 	}
                   3176: 
                   3177: 	# Now process the applet; just replace it with its alt attribute.
                   3178: 
1.177     albertel 3179: 	my $alttag= &Apache::lonxml::get_param('alt',$parstack,
                   3180: 					       $safeeval,undef,1);
                   3181: 	unless ($alttag) {
                   3182: 	    my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,
                   3183: 						undef,1);
                   3184: 	    $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],
                   3185: 					     $code);
1.175     sakharuk 3186: 	}
1.177     albertel 3187: 	$currentstring.='\begin{center} \fbox{Java Applet: '.$alttag.
                   3188: 	    '.}\end{center}';
1.361     foxr     3189: 
                   3190: 	# Turn stuff back on that we can't be inside of.
                   3191: 
                   3192: 	if ($restart_sub) {
                   3193: 	    $currentstring .= &start_sub($target, $token, $tagstack,
                   3194: 					$parstack, $parser, $safeeval);
                   3195: 	}
                   3196: 	if ($restart_sup) {
                   3197: 	    $currentstring .= &start_sup($target, $token, $tagstack,
                   3198: 					 $parstack, $parser, $safeeval);
                   3199: 	}
1.122     albertel 3200:     } 
                   3201:     return $currentstring;
                   3202: }
                   3203: 
                   3204: sub end_applet {
                   3205:     my ($target,$token) = @_;
                   3206:     my $currentstring = '';
1.325     albertel 3207:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3208: 	$currentstring = $token->[2];
                   3209:     } elsif ($target eq 'tex') {
                   3210:     } 
                   3211:     return $currentstring;
                   3212: }
                   3213: 
1.181     sakharuk 3214: #-- <embed> tag (end tag optional/required)
1.122     albertel 3215: sub start_embed {    
                   3216:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   3217:     my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
1.290     albertel 3218:     &Apache::lonxml::extlink($src);
1.122     albertel 3219:     my $currentstring = '';
1.325     albertel 3220:     if ($target eq 'web' || $target eq 'webgrade') {
1.267     albertel 3221: 	if ($env{'browser.embedsuppress'} ne 'on') {
1.250     albertel 3222: 	    $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});
1.122     albertel 3223: 	} else {
                   3224: 	    my $alttag=&Apache::lonxml::get_param
                   3225: 		('alt',$parstack,$safeeval,undef,1);
                   3226: 	    unless ($alttag) {
                   3227: 		$alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src);
1.42      albertel 3228: 	    }
1.122     albertel 3229: 	    $currentstring='[EMBED: '.$alttag.']';
1.10      www      3230: 	}
1.122     albertel 3231:     } elsif ($target eq 'tex') {
                   3232:     } 
                   3233:     return $currentstring;
                   3234: }
                   3235: 
                   3236: sub end_embed {
                   3237:     my ($target,$token) = @_;
                   3238:     my $currentstring = '';
1.325     albertel 3239:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3240: 	$currentstring = $token->[2];     
1.175     sakharuk 3241:     } elsif ($target eq 'tex') {  
1.122     albertel 3242:     } 
                   3243:     return $currentstring;
                   3244: }
                   3245: 
1.181     sakharuk 3246: #-- <param> tag (end tag forbidden)
1.122     albertel 3247: sub start_param {
                   3248:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.290     albertel 3249:     if (&Apache::lonxml::get_param('name',$parstack,
                   3250: 				   $safeeval,undef,1)=~/^cabbase$/i) {
                   3251: 	my $value=&Apache::lonxml::get_param('value',$parstack,
                   3252: 					     $safeeval,undef,1);
                   3253: 	&Apache::lonxml::extlink($value);
                   3254:     } 
                   3255:   
                   3256:     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
                   3257:     &Apache::lonxml::extlink($src);
1.122     albertel 3258:     my $currentstring = '';
1.325     albertel 3259:     if ($target eq 'web' || $target eq 'webgrade') {
1.250     albertel 3260: 	my %toconvert;
                   3261: 	my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
                   3262: 	if ($src) { $toconvert{'src'}= $src; }
                   3263: 	my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval,
                   3264: 					    undef,1);
1.251     albertel 3265: 	if ($name=~/^cabbase$/i) {
                   3266: 	    $toconvert{'value'}=&Apache::lonxml::get_param('value',$parstack,
                   3267: 							   $safeeval,undef,1);
                   3268: 	}
1.250     albertel 3269: 	$currentstring = &Apache::lonenc::encrypt_ref($token,\%toconvert);
1.122     albertel 3270:     } elsif ($target eq 'tex') {
                   3271:     } 
                   3272:     return $currentstring;
                   3273: }
                   3274: 
                   3275: sub end_param {
                   3276:     my ($target,$token) = @_;
                   3277:     my $currentstring = '';
1.325     albertel 3278:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3279: 	$currentstring = $token->[2];     
                   3280:     } elsif ($target eq 'tex') {
                   3281:     } 
                   3282:     return $currentstring;
                   3283: }
                   3284: 
                   3285: #-- <allow> tag
                   3286: sub start_allow {
                   3287:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   3288:     my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
1.290     albertel 3289:     &Apache::lonxml::extlink($src);
                   3290: 
1.241     albertel 3291:     if ($target eq 'tex') { &image_replication($src); }
1.122     albertel 3292:     my $result;
                   3293:     if ($target eq 'edit') {
                   3294: 	$result .=&Apache::edit::tag_start($target,$token);
                   3295: 	$result .=&Apache::edit::text_arg('File Spec:','src',$token,70);
                   3296: 	$result .=&Apache::edit::end_row();#.&Apache::edit::start_spanning_row();
                   3297:     } elsif ($target eq 'modified') {
                   3298: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                   3299: 						     $safeeval,'src');
                   3300: 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
                   3301:     }
                   3302:     return $result;
                   3303: }
                   3304: 
                   3305: sub end_allow {
                   3306:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   3307:     if ( $target eq 'edit') { return (&Apache::edit::end_table()); }
                   3308:     return '';
                   3309: }
1.119     www      3310: 
1.181     sakharuk 3311: #-- Frames (end tag required)
                   3312: #-- <frameset>
1.122     albertel 3313: sub start_frameset {
                   3314:     my ($target,$token) = @_;
1.277     foxr     3315:     my $currentstring = '';	# Close any pending para.
1.325     albertel 3316:     if ($target eq 'web' || $target eq 'webgrade') { 
1.328     albertel 3317: 	$currentstring = 
                   3318: 	    &Apache::loncommon::start_page($Apache::londefdef::title,
                   3319: 					   $Apache::londefdef::head,
                   3320: 					   {'add_entries'    => $token->[2],
                   3321: 					    'no_title'       => 1,
                   3322: 					    'force_register' => 1,
                   3323: 					    'frameset'       => 1,});
                   3324: 
1.122     albertel 3325:     }
                   3326:     return $currentstring;
                   3327: }
                   3328: 
                   3329: sub end_frameset {
                   3330:     my ($target,$token) = @_;
                   3331:     my $currentstring = '';
1.325     albertel 3332:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3333: 	$currentstring = $token->[2];
                   3334:     }
                   3335:     return $currentstring;
                   3336: }
1.162     sakharuk 3337: 
1.181     sakharuk 3338: #-- <xmp> (end tag required)
1.162     sakharuk 3339: sub start_xmp {
                   3340:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   3341:     my $currentstring = '';
1.325     albertel 3342:     if ($target eq 'web' || $target eq 'webgrade') {
1.162     sakharuk 3343: 	$currentstring .= $token->[4];
                   3344:     } elsif ($target eq 'tex') {
                   3345: 	$currentstring .= '\begin{verbatim}';
                   3346:     } 
                   3347:     return $currentstring;
                   3348: }
                   3349: 
                   3350: sub end_xmp {
                   3351:     my ($target,$token) = @_;
                   3352:     my $currentstring = '';
1.325     albertel 3353:     if ($target eq 'web' || $target eq 'webgrade') {
1.162     sakharuk 3354: 	$currentstring .= $token->[2];
                   3355:     } elsif ($target eq 'tex') {
                   3356: 	$currentstring .= '\end{verbatim}';
                   3357:     }
                   3358:     return $currentstring;
                   3359: }
                   3360: 
1.181     sakharuk 3361: #-- <pre> (end tag required)
1.122     albertel 3362: sub start_pre {
1.126     sakharuk 3363:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr     3364:     my $currentstring = &end_p();	# close off pending <p>
1.325     albertel 3365:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3366: 	$currentstring .= $token->[4];
                   3367:     } elsif ($target eq 'tex') {
1.136     sakharuk 3368: 	$currentstring .= '\begin{verbatim}';
1.319     albertel 3369: 	&Apache::lonxml::disable_LaTeX_substitutions();
1.122     albertel 3370:     } 
                   3371:     return $currentstring;
                   3372: }
                   3373: 
                   3374: sub end_pre {
                   3375:     my ($target,$token) = @_;
                   3376:     my $currentstring = '';
1.325     albertel 3377:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3378: 	$currentstring .= $token->[2];
                   3379:     } elsif ($target eq 'tex') {
1.136     sakharuk 3380: 	$currentstring .= '\end{verbatim}';
1.319     albertel 3381: 	&Apache::lonxml::enable_LaTeX_substitutions();
1.122     albertel 3382:     }
                   3383:     return $currentstring;
                   3384: }
                   3385: 
                   3386: #-- <insert>
                   3387: sub start_insert {
                   3388:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   3389:     my $currentstring = '';
1.325     albertel 3390:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3391: 	my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1);
                   3392: 	$currentstring .= '<b>'.$display.'</b>';;
                   3393:     }
                   3394:     return $currentstring;
                   3395: }
                   3396: 
                   3397: sub end_insert {
                   3398:     my ($target,$token) = @_;
                   3399:     my $currentstring = '';
1.325     albertel 3400:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3401: 	$currentstring .= '';
                   3402:     }
                   3403:     return $currentstring;
                   3404: }
                   3405: 
                   3406: #-- <externallink>
                   3407: sub start_externallink {
                   3408:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
                   3409:     my $currentstring = '';
1.325     albertel 3410:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3411: 	my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1);
                   3412: 	$currentstring .= '<b>'.$display.'</b>';;
                   3413:     }
                   3414:     return $currentstring;
                   3415: }
                   3416: 
                   3417: sub end_externallink {
                   3418:     my ($target,$token) = @_;
                   3419:     my $currentstring = '';
1.325     albertel 3420:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3421: 	$currentstring .= '';
                   3422:     }
                   3423:     return $currentstring;
                   3424: }
                   3425: 
                   3426: #-- <blankspace heigth="">
                   3427: sub start_blankspace {
                   3428:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.279     foxr     3429:     my $currentstring = &end_p();	# closes off any unclosed <p>
1.122     albertel 3430:     if ($target eq 'tex') {
                   3431: 	my $howmuch = &Apache::lonxml::get_param('heigth',$parstack,$safeeval,undef,1);
                   3432: 	$currentstring .= '\vskip '.$howmuch.' ';
                   3433:     }
                   3434:     return $currentstring;
                   3435: }
                   3436: 
                   3437: sub end_blankspace {
                   3438:     my ($target,$token) = @_;
                   3439:     my $currentstring = '';
                   3440:     if ($target eq 'tex') {
                   3441: 	$currentstring .= '';
                   3442:     }
                   3443:     return $currentstring;
                   3444: }
                   3445: 
1.181     sakharuk 3446: #-- <abbr> tag (end tag required)
1.122     albertel 3447: sub start_abbr {
                   3448:     my ($target,$token) = @_;
                   3449:     my $currentstring = '';
1.325     albertel 3450:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3451: 	$currentstring = $token->[4];     
                   3452:     } 
                   3453:     return $currentstring;
                   3454: }
                   3455: 
                   3456: sub end_abbr {
                   3457:     my ($target,$token) = @_;
                   3458:     my $currentstring = '';
1.325     albertel 3459:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3460: 	$currentstring = $token->[2];    
                   3461:     } 
                   3462:     return $currentstring;
                   3463: }
                   3464: 
1.181     sakharuk 3465: #-- <acronym> tag (end tag required)
1.122     albertel 3466: sub start_acronym {
                   3467:     my ($target,$token) = @_;
                   3468:     my $currentstring = '';
1.325     albertel 3469:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3470: 	$currentstring = $token->[4];     
                   3471:     } 
                   3472:     return $currentstring;
                   3473: }
                   3474: 
                   3475: sub end_acronym {
                   3476:     my ($target,$token) = @_;
                   3477:     my $currentstring = '';
1.325     albertel 3478:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3479: 	$currentstring = $token->[2];    
                   3480:     } 
                   3481:     return $currentstring;
                   3482: }
                   3483: 
1.181     sakharuk 3484: #-- <area> tag (end tag forbidden)
1.122     albertel 3485: sub start_area {
                   3486:     my ($target,$token) = @_;
                   3487:     my $currentstring = '';
1.325     albertel 3488:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3489: 	$currentstring = $token->[4];     
                   3490:     } 
                   3491:     return $currentstring;
                   3492: }
                   3493: 
                   3494: sub end_area {
                   3495:     my ($target,$token) = @_;
                   3496:     my $currentstring = '';
1.325     albertel 3497:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3498: 	$currentstring = $token->[2];    
                   3499:     } 
                   3500:     return $currentstring;
                   3501: }
                   3502: 
1.181     sakharuk 3503: #-- <base> tag (end tag forbidden)
1.122     albertel 3504: sub start_base {
                   3505:     my ($target,$token) = @_;
                   3506:     my $currentstring = '';
1.325     albertel 3507:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3508: 	$currentstring = $token->[4];     
1.161     sakharuk 3509:     }
1.122     albertel 3510:     return $currentstring;
                   3511: }
                   3512: 
                   3513: sub end_base {
                   3514:     my ($target,$token) = @_;
                   3515:     my $currentstring = '';
1.325     albertel 3516:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3517: 	$currentstring = $token->[2];    
                   3518:     } 
                   3519:     return $currentstring;
                   3520: }
                   3521: 
1.181     sakharuk 3522: #-- <bdo> tag (end tag required)
1.122     albertel 3523: sub start_bdo {
                   3524:     my ($target,$token) = @_;
                   3525:     my $currentstring = '';
1.325     albertel 3526:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3527: 	$currentstring = $token->[4];     
                   3528:     } 
                   3529:     return $currentstring;
                   3530: }
                   3531: 
                   3532: sub end_bdo {
                   3533:     my ($target,$token) = @_;
                   3534:     my $currentstring = '';
1.325     albertel 3535:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3536: 	$currentstring = $token->[2];    
                   3537:     } 
                   3538:     return $currentstring;
                   3539: }
                   3540: 
1.181     sakharuk 3541: #-- <bgsound> tag (end tag optional)
1.122     albertel 3542: sub start_bgsound {
                   3543:     my ($target,$token) = @_;
                   3544:     my $currentstring = '';
1.325     albertel 3545:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3546: 	$currentstring = $token->[4];     
                   3547:     } 
                   3548:     return $currentstring;
                   3549: }
                   3550: 
                   3551: sub end_bgsound {
                   3552:     my ($target,$token) = @_;
                   3553:     my $currentstring = '';
1.325     albertel 3554:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3555: 	$currentstring = $token->[2];    
                   3556:     } 
                   3557:     return $currentstring;
                   3558: }
                   3559: 
1.181     sakharuk 3560: #-- <blink> tag (end tag required)
1.122     albertel 3561: sub start_blink {
                   3562:     my ($target,$token) = @_;
                   3563:     my $currentstring = '';
1.325     albertel 3564:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3565: 	$currentstring = $token->[4];     
                   3566:     } 
                   3567:     return $currentstring;
                   3568: }
                   3569: 
                   3570: sub end_blink {
                   3571:     my ($target,$token) = @_;
                   3572:     my $currentstring = '';
1.325     albertel 3573:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3574: 	$currentstring = $token->[2];    
                   3575:     } 
                   3576:     return $currentstring;
                   3577: }
                   3578: 
1.181     sakharuk 3579: #-- <blockquote> tag (end tag required)
1.122     albertel 3580: sub start_blockquote {
                   3581:     my ($target,$token) = @_;
1.279     foxr     3582:     my $currentstring = &end_p();	# Close any unclosed <p>
1.325     albertel 3583:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     3584: 	$currentstring .= $token->[4];     
1.122     albertel 3585:     } 
1.339     foxr     3586:     if ($target eq 'tex') {
                   3587: 	$currentstring .= '\begin{quote}';
                   3588:     }
1.122     albertel 3589:     return $currentstring;
                   3590: }
                   3591: 
                   3592: sub end_blockquote {
                   3593:     my ($target,$token) = @_;
                   3594:     my $currentstring = '';
1.325     albertel 3595:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3596: 	$currentstring = $token->[2];    
                   3597:     } 
1.339     foxr     3598:     if ($target eq 'tex') {
                   3599: 	$currentstring = '\end{quote}';
                   3600:     }
1.122     albertel 3601:     return $currentstring;
                   3602: }
                   3603: 
1.181     sakharuk 3604: #-- <button> tag (end tag required)
1.122     albertel 3605: sub start_button {
                   3606:     my ($target,$token) = @_;
                   3607:     my $currentstring = '';
1.325     albertel 3608:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3609: 	$currentstring = $token->[4];     
                   3610:     } 
                   3611:     return $currentstring;
                   3612: }
                   3613: 
                   3614: sub end_button {
                   3615:     my ($target,$token) = @_;
                   3616:     my $currentstring = '';
1.325     albertel 3617:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3618: 	$currentstring = $token->[2];    
                   3619:     } 
                   3620:     return $currentstring;
                   3621: }
                   3622: 
1.181     sakharuk 3623: #-- <caption> tag (end tag required)
1.122     albertel 3624: sub start_caption {
                   3625:     my ($target,$token) = @_;
                   3626:     my $currentstring = '';
1.325     albertel 3627:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3628: 	$currentstring = $token->[4];     
                   3629:     } 
                   3630:     return $currentstring;
                   3631: }
                   3632: 
                   3633: sub end_caption {
                   3634:     my ($target,$token) = @_;
                   3635:     my $currentstring = '';
1.325     albertel 3636:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3637: 	$currentstring = $token->[2];    
                   3638:     } 
                   3639:     return $currentstring;
                   3640: }
                   3641: 
1.181     sakharuk 3642: #-- <col> tag (end tag forbdden)
1.122     albertel 3643: sub start_col {
                   3644:     my ($target,$token) = @_;
                   3645:     my $currentstring = '';
1.325     albertel 3646:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3647: 	$currentstring = $token->[4];     
                   3648:     } 
                   3649:     return $currentstring;
                   3650: }
                   3651: 
                   3652: sub end_col {
                   3653:     my ($target,$token) = @_;
                   3654:     my $currentstring = '';
1.325     albertel 3655:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3656: 	$currentstring = $token->[2];    
                   3657:     } 
                   3658:     return $currentstring;
                   3659: }
                   3660: 
1.181     sakharuk 3661: #-- <colgroup> tag (end tag optional)
1.122     albertel 3662: sub start_colgroup {
                   3663:     my ($target,$token) = @_;
                   3664:     my $currentstring = '';
1.325     albertel 3665:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3666: 	$currentstring = $token->[4];     
                   3667:     } 
                   3668:     return $currentstring;
                   3669: }
                   3670: 
                   3671: sub end_colgroup {
                   3672:     my ($target,$token) = @_;
                   3673:     my $currentstring = '';
1.325     albertel 3674:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3675: 	$currentstring = $token->[2];    
                   3676:     } 
                   3677:     return $currentstring;
                   3678: }
                   3679: 
1.181     sakharuk 3680: #-- <del> tag (end tag required)
1.122     albertel 3681: sub start_del {
                   3682:     my ($target,$token) = @_;
                   3683:     my $currentstring = '';
1.325     albertel 3684:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3685: 	$currentstring = $token->[4];     
                   3686:     } 
                   3687:     return $currentstring;
                   3688: }
                   3689: 
                   3690: sub end_del {
                   3691:     my ($target,$token) = @_;
                   3692:     my $currentstring = '';
1.325     albertel 3693:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3694: 	$currentstring = $token->[2];    
                   3695:     } 
                   3696:     return $currentstring;
                   3697: }
                   3698: 
1.181     sakharuk 3699: #-- <fieldset> tag (end tag required)
1.122     albertel 3700: sub start_fieldset {
                   3701:     my ($target,$token) = @_;
                   3702:     my $currentstring = '';
1.325     albertel 3703:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3704: 	$currentstring = $token->[4];     
                   3705:     } 
                   3706:     return $currentstring;
                   3707: }
                   3708: 
                   3709: sub end_fieldset {
                   3710:     my ($target,$token) = @_;
                   3711:     my $currentstring = '';
1.325     albertel 3712:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3713: 	$currentstring = $token->[2];    
                   3714:     } 
                   3715:     return $currentstring;
                   3716: }
                   3717: 
1.181     sakharuk 3718: #-- <frame> tag (end tag forbidden)
1.122     albertel 3719: sub start_frame {
                   3720:     my ($target,$token) = @_;
                   3721:     my $currentstring = '';
1.325     albertel 3722:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3723: 	$currentstring = $token->[4];     
                   3724:     } 
                   3725:     return $currentstring;
                   3726: }
                   3727: 
                   3728: sub end_frame {
                   3729:     my ($target,$token) = @_;
                   3730:     my $currentstring = '';
1.325     albertel 3731:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3732: 	$currentstring = $token->[2];    
                   3733:     } 
                   3734:     return $currentstring;
                   3735: }
                   3736: 
1.181     sakharuk 3737: #-- <iframe> tag (end tag required)
1.122     albertel 3738: sub start_iframe {
                   3739:     my ($target,$token) = @_;
                   3740:     my $currentstring = '';
1.325     albertel 3741:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3742: 	$currentstring = $token->[4];     
                   3743:     } 
                   3744:     return $currentstring;
                   3745: }
                   3746: 
                   3747: sub end_iframe {
                   3748:     my ($target,$token) = @_;
                   3749:     my $currentstring = '';
1.325     albertel 3750:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3751: 	$currentstring = $token->[2];    
                   3752:     } 
                   3753:     return $currentstring;
                   3754: }
                   3755: 
1.181     sakharuk 3756: #-- <ins> tag (end tag required)
1.122     albertel 3757: sub start_ins {
                   3758:     my ($target,$token) = @_;
                   3759:     my $currentstring = '';
1.325     albertel 3760:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3761: 	$currentstring = $token->[4];     
                   3762:     } 
                   3763:     return $currentstring;
                   3764: }
                   3765: 
                   3766: sub end_ins {
                   3767:     my ($target,$token) = @_;
                   3768:     my $currentstring = '';
1.325     albertel 3769:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3770: 	$currentstring = $token->[2];    
                   3771:     } 
                   3772:     return $currentstring;
                   3773: }
                   3774: 
1.181     sakharuk 3775: #-- <isindex> tag (end tag forbidden)
1.122     albertel 3776: sub start_isindex {
                   3777:     my ($target,$token) = @_;
                   3778:     my $currentstring = '';
1.325     albertel 3779:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3780: 	$currentstring = $token->[4];     
                   3781:     } 
                   3782:     return $currentstring;
                   3783: }
                   3784: 
                   3785: sub end_isindex {
                   3786:     my ($target,$token) = @_;
                   3787:     my $currentstring = '';
1.325     albertel 3788:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3789: 	$currentstring = $token->[2];    
                   3790:     } 
                   3791:     return $currentstring;
                   3792: }
                   3793: 
1.181     sakharuk 3794: #-- <keygen> tag (end tag forbidden)
1.122     albertel 3795: sub start_keygen {
                   3796:     my ($target,$token) = @_;
                   3797:     my $currentstring = '';
1.325     albertel 3798:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3799: 	$currentstring = $token->[4];     
                   3800:     } 
                   3801:     return $currentstring;
                   3802: }
                   3803: 
                   3804: sub end_keygen {
                   3805:     my ($target,$token) = @_;
                   3806:     my $currentstring = '';
1.325     albertel 3807:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3808: 	$currentstring = $token->[2];    
                   3809:     } 
                   3810:     return $currentstring;
                   3811: }
                   3812: 
                   3813: #-- <label> tag
                   3814: sub start_label {
                   3815:     my ($target,$token) = @_;
                   3816:     my $currentstring = '';
1.325     albertel 3817:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3818: 	$currentstring = $token->[4];     
                   3819:     } 
                   3820:     return $currentstring;
                   3821: }
                   3822: 
                   3823: sub end_label {
                   3824:     my ($target,$token) = @_;
                   3825:     my $currentstring = '';
1.325     albertel 3826:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3827: 	$currentstring = $token->[2];    
                   3828:     } 
                   3829:     return $currentstring;
                   3830: }
                   3831: 
1.181     sakharuk 3832: #-- <layer> tag (end tag required)
1.122     albertel 3833: sub start_layer {
                   3834:     my ($target,$token) = @_;
                   3835:     my $currentstring = '';
1.325     albertel 3836:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3837: 	$currentstring = $token->[4];     
                   3838:     } 
                   3839:     return $currentstring;
                   3840: }
                   3841: 
                   3842: sub end_layer {
                   3843:     my ($target,$token) = @_;
                   3844:     my $currentstring = '';
1.325     albertel 3845:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3846: 	$currentstring = $token->[2];    
                   3847:     } 
                   3848:     return $currentstring;
                   3849: }
                   3850: 
1.181     sakharuk 3851: #-- <legend> tag (end tag required)
1.122     albertel 3852: sub start_legend {
                   3853:     my ($target,$token) = @_;
                   3854:     my $currentstring = '';
1.325     albertel 3855:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3856: 	$currentstring = $token->[4];     
                   3857:     } 
                   3858:     return $currentstring;
                   3859: }
                   3860: 
                   3861: sub end_legend {
                   3862:     my ($target,$token) = @_;
                   3863:     my $currentstring = '';
1.325     albertel 3864:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3865: 	$currentstring = $token->[2];    
                   3866:     } 
                   3867:     return $currentstring;
                   3868: }
                   3869: 
1.181     sakharuk 3870: #-- <link> tag (end tag forbidden)
1.122     albertel 3871: sub start_link {
1.292     albertel 3872:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
1.122     albertel 3873:     my $currentstring = '';
1.324     albertel 3874:     if ($target eq 'web' || $target eq 'webgrade') {
1.291     albertel 3875: 	my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
                   3876: 					    undef,1);
                   3877: 	&Apache::lonxml::extlink($href);
1.122     albertel 3878: 	$currentstring = $token->[4];     
                   3879:     } 
                   3880:     return $currentstring;
                   3881: }
                   3882: 
                   3883: sub end_link {
                   3884:     my ($target,$token) = @_;
                   3885:     my $currentstring = '';
1.325     albertel 3886:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3887: 	$currentstring = $token->[2];    
                   3888:     } 
                   3889:     return $currentstring;
                   3890: }
                   3891: 
1.181     sakharuk 3892: #-- <marquee> tag (end tag optional)
1.122     albertel 3893: sub start_marquee {
                   3894:     my ($target,$token) = @_;
                   3895:     my $currentstring = '';
1.325     albertel 3896:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3897: 	$currentstring = $token->[4];     
                   3898:     } 
                   3899:     return $currentstring;
                   3900: }
                   3901: 
                   3902: sub end_marquee {
                   3903:     my ($target,$token) = @_;
                   3904:     my $currentstring = '';
1.325     albertel 3905:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3906: 	$currentstring = $token->[2];    
                   3907:     } 
                   3908:     return $currentstring;
                   3909: }
                   3910: 
1.179     sakharuk 3911: #-- <multicol> tag (end tag required)
                   3912: sub start_multicol {
1.122     albertel 3913:     my ($target,$token) = @_;
1.279     foxr     3914:     my $currentstring = &end_p();	# Close any pending <p>
1.325     albertel 3915:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     3916: 	$currentstring .= $token->[4];     
1.122     albertel 3917:     } 
                   3918:     return $currentstring;
                   3919: }
                   3920: 
1.179     sakharuk 3921: sub end_multicol {
1.122     albertel 3922:     my ($target,$token) = @_;
                   3923:     my $currentstring = '';
1.325     albertel 3924:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3925: 	$currentstring = $token->[2];    
                   3926:     } 
                   3927:     return $currentstring;
                   3928: }
                   3929: 
1.179     sakharuk 3930: #-- <nobr> tag (end tag required)
1.122     albertel 3931: sub start_nobr {
                   3932:     my ($target,$token) = @_;
                   3933:     my $currentstring = '';
1.325     albertel 3934:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3935: 	$currentstring = $token->[4];     
1.179     sakharuk 3936:     }  elsif ($target eq 'tex') {
                   3937: 	$currentstring='\mbox{';
                   3938:     }
1.122     albertel 3939:     return $currentstring;
                   3940: }
                   3941: 
                   3942: sub end_nobr {
                   3943:     my ($target,$token) = @_;
                   3944:     my $currentstring = '';
1.325     albertel 3945:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3946: 	$currentstring = $token->[2];    
1.179     sakharuk 3947:     }   elsif ($target eq 'tex') {
                   3948: 	$currentstring='}';
                   3949:     }
1.122     albertel 3950:     return $currentstring;
                   3951: }
                   3952: 
1.179     sakharuk 3953: #-- <noembed> tag (end tag required)
1.122     albertel 3954: sub start_noembed {
                   3955:     my ($target,$token) = @_;
                   3956:     my $currentstring = '';
1.325     albertel 3957:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3958: 	$currentstring = $token->[4];     
                   3959:     } 
                   3960:     return $currentstring;
                   3961: }
                   3962: 
                   3963: sub end_noembed {
                   3964:     my ($target,$token) = @_;
                   3965:     my $currentstring = '';
1.325     albertel 3966:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3967: 	$currentstring = $token->[2];    
                   3968:     } 
                   3969:     return $currentstring;
                   3970: }
                   3971: 
1.179     sakharuk 3972: #-- <noframes> tag (end tag required)
1.122     albertel 3973: sub start_noframes {
                   3974:     my ($target,$token) = @_;
                   3975:     my $currentstring = '';
1.325     albertel 3976:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3977: 	$currentstring = $token->[4];     
                   3978:     } 
                   3979:     return $currentstring;
                   3980: }
                   3981: 
                   3982: sub end_noframes {
                   3983:     my ($target,$token) = @_;
                   3984:     my $currentstring = '';
1.325     albertel 3985:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3986: 	$currentstring = $token->[2];    
                   3987:     } 
                   3988:     return $currentstring;
                   3989: }
                   3990: 
1.179     sakharuk 3991: #-- <nolayer> tag (end tag required)
1.122     albertel 3992: sub start_nolayer {
                   3993:     my ($target,$token) = @_;
                   3994:     my $currentstring = '';
1.325     albertel 3995:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 3996: 	$currentstring = $token->[4];     
                   3997:     } 
                   3998:     return $currentstring;
                   3999: }
                   4000: 
                   4001: sub end_nolayer {
                   4002:     my ($target,$token) = @_;
                   4003:     my $currentstring = '';
1.325     albertel 4004:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4005: 	$currentstring = $token->[2];    
                   4006:     } 
                   4007:     return $currentstring;
                   4008: }
                   4009: 
1.179     sakharuk 4010: #-- <noscript> tag (end tag required)
1.122     albertel 4011: sub start_noscript {
                   4012:     my ($target,$token) = @_;
                   4013:     my $currentstring = '';
1.325     albertel 4014:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4015: 	$currentstring = $token->[4];     
                   4016:     } 
                   4017:     return $currentstring;
                   4018: }
                   4019: 
                   4020: sub end_noscript {
                   4021:     my ($target,$token) = @_;
                   4022:     my $currentstring = '';
1.325     albertel 4023:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4024: 	$currentstring = $token->[2];    
                   4025:     } 
                   4026:     return $currentstring;
                   4027: }
                   4028: 
1.179     sakharuk 4029: #-- <object> tag (end tag required)
1.122     albertel 4030: sub start_object {
                   4031:     my ($target,$token) = @_;
                   4032:     my $currentstring = '';
1.325     albertel 4033:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4034: 	$currentstring = $token->[4];     
                   4035:     } 
                   4036:     return $currentstring;
                   4037: }
                   4038: 
                   4039: sub end_object {
                   4040:     my ($target,$token) = @_;
                   4041:     my $currentstring = '';
1.325     albertel 4042:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4043: 	$currentstring = $token->[2];    
                   4044:     } 
                   4045:     return $currentstring;
                   4046: }
                   4047: 
1.179     sakharuk 4048: #-- <optgroup> tag (end tag required)
1.122     albertel 4049: sub start_optgroup {
                   4050:     my ($target,$token) = @_;
                   4051:     my $currentstring = '';
1.325     albertel 4052:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4053: 	$currentstring = $token->[4];     
                   4054:     } 
                   4055:     return $currentstring;
                   4056: }
                   4057: 
                   4058: sub end_optgroup {
                   4059:     my ($target,$token) = @_;
                   4060:     my $currentstring = '';
1.325     albertel 4061:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4062: 	$currentstring = $token->[2];    
                   4063:     } 
                   4064:     return $currentstring;
                   4065: }
                   4066: 
1.179     sakharuk 4067: #-- <samp> tag (end tag required)
1.122     albertel 4068: sub start_samp {
                   4069:     my ($target,$token) = @_;
                   4070:     my $currentstring = '';
1.325     albertel 4071:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4072: 	$currentstring = $token->[4];     
1.179     sakharuk 4073:     } elsif ($target eq 'tex') {
                   4074: 	$currentstring='\texttt{';
                   4075:     }
1.122     albertel 4076:     return $currentstring;
                   4077: }
                   4078: 
                   4079: sub end_samp {
                   4080:     my ($target,$token) = @_;
                   4081:     my $currentstring = '';
1.325     albertel 4082:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4083: 	$currentstring = $token->[2];    
1.179     sakharuk 4084:     } elsif ($target eq 'tex') {
                   4085: 	$currentstring='}';
                   4086:     }
1.122     albertel 4087:     return $currentstring;
                   4088: }
                   4089: 
                   4090: #-- <server> tag
                   4091: sub start_server {
                   4092:     my ($target,$token) = @_;
                   4093:     my $currentstring = '';
1.325     albertel 4094:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4095: 	$currentstring = $token->[4];     
                   4096:     } 
                   4097:     return $currentstring;
                   4098: }
                   4099: 
                   4100: sub end_server {
                   4101:     my ($target,$token) = @_;
                   4102:     my $currentstring = '';
1.325     albertel 4103:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4104: 	$currentstring = $token->[2];    
                   4105:     } 
                   4106:     return $currentstring;
                   4107: }
                   4108: 
1.179     sakharuk 4109: #-- <spacer> tag (end tag forbidden)
1.122     albertel 4110: sub start_spacer {
                   4111:     my ($target,$token) = @_;
1.279     foxr     4112:     my $currentstring = &end_p();	# Close off any open <p> tag.
1.325     albertel 4113:     if ($target eq 'web' || $target eq 'webgrade') {
1.277     foxr     4114: 	$currentstring .= $token->[4];     
1.122     albertel 4115:     } 
                   4116:     return $currentstring;
                   4117: }
                   4118: 
                   4119: sub end_spacer {
                   4120:     my ($target,$token) = @_;
                   4121:     my $currentstring = '';
1.325     albertel 4122:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4123: 	$currentstring = $token->[2];    
                   4124:     } 
                   4125:     return $currentstring;
                   4126: }
                   4127: 
1.179     sakharuk 4128: #-- <span> tag (end tag required)
1.122     albertel 4129: sub start_span {
                   4130:     my ($target,$token) = @_;
                   4131:     my $currentstring = '';
1.325     albertel 4132:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4133: 	$currentstring = $token->[4];     
                   4134:     } 
                   4135:     return $currentstring;
                   4136: }
                   4137: 
                   4138: sub end_span {
                   4139:     my ($target,$token) = @_;
                   4140:     my $currentstring = '';
1.325     albertel 4141:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4142: 	$currentstring = $token->[2];    
                   4143:     } 
                   4144:     return $currentstring;
                   4145: }
                   4146: 
1.179     sakharuk 4147: #-- <tbody> tag (end tag optional)
1.122     albertel 4148: sub start_tbody {
                   4149:     my ($target,$token) = @_;
                   4150:     my $currentstring = '';
1.325     albertel 4151:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4152: 	$currentstring = $token->[4];     
                   4153:     } 
                   4154:     return $currentstring;
                   4155: }
                   4156: 
                   4157: sub end_tbody {
                   4158:     my ($target,$token) = @_;
                   4159:     my $currentstring = '';
1.325     albertel 4160:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4161: 	$currentstring = $token->[2];    
                   4162:     } 
                   4163:     return $currentstring;
                   4164: }
                   4165: 
1.166     sakharuk 4166: #-- <tfoot> tag (end tag optional)
1.122     albertel 4167: sub start_tfoot {
                   4168:     my ($target,$token) = @_;
                   4169:     my $currentstring = '';
1.325     albertel 4170:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4171: 	$currentstring = $token->[4];     
                   4172:     } 
                   4173:     return $currentstring;
                   4174: }
                   4175: 
                   4176: sub end_tfoot {
                   4177:     my ($target,$token) = @_;
                   4178:     my $currentstring = '';
1.325     albertel 4179:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4180: 	$currentstring = $token->[2];    
                   4181:     } 
                   4182:     return $currentstring;
                   4183: }
                   4184: 
1.166     sakharuk 4185: #-- <thead> tag (end tag optional)
1.122     albertel 4186: sub start_thead {
                   4187:     my ($target,$token) = @_;
                   4188:     my $currentstring = '';
1.325     albertel 4189:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4190: 	$currentstring = $token->[4];     
                   4191:     } 
                   4192:     return $currentstring;
                   4193: }
1.10      www      4194: 
1.122     albertel 4195: sub end_thead {
                   4196:     my ($target,$token) = @_;
                   4197:     my $currentstring = '';
1.325     albertel 4198:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4199: 	$currentstring = $token->[2];    
                   4200:     } 
                   4201:     return $currentstring;
                   4202: }
1.119     www      4203: 
1.122     albertel 4204: #-- <var> tag
                   4205: sub start_var {
1.44      sakharuk 4206:     my ($target,$token) = @_;
                   4207:     my $currentstring = '';
1.325     albertel 4208:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4209: 	$currentstring = $token->[4];     
1.163     sakharuk 4210:     } elsif ($target eq 'tex') {
                   4211: 	$currentstring = '\textit{'; 
                   4212:     }
1.44      sakharuk 4213:     return $currentstring;
                   4214: }
1.10      www      4215: 
1.122     albertel 4216: sub end_var {
                   4217:     my ($target,$token) = @_;
1.44      sakharuk 4218:     my $currentstring = '';
1.325     albertel 4219:     if ($target eq 'web' || $target eq 'webgrade') {
1.163     sakharuk 4220: 	$currentstring = $token->[2];
                   4221:     } elsif ($target eq 'tex') {
                   4222: 	$currentstring = '}'; 
1.44      sakharuk 4223:     } 
                   4224:     return $currentstring;
                   4225: }
1.119     www      4226: 
1.163     sakharuk 4227: #-- <wbr> tag (end tag forbidden)
1.122     albertel 4228: sub start_wbr {
                   4229:     my ($target,$token) = @_;
                   4230:     my $currentstring = '';
1.325     albertel 4231:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4232: 	$currentstring = $token->[4];     
                   4233:     } 
                   4234:     return $currentstring;
1.98      albertel 4235: }
                   4236: 
1.122     albertel 4237: sub end_wbr {
                   4238:     my ($target,$token) = @_;
                   4239:     my $currentstring = '';
1.325     albertel 4240:     if ($target eq 'web' || $target eq 'webgrade') {
1.122     albertel 4241: 	$currentstring = $token->[2];    
                   4242:     } 
                   4243:     return $currentstring;
1.98      albertel 4244: }
1.134     sakharuk 4245: 
                   4246: #-- <hideweboutput> tag
                   4247: sub start_hideweboutput {
                   4248:     my ($target,$token) = @_;
1.325     albertel 4249:     if ($target eq 'web' || $target eq 'webgrade') {
1.134     sakharuk 4250: 	&Apache::lonxml::startredirection();     
                   4251:     } 
                   4252:     return '';
                   4253: }
                   4254: 
                   4255: sub end_hideweboutput {
                   4256:     my ($target,$token) = @_;
                   4257:     my $currentstring = '';
1.325     albertel 4258:     if ($target eq 'web' || $target eq 'webgrade') {
1.134     sakharuk 4259: 	$currentstring = &Apache::lonxml::endredirection();    
                   4260:     } 
                   4261:     return '';
                   4262: }
                   4263: 
1.94      sakharuk 4264: 
                   4265: sub image_replication {
                   4266:     my $src = shift;
1.187     albertel 4267:     if (not -e $src) { &Apache::lonnet::repcopy($src); }
                   4268:     #replicates eps or ps 
                   4269:     my $epssrc = my $pssrc = $src;
                   4270:     $epssrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i;
                   4271:     $pssrc  =~ s/\.(gif|jpg|jpeg|png)$/.ps/i;
                   4272:     if (not -e $epssrc && not -e $pssrc) {
                   4273: 	my $result=&Apache::lonnet::repcopy($epssrc);
1.264     raeburn  4274: 	if ($result ne 'ok') { &Apache::lonnet::repcopy($pssrc); }
1.94      sakharuk 4275:     }
                   4276:     return '';
1.195     sakharuk 4277: }
1.275     foxr     4278: #
                   4279: #   Get correct sizing parameter for an image given
                   4280: #   it's initial ht. and wid.  This allows sizing of
                   4281: #   images that are generated on-the-fly (e.g. gnuplot)
                   4282: #   as well as serving as a utility for image_size.
                   4283: # 
                   4284: #  Parameter:
                   4285: #        height_param
                   4286: #        width_param    - Initial picture dimensions.
                   4287: #        scaling        - A scale factor.
                   4288: #        parstack,      - the current stack of tag attributes 
                   4289: #                         from the xml parser
                   4290: #        safeeval,      - pointer to the safespace
                   4291: #        depth,         - from what level in the stack to look for attributes
                   4292: #                         (assumes -1 if unspecified)
                   4293: #        cis            - look for attrubutes case insensitively
                   4294: #                         (assumes false)
                   4295: #
                   4296: # Returns:
                   4297: #   height, width   - new dimensions.
                   4298: #
                   4299: sub resize_image {
                   4300:     my ($height_param, $width_param, $scaling,
                   4301: 	$parstack, $safeeval, $depth, $cis) = @_;
                   4302: 
                   4303:     # First apply the scaling...
1.271     foxr     4304: 
1.275     foxr     4305:     $height_param = $height_param * $scaling;
                   4306:     $width_param  = $width_param  * $scaling;
1.261     foxr     4307: 
1.197     sakharuk 4308:     #do we have any specified LaTeX size of the picture?
1.261     foxr     4309:     my $toget='TeXwidth'; 
                   4310:     if ($cis) { 
                   4311: 	$toget=lc($toget); 
                   4312:     }
1.256     albertel 4313:     my $TeXwidth = &Apache::lonxml::get_param($toget,$parstack,
                   4314: 					      $safeeval,$depth,$cis);
                   4315:     $toget='TeXheight'; if ($cis) { $toget=lc($toget); }
                   4316:     my $TeXheight = &Apache::lonxml::get_param($toget,$parstack,
                   4317: 					       $safeeval,$depth,$cis);
1.197     sakharuk 4318:     #do we have any specified web size of the picture?
                   4319:     my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval,
1.256     albertel 4320: 					   $depth,1);
                   4321:     if ($TeXwidth) { 
1.252     matthew  4322: 	my $old_width_param=$width_param;
1.197     sakharuk 4323: 	if ($TeXwidth=~/(\d+)\s*\%/) {
1.267     albertel 4324: 	    $width_param = $1*$env{'form.textwidth'}/100;
1.197     sakharuk 4325: 	} else { 
                   4326: 	    $width_param = $TeXwidth;
                   4327: 	}
1.266     albertel 4328: 	if ($TeXheight) {
                   4329: 	    $height_param = $TeXheight;
                   4330: 	} elsif ($old_width_param) {
                   4331: 	    $height_param=$TeXwidth/$old_width_param*$height_param;
                   4332: 	}
1.256     albertel 4333:     } elsif ($TeXheight) {
1.248     foxr     4334: 	$height_param = $TeXheight;
1.266     albertel 4335: 	if ($height_param) {
                   4336: 	    $width_param  = $TeXheight/$height_param*$width_param;
                   4337: 	}
1.256     albertel 4338:     } elsif ($width) {
1.252     matthew  4339: 	my $old_width_param=$width_param;
1.256     albertel 4340: 	$width_param = $width*$scaling;
1.266     albertel 4341: 	if ($old_width_param) {
                   4342: 	    $height_param=$width_param/$old_width_param*$height_param;
                   4343: 	}
1.252     matthew  4344:     }
1.267     albertel 4345:     if ($width_param > $env{'form.textwidth'}) {
1.252     matthew  4346:         my $old_width_param=$width_param;
1.267     albertel 4347: 	$width_param =0.95*$env{'form.textwidth'};
1.266     albertel 4348: 	if ($old_width_param) {
                   4349: 	    $height_param=$width_param/$old_width_param*$height_param;
                   4350: 	}
1.197     sakharuk 4351:     }
1.275     foxr     4352: 
                   4353:     return ($height_param, $width_param);
                   4354: }
                   4355: 
                   4356: sub image_size {
                   4357:     my ($src,$scaling,$parstack,$safeeval,$depth,$cis)=@_;
                   4358: 
                   4359:     #size of image from gif/jpg/jpeg/png 
                   4360:     my $ressrc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
                   4361:     if (-e $ressrc) {
                   4362: 	$src = $ressrc;
                   4363:     }
                   4364:     my $image = Image::Magick->new;
                   4365:     my $current_figure = $image->Read($src);
                   4366:     my $width_param = $image->Get('width');
                   4367:     my $height_param = $image->Get('height');
                   4368:     &Apache::lonxml::debug("Image magick says: $src :  Height = $height_param width = $width_param");
                   4369:     undef($image);
                   4370: 
                   4371:     ($height_param, $width_param) = &resize_image($height_param, $width_param,
                   4372: 						  $scaling, $parstack, $safeeval, 
                   4373: 						  $depth, $cis);
                   4374: 
1.248     foxr     4375:     return ($height_param, $width_param);
                   4376: }
                   4377: 
                   4378: sub image_width {
                   4379:     my ($height, $width) = &image_size(@_);
                   4380:     return $width;
                   4381: }
                   4382: #  Not yet 100% sure this is correct in all circumstances..
                   4383: #  due to my uncertainty about mods to image_size.
                   4384: #
                   4385: sub image_height {
                   4386:     my ($height, $width) = &image_size(@_);
                   4387:     return $height;
1.197     sakharuk 4388: }
                   4389: 
1.256     albertel 4390: sub get_eps_image {
                   4391:     my ($src)=@_;
1.261     foxr     4392:     my $orig_src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1], $src);
1.285     foxr     4393: 
                   4394:     # In order to prevent the substitution of the alt text, we need to
                   4395:     # be sure the orig_src file is on system now so:
                   4396: 
                   4397:     if (! -e $orig_src) {
                   4398: 	&Apache::lonnet::repcopy($orig_src); # Failure is not completely fatal.
                   4399:     }
1.275     foxr     4400:     &Apache::lonxml::debug("get_eps_image: Original image: $orig_src");
1.344     albertel 4401:     my ($spath, $sname, $sext) = &fileparse($src, qr/\.(gif|png|jpg|jpeg)/i);
1.256     albertel 4402:     $src=~s/\.(gif|png|jpg|jpeg)$/\.eps/i;
                   4403:     $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
1.275     foxr     4404:     &Apache::lonxml::debug("Filelocation gives: $src");
1.256     albertel 4405:     if (! -e $src) {
1.261     foxr     4406: 	&Apache::lonxml::debug("$src does not exist");
1.264     raeburn  4407: 	if (&Apache::lonnet::repcopy($src) ne 'ok' ) {
1.261     foxr     4408: 	    &Apache::lonxml::debug("Repcopy of $src failed (1)");
1.256     albertel 4409: 	    #if replication failed try to find ps file
                   4410: 	    $src=~s/\.eps$/\.ps/;
1.261     foxr     4411: 	    &Apache::lonxml::debug("Now looking for $src");
1.270     foxr     4412: 	    #if no ps file try to replicate it.
                   4413: 	    my $didrepcopy = &Apache::lonnet::repcopy($src);
                   4414: 	    &Apache::lonxml::debug("repcopy of $src ... $didrepcopy");
                   4415: 	    if ( (not -e $src) ||
                   4416: 		($didrepcopy ne 'ok')) {
1.261     foxr     4417: 		&Apache::lonxml::debug("Failed to find or replicate $src");
                   4418: 
1.256     albertel 4419: 		#if replication failed try to produce eps file dynamically
                   4420: 		$src=~s/\.ps$/\.eps/;
                   4421: 		my $temp_file;
1.267     albertel 4422: 		open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat");
1.256     albertel 4423: 		my $newsrc=$orig_src;
                   4424: 		$newsrc =~ s|(.*)/res/|/home/httpd/html/res/|;
1.275     foxr     4425: 		&Apache::lonxml::debug("queueing $newsrc for dynamic eps production.");
1.344     albertel 4426: 		print FILE ("$newsrc\n");
                   4427: 		close(FILE);
1.256     albertel 4428: 		$src=~s|/home/httpd/html/res|/home/httpd/prtspool|;
                   4429: 		$src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;
1.283     albertel 4430: 		if ($sext ne "") {	 # Put the ext. back in to uniquify.
                   4431: 		    $src =~ s/\.eps$/$sext.eps/;
                   4432: 		}
1.341     foxr     4433: 
1.256     albertel 4434: 	    }
1.343     foxr     4435: 
1.256     albertel 4436: 	}
1.341     foxr     4437:     } else {
                   4438: 	# If the postscript file has spaces in its name,
                   4439: 	# LaTeX will gratuitiously vomit.  Therefore
                   4440: 	# queue such files for copy with " " replaced by "_".
                   4441: 	# printout.pm will know them by their .ps  or .eps extensions.
                   4442: 	my $newsrc = $orig_src;
                   4443: 	$newsrc    =~  s|(.*)/res/|/home/httpd/html/res/|;
                   4444: 	open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat");
1.343     foxr     4445: 	print FILE "$src\n";
1.341     foxr     4446: 	close FILE;
                   4447: 	$src=~s|/home/httpd/html/res|/home/httpd/prtspool|;
                   4448: 	$src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|;
1.256     albertel 4449:     }
                   4450:     my ($path,$file)=($src=~m|(.*)/([^/]*)$|);
1.344     albertel 4451:     $path =~ s/ /\_/g;
1.343     foxr     4452:     $file =~ s/ /\_/g;
1.261     foxr     4453:     &Apache::lonxml::debug("get_eps_image returning: $path / $file<BR />");
1.256     albertel 4454:     return ($path.'/',$file);
                   4455: }
                   4456: 
1.195     sakharuk 4457: sub eps_generation {
                   4458:     my ($src,$file,$width_param) = @_;	     
1.267     albertel 4459:     my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.195     sakharuk 4460:     my $temp_file = Apache::File->new('>>'.$filename); 
                   4461:     print $temp_file "$src\n";
                   4462:     my $newsrc = $src;
                   4463:     $newsrc =~ s/(\.gif|\.jpg|\.jpeg)$/\.eps/i;
1.345     albertel 4464:     $newsrc=~s{/home/httpd/html/res}{};
                   4465:     $newsrc=~s{/home/($LONCAPA::username_re)/public_html/}{/$1/};
                   4466:     $newsrc=~s{/\./}{/};
                   4467:     $newsrc=~s{/([^/]+)\.(ps|eps)}{/};
                   4468:     if ($newsrc=~m{/home/httpd/lonUsers/}) {
                   4469: 	$newsrc=~s{/home/httpd/lonUsers}{};
                   4470: 	$newsrc=~s{/($LONCAPA::domain_re)/./././}{/$1/};
1.213     sakharuk 4471:     }
1.345     albertel 4472:     if ($newsrc=~m{/userfiles/}) {
1.239     sakharuk 4473: 	return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
                   4474:     } else {
                   4475: 	return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
                   4476:     }
1.197     sakharuk 4477: }
                   4478: 
                   4479: sub file_path {     
                   4480:     my $src=shift;
                   4481:     my ($file,$path); 
                   4482:     if ($src =~ m!(.*)/([^/]*)$!) {
                   4483: 	$file = $2; 
                   4484: 	$path = $1.'/'; 
                   4485:     } 
                   4486:     return $file,$path;
1.126     sakharuk 4487: }
1.294     foxr     4488: #  Converts a measurement in to mm from any of 
                   4489: #  the other valid LaTeX units of measure.
                   4490: #  If the units of measure are missing from the 
                   4491: #  parameter, it is assumed to be in and returned
                   4492: #  with mm units of measure
1.126     sakharuk 4493: sub recalc {
                   4494:     my $argument = shift;
                   4495:     if (not $argument=~/(mm|cm|in|pc|pt)/) {return $argument.' mm';}
1.132     sakharuk 4496:     $argument=~/\s*(\d+\.?\d*)\s*(mm|cm|in|pc|pt)/;
1.126     sakharuk 4497:     my $value=$1;
                   4498:     my $units=$2;
                   4499:     if ($units eq 'cm') {
                   4500: 	$value*=10;
                   4501:     } elsif ($units eq 'in') {
                   4502: 	$value*=25.4;
                   4503:     } elsif ($units eq 'pc') {
                   4504: 	$value*=(25.4*12/72.27);
                   4505:     } elsif ($units eq 'pt') {
                   4506: 	$value*=(25.4/72.27);
                   4507:     }
                   4508:     return $value.' mm';
1.94      sakharuk 4509: }
1.184     sakharuk 4510: 
                   4511: sub LATEX_length {
                   4512:     my $garbage=shift;
1.206     sakharuk 4513:     $garbage=~s/^\s+$//;
                   4514:     $garbage=~s/^\s+(\S.*)/$1/;#space before 
                   4515:     $garbage=~s/(.*\S)\s+$/$1/;#space after 
                   4516:     $garbage=~s/(\s)+/$1/;#only one space
                   4517:     $garbage=~s/(\\begin{([^\}]+)}|\\end{([^\}]+)})//g;#remove LaTeX \begin{...} and \end{...}
                   4518:     $garbage=~s/(\$\_\{|\$\_|\$\^{|\$\^|\}\$)//g;#remove $_{,$_,$^{,$^,}$
                   4519:     $garbage=~s/([^\\])\$/$1/g;#$
                   4520:     $garbage=~s/(\\ensuremath\{\_\{|\\ensuremath\{\_|\\ensuremath\{\^{|\\ensuremath\{\^|\})//g;#remove \ensuremath{...}
                   4521:    $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;
1.184     sakharuk 4522:     $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;
                   4523:     $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;
                   4524:     $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;
1.206     sakharuk 4525:     $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;
                   4526:     $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;
                   4527:     $garbage=~s/(\\hat{([^}]+)}|\\check{([^}]+)}|\\dot{([^}]+)}|\\breve{([^}]+)}|\\acute{([^}]+)}|\\ddot{([^}]+)}|\\grave{([^}]+)}|\\tilde{([^}]+)}|\\mathring{([^}]+)}|\\bar{([^}]+)}|\\vec{([^}]+)})/$1/g;
                   4528:     #remove some other LaTeX command
                   4529:     $garbage=~s|\\(\w+)\\|\\|g;	 
                   4530:     $garbage=~s|\\(\w+)(\s*)|$2|g;	 	 
                   4531:     $garbage=~s|\+|11|g;
1.184     sakharuk 4532:     my  $value=length($garbage);
                   4533:     return $value;
                   4534: }
                   4535: 
1.353     foxr     4536: #   Wrap image 'stuff' inside of the LaTeX required to implement 
                   4537: #   alignment:
                   4538: #     align_tex_image(align, latex_rendering, image)
                   4539: #   Where:
                   4540: #     align   - The HTML alignment specification.
                   4541: #     latex_rendering - rendering hint for latex.
                   4542: #     image   - The LaTeX needed to insert the image itsef.
                   4543: #     width,height - dimensions of the image.
1.354     foxr     4544: # Returns:
                   4545: #    The 1/2 wrapped image and the stuff required to close the
                   4546: #    wrappage.  This allows e.g. randomlabel to insert more stuff
                   4547: #    into the closure.
1.353     foxr     4548: #
                   4549: sub align_latex_image {
                   4550:     my ($align, $latex_rendering, $image, $width, $height) = @_;
1.354     foxr     4551:     my $currentstring;        # The 1/2 wrapped image.
                   4552:     my $closure;              # The closure of the wrappage.
1.379     albertel 4553: 
                   4554:     # if it's none just return it back
                   4555:     if ($latex_rendering eq 'none') {
                   4556: 	return ($image,'');
                   4557:     }
                   4558: 
1.353     foxr     4559:     #    If there's an alignment specification we need to honor it here.
                   4560:     #    For the horizontal alignments, we will also honor the
                   4561:     #    value of the latex specfication.  The default is parbox,
                   4562:     #    and that's used for illegal values too.  
                   4563:     #    
                   4564:     #    Even though we set a default alignment value, the user
                   4565:     #    could have given us an illegal value.  In that case we
                   4566:     #    just use the default alignment of bottom..
1.354     foxr     4567:     $currentstring = "\n% figurewrapping \n";
1.353     foxr     4568:     if      ($align eq "top")    {
1.354     foxr     4569: 	$currentstring .= '\raisebox{-'.$height.'mm}{'.$image;
                   4570: 	$closure = '}';
1.353     foxr     4571:     } elsif (($align eq "center") || ($align eq "middle")) { # Being kind
                   4572: 	my $offset = $height/2;
1.354     foxr     4573: 	$currentstring .= '\raisebox{-'.$offset.'mm}{'.$image;
                   4574: 	$closure       = '}';
1.353     foxr     4575:     } elsif ($align eq "left")   { 
                   4576: 	if ($latex_rendering eq "parpic") { 
1.354     foxr     4577: 	    $currentstring .= '\parpic[l]{'.$image;
                   4578: 	    $closure       = '}';
1.353     foxr     4579: 	} elsif ($latex_rendering eq "parbox") {
1.354     foxr     4580: 	    $currentstring .= '\begin{minipage}[l]{'.$width.'mm}'
                   4581: 		.$image;
                   4582: 	    $closure = '\end{minipage}';
1.353     foxr     4583: 	} elsif ($latex_rendering eq "wrapfigure"
                   4584: 		 || $latex_rendering ne 'none') {  # wrapfig render
1.354     foxr     4585: 	    $currentstring .= 
1.353     foxr     4586: 		'\begin{wrapfigure}{l}{'.$width.'mm}'
1.354     foxr     4587: 		.'\scalebox{1.0}{'.$image;
                   4588: 	    $closure = '}\end{wrapfigure}';
1.353     foxr     4589: 	}
                   4590:     } elsif ($align eq "right")  {   
                   4591: 	if ($latex_rendering eq "parpic") {
1.354     foxr     4592: 	    $currentstring .= '\parpic[r]{'.$image;
                   4593: 	    $closure = '}';
1.353     foxr     4594: 	} elsif ($latex_rendering eq "parbox") {
1.354     foxr     4595: 	    $currentstring .=  '\begin{minipage}[r]{'.$width.'mm}'
                   4596: 		.$image;
                   4597: 	    $closure = '\end{minipage}';
1.353     foxr     4598: 	} elsif ($latex_rendering eq "wrapfigure"
                   4599: 		 || $latex_rendering ne 'none') {  # wrapfig render
1.354     foxr     4600: 	    $currentstring .= 
1.353     foxr     4601: 		'\begin{wrapfigure}{r}{'.$width.'mm}'
1.354     foxr     4602: 		.'\scalebox{1.0}{'.$image;
                   4603: 	    $closure = '}\end{wrapfigure}';
1.353     foxr     4604: 	}
                   4605:     } else {		# Bottom is also default.
                   4606: 	# $currentstring = '\raisebox{'.$height.'mm}{'.$image.'}';
1.354     foxr     4607: 	$currentstring .= "{$image";
                   4608: 	$closure       = '}';
1.353     foxr     4609:     }
1.354     foxr     4610:     $currentstring .= "\n% end wrappage\n";
                   4611:     $closure        = "\n% Begin closure\n".$closure."\n% End closure\n";
                   4612:     return ($currentstring, $closure);
1.353     foxr     4613: }
1.184     sakharuk 4614: 
1.287     foxr     4615: # is_inside_of $tagstack $tag
                   4616: #    This sub returns true if the current state of Xml processing
                   4617: #    is inside of the tag.   
                   4618: # Parameters:
                   4619: #     tagstack   - The tagstack from the parser.
                   4620: #     tag        - The tag (without the <>'s.).
                   4621: # Sample usage:
                   4622: #     if (is_inside_of($tagstack "table")) {
                   4623: #          # I'm in a table....
                   4624: #      }
                   4625: sub is_inside_of {
                   4626:     my ($tagstack, $tag) = @_;
                   4627:     my @stack = @$tagstack;
                   4628:     for (my $i = ($#stack - 1); $i >= 0; $i--) {
                   4629: 	if ($stack[$i] eq $tag) {
                   4630: 	    return 1;
                   4631: 	}
                   4632:     }
                   4633:     return 0;
                   4634: }
1.184     sakharuk 4635: 
1.94      sakharuk 4636: 
1.1       sakharuk 4637: 1;
                   4638: __END__

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

Internal Server Error

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

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

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