--- loncom/xml/londefdef.pm 2004/10/12 22:55:22 1.242 +++ loncom/xml/londefdef.pm 2005/02/09 15:56:45 1.254 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Tags Default Definition Module # -# $Id: londefdef.pm,v 1.242 2004/10/12 22:55:22 albertel Exp $ +# $Id: londefdef.pm,v 1.254 2005/02/09 15:56:45 www Exp $ # # # Copyright Michigan State University Board of Trustees @@ -36,10 +36,6 @@ # The C source of the Code may not be distributed by the Licensee # to any other parties under any circumstances. # -# -# last modified 06/26/00 by Alexander Sakharuk -# 11/6,11/30,02/01/01,5/4 Gerd Kortemeyer -# 01/18 Alex Sakharuk package Apache::londefdef; @@ -63,9 +59,10 @@ sub initialize_londefdef { $Apache::londefdef::TD_redirection=0; @Apache::londefdef::table = (); $Apache::londefdef::select=0; - @Apache::londefdef::description=(); - $Apache::londefdef::DD_redirection=0; - $Apache::londefdef::DT_redirection=0; + undef(@Apache::londefdef::description); + @Apache::londefdef::DD=(0); + @Apache::londefdef::DT=(0); + @Apache::londefdef::seenDT=(0); $Apache::londefdef::list_index=0; } @@ -154,14 +151,16 @@ sub start_html { $currentstring = &Apache::lonxml::xmlbegin(); } elsif ($target eq 'tex') { @Apache::londefdef::table = (); - $currentstring .= '\documentclass[letterpaper]{book}'; - if ($ENV{'form.latex_type'}=~'batchmode') {$currentstring .='\batchmode';} + $currentstring .= '\documentclass[letterpaper]{article}'; + if (($ENV{'form.latex_type'}=~'batchmode') || + (!$ENV{'request.role.adv'})) {$currentstring .='\batchmode';} $currentstring .= '\newcommand{\keephidden}[1]{}'. '\renewcommand{\deg}{$^{\circ}$}'. '\usepackage{longtable}'. '\usepackage{textcomp}'. '\usepackage{makeidx}'. '\usepackage[dvips]{graphicx}'. + '\usepackage{picins}'. '\usepackage{epsfig}'. '\usepackage{calc}'. '\usepackage{amsmath}'. @@ -478,6 +477,7 @@ sub end_accessrule { sub start_body { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; + if ($target eq 'web') { if ($Apache::lonhomework::parsing_a_problem) { &Apache::lonxml::warning(" tag found inside of tag this can cause problems."); @@ -529,12 +529,19 @@ sub start_body { $token->[2]->{'onunload'}=&Apache::lonmenu::unloadevents(). ';'.$onUnload; - $currentstring .= '<'.$token->[1]; + if ($ENV{'request.state'} ne 'construct') { + $currentstring .= '<'.$token->[1]; + } foreach (keys %{$token->[2]}) { $currentstring.=' '.$_.'="'.$token->[2]->{$_}.'"'; } - $currentstring.='>'; + if ($ENV{'request.state'} ne 'construct') { + $currentstring.='>'; + } if ($ENV{'request.state'} ne 'published') { + my $remote=($ENV{'environment.remote'} ne 'off'); + $currentstring=&Apache::loncommon::bodytag(undef,undef, + $currentstring,$remote); $currentstring.=(< @@ -1453,7 +1460,9 @@ sub start_a { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; my $currentstring = ''; if ($target eq 'web') { - $currentstring .= $token->[4]; + my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval, + undef,1); + $currentstring=&Apache::lonenc::encrypt_ref($token,{'href'=>$href}); } elsif ($target eq 'tex') { my $a=&Apache::lonxml::get_param('href',$parstack,$safeeval,undef,1); my $b=&Apache::lonxml::get_param('name',$parstack,$safeeval,undef,1); @@ -1697,9 +1706,11 @@ sub start_dl { $currentstring = $token->[4]; } elsif ($target eq 'tex') { $currentstring = '\begin{description}'; - @Apache::londefdef::description=(); - $Apache::londefdef::DD_redirection=0; - $Apache::londefdef::DT_redirection=0; + $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; } @@ -1710,18 +1721,17 @@ sub end_dl { if ($target eq 'web') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { - if ($Apache::londefdef::DT_redirection) { - my $data=&item_cleanup; - push @Apache::londefdef::description,'\item['.$data.']'; - $Apache::londefdef::DT_redirection=0; - } elsif ($Apache::londefdef::DD_redirection) { - $Apache::londefdef::description[-1].=&Apache::lonxml::endredirection(); - } - foreach my $element (@Apache::londefdef::description) { + if ($Apache::londefdef::DT[-1]) { &end_dt(@_); } + if ($Apache::londefdef::DD[-1]) { &end_dd(@_); } + foreach my $element (@{$Apache::londefdef::description[-1]}) { $currentstring.=' '.$element.' '; } - @Apache::londefdef::description=(); + 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; } @@ -1733,16 +1743,11 @@ sub start_dt { if ($target eq 'web') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { - if ($Apache::londefdef::DT_redirection) { - my $data=&item_cleanup; - push @Apache::londefdef::description,'\item['.$data.']'; - $Apache::londefdef::DT_redirection=0; - } elsif ($Apache::londefdef::DD_redirection) { - $Apache::londefdef::description[-1].=&Apache::lonxml::endredirection(); - $Apache::londefdef::DD_redirection=0; - } + if ($Apache::londefdef::DT[-1]) { &end_dt(@_); } + if ($Apache::londefdef::DD[-1]) { &end_dd(@_); } &Apache::lonxml::startredirection(); - $Apache::londefdef::DT_redirection=1; + $Apache::londefdef::DT[-1]++; + $Apache::londefdef::seenDT[-1]=1; } return $currentstring; } @@ -1753,9 +1758,11 @@ sub end_dt { if ($target eq 'web') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { - my $data=&item_cleanup; - push @Apache::londefdef::description,'\item['.$data.']'; - $Apache::londefdef::DT_redirection=0; + 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; } @@ -1774,12 +1781,14 @@ sub start_dd { if ($target eq 'web') { $currentstring = $token->[4]; } elsif ($target eq 'tex') { - if ($Apache::londefdef::DT_redirection) { - my $data=&item_cleanup; - push @Apache::londefdef::description,'\item['.$data.']'; - $Apache::londefdef::DT_redirection=0; - } - $Apache::londefdef::DD_redirection=1; + 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; @@ -1791,8 +1800,9 @@ sub end_dd { if ($target eq 'web') { $currentstring = $token->[2]; } elsif ($target eq 'tex') { - $Apache::londefdef::description[-1].=&Apache::lonxml::endredirection(); - $Apache::londefdef::DD_redirection=0; + $Apache::londefdef::description[-1]->[-1].= + &Apache::lonxml::endredirection().' \vskip 0mm '; + $Apache::londefdef::DD[-1]--; } return $currentstring; } @@ -2409,6 +2419,16 @@ sub end_th { } #-- tag (end tag forbidden) +# +# Render the tag. +# 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) = @_; my $src = &Apache::lonxml::get_param('src',$parstack,$safeeval, @@ -2420,9 +2440,12 @@ sub start_img { $Apache::lonxml::extlinks[$#Apache::lonxml::extlinks+1]=$src; my $currentstring = ''; my $scaling = .3; + + # Render unto browsers that which are the browser's... + if ($target eq 'web') { if ($ENV{'browser.imagesuppress'} ne 'on') { - $currentstring.= $token->[4]; + $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src}); } else { my $alttag= &Apache::lonxml::get_param ('alt',$parstack,$safeeval,undef,1); @@ -2432,14 +2455,50 @@ sub start_img { } $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 = "parbox"; + } + &Apache::lonxml::debug("LaTeX rendering = $latex_rendering"); + my $oldSRC=$src; $oldSRC=~s/\.(gif|jpg|png)$/\.eps/; $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src); #if original gif/jpg/png file exist do following: if (-e $src) { #what is the image size? - my $width_param=&image_size($src,$scaling,$parstack,$safeeval); + my $width_param=&image_width($src,$scaling,$parstack,$safeeval); + my $height_param=&image_height($src,$scaling,$parstack,$safeeval); my ($file,$path)=&file_path($src); my $newsrc = $src; $newsrc =~ s/\.(gif|jpg|png)$/.eps/i; @@ -2449,7 +2508,8 @@ sub start_img { if (-e $newsrc) { #eps counterpart for image exist if ($path) { - $currentstring .= '\vskip 1 mm \noindent\graphicspath{{'.$path.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} '; + $currentstring .= '\graphicspath{{'.$path.'}}' + .'\includegraphics[width='.$width_param.' mm,height='.$height_param.'mm]{'.$file.'} '; } } else { #there is no eps counterpart for image - check for ps one @@ -2458,13 +2518,42 @@ sub start_img { #ps counterpart for image exist $file =~ s/\.eps$/\.ps/; if ($path) { - $currentstring .= '\vskip 1 mm \noindent\graphicspath{{'.$path.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} '; + $currentstring .= '\graphicspath{{'.$path.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} '; } } else { #care about eps dynamical generation - $currentstring.='\vskip 1 mm '.&eps_generation($src,$file,$width_param); + $currentstring.=&eps_generation($src,$file,$width_param); } } + # 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.. + if ($align eq "top") { + $currentstring = '\raisebox{-'.$height_param.'mm}{'.$currentstring.'}'; + } elsif (($align eq "center") || ($align eq "middle")) { # Being kind + my $offset = $height_param/2; + $currentstring = '\raisebox{-'.$offset.'mm}{'.$currentstring.'}'; + } elsif ($align eq "left") { + if ($latex_rendering eq "parpic") { + $currentstring = '\parpic[l]{'.$currentstring.'}'; + } else { # parbox rendering + $currentstring = "\n".'\parbox{'.$width_param.'mm}{'.$currentstring.'}'; + } + } elsif ($align eq "right") { + if ($latex_rendering eq "parpic") { + $currentstring = '\parpic[r]{'.$currentstring.'}'; + } else { # parbox rendering. + $currentstring = '\parbox{'.$width_param.'mm}{\begin{flushright}' + .$currentstring.'\end{flushright}} \newline'."\n"; + } + } else { # Bottom is also default. + # $currentstring = '\raisebox{'.$height_param.'mm}{'.$currentstring.'}'; + } } else { #original image file doesn't exist so check the alt attribute my $alt = @@ -2479,6 +2568,11 @@ sub start_img { # tag will care about replication } } + + # 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') { $currentstring .=&Apache::edit::tag_start($target,$token); $currentstring .=&Apache::edit::text_arg('Image Url:','src',$token,70). @@ -2491,11 +2585,15 @@ sub start_img { $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', + ['', 'parbox', 'parpic'], $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); + 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); + + $currentstring .= ''.$alt.'[2]{'src'},$token->[2]{'width'},$token->[2]{'height'}); my $ctag=&Apache::edit::get_new_args($token,$parstack, $safeeval,'src','alt','align', - 'TeXwidth','TeXheight', + 'TeXwidth','TeXheight', 'TeXwrap', 'width','height'); my ($nsrc,$nwidth,$nheight)= ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'}); @@ -2569,7 +2667,10 @@ sub start_applet { my $currentstring = ''; if ($target eq 'web') { if ($ENV{'browser.appletsuppress'} ne 'on') { - $currentstring = $token->[4]; + $currentstring = &Apache::lonenc::encrypt_ref($token, + {'code'=>$code, + 'archive'=>$archive} + ); } else { my $alttag= &Apache::lonxml::get_param('alt',$parstack, $safeeval,undef,1); @@ -2612,7 +2713,7 @@ sub start_embed { my $currentstring = ''; if ($target eq 'web') { if ($ENV{'browser.embedsuppress'} ne 'on') { - $currentstring = $token->[4]; + $currentstring=&Apache::lonenc::encrypt_ref($token,{'src'=>$src}); } else { my $alttag=&Apache::lonxml::get_param ('alt',$parstack,$safeeval,undef,1); @@ -2648,7 +2749,16 @@ sub start_param { &Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1); my $currentstring = ''; if ($target eq 'web') { - $currentstring = $token->[4]; + 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; @@ -3683,18 +3793,39 @@ sub image_size { my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval, undef,1); if ($TeXwidth ne '') { + my $old_width_param=$width_param; if ($TeXwidth=~/(\d+)\s*\%/) { $width_param = $1*$ENV{'form.textwidth'}/100; } else { $width_param = $TeXwidth; } + $height_param=$TeXwidth/$old_width_param*$height_param; } elsif ($TeXheight ne '') { - $width_param = $TeXheight/$height_param*$width_param; + $height_param = $TeXheight; + $width_param = $TeXheight/$height_param*$width_param; } elsif ($width ne '') { + my $old_width_param=$width_param; $width_param = $width*$scaling; + $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'}; + $height_param=$width_param/$old_width_param*$height_param; } - if ($width_param > $ENV{'form.textwidth'}) {$width_param =0.95*$ENV{'form.textwidth'}} - return $width_param; + 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 eps_generation {