--- loncom/xml/londefdef.pm 2000/10/12 13:51:50 1.5 +++ loncom/xml/londefdef.pm 2009/04/13 20:42:32 1.401 @@ -1,1071 +1,4940 @@ # The LearningOnline Network with CAPA # Tags Default Definition Module # -# last modified 06/26/00 by Alexander Sakharuk +# $Id: londefdef.pm,v 1.401 2009/04/13 20:42:32 raeburn Exp $ +# +# +# Copyright Michigan State University Board of Trustees +# +# This file is part of the LearningOnline Network with CAPA (LON-CAPA). +# +# LON-CAPA is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LON-CAPA is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LON-CAPA; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# /home/httpd/html/adm/gpl.txt +# +# http://www.lon-capa.org/ +## Copyright for TtHfunc and TtMfunc by Ian Hutchinson. +# TtHfunc and TtMfunc (the "Code") may be compiled and linked into +# binary executable programs or libraries distributed by the +# Michigan State University (the "Licensee"), but any binaries so +# distributed are hereby licensed only for use in the context +# of a program or computational system for which the Licensee is the +# primary author or distributor, and which performs substantial +# additional tasks beyond the translation of (La)TeX into HTML. +# The C source of the Code may not be distributed by the Licensee +# to any other parties under any circumstances. +# package Apache::londefdef; +use Apache::lonnet; use strict; use Apache::lonxml; +use Apache::lontable; +use Apache::File(); +use Image::Magick; +use Apache::lonmenu(); +use Apache::lonmeta(); +use Apache::lonlocal; +use Apache::Constants qw(:common); +use File::Basename; +use LONCAPA(); +# use Data::Dumper; + +BEGIN { + + &Apache::lonxml::register('Apache::londefdef',('a','abbr','acronym','accessrule','address','allow','applet','area','b','base','basefont','bgo','bgsound','big','blink','blockquote','blankspace','body','br','button','caption','center','cite','code','col','colgroup','dd','del','dfn','dir','div','dl','dt','em','embed','externallink','fieldset','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','i','iframe','img','input','ins','insert','isindex','kbd','keygen','label','layer','legend','li','link','m','map','marquee','menu','meta','multicol','nobr','noembed','noframes','nolayer','noscript','object','ol','optgroup','option','output','p','param','pre','q','s','samp','select','server','small','spacer','span','strike','strong','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','tthoption','u','ul','var','wbr','hideweboutput')); + +} + -sub BEGIN { - &Apache::lonxml::register('Apache::londefdef',('m','html','head','map','applet','select','option','input','textarea','form','meta','title','body','center','b','strong','table','dt','h1','h2','h3','h4','h5','h6','cite','i','address','dd','dl','dir','ol','ul','menu','dfn','kbd','tt','code','em','q','p','br','big','small','basefont','font','s','sub','strike','sup','hr','a','li','u')); +sub initialize_londefdef { + $Apache::londefdef::TD_redirection=0; + @Apache::londefdef::table = (); + $Apache::londefdef::select=0; + undef(@Apache::londefdef::description); + @Apache::londefdef::DD=(0); + @Apache::londefdef::DT=(0); + @Apache::londefdef::seenDT=(0); + $Apache::londefdef::list_index=0; + undef($Apache::londefdef::head); + undef($Apache::londefdef::title); } -#===================================================================== TAG SUBROUTINES +#======================= TAG SUBROUTINES ===================== +#-- <output> +sub start_output { + my ($target) = @_; + if ($target eq 'meta') { $Apache::lonxml::metamode--; } + return ''; +} +sub end_output { + my ($target) = @_; + if ($target eq 'meta') { $Apache::lonxml::metamode++; } + return ''; +} #-- <m> tag - sub start_m { - my ($target,$token,$parstack,$parser) = @_; - my $currentstring = ''; - if ($target eq 'web') { - my $inside = &Apache::lonxml::get_all_text("/m",$$parser[$#$parser]); - $inside ='\\documentstyle{article}'.$inside; -# &Apache::lonxml::debug($inside); - $currentstring = &Apache::lontexconvert::converted(\$inside); -# &Apache::lonxml::debug($currentstring); +sub start_m { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; + my $currentstring = ''; + my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser); + if ($target eq 'web' || $target eq 'analyze') { + &Apache::lonxml::debug("M is starting with:$inside:"); + my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval); + if ($eval eq 'on') { + $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]); + #&Apache::lonxml::debug("M is evaluated to:$inside:"); + } + my $tex = $inside; + my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval); + $currentstring = &Apache::lontexconvert::converted(\$inside,$display); + if ($Apache::lontexconvert::errorstring) { + my $errormsg='<pre>'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'</pre> occurred while attempting to convert this TeX: <pre>'; + $tex = &HTML::Entities::encode($tex,'<>&"'); + my ($linenumber) = + ($Apache::lontexconvert::errorstring =~ /Line (\d+)/); + if (defined($linenumber)) { + my @tex=split("\n",$tex); + $tex[$linenumber]='<b><font color="red">'. + $tex[$linenumber].'</font></b>'; + $tex=join("\n",@tex); + } + &Apache::lonxml::warning($errormsg.$tex.'</pre>'); + $Apache::lontexconvert::errorstring=''; + } + #&Apache::lonxml::debug("M is ends with:$currentstring:"); + $Apache::lonxml::post_evaluate=0; + } elsif ($target eq 'tex') { - } elsif ($target eq 'tex') { - $currentstring = "\$"; - } - return $currentstring; + $currentstring = $inside; + my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval); + if ($eval eq 'on') { + $currentstring=&Apache::run::evaluate($currentstring,$safeeval,$$parstack[-1]); + } + if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';} + # detect simple math mode entry exits, and convert them + # to use \ensuremath ... unless there's a \verb inside. + if (! ($currentstring=~/\\verb/)) { + if ($currentstring=~/^\s*\$[^\$].*\$\s*$/) { + $currentstring=~s/^(\s*)\$/$1/; + $currentstring=~s/\$(\s*)$/$1/; + $currentstring='\ensuremath{'.$currentstring.'}'; + } } - sub end_m { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - } elsif ($target eq 'tex') { - $currentstring = "\$"; - } - return $currentstring; + $Apache::lonxml::post_evaluate=0; + } + return $currentstring; +} + +sub end_m { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'tex') { + $currentstring = ""; + } + return $currentstring; +} + +sub start_tthoption { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; + my $result; + if ($target eq 'web' || $target eq 'webgrade') { + my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser, + $style); + $inside=~s/^\s*//; + if ($env{'browser.mathml'}) { + &tth::ttmoptions($inside); + } else { + &tth::tthoptions($inside); } -#-------------------------------------------------------------------------- <html> tag - sub start_html { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_html { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#-------------------------------------------------------------------------- <head> tag - sub start_head { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_head { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#--------------------------------------------------------------------------- <map> tag - sub start_map { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_map { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#------------------------------------------------------------------------ <applet> tag - sub start_applet { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_applet { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#------------------------------------------------------------------------ <select> tag - sub start_select { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_select { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#------------------------------------------------------------------------ <option> tag - sub start_option { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_option { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#------------------------------------------------------------------------- <input> tag - sub start_input { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_input { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#---------------------------------------------------------------------- <textarea> tag - sub start_textarea { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_textarea { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#-------------------------------------------------------------------------- <form> tag - sub start_form { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_form { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#------------------------------------------------------------------------- <title> tag - sub start_title { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_title { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#-------------------------------------------------------------------------- <meta> tag - sub start_meta { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_meta { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#-------------------------------------------------------------------------- <body> tag - sub start_body { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " \\begin{document} "; - } - return $currentstring; - } - sub end_body { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = " \\end{document}"; - } - return $currentstring; - } -#------------------------------------------------------------------------ <center> tag - sub start_center { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " \\begin{center} "; - } - return $currentstring; - } - sub end_center { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = " \\end{center}"; - } - return $currentstring; - } -#----------------------------------------------------------------------------- <b> tag - sub start_b { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " {\\bf "; - } - return $currentstring; - } - sub end_b { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = "}"; - } - return $currentstring; - } -#------------------------------------------------------------------------ <strong> tag - sub start_strong { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " {\\bf "; - } - return $currentstring; - } - sub end_strong { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <h1> tag - sub start_h1 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\\chapter{ "; - } - return $currentstring; - } - sub end_h1 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <h2> tag - sub start_h2 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\\section{ "; - } - return $currentstring; - } - sub end_h2 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <h3> tag - sub start_h3 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\\subsection{ "; - } - return $currentstring; - } - sub end_h3 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <h4> tag - sub start_h4 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\\subsubsection{ "; - } - return $currentstring; - } - sub end_h4 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <h5> tag - sub start_h5 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\\paragraph{ "; - } - return $currentstring; - } - sub end_h5 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <h6> tag - sub start_h6 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\\subparagraph{ "; - } - return $currentstring; - } - sub end_h6 { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#-------------------------------------------------------------------------- <cite> tag - sub start_cite { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\it "; - } - return $currentstring; - } - sub end_cite { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#----------------------------------------------------------------------------- <i> tag - sub start_i { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\it "; - } - return $currentstring; - } - sub end_i { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#----------------------------------------------------------------------- <address> tag - sub start_address { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\it "; - } - return $currentstring; - } - sub end_address { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#--------------------------------------------------------------------------- <dfn> tag - sub start_dfn { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\it "; - } - return $currentstring; - } - sub end_dfn { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <tt> tag - sub start_tt { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\tt "; - } - return $currentstring; - } - sub end_tt { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <kbd> tag - sub start_kbd { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\tt "; - } - return $currentstring; - } - sub end_kbd { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#-------------------------------------------------------------------------- <code> tag - sub start_code { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\tt "; - } - return $currentstring; - } - sub end_code { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <em> tag - sub start_em { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\emph "; - } - return $currentstring; - } - sub end_em { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#----------------------------------------------------------------------------- <q> tag - sub start_q { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{ \\emph "; - } - return $currentstring; - } - sub end_q { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= "}"; - } - return $currentstring; - } -#----------------------------------------------------------------------------- <p> tag - sub start_p { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{\\par "; - } - return $currentstring; - } - sub end_p { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= " }"; - } - return $currentstring; + } + return $result; +} + +sub end_tthoption { + my ($target,$token) = @_; + my $result; + return $result; +} + +#-- <html> tag (end tag optional) +sub start_html { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'edit' || $target eq 'webgrade' ) { + # start_body() takes care of emitting the <html> + } elsif ($target eq 'tex') { + + $currentstring .= &latex_header(); + } + return $currentstring; +} + +sub end_html { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + # end_body takes care of the </html> + } + return $currentstring; +} + +#-- <head> tag (end tag optional) +sub start_head { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + &Apache::lonxml::startredirection(); + } + return $currentstring; +} + +sub end_head { + my ($target,$token) = @_; + my $currentstring = ''; + if (($target eq 'web' && $env{'request.state'} eq 'published') || + ($target eq 'webgrade' && $env{'request.state'} eq 'published')) { + # in case there is a </head> but no <head> + if ($Apache::lonxml::redirection) { + $Apache::londefdef::head = &Apache::lonxml::endredirection(); } -#---------------------------------------------------------------------------- <br> tag - sub start_br { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\\\\"; - } - return $currentstring; - } - sub end_br { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } - return $currentstring; - } -#--------------------------------------------------------------------------- <big> tag - sub start_big { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{\\large "; - } - return $currentstring; - } - sub end_big { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= " }"; - } - return $currentstring; + } + return $currentstring; +} + +#-- <map> tag (end tag required) +sub start_map { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_map { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <select> tag (end tag required) +sub start_select { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + $Apache::londefdef::select=0; + } + return $currentstring; +} + +sub end_select { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <option> tag (end tag optional) +sub start_option { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + $Apache::londefdef::select++; + if ($Apache::londefdef::select == 1) { + $currentstring='\noindent\fbox{'.&Apache::lonxml::get_param('value',$parstack,$safeeval).'}\keephidden{'; + } else { + $currentstring='\keephidden{'; } -#------------------------------------------------------------------------- <small> tag - sub start_small { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{\\footnotesize "; - } - return $currentstring; - } - sub end_small { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= " }"; + } + return $currentstring; +} + +sub end_option { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring='}'; + } + return $currentstring; +} + +#-- <input> tag (end tag forbidden) +sub start_input { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_input { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <textarea> tag (end tag required) +sub start_textarea { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_textarea { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <form> tag (end tag required) +sub start_form { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_form { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <title> tag (end tag required) +sub start_title { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $Apache::londefdef::title = + &Apache::lonxml::get_all_text('/title',$parser,$style); + } elsif ($target eq 'tex') { + $currentstring .= '\keephidden{Title of the document: ' + } + if ($target eq 'meta') { + $currentstring='<title>'; + &start_output($target); + } + return $currentstring; +} + +sub end_title { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + # start_title takes care of swallowing the title + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + if ($target eq 'meta') { + &end_output($target); + $currentstring='</title>'; + } + return $currentstring; +} + +#-- <meta> tag (end tag forbidden) +sub start_meta { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + my $args=''; + if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; } + if ($args eq '') { + &Apache::lonxml::get_all_text("/meta",$parser,$style); + } else { + $currentstring = $token->[4]; + } + } elsif ($target eq 'meta') { + unless (&Apache::lonxml::get_param + ('http-equiv',$parstack,$safeeval,undef,1)) { + my $name=$token->[2]->{'name'}; + $name=~tr/A-Z/a-z/; + $name=~s/\s/\_/gs; + $name=~s/\W//gs; + if ($name) { + $currentstring='<'.$name; + my $display=&Apache::lonxml::get_param + ('display',$parstack,$safeeval,undef,1); + if ($display) { + $display=~s/\"/\'/g; + $currentstring.=' display="'.$display.'"'; + } + $currentstring.='>'. + &Apache::lonxml::get_param + ('content',$parstack,$safeeval,undef,1). + '</'.$name.'>'; + } + my $display=&Apache::lonxml::get_param + ('display',$parstack,$safeeval,undef,1); + if ($display) { + $display=&HTML::Entities::encode($display,'<>&"'); + $currentstring.='<'.$name.'.display>'.$display. + '</'.$name.'.display>'; } - return $currentstring; } -#---------------------------------------------------------------------- <basefont> tag - sub start_basefont { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } -#-------------------------------------------------------------------------- <font> tag - sub start_font { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_font { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#------------------------------------------------------------------------ <strike> tag - sub start_strike { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{\\underline "; - } - return $currentstring; - } - sub end_strike { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= " }"; - } - return $currentstring; + } elsif ($target eq 'tex') { + my $content=&Apache::lonxml::get_param('content',$parstack,$safeeval); + my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval); + if ((not defined $content) && (not defined $name)) { + &Apache::lonxml::startredirection(); + } + } elsif ($target eq 'edit') { + $currentstring .= &Apache::edit::tag_start($target,$token); + $currentstring .= &Apache::edit::text_arg('Name:','name',$token,30); + $currentstring .= &Apache::edit::text_arg('Content:','content',$token,70); + $currentstring .= &Apache::edit::end_row(); + } elsif ($target eq 'modified') { + my $constructtag = + &Apache::edit::get_new_args($token,$parstack,$safeeval, + 'name','content'); + if ($constructtag) { $currentstring = &Apache::edit::rebuild_tag($token); } + } + return $currentstring; +} + +sub end_meta { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + my $args=''; + if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; } + if ($args ne '') { + $currentstring = $token->[4]; + } + } elsif ($target eq 'tex') { + my $content=&Apache::lonxml::get_param('content',$parstack,$safeeval); + my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval); + if ((not defined $content) && (not defined $name)) { + &Apache::lonxml::endredirection(); } -#----------------------------------------------------------------------------- <s> tag - sub start_s { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{\\underline "; - } - return $currentstring; - } - sub end_s { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= " }"; - } - return $currentstring; + } + return $currentstring; +} + +sub insert_meta { + return ' + <meta />'; +} + +# accessrule +sub start_accessrule { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; + my $currentstring = ''; + my $eff =&Apache::lonxml::get_param('effect',$parstack,$safeeval,undef,1); + my $realm=&Apache::lonxml::get_param('realm', $parstack,$safeeval,undef,1); + my $role =&Apache::lonxml::get_param('role', $parstack,$safeeval,undef,1); + my $type =&Apache::lonxml::get_param('type', $parstack,$safeeval,undef,1); + + my ($dom,$crs,$sec,$separator); + if ($type eq 'user') { + ($dom,$crs,$sec)=split(m{/},$realm); + $crs = &LONCAPA::clean_username($crs); + $separator = '/'; + } else { + ($dom,$crs,$sec)=split(/\_/,$realm); + $crs = &LONCAPA::clean_courseid($crs); + $separator = '_'; + } + $dom = &LONCAPA::clean_domain($dom); + + $sec =~s/\W//; + $realm = $dom; + if ($crs =~ /\S/) { $realm .= $separator.$crs; } + if ($sec =~ /\S/) { $realm .= $separator.$sec; } + $role=~s/\W//g; + + if ($target eq 'web') { + my $args=''; + if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; } + if ($args eq '') { + &Apache::lonxml::get_all_text("/accessrule",$parser,$style); + } else { + $currentstring = $token->[4]; + } + } + if ($target eq 'meta') { + $currentstring='<rule>'.$eff.':'.$realm.':'.$role.':'.$type.'</rule>'; + } + return $currentstring; +} + +sub end_accessrule { + my ($target,$token,$tagstack,$parstack,$parser) = @_; + my $currentstring = ''; + if ($target eq 'web') { + my $args=''; + if ( $#$parstack > -1 ) { $args=$$parstack[$#$parstack]; } + if ($args ne '') { + $currentstring = $token->[4]; } -#--------------------------------------------------------------------------- <sub> tag - sub start_sub { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\$_{ "; - } - return $currentstring; - } - sub end_sub { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= " }\$"; - } - return $currentstring; + } + return $currentstring; +} + +sub generate_css_links { + my $links; + my $css_href = &Apache::lonnet::EXT('resource.0.cssfile'); + if ($css_href =~ /\S/) { + &Apache::lonxml::extlink($css_href); + $links .= + '<link rel="stylesheet" type="text/css" href="'.$css_href.'" />'; + } + return $links; +} + +#-- <body> tag (end tag required) +sub start_body { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + + if ($target eq 'web' || $target eq 'webgrade') { + if ($Apache::lonhomework::parsing_a_problem) { + &Apache::lonxml::warning("<body> tag found inside of <problem> tag this can cause problems."); + return ''; + } + + if (&is_inside_of($tagstack, "head")) { + &end_head(@_); } -#--------------------------------------------------------------------------- <sup> tag - sub start_sup { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\$^{ "; - } - return $currentstring; - } - sub end_sup { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= " }\$"; - } - return $currentstring; + + my $extra_head = &generate_css_links(); + + $currentstring = + &Apache::loncommon::start_page($Apache::londefdef::title, + $Apache::londefdef::head + .$extra_head, + {'add_entries' => $token->[2], + 'no_title' => 1, + 'force_register' => 1}); + + if ($env{'request.state'} ne 'published') { + $currentstring.=&Apache::lonmenu::constspaceform(); + $currentstring.=&Apache::londefdef::edit_controls(); + } + $currentstring.=&Apache::lonxml::message_location(); + } elsif ($target eq 'tex') { + $currentstring = '\begin{document}'; + } + return $currentstring; +} + +sub edit_controls { + my ($nochgview) = @_; + my $result .= ' +<form method="post"> +<div class="LC_edit_problem_header">'; + unless ($nochgview) { + $result .= ' +<div class="LC_edit_problem_header_row1">'. +&Apache::lonxml::renderingoptions().' +<input type="submit" name="changeproblemmode" value="'.&mt('Change View').'" /> +</div>'; + } + $result .= ' +<div class="LC_edit_problem_header_edit_row"><input type="submit" name="editmode" accesskey="e" value="'.&mt('Edit').'" /></div></div> +</form> +<br />'; + return $result; +} + +sub end_body { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close off unclosed <p> + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= &Apache::loncommon::end_page({'discussion' => 1}); + } elsif ($target eq 'tex') { + $currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}'; + } + return $currentstring; +} + +# \begin{center} causes a new paragprah spacing that looks odd inside +# of a table cell. Same at the end of a \center but with a slightly +# larger space .. hence center_correction and center_end_correction. +# +sub center_correction { return '\vspace*{-6 mm}'; } +sub center_end_correction { return '\vspace*{-7 mm}'; } + +#-- <center> tag (end tag required) +sub start_center { + my ($target,$token,$tagstack) = @_; + my $currentstring = &end_p(); # Close off any prior para. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + if (&is_inside_of($tagstack, "table")) { + $currentstring .= ¢er_correction(); + } + $currentstring .= '\begin{center}'; + } + return $currentstring; +} + +sub end_center { + my ($target,$token,$tagstack) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring = '\end{center}'; + if (&is_inside_of($tagstack, "table")) { + $currentstring .= ¢er_end_correction(); } -#---------------------------------------------------------------------------- <hr> tag - sub start_hr { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "\\hline "; - } - return $currentstring; - } -#----------------------------------------------------------------------------- <a> tag - sub start_a { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - } - return $currentstring; - } - sub end_a { - my ($target,$token,$stackref) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - my $tempor_var = $stackref->[$#$stackref]; - if (index($tempor_var,'name') != -1 ) { - $tempor_var =~ s/name=([^,]*),/$1/g; - $currentstring .= " \\label{$tempor_var}"; - } elsif (index($tempor_var,'href') != -1 ) { - $tempor_var =~ s/href=([^,]*),/$1/g; - $currentstring .= " \\ref{$tempor_var}"; - } - } - return $currentstring; + } + return $currentstring; +} + +#-- <b> tag (end tag required) +# NOTE: In TeX mode disables internal <p> +sub start_b { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + &disable_para(); + $currentstring .= '\textbf{'; + } + return $currentstring; +} + +sub end_b { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + &enable_para(); + $currentstring = '}'; + } + return $currentstring; +} + +#-- <strong> tag (end tag required) +# NOTE: in TeX mode disables internal <p> +sub start_strong { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + &disable_para(); + $currentstring = '\textbf{'; + } + return $currentstring; +} + +sub end_strong { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + &enable_para(); + $currentstring = '}'; + } + return $currentstring; +} + +#-- <h1> tag (end tag required) +sub start_h1 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close off any prior para. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + my $pre; + my $align=lc(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1)); + if ($align eq 'center') { + $pre='\begin{center}'; + } elsif ($align eq 'left') { + $pre='\rlap{'; + } elsif ($align eq 'right') { + $pre=' \hfill \llap{'; + } + my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0); + if (not defined $TeXsize) {$TeXsize="large";} + $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; + } elsif ($target eq 'meta') { + $currentstring.='<subject>'; + &start_output($target); + } + return $currentstring; +} + +sub end_h1 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + my $post='\vskip 0 mm '; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $post='\end{center}'; + } elsif ($align eq 'left') { + $post='} \hfill'.'\vskip 0 mm '; + } elsif ($align eq 'right') { + $post='}'.'\vskip 0 mm '; + } + $currentstring .= '}}'.$post; + } elsif ($target eq 'meta') { + &end_output($target); + $currentstring='</subject>'; + } + return $currentstring; +} + +#-- <h2> tag +sub start_h2 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close off any prior para. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + my $pre; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $pre='\begin{center}'; + } elsif ($align eq 'left') { + $pre='\rlap{'; + } elsif ($align eq 'right') { + $pre=' \hfill \llap{'; + } + my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0); + if (not defined $TeXsize) {$TeXsize="large";} + $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; + } + return $currentstring; +} + +sub end_h2 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + my $post='\vskip 0 mm '; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $post='\end{center}'; + } elsif ($align eq 'left') { + $post='} \hfill'.'\vskip 0 mm '; + } elsif ($align eq 'right') { + $post='}'.'\vskip 0 mm '; + } + $currentstring .= '}}'.$post; + } + return $currentstring; +} + +#-- <h3> tag +sub start_h3 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close off any prior para. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + my $pre; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $pre='\begin{center}'; + } elsif ($align eq 'left') { + $pre='\rlap{'; + } elsif ($align eq 'right') { + $pre=' \hfill \llap{'; + } + my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0); + if (not defined $TeXsize) {$TeXsize="large";} + $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; + } + return $currentstring; +} + +sub end_h3 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + my $post='\vskip 0 mm '; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $post='\end{center}'; + } elsif ($align eq 'left') { + $post='} \hfill'.'\vskip 0 mm '; + } elsif ($align eq 'right') { + $post='}'.'\vskip 0 mm '; + } + $currentstring .= '}}'.$post; + } + return $currentstring; +} + +#-- <h4> tag +sub start_h4 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close off any prior para. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + my $pre; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $pre='\begin{center}'; + } elsif ($align eq 'left') { + $pre='\rlap{'; + } elsif ($align eq 'right') { + $pre=' \hfill \llap{'; + } + my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0); + if (not defined $TeXsize) {$TeXsize="large";} + $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; + } + return $currentstring; +} + +sub end_h4 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + my $post='\vskip 0 mm '; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $post='\end{center}'; + } elsif ($align eq 'left') { + $post='} \hfill'.'\vskip 0 mm '; + } elsif ($align eq 'right') { + $post='}'.'\vskip 0 mm '; + } + $currentstring .= '}}'.$post; + } + return $currentstring; +} + +#-- <h5> tag +sub start_h5 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close off any prior paras. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + my $pre; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $pre='\begin{center}'; + } elsif ($align eq 'left') { + $pre='\rlap{'; + } elsif ($align eq 'right') { + $pre=' \hfill \llap{'; + } + my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0); + if (not defined $TeXsize) {$TeXsize="large";} + $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; + } + return $currentstring; +} + +sub end_h5 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + my $post='\vskip 0 mm '; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $post='\end{center}'; + } elsif ($align eq 'left') { + $post='} \hfill'.'\vskip 0 mm '; + } elsif ($align eq 'right') { + $post='}'.'\vskip 0 mm '; + } + $currentstring .= '}}'.$post; + } + return $currentstring; +} + +#-- <h6> tag +sub start_h6 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close off any prior paras. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + my $pre; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $pre='\begin{center}'; + } elsif ($align eq 'left') { + $pre='\rlap{'; + } elsif ($align eq 'right') { + $pre=' \hfill \llap{'; + } + my $TeXsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval,undef,0); + if (not defined $TeXsize) {$TeXsize="large";} + $currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{'; + } + return $currentstring; +} + +sub end_h6 { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + my $post='\vskip 0 mm '; + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $post='\end{center}'; + } elsif ($align eq 'left') { + $post='} \hfill'.'\vskip 0 mm '; + } elsif ($align eq 'right') { + $post='}'.'\vskip 0 mm '; + } + $currentstring .= '}}'.$post; + } + return $currentstring; +} + +#--- <cite> tag (end tag required) +sub start_cite { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\textit{'; + } + return $currentstring; +} + +sub end_cite { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <i> tag (end tag required) +sub start_i { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\textit{'; + } + return $currentstring; +} + +sub end_i { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <address> tag (end tag required) +sub start_address { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\textit{'; + } + return $currentstring; +} + +sub end_address { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <dfn> tag (end tag required) +sub start_dfn { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\textit{'; + } + return $currentstring; +} + +sub end_dfn { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <tt> tag (end tag required) +sub start_tt { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\texttt{'; + } + return $currentstring; +} + +sub end_tt { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <kbd> tag (end tag required) +sub start_kbd { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\texttt{'; + } + return $currentstring; +} + +sub end_kbd { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <code> tag (end tag required) +sub start_code { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\texttt{'; + } + return $currentstring; +} + +sub end_code { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <em> tag (end tag required) +sub start_em { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\emph{'; + } + return $currentstring; +} + +sub end_em { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <q> tag (end tag required) +sub start_q { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\emph{'; + } + return $currentstring; +} + +sub end_q { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +# <p> is a bit strange since it does not require a closing </p> +# However in latex, we must often output closing stuff to end +# environments and {}'s etc. Therefore we do all the work +# of figuring out the ending strings in the start tag processing, +# and provide a mechanism to output the stop text external +# to tag processing. +# +{ + + my $closing_string = ''; # String required to close <p> + +# Some tags are <p> fragile meaning that <p> inside of them +# does not work within TeX mode. This is managed via the +# counter below: +# + + my $para_disabled = 0; + +sub disable_para { + $para_disabled++; +} +sub enable_para { + $para_disabled--; +} + + +#-- <p> tag (end tag optional) +#optional attribute - align="center|left|right" +sub start_p { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= &end_p(); # close off prior para if in progress. + $currentstring .= $token->[4]; + if (! ($currentstring =~ /\//)) { + $closing_string = '</p>'; # Deal correctly with <p /> e.g. } -#---------------------------------------------------------------------------- <li> tag - sub start_li { - my ($target,$token,$stackref) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - my $tempor_var = $stackref->[$#$stackref-1]; - if (index($tempor_var,'circle') != -1 ) { - $currentstring .= " \\item[o] "; - } elsif (index($tempor_var,'square') != -1 ) { - $currentstring .= " \\item[$\Box$] "; - } else { - $currentstring .= " \\item "; - } - } - return $currentstring; - } - sub end_li { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#----------------------------------------------------------------------------- <u> tag - sub start_u { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[4]; - } elsif ($target eq 'tex') { - $currentstring .= "{\\underline "; - } - return $currentstring; - } - sub end_u { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring .= $token->[2]; - } elsif ($target eq 'tex') { - $currentstring .= " }"; + } elsif ($target eq 'tex' && !$para_disabled) { + + $currentstring .= &end_p(); # close off prior para if in progress. + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($align eq 'center') { + $currentstring .='\begin{center}\par '; + $closing_string = '\end{center}'; + if (&is_inside_of($tagstack, "table")) { + $currentstring = ¢er_correction().$currentstring; + } + } elsif ($align eq 'right') { + $currentstring.="\n".'{\flushright '; +# $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{'; + $closing_string= "}\n"; + } elsif ($align eq 'left') { + $currentstring.= "\n".'{\flushleft '; +# $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{{'; + $closing_string = "}\n"; + } else { + $currentstring.='\par '; + if (&is_inside_of($tagstack, 'table')) { + $closing_string = '\vskip 0pt'; # Seems to be consistent with <p> in tables. + } else { + $closing_string = '\strut\\\\\strut '; + } + } + + } + return $currentstring; +} +# +# End paragraph processing just requires that we output the +# closing string that was saved and blank it. +sub end_p { + # Note only 'tex' mode uses disable_para and enable_para + # so we don't need to know the target in the check below: + + if (!$para_disabled) { + my $current_string = $closing_string; + $closing_string = ''; # Not in a para anymore. + return $current_string; + } else { + return ''; + } + +} +} +#-- <br> tag (end tag forbidden) +sub start_br { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + my @tempo=@$tagstack; + my $signal=0; + # Not going to factor this to is_inside_of since that would require + # multiple stack traversals. + # + for (my $i=$#tempo;$i>=0;$i--) { + if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') || + ($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul')) { + $signal=1; + } + if (($tempo[$i] eq 'td') || ($tempo[$i] eq 'th')) { + $signal = 1; + } + } + if ($signal != 1) { + $currentstring .= '\strut \\\\ \strut '; + } + + } + return $currentstring; +} + +sub end_br { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } + return $currentstring; +} + +#-- <big> tag (end tag required) +sub start_big { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '{\large '; + } + return $currentstring; +} + +sub end_big { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <small> tag (end tag required) +sub start_small { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '{\footnotesize '; + } + return $currentstring; +} + +sub end_small { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}'; + } + return $currentstring; +} + +#-- <basefont> tag (end tag forbidden) +sub start_basefont { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval); + if (defined $basesize) { + $currentstring = '{\\'.$basesize.' '; + } + } + return $currentstring; +} + +sub end_basefont { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + my $basesize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval); + if (defined $basesize) { + $currentstring = '}'; + } + } + return $currentstring; +} + +#-- <font> tag (end tag required) +sub start_font { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + my $face=&Apache::lonxml::get_param('face',$parstack,$safeeval); + if ($face!~/symbol/i) { + if (($env{'browser.fontenhance'} eq 'on') || + ($env{'browser.blackwhite'} eq 'on')) { return ''; } + } + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval); + if (defined $fontsize) { + $currentstring = '{\\'.$fontsize.' '; + } + } + return $currentstring; +} + +sub end_font { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + my $fontsize=&Apache::lonxml::get_param('TeXsize',$parstack,$safeeval); + if (defined $fontsize) { + $currentstring = '}'; + } + } + return $currentstring; +} + +#-- <strike> tag (end tag required) +sub start_strike { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + &Apache::lonxml::startredirection(); + } + return $currentstring; +} + +sub end_strike { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring=&Apache::lonxml::endredirection(); + $currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g; + $currentstring=~s/^\s*(\S)/\\underline\{$1/; + $currentstring=~s/(\S)\s*$/$1\}/; + } + return $currentstring; +} + +#-- <s> tag (end tag required) +sub start_s { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + &Apache::lonxml::startredirection(); + } + return $currentstring; +} + +sub end_s { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring=&Apache::lonxml::endredirection(); + $currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g; + $currentstring=~s/^\s*(\S)/\\underline\{$1/; + $currentstring=~s/(\S)\s*$/$1\}/; + } + return $currentstring; +} + +#-- <sub> tag (end tag required) +sub start_sub { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\raisebox{-\smallskipamount}{\scriptsize{'; + } + return $currentstring; +} + +sub end_sub { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}}'; + } + return $currentstring; +} + +#-- <sup> tag (end tag required) +sub start_sup { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\raisebox{\smallskipamount}{\scriptsize{'; + } + return $currentstring; +} + +sub end_sup { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '}}'; + } + return $currentstring; +} + +#-- <hr> tag (end tag forbidden) +sub start_hr { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # End enclosing para. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + + # <hr /> can't be inside of <sup><sub> thank you LaTeX. + # + my $restart_sub = 0; + my $restart_sup = 0; + + # Since <sub> and <sup> are simple tags it's ok to turn off/on + # using the start_ stop_ functions.. those tags only care about + # $target. + + if (&is_inside_of($tagstack, "sub")) { + $restart_sub = 1; + $currentstring .= &end_sub($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + if (&is_inside_of($tagstack, "sup")) { + $restart_sup = 1; + $currentstring .= &end_sup($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + + my $LaTeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); + if (defined $LaTeXwidth) { + if ($LaTeXwidth=~/^%/) { + substr($LaTeXwidth,0,1)=''; + $LaTeXwidth=($LaTeXwidth/100).'\textwidth'; + } + } else { + $LaTeXwidth ='0.9\textwidth'; + } + my ($pre,$post); + my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if (($align eq 'center') || (not defined $align)) { + $pre=''; $post=''; + } elsif ($align eq 'left') { + $pre='\rlap{'; $post='} \hfill'; + } elsif ($align eq 'right') { + $pre=' \hfill \llap{'; $post='}'; + } + $currentstring .= ' \vskip 0 mm \noindent\makebox['.$LaTeXwidth.']{'.$pre.'\makebox['. + $LaTeXwidth.'][b]{\hrulefill}'.$post.'}\vskip 0 mm '; + # Turn stuff back on that we can't be inside of. + + if ($restart_sub) { + $currentstring .= &start_sub($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + if ($restart_sup) { + $currentstring .= &start_sup($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + } + return $currentstring; +} + +sub end_hr { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } + return $currentstring; +} + +#-- <div> tag (end tag required) +{ + +# Since div can be nested, the stack below is used +# in 'tex' mode to store the ending strings +# for the div stack. + + my @div_end_stack; + +sub start_div { + my ($target,$token, $tagstack, $parstack, $parser, $safeeval) = @_; + my $currentstring = &end_p(); # Close enclosing para. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } + if ($target eq 'tex') { + # 4 possible alignments: left, right, center, and -missing-. + # If inside a table row, we must let the table logic + # do the alignment, however. + # + + my $endstring = ''; + + my $align = lc(&Apache::lonxml::get_param('align', $parstack, + $safeeval, undef, 1)); + if ($align eq 'center') { + $currentstring .= '\begin{center}'; + $endstring = '\end{center}'; + if (&is_inside_of($tagstack, "table")) { + $currentstring = ¢er_correction().$currentstring; + $endstring .= ¢er_end_correction(); + } + } + elsif ($align eq 'right') { + $currentstring .= '\begin{flushright}'; + $endstring .= '\end{flushright}'; + } elsif ($align eq 'left') { + $currentstring .= '\begin{flushleft}'; + $endstring = '\end{flushleft}'; + } else { + + } + $currentstring .= "\n"; # For human readability. + $endstring = "\n$endstring\n"; # For human readability + push(@div_end_stack, $endstring); + } + return $currentstring; +} + +sub end_div { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } + if ($target eq 'tex') { + my $endstring = pop @div_end_stack; + $currentstring .= $endstring; + } + return $currentstring; +} +} + +#-- <a> tag (end tag required) +sub start_a { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval, + undef,1); + $currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href}); + if ($href =~ /\S/) { + if ($href !~ m{^https?://}) { + my $url=&Apache::lonnet::hreflocation('',$env{'request.filename'}); + my $linkurl; + if ($href =~ m{^/uploaded/}) { + $linkurl = $href; + } elsif ($href =~ m{^[^/]}) { + my $path = $url; + $path =~ s{[^/]*$}{}; + $linkurl = $path.$href; + } + if ($linkurl =~ m{^/uploaded/}) { + if (!&Apache::lonnet::allowed('bre',$linkurl)) { + if (&Apache::lonnet::is_on_map($url)) { + &Apache::lonxml::extlink($linkurl); + } + } + } } - return $currentstring; + } + } + return $currentstring; +} + +sub end_a { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } + if ($target eq 'tex') { + my $href = + &Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1); + my $name = + &Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1); + my $uriprint = + &Apache::lonxml::get_param('uriprint',$parstack,$safeeval,undef,1); + my $anchorprint = + &Apache::lonxml::get_param('anchorprint',$parstack,$safeeval,undef,1); + if (($href =~ /\S/) && ($uriprint=~/^on|uriprint|yes|1$/i)) { + $href =~ s/([^\\])%/$1\\\%/g; + # Substitute special symbols... and allow line breaks at each / + # + $href = &Apache::lonxml::latex_special_symbols($href); + $href =~ s/\//\/\\-/g; # Map / to /\- to allow hyphenation. + $currentstring .= ' ({\tt URI:'.$href.'})'; + } elsif (($name =~ /\S/) && ($anchorprint=~/^on|anchorprint|yes|1$/i)) { + $currentstring .= ' ({\tt Anchor:'.&Apache::lonxml::latex_special_symbols($name).'})'; + } else { + $currentstring.=''; + } + } + return $currentstring; +} + +#-- <li> tag (end tag optional) +sub start_li { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0); + my $value=&Apache::lonxml::get_param('value',$parstack,$safeeval,undef,0); + #FIXME need to support types i and I + if ($type=~/disc/) { + $currentstring .= ' \item[$\bullet$] '; + } elsif ($type=~/circle/) { + $currentstring .= ' \item[$\circ$] '; + } elsif ($type=~/square/) { + $currentstring .= ' \item[$\diamond$] '; + } elsif ($type eq '1') { + $currentstring .= ' \item['.($Apache::londefdef::list_index+1).'.]'; + } elsif ($type eq 'A') { + $currentstring .= ' \item['.('A'..'Z')[$Apache::londefdef::list_index].'.]'; + } elsif ($type eq 'a') { + $currentstring .= ' \item['.('a'..'z')[$Apache::londefdef::list_index].'.]'; + } elsif ($value ne '') { + $currentstring .= ' \item['.$value.'] '; + } else { + $currentstring .= ' \item '; + } + $Apache::londefdef::list_index++; + } + return $currentstring; +} + +sub end_li { + my ($target,$token) = @_; + my $currentstring = &end_p(); # In case there's a <p> in the <li> + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } + return $currentstring; +} + +#-- <u> tag (end tag required) +sub start_u { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + &Apache::lonxml::startredirection(); + } + return $currentstring; +} + +sub end_u { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring=&Apache::lonxml::endredirection(); + $currentstring=~s/(\S)(\s+)(\S)/$1\}$2\\underline\{$3/g; + $currentstring=~s/^\s*(\S)/\\underline\{$1/; + $currentstring=~s/(\S)\s*$/$1\}/; + } + return $currentstring; +} + +#-- <ul> tag (end tag required) +sub start_ul { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close off enclosing list. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + my $TeXtype=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0); + $Apache::londefdef::list_index=0; + if ($TeXtype eq 'disc') { + $currentstring .= '\renewcommand{\labelitemi}{$\bullet$}'. + '\renewcommand{\labelitemii}{$\bullet$}'. + '\renewcommand{\labelitemiii}{$\bullet$}'. + '\renewcommand{\labelitemiv}{$\bullet$}'; + } elsif ($TeXtype eq 'circle') { + $currentstring .= '\renewcommand{\labelitemi}{$\circ$}'. + '\renewcommand{\labelitemii}{$\circ$}'. + '\renewcommand{\labelitemiii}{$\circ$}'. + '\renewcommand{\labelitemiv}{$\circ$}'; + } elsif ($TeXtype eq 'square') { + $currentstring .= '\renewcommand{\labelitemi}{$\diamond$}'. + '\renewcommand{\labelitemii}{$\diamond$}'. + '\renewcommand{\labelitemiii}{$\diamond$}'. + '\renewcommand{\labelitemiv}{$\diamond$}'; + } + $currentstring .= '\strut \begin{itemize}'; + } + return $currentstring; +} + +sub end_ul { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring = '\end{itemize} \renewcommand{\labelitemi}{$\bullet$}'. + '\renewcommand{\labelitemii}{$\bullet$}'. + '\renewcommand{\labelitemiii}{$\bullet$}'. + '\renewcommand{\labelitemiv}{$\bullet$}\strut '; + } + return $currentstring; +} + +#-- <menu> tag (end tag required) +sub start_menu { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + $currentstring = " \\begin{itemize} "; + } + return $currentstring; +} + +sub end_menu { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring = " \\end{itemize}"; + } + return $currentstring; +} + +#-- <dir> tag (end tag required) +sub start_dir { + my ($target,$token) = @_; + my $currentstring = &end_p(); # In case there's a <p> prior to the list. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= " \\begin{itemize} "; + } + return $currentstring; +} + +sub end_dir { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring = " \\end{itemize}"; + } + return $currentstring; +} + +#-- <ol> tag (end tag required) +sub start_ol { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # In case there's a <p> prior to the list. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $Apache::londefdef::list_index=0; + my $type=&Apache::lonxml::get_param('type',$parstack,$safeeval,undef,0); + if ($type eq '1') { + $currentstring .= '\renewcommand{\labelenumi}{\arabic{enumi}.}'. + '\renewcommand{\labelenumii}{\arabic{enumii}.}'. + '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'. + '\renewcommand{\labelenumiv}{\arabic{enumiv}.}'; + } elsif ($type eq 'A') { + $currentstring .= '\renewcommand{\labelenumi}{\Alph{enumi}.}'. + '\renewcommand{\labelenumii}{\Alph{enumii}.}'. + '\renewcommand{\labelenumiii}{\Alph{enumiii}.}'. + '\renewcommand{\labelenumiv}{\Alph{enumiv}.}'; + } elsif ($type eq 'a') { + $currentstring .= '\renewcommand{\labelenumi}{\alph{enumi}.}'. + '\renewcommand{\labelenumii}{\alph{enumii}.}'. + '\renewcommand{\labelenumiii}{\alph{enumiii}.}'. + '\renewcommand{\labelenumiv}{\alph{enumiv}.}'; + } elsif ($type eq 'i') { + $currentstring .= '\renewcommand{\labelenumi}{\roman{enumi}.}'. + '\renewcommand{\labelenumii}{\roman{enumii}.}'. + '\renewcommand{\labelenumiii}{\roman{enumiii}.}'. + '\renewcommand{\labelenumiv}{\roman{enumiv}.}'; + } elsif ($type eq 'I') { + $currentstring .= '\renewcommand{\labelenumi}{\Roman{enumi}.}'. + '\renewcommand{\labelenumii}{\Roman{enumii}.}'. + '\renewcommand{\labelenumiii}{\Roman{enumiii}.}'. + '\renewcommand{\labelenumiv}{\Roman{enumiv}.}'; + } + $currentstring .= '\strut \begin{enumerate}'; + } + return $currentstring; +} + +sub end_ol { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring = '\end{enumerate}\renewcommand{\labelenumi}{\arabic{enumi}.}'. + '\renewcommand{\labelenumii}{\arabic{enumii}.}'. + '\renewcommand{\labelenumiii}{\arabic{enumiii}.}'. + '\renewcommand{\labelenumiv}{\arabic{enumiv}.}\strut '; + } + return $currentstring; +} + +#-- <dl> tag (end tag required) +sub start_dl { + my ($target,$token) = @_; + my $currentstring = &end_p(); # In case there's a <p> unclosed prior to the list. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\begin{description}'; + $Apache::londefdef::DL++; + push(@Apache::londefdef::description,[]); + $Apache::londefdef::DD[$Apache::londefdef::DL]=0; + $Apache::londefdef::DT[$Apache::londefdef::DL]=0; + $Apache::londefdef::seenDT[$Apache::londefdef::DL]=0; + } + return $currentstring; +} + +sub end_dl { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + if ($Apache::londefdef::DT[-1]) { &end_dt(@_); } + if ($Apache::londefdef::DD[-1]) { &end_dd(@_); } + foreach my $element (@{$Apache::londefdef::description[-1]}) { + $currentstring.=' '.$element.' '; + } + pop(@Apache::londefdef::description); + $currentstring.='\end{description}'; + delete($Apache::londefdef::DD[$Apache::londefdef::DL]); + delete($Apache::londefdef::DT[$Apache::londefdef::DL]); + delete($Apache::londefdef::seenDT[$Apache::londefdef::DL]); + $Apache::londefdef::DL--; + } + return $currentstring; +} + +#-- <dt> tag (end tag optional) +sub start_dt { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring=''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + if ($Apache::londefdef::DT[-1]) { &end_dt(@_); } + if ($Apache::londefdef::DD[-1]) { &end_dd(@_); } + &Apache::lonxml::startredirection(); + $Apache::londefdef::DT[-1]++; + $Apache::londefdef::seenDT[-1]=1; + } + return $currentstring; +} + +sub end_dt { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + if ($Apache::londefdef::DT[-1]) { + my $data=&item_cleanup(); + push(@{$Apache::londefdef::description[-1]},'\item['.$data.'] \strut \vskip 0mm'); + $Apache::londefdef::DT[-1]--; + } + } + return $currentstring; +} + +sub item_cleanup { + my $item=&Apache::lonxml::endredirection(); + $item=~s/\\begin{center}//g; + $item=~s/\\end{center}//g; + return $item; +} + +#-- <dd> tag (end tag optional) +sub start_dd { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + if ($Apache::londefdef::DT[-1]) { &end_dt(@_); } + if ($Apache::londefdef::DD[-1]) { &end_dd(@_);} + if (!$Apache::londefdef::seenDT[-1]) { + push(@{$Apache::londefdef::description[-1]},'\item[\strut] \strut \vskip 0mm '); + } + push(@{$Apache::londefdef::description[-1]},''); + $Apache::londefdef::description[-1]->[-1].=' \strut '; + $Apache::londefdef::DD[-1]++; + &Apache::lonxml::startredirection(); + } + return $currentstring; +} + +sub end_dd { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $Apache::londefdef::description[-1]->[-1].= + &Apache::lonxml::endredirection().' \vskip 0mm '; + $Apache::londefdef::DD[-1]--; + } + return $currentstring; +} + +#-- <table> tag (end tag required) +# <table> also ends any prior <p> that is not closed. +# but, unless I allow <p>'s to nest, that's the +# only way I could think of to allow <p> in +# <tr> <th> bodies +# +#list of supported attributes: border,width,TeXwidth,TeXtheme +# align +sub start_table { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $textwidth = ''; + my $currentstring = &end_p(); + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + &disable_para(); # Can't have paras in a table. + + + # New table code: + + # Get the parameters that we can do something about: + + my $border = &Apache::lonxml::get_param('border', $parstack, $safeeval, undef, 0); + my $width = &Apache::lonxml::get_param('TeXwidth', $parstack, $safeeval, undef, 0); + my $theme = &Apache::lonxml::get_param('TeXtheme', $parstack, $safeeval, undef, 0); + my $align = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef, 0); + + # The only thing that needs any figuring out is the width.. and then only if it is + # a percent. If not it's assumed to be some valid TeX measurement unit e.g. 3.0cm + # + + my $table = new Apache::lontable(); + if ($border ne '') { + $table->table_border(1); + $table->cell_border(1); + } + if ($theme ne '') { + $table->theme($theme); + } + if ($align ne '') { + $table->alignment($align); + } + + # Missing width is most of page width + + if ($width eq "") { + $width = '70%'; + } + + # If a percentage, need to calculate what this means in terms of + # page width: + + if ($width =~ /%$/) { + my $textwidth = &recalc($env{'form.textwidth'}); # Page width in mm. + $width =~ s/%//; + $width = $width * $textwidth / 100.0; + $width .= " mm"; + $table->width($width); + } + + push(@Apache::londefdef::table, $table); + $currentstring.=' \keephidden{NEW TABLE ENTRY}'; + + #-------------------------------------------------------- + # Old table code here. + #-------------------------------------------------------- + + + if (0) { + push(@Apache::londefdef::table, {}); + $Apache::londefdef::table[-1]{'row_number'} = -1; + #maximum table's width (default coincides with text line length) + if ($#Apache::londefdef::table==0) { + $textwidth=&recalc($env{'form.textwidth'}); #result is always in mm + $textwidth=~/(\d+\.?\d*)/; + $textwidth=0.85*$1; #accounts "internal" LaTeX space for table frame + } else { + if ($Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]=~/\d/) { + #the maximum width of nested table is determined by LATeX width of parent cell + $textwidth=$Apache::londefdef::table[-2]{'TeXlen'}[$Apache::londefdef::table[-2]{'row_number'}][$Apache::londefdef::table[-2]{'counter_columns'}]; + } else { + #try to use all space not used before (minus 5% for LaTeX table internal) - rather silly + $textwidth=$Apache::londefdef::table[-2]{'width'}; + for (my $i=0;$i<$Apache::londefdef::table[-2]{'counter_columns'};$i++) { + $textwidth=$textwidth-$Apache::londefdef::table[-2]{'TeXlen'}[0][$i]; + } + } } -#---------------------------------------------------------------------------- <ul> tag - sub start_ul { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " \\begin{itemize} "; - } - return $currentstring; - } - sub end_ul { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = " \\end{itemize}"; - } - return $currentstring; - } -#-------------------------------------------------------------------------- <menu> tag - sub start_menu { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " \\begin{itemize} "; - } - return $currentstring; - } - sub end_menu { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = " \\end{itemize}"; - } - return $currentstring; - } -#--------------------------------------------------------------------------- <dir> tag - sub start_dir { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " \\begin{itemize} "; - } - return $currentstring; - } - sub end_dir { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = " \\end{itemize}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <ol> tag - sub start_ol { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " \\begin{enumerate} "; - } - return $currentstring; - } - sub end_ol { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = " \\end{enumerate}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <dl> tag - sub start_dl { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " \\begin{description} "; - } - return $currentstring; - } - sub end_dl { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = " \\end{description}"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <dt> tag - sub start_dt { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = "\\item[ "; - } - return $currentstring; - } - sub end_dt { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = "]"; - } - return $currentstring; - } -#---------------------------------------------------------------------------- <dd> tag - sub start_dd { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } - return $currentstring; - } - sub end_dd { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } - return $currentstring; - } -#------------------------------------------------------------------------- <table> tag - sub start_table { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[4]; - } elsif ($target eq 'tex') { - $currentstring = " \\begin{tabular} "; - } - return $currentstring; - } - sub end_table { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $currentstring = $token->[2]; - } elsif ($target eq 'tex') { - $currentstring = " \\end{tabular}"; - } - return $currentstring; + + # width either comes forced from the TeXwidth or the width parameters. + # in either case it can be a percentage or absolute width. + # in the width case we ignore absolute width + my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); + if (!defined($TeXwidth)) { + my $htmlwidth = &Apache::lonxml::get_param('width',$parstack, + $safeeval,undef,1); + if ($htmlwidth =~ /%/) { + $TeXwidth = $htmlwidth; + } else { + $TeXwidth = $textwidth; + } } + # if the width is specified as a % it is converted to an absolute width. + # otherwise.. just plugged right in the hash + + if ($TeXwidth=~/%/) { + $TeXwidth=~/(\d+)/; + $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100; + } else { + $Apache::londefdef::table[-1]{'width'}=$TeXwidth; + } + # In the end, however the table width cannot be wider than $textwidth... + + if ($Apache::londefdef::table[-1]{'width'} > $textwidth) { + $Apache::londefdef::table[-1]{'width'} = $textwidth; + } + #table's border + my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval); + my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0); + unless (defined $border) { $border = 0; } + if ($border) { + $Apache::londefdef::table[-1]{'hinc'} = '\hline '; + $Apache::londefdef::table[-1]{'vinc'} = '&'; + $Apache::londefdef::table[-1]{'vvinc'} = '|'; + } else { + $Apache::londefdef::table[-1]{'hinc'} = ''; + $Apache::londefdef::table[-1]{'vinc'} = '&'; + $Apache::londefdef::table[-1]{'vvinc'} = ''; + } + if ($#Apache::londefdef::table==0) { + # Note that \newline seems to destroy the alignment envs. + # $Apache::londefdef::table[-1]{'output'}='\strut\newline\strut\setlength{\tabcolsep}{1 mm}'; + $Apache::londefdef::table[-1]{'output'}='\strut'.'\\\\'."\n".'\strut\setlength{\tabcolsep}{1 mm}'; + } + $Apache::londefdef::table[-1]{'output'}.=' \noindent \begin{tabular} '; + $Apache::londefdef::table[-1]{'TeXlen'}=[]; + $Apache::londefdef::table[-1]{'objectlen'}=[]; + $Apache::londefdef::table[-1]{'objectsignal'}=[]; + $Apache::londefdef::table[-1]{'maxlen'}=[]; + $Apache::londefdef::table[-1]{'minlen'}=[]; + $Apache::londefdef::table[-1]{'content'}=[]; + $Apache::londefdef::table[-1]{'align'}=[]; + $currentstring.=' \keephidden{NEW TABLE ENTRY}'; + } + + } + return $currentstring; +} + +sub end_table { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + + + # New table code: + + my $table = pop(@Apache::londefdef::table); + my $t = $table->generate(); + $currentstring = $t->generate_string(); + &enable_para(); + #-------------------------------------------------------------- + # Old table code: + #-------------------------------------------------------------- + + if (0) { + + my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval); + my $inmemory = ''; + my $output = ''; + my $WARNING=''; + #width of columns from TeXwidth attributes + + # Protect against unbalanced </table> tag. + + if (scalar(@Apache::londefdef::table) > 0) { + + for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { + for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) { + if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]<$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]) { + $Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]=$Apache::londefdef::table[-1]{'TeXlen'}[$in][$jn]; + } + } + } + #free space and number of empty columns + my ($available_space,$empty_columns)=($Apache::londefdef::table[-1]{'width'},0); + if ($#Apache::londefdef::table ne 0) {$available_space=0.9*$available_space;} + for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) { + if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]==0) { + $empty_columns++; + } else { + $available_space=$available_space-$Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]; + } + } + + #boundaries for contents columns + my @min_len=();#columns can not be narrower + my @max_len=();#maximum length of column + my $avg_max; + my $avg_min; + my $counter_cols = $Apache::londefdef::table[-1]{'counter_columns'}; + for (my $jn=0;$jn<=$counter_cols; $jn++) { + my ($localmin,$localmax)=(0,0); + for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { + if ($localmin<$Apache::londefdef::table[-1]{'minlen'}[$in][$jn]) { + $localmin=$Apache::londefdef::table[-1]{'minlen'}[$in][$jn]; + } + if ($localmax<$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn]) { + $localmax=$Apache::londefdef::table[-1]{'maxlen'}[$in][$jn]; + } + } + push @min_len, $localmin; + push @max_len, $localmax; + $avg_max = $localmax + $avg_max; + $avg_min = $localmin + $avg_min; + } + # Does not really matter what the average max/min are if there are no cols. + # and this prevents div 0 in that case. + + if ($counter_cols != 0) { + $avg_max = $avg_max/$counter_cols; + $avg_min = $avg_min/$counter_cols; + } + + + # I don't think the below is needed.. but just in case: + + if ($avg_min > $avg_max) { + my $temp = $avg_min; + $avg_min = $avg_max; + $avg_max = $temp; + } + + + for (my $jn=0;$jn<=$counter_cols;$jn++) { + my $localmin=0,; + for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { + if ($localmin<$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn]) { + $localmin=$Apache::londefdef::table[-1]{'objectlen'}[$in][$jn]; + } + } + if ($max_len[$jn]<$localmin) { + $max_len[$jn]=$localmin; + $Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1; + }#object size is bigger + if ($min_len[$jn]<$localmin) { + $min_len[$jn]=$localmin; + $Apache::londefdef::table[-1]{'objectsignal'}[$jn]=1; + }#object size is bigger + if ($Apache::londefdef::table[-1]{'TeXlen'}[0][$jn]!=0) { + $min_len[$jn]=0; + $max_len[$jn]=0; + } + # Spans seem to be really bothered by max/min = 0. So if we have one + # make it an average joe max/min. + + if ($max_len[$jn] == 0) { + $max_len[$jn] = $avg_max; + } + if ($min_len[$jn] == 0) { + $min_len[$jn] = $avg_min; + } + + } + #final adjustment of column width + my @fwidth=@{$Apache::londefdef::table[-1]{'TeXlen'}[0]};#final width array + my @adjust=(); + #step 1. adjustment by maximum value + my $space_needed=0; + for (my $jn=0;$jn<=$#max_len;$jn++) { + $space_needed=$space_needed+$max_len[$jn]; + } + if ($space_needed<=$available_space) { + + for (my $jn=0;$jn<=$#max_len;$jn++) { + if ($fwidth[$jn]==0) { + $fwidth[$jn]=$max_len[$jn]; + } + } + } else { + #step 2. adjustment by minimum value (estimation) + $space_needed=0; + for (my $jn=0;$jn<=$#min_len;$jn++) { + $space_needed+=$min_len[$jn]; + } + if ($space_needed>$available_space) { + $WARNING=' \textbf{NOT ENOUGH SPACE FOR TABLE} '; + for (my $jn=0;$jn<=$#max_len;$jn++) { + if ($fwidth[$jn]==0) { + $fwidth[$jn]=$min_len[$jn]; + } + } + #check if we have objects which can be scaled + my $how_many_to_scale=0; + my @to_scale=(); + for (my $jn=0;$jn<=$#max_len;$jn++) { + if ($Apache::londefdef::table[-1]{'objectsignal'}[$jn] eq '1') { + $how_many_to_scale++; + push @to_scale, $jn; + } + } + if ($how_many_to_scale>0) { + my $space_to_adjust=($space_needed-$available_space)/$how_many_to_scale; + foreach my $jn (@to_scale) { + for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { + $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/; + if ($1 ne '') { + my $current_length=&recalc($1); + $current_length=~/(\d+\.?\d*)/; + $current_length=$current_length-$space_to_adjust; + $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/width=$current_length mm/; + } + $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~m/\[(\d+\.?\d*)\s*mm\]/; + if ($1 ne '') { + my $current_length=$1; + $current_length=$current_length-$space_to_adjust; + $Apache::londefdef::table[-1]{'content'}[$in][$jn]=~s/\[(\d+\.?\d*)\s*mm\]/\[$current_length mm\]/; + } + } + $fwidth[$jn]=$fwidth[$jn]-$space_to_adjust; + } + } + } else { + #step 3. adjustment over minimal + corrections + my $enlarge_coef=$available_space/$space_needed; + my $acsessive=0; + for (my $jn=0;$jn<=$#min_len;$jn++) { + $adjust[$jn]=$min_len[$jn]*$enlarge_coef; + if ($adjust[$jn]>$max_len[$jn]) { + $fwidth[$jn]=$max_len[$jn]; + $acsessive=$acsessive+$adjust[$jn]-$max_len[$jn]; + $adjust[$jn]=0; + + } + } + if ($acsessive>0) { + #we have an excess of space and can redistribute it + my $notempty_columns=0; + for (my $jn=0;$jn<=$#min_len;$jn++) { + if ($adjust[$jn]!=0) { + $notempty_columns++; + } + } + my $per_column=$acsessive/$notempty_columns; + for (my $jn=0;$jn<=$#min_len;$jn++) { + if ($adjust[$jn]!=0) { + $adjust[$jn]+=$per_column; + $fwidth[$jn]=$adjust[$jn]; + } + } + } else { + for (my $jn=0;$jn<=$#min_len;$jn++) { + $fwidth[$jn]=$adjust[$jn]; + } + } + } + } + # use all available width or specified width as if not specified, + # the specified width gets defaulted to the available width. + + my $current=0; + for (my $i=0;$i<=$#fwidth;$i++) { + $current+=$fwidth[$i]; + } + if ($current == 0) { + $current = $Apache::londefdef::table[-1]{'width'}; + } + my $coef=$Apache::londefdef::table[-1]{'width'}/$current; + for (my $i=0;$i<=$#fwidth;$i++) { + $fwidth[$i]*=$coef; + } + #removing of empty columns if allowed + my $permission=&Apache::lonxml::get_param('TeXDropEmptyColumns',$parstack,$safeeval,undef,0); + if ($permission eq 'yes') { + my @cleaned_table=(); + my @cleaned_header=(); + my $colind=0; + for (my $jn=0;$jn<=$Apache::londefdef::table[-1]{'counter_columns'};$jn++) { + if ($fwidth[$jn]!=0) { + #we need to copy column + for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { + $cleaned_table[$in][$colind]=$Apache::londefdef::table[-1]{'content'}[$in][$jn]; + $cleaned_header[$colind]=$fwidth[$jn]; + } + $colind++; + } + } + $Apache::londefdef::table[-1]{'content'}=\@cleaned_table; + @fwidth=@cleaned_header; + } + + + #construct header of the table + my $header_of_table = '{'.$Apache::londefdef::table[-1]{'vvinc'}; + for (my $in=0;$in<=$#fwidth;$in++) { + $header_of_table.='p{'.$fwidth[$in].' mm}'.$Apache::londefdef::table[-1]{'vvinc'}; + } + $header_of_table .= '}'; + + #fill the table + for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) { + my $have_rowspan = 0; + for (my $jn=0;$jn<=$#fwidth;$jn++) { + + #----------------------------------------------------------- + # I think this order of doing things will ensure that + # single rowspan, columspan and combined row/colspans will + # work correctly. LaTeX is delicate here. + # RF. + + # Start a rowspan if necessary: + + my $primary_col_width = $fwidth[$jn]; # Width of primary column. + my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn]; + my $colspan = $Apache::londefdef::table[-1]{'colspan'}[$in][$jn]; + # + # Do the appropriate magic if this has a colspan + # + + my $border_char = ""; + if ($border) { + $border_char = "|"; + } + my $spanwidth = 0; + if ($colspan > 1) { + for (my $spancol = $jn; $spancol < $jn + $colspan; $spancol++) { + $spanwidth += $fwidth[$spancol]; + } + $output .= '\multicolumn{'. + $colspan + ."}"; + if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { + $output .= '{'.$border_char.'c'.$border_char.'}{'; + } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { + $output .= '{'.$border_char.'r'.$border_char.'}{'; + } + else { + $output .= '{'.$border_char."p{$spanwidth mm}".$border_char.'}{'; + } + + } else { + $spanwidth = $primary_col_width; # If no span width will be just colwidth + } + + # Rowspan... if colspan is 1, and there's an alignment we'll need + # to kick in a multicolumn in order to get the alignment spec. + # this must precede the multirow or LaTex gets quite upset. + # Naturally if colspan > 1 we've already done that above ^ + # + my $multirow_aligned = 0; + if ($rowspan > 1) { + if ($colspan == 1) { + if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { + $output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{'; + $multirow_aligned = 1; + } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { + $output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{'; + $multirow_aligned = 1; + } + } + $have_rowspan++; + if ($multirow_aligned) { + $output .= '\multirow{'.$rowspan.'}[0]{*}{'; + } else { + $output .= '\multirow{'.$rowspan."}[0]{$spanwidth mm}{"; + } + + $Apache::londefdef::table[-1]{'content'}[$in][$jn] =~ + s{^\s*\\par\s*}{}; + $Apache::londefdef::table[-1]{'content'}[$in][$jn] =~ + s{\s*\\vskip\s*0pt\s*$}{}; + + # + # If we did not throw in a multicolumn to align, then add + # an extra { + # so we close correctly without having to keep additional state + # around + # + if (!$multirow_aligned) { + $output .= '{'; + } + } + if (($rowspan eq '^') || ($rowspan eq '_')) { + $have_rowspan++; + } + #-------------------------------------------------------------- + + + # For right and center alignment of single cells. + # we are going to use a multicolumn with a span of 1 to specify alignment. + # + if ($colspan == 1 && $rowspan == 1) { + if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') { + $output .= '\multicolumn{1}{'.$border_char.'c'.$border_char.'}{'; + } elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') { + $output .= '\multicolumn{1}{'.$border_char.'r'.$border_char.'}{'; + } + } + + $output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn]; + + if (($colspan == 1 && $rowspan == 1) && + (($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') || + ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r'))) { + $output .= '}'; + } + + # Close off any open multirow: + + if ($rowspan > 1) { + $output .= '}}'; + } + # Close off the colspan... + # + if ($colspan > 1) { + $output .= '}'; + $jn += $colspan-1; # Adjust for number of rows really left. + } + if ($jn!=$#fwidth) {$output.=' '.$Apache::londefdef::table[-1]{'vinc'};} + } + # If have_rowspan > 0, and borders are on, then + # we need to do more than put an \hline at the bottom of row. + # we need to do the appropriate \cline to ensure that + # the spanned rows don't have \hlines through them. + + if (($Apache::londefdef::table[-1]{'hinc'} =~ /\\hline/) && $have_rowspan) { + $output .= ' \\\\ '; + for (my $jn=0; $jn<=$#fwidth;$jn++) { + my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn]; + if ($rowspan ne "^") { + if (($rowspan <= 1) || ($rowspan eq '_')) { + my $column = $jn+1; + $output .= '\cline{'.$column.'-'.$column.'} '; + } + } + } + + } else { + $output.=' \\\\ '.$Apache::londefdef::table[-1]{'hinc'}.' '; + } + } + # Note that \newline destroys alignment env's produced by e.g. <div> + # $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut\newline\strut '; + $Apache::londefdef::table[-1]{'output'} .= $header_of_table.$Apache::londefdef::table[-1]{'hinc'}.$output.'\end{tabular}\strut'.'\\\\'."\n".'\strut '; + if ($#Apache::londefdef::table > 0) { + my $inmemory = $Apache::londefdef::table[-1]{'output'}; + # Figure out max/and min width by summing us and then + # apply that to the current column of the table we nest in + # if it's larger than the current width or the current width + # is undefined. + # + my $min_nested_width = 0; + my $max_nested_width = 0; + for (my $col = 0; $col <= $Apache::londefdef::table[-1]{'counter_columns'}; $col++) { + $min_nested_width += $min_len[$col]; + $max_nested_width += $max_len[$col]; + + } + # Fudge in an extra 5 mm for borders etc: + + $min_nested_width += 5; + $max_nested_width += 5; + + my $outer_column = $Apache::londefdef::table[-2]{'counter_columns'}; + my $outer_row = $Apache::londefdef::table[-2]{'row_number'}; + if ($min_nested_width > $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column]) { + $Apache::londefdef::table[-2]{'minlen'}[$outer_row][$outer_column] = $min_nested_width; + } + if ($max_nested_width > $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column]) { + $Apache::londefdef::table[-2]{'maxlen'}[$outer_row][$outer_column] = $max_nested_width; + } + + pop @Apache::londefdef::table; + push @{$Apache::londefdef::table[-1]{'include'}}, $inmemory; + } else { + $currentstring .= $Apache::londefdef::table[-1]{'output'}; + pop @Apache::londefdef::table; + undef @Apache::londefdef::table; + } + } + &enable_para(); + } + } + return $currentstring; +} + +#-- <tr> tag (end tag optional) +sub start_tr { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + + my $align = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef, 1); + $Apache::londefdef::table[-1]->start_row(); + + if ($align ne '') { + $Apache::londefdef::table[-1]->configure_row({default_halign => $align}); + } + + #--------------------------------------------------------------- + # Old table code. + #--------------------------------------------------------------- + + if (0) { + $Apache::londefdef::table[-1]{'row_number'}++; + my $alignchar=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1); + if ($alignchar ne '') { + push @ {$Apache::londefdef::table[-1]{'rows'} },substr($alignchar,0,1); + } else { + push @ {$Apache::londefdef::table[-1]{'rows'} }, 'l'; + } + push ( @{ $Apache::londefdef::table[-1]{'rowdata'} }, $Apache::londefdef::table[-1]{'hinc'}); + # + # Need to save the number of table columns to preserve the max # columns. + # + $Apache::londefdef::table[-1]{'prior_columns'} = $Apache::londefdef::table[-1]{'counter_columns'}; + $Apache::londefdef::table[-1]{'counter_columns'} = -1; + push @ {$Apache::londefdef::table[-1]{'TeXlen'}}, []; + push @ {$Apache::londefdef::table[-1]{'objectlen'}}, []; + push @ {$Apache::londefdef::table[-1]{'minlen'}}, []; + push @ {$Apache::londefdef::table[-1]{'maxlen'}}, []; + push @ {$Apache::londefdef::table[-1]{'content'}}, []; + } + } + return $currentstring; +} + +sub end_tr { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close any pending <p> in the row. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + + # In case the user is missing a </td> or </th> tag: + + if ($Apache::londefdef::TD_redirection) { + &end_td_tex($parstack,$parser,$safeeval); + } + $Apache::londefdef::table[-1]->end_row(); + + #----------------------------------------------- + # Old table code + #----------------------------------------------- + + if (0) { + if ($Apache::londefdef::TD_redirection) { + &end_td_tex($parstack,$parser,$safeeval); + } + # Counter columns must be the maximum number of columns seen + # in the table so far so: + if ($Apache::londefdef::table[-1]{'prior_columns'} > $Apache::londefdef::table[-1]{'counter_columns'}) { + $Apache::londefdef::table[-1]{'counter_columns'} = $Apache::londefdef::table[-1]{'prior_columns'}; + } + } + + + } + return $currentstring; +} + +#-- <td> tag (end tag optional) +sub start_td { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + $Apache::londefdef::TD_redirection = 1; + &tag_check('tr','td',$tagstack,$parstack,$parser,$safeeval); + } + return $currentstring; +} + +sub tag_check { + my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_; + my @ar=@$parstack; + for (my $i=$#ar-1;$i>=0;$i--) { + if (lc($$tagstack[$i]) eq $good_tag) { + &start_td_tex($parstack,$parser,$safeeval); + last; + } elsif (lc($$tagstack[$i]) eq $bad_tag) { + splice @ar, $i+1; + &end_td_tex(\@ar,$parser,$safeeval); + &start_td_tex($parstack,$parser,$safeeval); + last; + } + } + return ''; +} + +# +# Factor out cell configuration hash generation: +# + +sub cell_config_hash { + my ($align, $rowspan, $colspan) = @_; + my %config; + if ($align ne '') { + $config{'halign'} = $align; + } + if ($colspan ne "") { + $config{'colspan'} = $colspan; + } + if ($rowspan ne '') { + $config{'rowspan'} = $rowspan; + } + return \%config; +} + +sub start_td_tex { + my ($parstack,$parser,$safeeval) = @_; + + # At this stage, an empty cell is created with the + # appropriate rowspan/colspan and alignment + # attributes, but empty of text. end_td_tex will + # fetch the contents from the recursive parse and + # fill the cell with them: + my $align = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef, 1); + my $rowspan = &Apache::lonxml::get_param('rowspan', $parstack, $safeeval, undef, 1); + my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 1); + + my $config = &cell_config_hash($align, $rowspan, $colspan); + + my $table = $Apache::londefdef::table[-1]; + $table->add_cell('', $config); + + + #------------------------------------------------ + # Old table code. + #------------------------------------------------ + + if (0) { + + my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1); + if ($alignchar eq '') { + $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1]; + } + push @{ $Apache::londefdef::table[-1]{'align'}[$Apache::londefdef::table[-1]{'row_number'}] }, $alignchar; + $Apache::londefdef::table[-1]{'counter_columns'}++; + my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); + if (defined $TeXwidth) { + my $current_length=&recalc($TeXwidth); + $current_length=~/(\d+\.?\d*)/; + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1; + } + } + &Apache::lonxml::startredirection(); + return ''; +} + +sub end_td_tex { + + my $text = &Apache::lonxml::endredirection(); + my $table = $Apache::londefdef::table[-1]; + $table->append_cell_text($text); + + #------------------------------------------------- + # Old table code + #------------------------------------------------- + + if (0) { + my ($parstack,$parser,$safeeval) = @_; + my $current_row = $Apache::londefdef::table[-1]{'row_number'}; + my $current_column = $Apache::londefdef::table[-1]{'counter_columns'}; + my $data = &Apache::lonxml::endredirection(); + + # The rowspan array of the table indicates which cells are part of a span. + # n indicates the start of a span set of n rows. + # ^ indicates a cell that continues a span set. + # _ indicates the cell is at the bottom of a span set. + # If this and subsequent cells are part of a rowspan, we must + # push along the row until we find one that is not. + + while ((defined $Apache::londefdef::table[-1]{'rowspan'}[$current_row] [$current_column]) + && ($Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column] =~ /[\^\_]/)) { + # Part of a span. + push @ {$Apache::londefdef::table[-1]{'content'}[-1]}, ''; + $current_column++; + } + $Apache::londefdef::table[-1]{'counter_columns'} = $current_column; + + + # Get the column and row spans. + # Colspan can be done via \multicolumn if I can figure out the data structs. + + my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 0); + if (!$colspan) { + $colspan = 1; + } + + my $rowspan = &Apache::lonxml::get_param('rowspan', $parstack, $safeeval, undef, 0); + if (!$rowspan) { + $rowspan = 1; + } + + + + for (my $c = 0; $c < $colspan; $c++) { + $Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column+$c] = $rowspan; + for (my $i = 1; $i < $rowspan; $i++) { + $Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column+$c] = '^'; + if ($i == ($rowspan-1)) { + $Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column+$c] = '_'; + } + } + } + + my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); + if (defined $TeXwidth) { + for (my $c = 0; $c < $colspan; $c++) { + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + } + } else { + if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) { + my $garbage_data=$data; + my $fwidth=0; + while ($garbage_data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) { + my $current_length=&recalc($1); + $current_length=~/(\d+\.?\d*)/; + if ($fwidth<$1) {$fwidth=$1;} + $garbage_data=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//; + } + while ($garbage_data=~m/\[(\d+\.?\d*)\s*mm\]/) { + my $current_length=$1; + if ($fwidth<$current_length) {$fwidth=$current_length;} + $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//; + } + for (my $c = 0; $c < $colspan; $c++) { + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + } + } elsif ($data=~/\\parbox\{\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*\s*\}/ or $data=~/\\epsfxsize\s*=\s*\d+\.?\d*\s*(mm|cm|in|pc|pt)*/) { + my $garbage_data=$data; + my $fwidth=0; + while ($garbage_data=~/\\parbox\{\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)\s*\}/) { + my $current_length=&recalc($1); + $current_length=~/(\d+\.?\d*)/; + if ($fwidth<$1) {$fwidth=$1;} + $garbage_data=~s/\\parbox\{\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//; + } + while ($garbage_data=~/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) { + my $current_length=&recalc($1); + $current_length=~/(\d+\.?\d*)/; + if ($fwidth<$1) {$fwidth=$1;} + $garbage_data=~s/\\epsfxsize\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//; + } + for (my $c = 0; $c < $colspan; $c++) { + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + } + $data=~s/\\\\\s*$//; + } else { + $data=~s/^\s+(\S.*)/$1/; + $data=~s/(.*\S)\s+$/$1/; + $data=~s/(\s)+/$1/; + my ($current_length,$min_length)=(0,0); + if ($data=~/\\vskip/) { + my $newdata=$data; + $newdata=~s/\\vskip \d*\.?\d*\s*mm/THISISJUSTTEMPORARYSEPARATOR/g; + my @newdata=split(/THISISJUSTTEMPORARYSEPARATOR/,$newdata); + foreach my $elementdata (@newdata) { + my $lengthnewdata=2.5*&LATEX_length($elementdata); + if ($lengthnewdata>$current_length) {$current_length=$lengthnewdata;} + my @words=split(/ /,$elementdata); + foreach my $word (@words) { + my $lengthword=2.5*&LATEX_length($word); + if ($min_length<$lengthword) {$min_length=$lengthword;} + } + } + } else { + $current_length=2.5*&LATEX_length($data); + my @words=split(/ /,$data); + foreach my $word (@words) { + my $lengthword=2*&LATEX_length($word); + if ($min_length<$lengthword) {$min_length=$lengthword;} + } + } + for (my $c = 0; $c < $colspan; $c++) { + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length; + } + } + } + # Substitute all of the tables nested in this cell in their appropriate places. + + + my $nested_count = $#{$Apache::londefdef::table[-1]{'include'}}; # This one is constant... + for (my $in=0; $in<=$nested_count; $in++) { + my $nested = shift @{$Apache::londefdef::table[-1]{'include'}}; + $nested =~ s/\\end\{tabular\}\\strut\\\\/\\end\{tabular\}/; + # $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/; + $data =~ s/\\keephidden\{NEW TABLE ENTRY\}/$nested/; + + } + # Should be be killing off the 'include' elements as they're used up? + + push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data; + + + + + # the colspan array will indicate how many columns will be spanned by this + # cell..this requires that counter_columns also be adjusted accordingly + # so that the next bunch of text goes in the right cell. Note that since + # counter_columns is incremented in the start_td_tex, we adjust by colspan-1. + # + + $Apache::londefdef::table[-1]{'counter_columns'} += $colspan -1; + for (my $i = 0; $i < ($colspan -1); $i++) { + push @ {$Apache::londefdef::table[-1]{'content'}[-1] },''; + } + for (my $r = 0; $r < $rowspan; $r++) { + $Apache::londefdef::table[-1]{'colspan'}[$current_row+$r][$current_column] = $colspan; + # Put empty text in spanned cols. + + } + + } + + return ''; +} + +sub end_td { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $Apache::londefdef::TD_redirection =0; + &end_td_tex($parstack,$parser,$safeeval); + } + return $currentstring; +} + +#-- <th> tag (end tag optional) +sub start_th { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + $Apache::londefdef::TD_redirection = 1; + &tagg_check('tr','th',$tagstack,$parstack,$parser,$safeeval); + } + return $currentstring; +} + +sub tagg_check { + my ($good_tag,$bad_tag,$tagstack,$parstack,$parser,$safeeval) = @_; + my @ar=@$parstack; + for (my $i=$#ar-1;$i>=0;$i--) { + if (lc($$tagstack[$i]) eq $good_tag) { + &start_th_tex($parstack,$parser,$safeeval); + last; + } elsif (lc($$tagstack[$i]) eq $bad_tag) { + splice @ar, $i+1; + &end_th_tex(\@ar,$parser,$safeeval); + &start_th_tex($parstack,$parser,$safeeval); + last; + } + } + return ''; +} + +sub start_th_tex { + my ($parstack,$parser,$safeeval) = @_; + + my $alignment = &Apache::lonxml::get_param('align', $parstack, $safeeval, undef,1); + my $rowspan = &Apache::lonxml::get_param('rowspan', $parstack, $safeeval, undef, 1); + my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 1); + + my $config = cell_config_hash($alignment, $rowspan, $colspan); + my $table = $Apache::londefdef::table[-1]; + $table->add_cell('\textbf{', $config); + + #------------------------------------------------------------------------------------- + # + # Old table code. + # + #-------------------------------------------------------------------------------------- + + if (0) { + + + my $alignchar = substr(&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1),0,1); + if ($alignchar eq '') { + $alignchar = $Apache::londefdef::table[-1]{'rows'}[-1]; + } + push @{ $Apache::londefdef::table[-1]{'align'}[$Apache::londefdef::table[-1]{'row_number'}] }, $alignchar; + $Apache::londefdef::table[-1]{'counter_columns'}++; + my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); + if (defined $TeXwidth) { + my $current_length=&recalc($TeXwidth); + $current_length=~/(\d+\.?\d*)/; + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$1; + } + } + + # Accept xml until the </th> tag. + + &Apache::lonxml::startredirection(); + return ''; +} + +sub end_th_tex { + my ($parstack,$parser,$safeeval) = @_; + + my $table = $Apache::londefdef::table[-1]; + my $text = &Apache::lonxml::endredirection(); + $table->append_cell_text($text.'}'); + + #----------------------------------------------------------------------------- + # Old table code: + #----------------------------------------------------------------------------- + + if (0) { + my $current_row = $Apache::londefdef::table[-1]{'row_number'}; + my $data=&Apache::lonxml::endredirection(); + my $TeXwidth=&Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0); + if (defined $TeXwidth) { + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + } else { + if (($data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) or ($data=~m/\[(\d+\.?\d*)\s*mm\]/)) { + my $garbage_data=$data; + my $fwidth=0; + while ($garbage_data=~m/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)/) { + my $current_length=&recalc($1); + $current_length=~/(\d+\.?\d*)/; + if ($fwidth<$1) {$fwidth=$1;} + $garbage_data=~s/width\s*=\s*(\d+\.?\d*\s*(mm|cm|in|pc|pt)*)//; + } + while ($garbage_data=~m/\[(\d+\.?\d*)\s*mm\]/) { + my $current_length=$1; + if ($fwidth<$current_length) {$fwidth=$current_length;} + $garbage_data=~s/\[(\d+\.?\d*)\s*mm\]//; + } + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$fwidth; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + } else { + $data=~s/^\s+(\S.*)/$1/; + $data=~s/(.*\S)\s+$/$1/; + $data=~s/(\s)+/$1/; + my ($current_length,$min_length)=(0,0); + if ($data=~/\\vskip/) { + my $newdata=$data; + $newdata=~s/\\vskip \d*\.?\d*\s*mm/THISISJUSTTEMPORARYSEPARATOR/g; + my @newdata=split(/THISISJUSTTEMPORARYSEPARATOR/,$newdata); + foreach my $elementdata (@newdata) { + my $lengthnewdata=2.5*&LATEX_length($elementdata); + if ($lengthnewdata>$current_length) {$current_length=$lengthnewdata;} + my @words=split(/ /,$elementdata); + foreach my $word (@words) { + my $lengthword=2.5*&LATEX_length($word); + if ($min_length<$lengthword) {$min_length=$lengthword;} + } + } + } else { + $current_length=2.5*&LATEX_length($data); + my @words=split(/ /,$data); + foreach my $word (@words) { + my $lengthword=2*&LATEX_length($word); + if ($min_length<$lengthword) {$min_length=$lengthword;} + } + } + push @ {$Apache::londefdef::table[-1]{'TeXlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'objectlen'}[$Apache::londefdef::table[-1]{'row_number'}] },'0'; + push @ {$Apache::londefdef::table[-1]{'maxlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$current_length; + push @ {$Apache::londefdef::table[-1]{'minlen'}[$Apache::londefdef::table[-1]{'row_number'}] },$min_length; + } + } + for (my $in=0; $in<=$#{$Apache::londefdef::table[-1]{'include'}};$in++) { + $data=~s/\\keephidden\{NEW TABLE ENTRY\}/$Apache::londefdef::table[-1]{'include'}[$in]/; + } + #make data bold + $data='\textbf{'.$data.'}'; + push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data; + } + return''; +} + +sub end_th { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # Close any open <p> in the row. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $Apache::londefdef::TD_redirection =0; + &end_th_tex($parstack,$parser,$safeeval); + } + return $currentstring; +} + +#-- <img> tag (end tag forbidden) +# +# Render the <IMG> tag. +# <IMG> has the following attributes (in addition to the +# standard HTML ones: +# TeXwrap - Governs how the tex target will try to wrap text around +# horizontally aligned images. +# TeXwidth - The width of the image when rendered for print (mm). +# TeXheight - The height of the image when rendered for print (mm) +# (Note there seems to also be support for this as a % of page size) +# +sub start_img { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; + my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval, + undef,1); + if (! $src && + ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex') + ) { + my $inside = &Apache::lonxml::get_all_text("/img",$parser,$style); + return ''; + } + &Apache::lonxml::extlink($src); + my $currentstring = ''; + my $scaling = .3; + + # Render unto browsers that which are the browser's... + + if ($target eq 'web' || $target eq 'webgrade') { + if ($env{'browser.imagesuppress'} ne 'on') { + my $enc = ('yes' eq + lc(&Apache::lonxml::get_param('encrypturl',$parstack, + $safeeval))); + $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src}, + $enc); + } else { + my $alttag = &Apache::lonxml::get_param('alt',$parstack,$safeeval, + undef,1); + if (!$alttag) { + $alttag = &Apache::lonmeta::alttag($Apache::lonxml::pwd[-1], + $src); + } + $currentstring.='[IMAGE: '.$alttag.']'; + } + + # and render unto TeX that which is LaTeX + + } elsif ($target eq 'tex') { + # + # The alignment will require some superstructure to be put around + # the \includegraphics stuff. At present we can only partially + # simulate the alignments offered by html. + # + # + my $align = lc(&Apache::lonxml::get_param('align', + $parstack, + $safeeval, + undef,1)); + if(!$align) { + $align = "bottom"; # This is html's default so it's ours too. + } + # + &Apache::lonxml::debug("Alignemnt = $align"); + # LaTeX's image/text wrapping is really bad since it wants to + # make figures float. + # The user has the optional parameter (applicable only to l/r + # alignment to use the picins/parpic directive to get wrapped text + # this is also imperfect.. that's why we give them a choice... + # so they can't yell at us for our choice. + # + my $latex_rendering = &Apache::lonxml::get_param('TeXwrap', + $parstack, + $safeeval, + undef,0); + # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering"); + if(!$latex_rendering) { + $latex_rendering = "texwrap"; + } + # using texwrap inside a table does not work. So, if after all of this, + # texwrap is on, we turn it off if we detect we're in a table: + # + if (($latex_rendering eq 'texwrap') && &is_inside_of($tagstack, "table")) { + $latex_rendering = 'parpic'; + } + + # &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src"); + + #if original bmp/gif/jpg/png file exist do following: + my $origsrc=$src; + my ($path,$file) = &get_eps_image($src); + # &Apache::lonnet::logthis("Image source: $src result: $path $file"); + $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src); + &Apache::lonxml::debug("path = $path file = $file src = $src"); + if (-e $src) { + &Apache::lonxml::debug("$src exists"); + my ($height_param,$width_param)= + &image_size($origsrc,0.3,$parstack,$safeeval); + my $size; + if ($width_param) { $size.='width='.$width_param.' mm,'; } + if ($height_param) { $size.='height='.$height_param.' mm]'; } + # Default size if not able to extract that (e.g. eps image). + + # &Apache::lonnet::logthis("Size = $size"); + + $size='['.$size; + $size=~s/,$/]/; + $currentstring .= '\graphicspath{{'.$path.'}}' + .'\includegraphics'.$size.'{'.$file.'} '; + my $closure; + ($currentstring, $closure) = &align_latex_image($align, + $latex_rendering, + $currentstring, + $width_param, + $height_param); + $currentstring .= $closure; + + } else { + &Apache::lonxml::debug("$src does not exist"); + #original image file doesn't exist so check the alt attribute + my $alt = + &Apache::lonxml::get_param('alt',$parstack,$safeeval,undef,1); + unless ($alt) { + $alt=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src); + } + + if ($alt) { $currentstring .= ' '.$alt.' '; } + } + + # And here's where the semi-quote breaks down: allow the user + # to edit the beast as well by rendering the problem for edit: + } elsif ($target eq 'edit') { + my $only = join(',',&Apache::loncommon::filecategorytypes('Pictures')); + $currentstring .=&Apache::edit::tag_start($target,$token); + $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70). + &Apache::edit::browse('src',undef,'alt',$only).' '. + &Apache::edit::search('src',undef,'alt').'<br />'; + $currentstring .=&Apache::edit::text_arg('Description:','alt',$token,70).'<br />'; + $currentstring .=&Apache::edit::text_arg('width (pixel):','width',$token,5); + $currentstring .=&Apache::edit::text_arg('height (pixel):','height',$token,5).'<br />'; + $currentstring .=&Apache::edit::text_arg('TeXwidth (mm):','TeXwidth',$token,5); + $currentstring .=&Apache::edit::text_arg('TeXheight (mm):','TeXheight',$token,5); + $currentstring .=&Apache::edit::select_arg('Alignment:','align', + ['','bottom','middle','top','left','right'],$token,5); + $currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap', + ['', 'none','parbox', 'parpic', 'wrapfigure'], $token, 2); + $currentstring .=&Apache::edit::select_arg('Encrypt URL:','encrypturl', + ['no','yes'], $token, 2); + $currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row(); + my $src= &Apache::lonxml::get_param('src',$parstack,$safeeval); + my $alt= &Apache::lonxml::get_param('alt',$parstack,$safeeval); + my $width= &Apache::lonxml::get_param('width',$parstack,$safeeval); + my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval); + + if ($token->[2]{'src'}=~/\$/) { + $currentstring.='Variable image source'; + } else { + $currentstring .= '<img src="'.$src.'" alt="'.$alt.'" '; + if ($width) { $currentstring.=' width="'.$width.'" '; } + if ($height) { $currentstring.=' height="'.$height.'" '; } + $currentstring .= ' />'; + } + } elsif ($target eq 'modified') { + my ($osrc,$owidth,$oheight)= + ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'}); + my $ctag=&Apache::edit::get_new_args($token,$parstack, + $safeeval,'src','alt','align', + 'TeXwidth','TeXheight', 'TeXwrap', + 'width','height','encrypturl'); + my ($nsrc,$nwidth,$nheight)= + ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'}); + my $loc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$nsrc); + &image_replication($loc); + my ($iwidth,$iheight); + if (-e $loc) { + my $image = Image::Magick->new; + $image->Read($loc); + ($iwidth, $iheight) = ($image->Get('width'), + $image->Get('height')); + } + if ($osrc ne $nsrc || (!$nwidth && !$nheight)) { + # changed image or no size specified, + # if they didn't explicitly change the + # width or height use the ones from the image + if ($iwidth && $iheight) { + if ($owidth == $nwidth || (!$nwidth && !$nheight)) { + $token->[2]{'width'} = $iwidth;$ctag=1; + } + if ($oheight == $nheight || (!$nwidth && !$nheight)) { + $token->[2]{'height'}=$iheight;$ctag=1; + } + } + } + my ($cwidth,$cheight)=($token->[2]{'width'},$token->[2]{'height'}); + # if we don't have a width or height + if ($iwidth && $cwidth && !$cheight) { + $token->[2]{'height'}=int(($cwidth/$iwidth)*$iheight);$ctag=1; + } + if ($iheight && $cheight && !$cwidth) { + $token->[2]{'width'}=int(($cheight/$iheight)*$iwidth);$ctag=1; + } + if ($ctag) {$currentstring=&Apache::edit::rebuild_tag($token);} + } + + return $currentstring; +} + +sub end_img { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring = ''; + } + return $currentstring; +} + +#-- <applet> tag (end tag required) +sub start_applet { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + + my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval,undef,1); + &Apache::lonxml::extlink($code); + my $archive=&Apache::lonxml::get_param('archive',$parstack,$safeeval, + undef,1); + &Apache::lonxml::extlink($archive); + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + if ($env{'browser.appletsuppress'} ne 'on') { + $currentstring = &Apache::lonenc::encrypt_ref($token, + {'code'=>$code, + 'archive'=>$archive} + ); + } else { + my $alttag= &Apache::lonxml::get_param('alt',$parstack, + $safeeval,undef,1); + unless ($alttag) { + $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1], + $code); + } + $currentstring='[APPLET: '.$alttag.']'; + } + } elsif ($target eq 'tex') { + # Turn off some stuff we can't be inside thank you LaTeX + + + my $restart_sub = 0; + my $restart_sup = 0; + + # Since <sub> and <sup> are simple tags it's ok to turn off/on + # using the start_ stop_ functions.. those tags only care about + # $target. + + if (&is_inside_of($tagstack, "sub")) { + $restart_sub = 1; + $currentstring .= &end_sub($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + if (&is_inside_of($tagstack, "sup")) { + $restart_sup = 1; + $currentstring .= &end_sup($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + + # Now process the applet; just replace it with its alt attribute. + + my $alttag= &Apache::lonxml::get_param('alt',$parstack, + $safeeval,undef,1); + unless ($alttag) { + my $code=&Apache::lonxml::get_param('code',$parstack,$safeeval, + undef,1); + $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1], + $code); + } + $currentstring.='\begin{center} \fbox{Java Applet: '.$alttag. + '.}\end{center}'; + + # Turn stuff back on that we can't be inside of. + + if ($restart_sub) { + $currentstring .= &start_sub($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + if ($restart_sup) { + $currentstring .= &start_sup($target, $token, $tagstack, + $parstack, $parser, $safeeval); + } + } + return $currentstring; +} + +sub end_applet { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + } + return $currentstring; +} + +#-- <embed> tag (end tag optional/required) +sub start_embed { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); + &Apache::lonxml::extlink($src); + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + if ($env{'browser.embedsuppress'} ne 'on') { + $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src}); + } else { + my $alttag=&Apache::lonxml::get_param + ('alt',$parstack,$safeeval,undef,1); + unless ($alttag) { + $alttag=&Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],$src); + } + $currentstring='[EMBED: '.$alttag.']'; + } + } elsif ($target eq 'tex') { + } + return $currentstring; +} + +sub end_embed { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + } + return $currentstring; +} + +#-- <param> tag (end tag forbidden) +sub start_param { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + if (&Apache::lonxml::get_param('name',$parstack, + $safeeval,undef,1)=~/^cabbase$/i) { + my $value=&Apache::lonxml::get_param('value',$parstack, + $safeeval,undef,1); + &Apache::lonxml::extlink($value); + } + + my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); + &Apache::lonxml::extlink($src); + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + my %toconvert; + my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); + if ($src) { $toconvert{'src'}= $src; } + my $name=&Apache::lonxml::get_param('name',$parstack,$safeeval, + undef,1); + if ($name=~/^cabbase$/i) { + $toconvert{'value'}=&Apache::lonxml::get_param('value',$parstack, + $safeeval,undef,1); + } + $currentstring = &Apache::lonenc::encrypt_ref($token,\%toconvert); + } elsif ($target eq 'tex') { + } + return $currentstring; +} + +sub end_param { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + } + return $currentstring; +} + +#-- <allow> tag +sub start_allow { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); + &Apache::lonxml::extlink($src); + + if ($target eq 'tex') { &image_replication($src); } + my $result; + if ($target eq 'edit') { + $result .=&Apache::edit::tag_start($target,$token); + $result .=&Apache::edit::text_arg('File Spec:','src',$token,70); + $result .=&Apache::edit::end_row();#.&Apache::edit::start_spanning_row(); + } elsif ($target eq 'modified') { + my $constructtag=&Apache::edit::get_new_args($token,$parstack, + $safeeval,'src'); + if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); } + } + return $result; +} + +sub end_allow { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + if ( $target eq 'edit') { return (&Apache::edit::end_table()); } + return ''; +} + +#-- Frames (end tag required) +#-- <frameset> +sub start_frameset { + my ($target,$token) = @_; + my $currentstring = ''; # Close any pending para. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = + &Apache::loncommon::start_page($Apache::londefdef::title, + $Apache::londefdef::head, + {'add_entries' => $token->[2], + 'no_title' => 1, + 'force_register' => 1, + 'frameset' => 1,}); + + } + return $currentstring; +} + +sub end_frameset { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <xmp> (end tag required) +sub start_xmp { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\begin{verbatim}'; + } + return $currentstring; +} + +sub end_xmp { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '\end{verbatim}'; + } + return $currentstring; +} + +#-- <pre> (end tag required) +sub start_pre { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # close off pending <p> + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } elsif ($target eq 'tex') { + $currentstring .= '\begin{verbatim}'; + &Apache::lonxml::disable_LaTeX_substitutions(); + } + return $currentstring; +} + +sub end_pre { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[2]; + } elsif ($target eq 'tex') { + $currentstring .= '\end{verbatim}'; + &Apache::lonxml::enable_LaTeX_substitutions(); + } + return $currentstring; +} + +#-- <insert> +sub start_insert { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1); + $currentstring .= '<b>'.$display.'</b>';; + } + return $currentstring; +} + +sub end_insert { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= ''; + } + return $currentstring; +} + +#-- <externallink> +sub start_externallink { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + my $display = &Apache::lonxml::get_param('display',$parstack,$safeeval,undef,1); + $currentstring .= '<b>'.$display.'</b>';; + } + return $currentstring; +} + +sub end_externallink { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= ''; + } + return $currentstring; +} + +#-- <blankspace heigth=""> +sub start_blankspace { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = &end_p(); # closes off any unclosed <p> + if ($target eq 'tex') { + my $howmuch = &Apache::lonxml::get_param('heigth',$parstack,$safeeval,undef,1); + $currentstring .= '\vskip '.$howmuch.' '; + } + return $currentstring; +} + +sub end_blankspace { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'tex') { + $currentstring .= ''; + } + return $currentstring; +} + +#-- <abbr> tag (end tag required) +sub start_abbr { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_abbr { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <acronym> tag (end tag required) +sub start_acronym { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_acronym { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <area> tag (end tag forbidden) +sub start_area { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_area { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <base> tag (end tag forbidden) +sub start_base { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_base { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <bdo> tag (end tag required) +sub start_bdo { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_bdo { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <bgsound> tag (end tag optional) +sub start_bgsound { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_bgsound { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <blink> tag (end tag required) +sub start_blink { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_blink { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <blockquote> tag (end tag required) +sub start_blockquote { + my ($target,$token) = @_; + my $currentstring = &end_p(); # Close any unclosed <p> + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } + if ($target eq 'tex') { + $currentstring .= '\begin{quote}'; + } + return $currentstring; +} + +sub end_blockquote { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + if ($target eq 'tex') { + $currentstring = '\end{quote}'; + } + return $currentstring; +} + +#-- <button> tag (end tag required) +sub start_button { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_button { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <caption> tag (end tag required) +sub start_caption { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_caption { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <col> tag (end tag forbdden) +sub start_col { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_col { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <colgroup> tag (end tag optional) +sub start_colgroup { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_colgroup { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <del> tag (end tag required) +sub start_del { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_del { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <fieldset> tag (end tag required) +sub start_fieldset { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_fieldset { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <frame> tag (end tag forbidden) +sub start_frame { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_frame { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <iframe> tag (end tag required) +sub start_iframe { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_iframe { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <ins> tag (end tag required) +sub start_ins { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_ins { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <isindex> tag (end tag forbidden) +sub start_isindex { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_isindex { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <keygen> tag (end tag forbidden) +sub start_keygen { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_keygen { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <label> tag +sub start_label { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_label { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <layer> tag (end tag required) +sub start_layer { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_layer { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <legend> tag (end tag required) +sub start_legend { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_legend { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <link> tag (end tag forbidden) +sub start_link { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval, + undef,1); + &Apache::lonxml::extlink($href); + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_link { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <marquee> tag (end tag optional) +sub start_marquee { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_marquee { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <multicol> tag (end tag required) +sub start_multicol { + my ($target,$token) = @_; + my $currentstring = &end_p(); # Close any pending <p> + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } + return $currentstring; +} + +sub end_multicol { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <nobr> tag (end tag required) +sub start_nobr { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + $currentstring='\mbox{'; + } + return $currentstring; +} + +sub end_nobr { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring='}'; + } + return $currentstring; +} + +#-- <noembed> tag (end tag required) +sub start_noembed { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_noembed { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <noframes> tag (end tag required) +sub start_noframes { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_noframes { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <nolayer> tag (end tag required) +sub start_nolayer { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_nolayer { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <noscript> tag (end tag required) +sub start_noscript { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_noscript { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <object> tag (end tag required) +sub start_object { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_object { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <optgroup> tag (end tag required) +sub start_optgroup { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_optgroup { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <samp> tag (end tag required) +sub start_samp { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + $currentstring='\texttt{'; + } + return $currentstring; +} + +sub end_samp { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring='}'; + } + return $currentstring; +} + +#-- <server> tag +sub start_server { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_server { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <spacer> tag (end tag forbidden) +sub start_spacer { + my ($target,$token) = @_; + my $currentstring = &end_p(); # Close off any open <p> tag. + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring .= $token->[4]; + } + return $currentstring; +} + +sub end_spacer { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <span> tag (end tag required) +sub start_span { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_span { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <tbody> tag (end tag optional) +sub start_tbody { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_tbody { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <tfoot> tag (end tag optional) +sub start_tfoot { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_tfoot { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <thead> tag (end tag optional) +sub start_thead { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_thead { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <var> tag +sub start_var { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } elsif ($target eq 'tex') { + $currentstring = '\textit{'; + } + return $currentstring; +} + +sub end_var { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } elsif ($target eq 'tex') { + $currentstring = '}'; + } + return $currentstring; +} + +#-- <wbr> tag (end tag forbidden) +sub start_wbr { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_wbr { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- <hideweboutput> tag +sub start_hideweboutput { + my ($target,$token) = @_; + if ($target eq 'web' || $target eq 'webgrade') { + &Apache::lonxml::startredirection(); + } + return ''; +} + +sub end_hideweboutput { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = &Apache::lonxml::endredirection(); + } + return ''; +} + + +sub image_replication { + my $src = shift; + if (not -e $src) { &Apache::lonnet::repcopy($src); } + #replicates eps or ps + my $epssrc = my $pssrc = $src; + $epssrc =~ s/\.(gif|jpg|jpeg|png)$/.eps/i; + $pssrc =~ s/\.(gif|jpg|jpeg|png)$/.ps/i; + if (not -e $epssrc && not -e $pssrc) { + my $result=&Apache::lonnet::repcopy($epssrc); + if ($result ne 'ok') { &Apache::lonnet::repcopy($pssrc); } + } + return ''; +} + + + +sub resize_image { + my ($height_param, $width_param, $scaling, + $parstack, $safeeval, $depth, $cis) = @_; + + # First apply the scaling... + + $height_param = $height_param * $scaling; + $width_param = $width_param * $scaling; + + #do we have any specified LaTeX size of the picture? + my $toget='TeXwidth'; + if ($cis) { + $toget=lc($toget); + } + my $TeXwidth = &Apache::lonxml::get_param($toget,$parstack, + $safeeval,$depth,$cis); + $toget='TeXheight'; if ($cis) { $toget=lc($toget); } + my $TeXheight = &Apache::lonxml::get_param($toget,$parstack, + $safeeval,$depth,$cis); + #do we have any specified web size of the picture? + my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval, + $depth,1); + if ($TeXwidth) { + my $old_width_param=$width_param; + if ($TeXwidth=~/(\d+)\s*\%/) { + $width_param = $1*$env{'form.textwidth'}/100; + } else { + $width_param = $TeXwidth; + } + if ($TeXheight) { + $height_param = $TeXheight; + } elsif ($old_width_param) { + $height_param=$TeXwidth/$old_width_param*$height_param; + } + } elsif ($TeXheight) { + $height_param = $TeXheight; + if ($height_param) { + $width_param = $TeXheight/$height_param*$width_param; + } + } elsif ($width) { + my $old_width_param=$width_param; + $width_param = $width*$scaling; + if ($old_width_param) { + $height_param=$width_param/$old_width_param*$height_param; + } + } + if ($width_param > $env{'form.textwidth'}) { + my $old_width_param=$width_param; + $width_param =0.95*$env{'form.textwidth'}; + if ($old_width_param) { + $height_param=$width_param/$old_width_param*$height_param; + } + } + + return ($height_param, $width_param); +} + +sub image_size { + my ($src,$scaling,$parstack,$safeeval,$depth,$cis)=@_; + + #size of image from gif/jpg/jpeg/png + my $ressrc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src); + if (-e $ressrc) { + $src = $ressrc; + } + my $image = Image::Magick->new; + my $current_figure = $image->Read($src); + my $width_param = $image->Get('width'); + my $height_param = $image->Get('height'); + &Apache::lonxml::debug("Image magick says: $src : Height = $height_param width = $width_param"); + undef($image); + + ($height_param, $width_param) = &resize_image($height_param, $width_param, + $scaling, $parstack, $safeeval, + $depth, $cis); + + return ($height_param, $width_param); +} + +sub image_width { + my ($height, $width) = &image_size(@_); + return $width; +} +# Not yet 100% sure this is correct in all circumstances.. +# due to my uncertainty about mods to image_size. +# +sub image_height { + my ($height, $width) = &image_size(@_); + return $height; +} + +sub get_eps_image { + my ($src)=@_; + my $orig_src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1], $src); + + # In order to prevent the substitution of the alt text, we need to + # be sure the orig_src file is on system now so: + + if (! -e $orig_src) { + &Apache::lonnet::repcopy($orig_src); # Failure is not completely fatal. + } + &Apache::lonxml::debug("get_eps_image: Original image: $orig_src"); + my ($spath, $sname, $sext) = &fileparse($src, qr/\.(bmp|gif|png|jpg|jpeg)/i); + $src=~s/\.(bmp|gif|png|jpg|jpeg)$/\.eps/i; + $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src); + &Apache::lonxml::debug("Filelocation gives: $src"); + if (! -e $src) { + &Apache::lonxml::debug("$src does not exist"); + if (&Apache::lonnet::repcopy($src) ne 'ok' ) { + &Apache::lonxml::debug("Repcopy of $src failed (1)"); + #if replication failed try to find ps file + $src=~s/\.eps$/\.ps/; + &Apache::lonxml::debug("Now looking for $src"); + #if no ps file try to replicate it. + my $didrepcopy = &Apache::lonnet::repcopy($src); + &Apache::lonxml::debug("repcopy of $src ... $didrepcopy"); + if ( (not -e $src) || + ($didrepcopy ne 'ok')) { + &Apache::lonxml::debug("Failed to find or replicate $src"); + + #if replication failed try to produce eps file dynamically + $src=~s/\.ps$/\.eps/; + my $temp_file; + open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat"); + my $newsrc=$orig_src; + $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|; + &Apache::lonxml::debug("queueing $newsrc for dynamic eps production."); + print FILE ("$newsrc\n"); + close(FILE); + $src=~s|/home/httpd/html/res|/home/httpd/prtspool|; + $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|; + if ($sext ne "") { # Put the ext. back in to uniquify. + $src =~ s/\.eps$/$sext.eps/; + } + + } + + } + } else { + # If the postscript file has spaces in its name, + # LaTeX will gratuitiously vomit. Therefore + # queue such files for copy with " " replaced by "_". + # printout.pm will know them by their .ps or .eps extensions. + my $newsrc = $orig_src; + $newsrc =~ s|(.*)/res/|/home/httpd/html/res/|; + open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat"); + print FILE "$src\n"; + close FILE; + $src=~s|/home/httpd/html/res|/home/httpd/prtspool|; + $src=~s|/home/([^/]*)/public_html/|/home/httpd/prtspool/$1/|; + } + my ($path,$file)=($src=~m|(.*)/([^/]*)$|); + $path =~ s/ /\_/g; + $file =~ s/ /\_/g; + &Apache::lonxml::debug("get_eps_image returning: $path / $file<BR />"); + return ($path.'/',$file); +} + +sub eps_generation { + my ($src,$file,$width_param) = @_; + my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat"; + my $temp_file = Apache::File->new('>>'.$filename); + print $temp_file "$src\n"; + my $newsrc = $src; + $newsrc =~ s/(\.bmp|\.gif|\.jpg|\.jpeg)$/\.eps/i; + $newsrc=~s{/home/httpd/html/res}{}; + $newsrc=~s{/home/($LONCAPA::username_re)/public_html/}{/$1/}; + $newsrc=~s{/\./}{/}; + $newsrc=~s{/([^/]+)\.(ps|eps)}{/}; + if ($newsrc=~m{/home/httpd/lonUsers/}) { + $newsrc=~s{/home/httpd/lonUsers}{}; + $newsrc=~s{/($LONCAPA::domain_re)/./././}{/$1/}; + } + if ($newsrc=~m{/userfiles/}) { + return ' \graphicspath{{'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} '; + } else { + return ' \graphicspath{{/home/httpd/prtspool'.$newsrc.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} '; + } +} + +sub file_path { + my $src=shift; + my ($file,$path); + if ($src =~ m!(.*)/([^/]*)$!) { + $file = $2; + $path = $1.'/'; + } + return $file,$path; +} + + +sub recalc { + my $argument = shift; + if (not $argument=~/(mm|cm|in|pc|pt)/) {return $argument.' mm';} + $argument=~/\s*(\d+\.?\d*)\s*(mm|cm|in|pc|pt)/; + my $value=$1; + my $units=$2; + if ($units eq 'cm') { + $value*=10; + } elsif ($units eq 'in') { + $value*=25.4; + } elsif ($units eq 'pc') { + $value*=(25.4*12/72.27); + } elsif ($units eq 'pt') { + $value*=(25.4/72.27); + } + return $value.' mm'; +} + +sub LATEX_length { + my $garbage=shift; + $garbage=~s/^\s+$//; + $garbage=~s/^\s+(\S.*)/$1/;#space before + $garbage=~s/(.*\S)\s+$/$1/;#space after + $garbage=~s/(\s)+/$1/;#only one space + $garbage=~s/(\\begin{([^\}]+)}|\\end{([^\}]+)})//g;#remove LaTeX \begin{...} and \end{...} + $garbage=~s/(\$\_\{|\$\_|\$\^{|\$\^|\}\$)//g;#remove $_{,$_,$^{,$^,}$ + $garbage=~s/([^\\])\$/$1/g;#$ + $garbage=~s/(\\ensuremath\{\_\{|\\ensuremath\{\_|\\ensuremath\{\^{|\\ensuremath\{\^|\})//g;#remove \ensuremath{...} + $garbage=~s/(\\alpha|\\beta|\\gamma|\\delta|\\epsilon|\\verepsilon|\\zeta|\\eta|\\theta|\\vartheta|\\iota|\\kappa|\\lambda|\\mu|\\nu|\\xi|\\pi|\\varpi|\\rho|\\varrho|\\sigma|\\varsigma|\\tau|\\upsilon|\\phi|\\varphi|\\chi|\\psi|\\omega|\\Gamma|\\Delta|\\Theta|\\Lambda|\\Xi|\\Pi|\\Sigma|\\Upsilon|\\Phi|\\Psi|\\Omega)/1/g; + $garbage=~s/(\\pm|\\mp|\\times|\\div|\\cdot|\\ast|\\star|\\dagger|\\ddagger|\\amalg|\\cap|\\cup|\\uplus|\\sqcap|\\sqcup|\\vee|\\wedge|\\oplus|\\ominus|\\otimes|\\circ|\\bullet|\\diamond|\\lhd|\\rhd|\\unlhd|\\unrhd|\\oslash|\\odot|\\bigcirc|\\Box|\\Diamond|\\bigtriangleup|\\bigtriangledown|\\triangleleft|\\triangleright|\\setminus|\\wr)/1/g; + $garbage=~s/(\\le|\\ll|\\leq|\\ge|\\geq|\\gg|\\neq|\\doreq|\\sim|\\simeq|\\subset|\\subseteq|\\sqsubset|\\sqsubseteq|\\in|\\vdash|\\models|\\supset|\\supseteq|\\sqsupset|\\sqsupseteq|\\ni|\\dash|\\perp|\\approx|\\cong|\\equiv|\\propto|\\prec|\\preceq|\\parallel|\\asymp|\\smile|\\frown|\\bowtie|\\succ|\\succeq|\\mid)/1/g; + $garbage=~s/(\\not<|\\\\not\\le|\\not\\prec|\\not\\preceq|\\not\\subset|\\not\\subseteq|\\not\\sqsubseteq|\\not\\in|\\not>|\\not\\ge|\\not\\succ|\\notsucceq|\\not\\supset|\\notsupseteq|\\not\\sqsupseteq|\\notin|\\not=|\\not\\equiv|\\not\\sim|\\not\\simeq|\\not\\approx|\\not\\cong|\\not\\asymp)/1/g; + $garbage=~s/(\\leftarrow|\\gets|\\Leftarrow|\\rightarrow|\\to|\\Rightarrow|\\leftrightarrow|\\Leftrightarrow|\\mapsto|\\hookleftarrow|\\leftharpoonup|\\leftkarpoondown|\\rightleftharpoons|\\longleftarrow|\\Longleftarrow|\\longrightarrow|\\Longrightarrow|\\longleftrightarrow|\\Longleftrightarrow|\\longmapsto|\\hookrightarrow|\\rightharpoonup|\\rightharpoondown|\\uparrow|\\Uparrow|\\downarrow|\\Downarrow|\\updownarrow|\\Updownarrow|\\nearrow|\\searrow|\\swarrow|\\nwarrow)/11/g; + $garbage=~s/(\\aleph|\\hbar|\\imath|\\jmath|\\ell|\\wp|\\Re|\\Im|\\mho|\\prime|\\emptyset|\\nabla|\\surd|\\partial|\\top|\\bot|\\vdash|\\dashv|\\forall|\\exists|\\neg|\\flat|\\natural|\\sharp|\\\||\\angle|\\backslash|\\Box|\\Diamond|\\triangle|\\clubsuit|\\diamondsuit|\\heartsuit|\\spadesuit|\\Join|\\infty)/11/g; + $garbage=~s/(\\hat{([^}]+)}|\\check{([^}]+)}|\\dot{([^}]+)}|\\breve{([^}]+)}|\\acute{([^}]+)}|\\ddot{([^}]+)}|\\grave{([^}]+)}|\\tilde{([^}]+)}|\\mathring{([^}]+)}|\\bar{([^}]+)}|\\vec{([^}]+)})/$1/g; + #remove some other LaTeX command + $garbage=~s|\\(\w+)\\|\\|g; + $garbage=~s|\\(\w+)(\s*)|$2|g; + $garbage=~s|\+|11|g; + my $value=length($garbage); + return $value; +} + + +sub align_latex_image { + my ($align, $latex_rendering, $image, $width, $height) = @_; + my $currentstring; # The 1/2 wrapped image. + my $closure; # The closure of the wrappage. + + # if it's none just return it back + if ($latex_rendering eq 'none') { + return ($image,''); + } + + # If there's an alignment specification we need to honor it here. + # For the horizontal alignments, we will also honor the + # value of the latex specfication. The default is parbox, + # and that's used for illegal values too. + # + # Even though we set a default alignment value, the user + # could have given us an illegal value. In that case we + # just use the default alignment of bottom.. + $currentstring = "\n% figurewrapping \n"; + if ($align eq "top") { + $currentstring .= '\raisebox{-'.$height.'mm}{'.$image; + $closure = '}'; + } elsif (($align eq "center") || ($align eq "middle")) { # Being kind + my $offset = $height/2; + $currentstring .= '\raisebox{-'.$offset.'mm}{'.$image; + $closure = '}'; + } elsif ($align eq "left") { + if ($latex_rendering eq "parpic") { + $currentstring .= '\parpic[l]{'.$image; + $closure = '}'; + } elsif ($latex_rendering eq "parbox") { + $currentstring .= '\begin{minipage}[l]{'.$width.'mm}' + .$image; + $closure = '\end{minipage}'; + } elsif ($latex_rendering eq "wrapfigure" + || $latex_rendering ne 'none') { # wrapfig render + $currentstring .= + '\begin{wrapfigure}{l}{'.$width.'mm}' + .'\scalebox{1.0}{'.$image; + $closure = '}\end{wrapfigure}'; + } + } elsif ($align eq "right") { + if ($latex_rendering eq "parpic") { + $currentstring .= '\parpic[r]{'.$image; + $closure = '}'; + } elsif ($latex_rendering eq "parbox") { + $currentstring .= '\begin{minipage}[r]{'.$width.'mm}' + .$image; + $closure = '\end{minipage}'; + } elsif ($latex_rendering eq "wrapfigure" + || $latex_rendering ne 'none') { # wrapfig render + $currentstring .= + '\begin{wrapfigure}{r}{'.$width.'mm}' + .'\scalebox{1.0}{'.$image; + $closure = '}\end{wrapfigure}'; + } + } else { # Bottom is also default. + # $currentstring = '\raisebox{'.$height.'mm}{'.$image.'}'; + $currentstring .= "{$image"; + $closure = '}'; + } + $currentstring .= "\n% end wrappage\n"; + $closure = "\n% Begin closure\n".$closure."\n% End closure\n"; + return ($currentstring, $closure); +} + + +sub is_inside_of { + my ($tagstack, $tag) = @_; + my @stack = @$tagstack; + for (my $i = ($#stack - 1); $i >= 0; $i--) { + if ($stack[$i] eq $tag) { + return 1; + } + } + return 0; +} + + +# +# This sub provides the typical LaTeX prefix matter for tex output: +# +sub latex_header +{ + my $currentstring = ''; + + $currentstring .= + '\documentclass[letterpaper,twoside]{article}\raggedbottom'; + if (($env{'form.latex_type'}=~'batchmode') || + (!$env{'request.role.adv'})) {$currentstring .='\batchmode';} + $currentstring .= '\newcommand{\keephidden}[1]{}'. + '\renewcommand{\deg}{$^{\circ}$}'. + '\usepackage{multirow}'. + '\usepackage{longtable}'. + '\usepackage{textcomp}'. + '\usepackage{makeidx}'. + '\usepackage[dvips]{graphicx}'. + '\usepackage{wrapfig}'. + '\usepackage{picins}'. + '\usepackage[T1]{fontenc}'."\n". + '\usepackage{lmodern}'."\n". + '\usepackage[postscript]{ucs}'."\n". + '\usepackage[utf8x]{inputenc}'."\n". + '\usepackage{pifont}' ."\n". + '\usepackage{latexsym}'."\n". + '\usepackage{epsfig}'. + "\\usepackage{xtab}\n". + "\\usepackage{tabularx}\n". + "\\usepackage{booktabs}\n". + "\\usepackage{array}\n". + "\\usepackage{colortbl}\n". + "\\usepackage{xcolor}\n". + '\usepackage{calc}'. + '\usepackage{amsmath}'. + '\usepackage{amssymb}'. + '\usepackage{amsfonts}'. + '\usepackage{amsthm}'. + '\usepackage{amscd}'; + + if($env{'form.pdfFormFields'} eq 'yes') { + $currentstring .= '\usepackage{hyperref}'. + '\usepackage{eforms}'. + '\usepackage{tabularx}'; + } + + $currentstring .= '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'. + '\renewenvironment{theindex}{\begin{list}{}{{\vskip 1mm \noindent \large\textbf{Index}} \newline \setlength{\rightmargin}{0in}\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.01in}\setlength{\itemsep}{0.1in}\setlength{\parsep}{-0.02in}\setlength{\belowdisplayskip}{0.01in}\setlength{\abovedisplayskip}{0.01in}\setlength{\abovedisplayshortskip}{-0.04in}\setlength{\belowdisplayshortskip}{0.01in}}}{\end{list}}'; + + return $currentstring; + +} + +=pod + +=head1 NAME + +Apache::londefdef.pm + +=head1 SYNOPSIS + +Tags Default Definition Module + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + + +=head1 NOTABLE SUBROUTINES + +=over + +=item start_hideweboutput() + +=item end_hideweboutput() + +=item image_replication() + +=item resize_image() + + Get correct sizing parameter for an image given + it's initial ht. and wid. This allows sizing of + images that are generated on-the-fly (e.g. gnuplot) + as well as serving as a utility for image_size. + + Parameter: + height_param + width_param - Initial picture dimensions. + scaling - A scale factor. + parstack, - the current stack of tag attributes + from the xml parser + safeeval, - pointer to the safespace + depth, - from what level in the stack to look for attributes + (assumes -1 if unspecified) + cis - look for attrubutes case insensitively + (assumes false) + + Returns: + height, width - new dimensions. + +=item image_size() + +=item image_width() + +=item image_height() + +=item get_eps_image() + +=item eps_generation() + +=item file_path() + +=item recalc() + + Converts a measurement in to mm from any of + the other valid LaTeX units of measure. + If the units of measure are missing from the + parameter, it is assumed to be in and returned + with mm units of measure + +=item LATEX_length() + +=item align_latex_image() + + Wrap image 'stuff' inside of the LaTeX required to implement + alignment: + align_tex_image(align, latex_rendering, image) + Where: + align - The HTML alignment specification. + latex_rendering - rendering hint for latex. + image - The LaTeX needed to insert the image itsef. + width,height - dimensions of the image. + Returns: + The 1/2 wrapped image and the stuff required to close the + wrappage. This allows e.g. randomlabel to insert more stuff + into the closure. + + +=item is_inside_of($tagstack, $tag) + This sub returns true if the current state of Xml processing is inside of the tag. + Parameters: + tagstack - The tagstack from the parser. + tag - The tag (without the <>'s.). + Sample usage: + if (is_inside_of($tagstack "table")) { + I'm in a table.... + } + + + +=back + +=cut + 1; __END__