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

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