File:  [LON-CAPA] / loncom / homework / randomlabel.pm
Revision 1.36: download - view: text, annotated - select for diffs
Tue Aug 27 18:21:27 2002 UTC (21 years, 8 months ago) by sakharuk
Branches: MAIN
CVS tags: version_0_5_1, HEAD
Now 1. Checks either original eps file exist on the current library server
       and use it if exist.
    2. Replicates eps file from owner's library server if it is absent on
       current library server.
    3. If replication fails it tries to find ps file on current library
       server (Ed has a lot of such files) and use it.
    4. Replicates ps file from owner's library server.
    5. If replication fails eps is dynamically originated.

# The LearningOnline Network with CAPA
# random labelling tool
#
# $Id: randomlabel.pm,v 1.36 2002/08/27 18:21:27 sakharuk 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/
#
# 7/20/2001 Isaac Tsai, initial syntax
# 8/10/2001 Isaac Tsai, 
# 8/30/2001 Isaac Tsai, 
# SYNTAX:
# <randomlabel bgimg="URL" width="12" height="45" texwidth="50">
#    <labelgroup name="GroupOne" type="image">
#      <location x="123" y="456" />
#      <location x="321" y="654" />
#      <location x="213" y="546" />
#      <label description="TEXT-1">IMG-URL</label>
#      <label description="TEXT-2">IMG-URL</label>
#      <label description="TEXT-3">IMG-URL</label>
#    </labelgroup>
#    <labelgroup name="GroupTwo" type="text">
#      <location x="12" y="45" />
#      <location x="32" y="65" />
#      <location x="21" y="54" />
#      <label>TEXT-1</label>
#      <label>TEXT-2</label>
#      <label>TEXT-3</label>
#    </labelgroup>
#   </randomlabel>
#  ===========================================
#  side effect:
#    location (123,456): $GroupOne[0] = 2  # images give out indexes
#             (321,654): $GroupOne[1] = 1
#             (213,546): $GroupOne[2] = 0
#    location (12,45)  : $GroupTwo[0] = "TEXT-3"
#             (32,65)  : $GroupTwo[1] = "TEXT-1"
#             (21,54)  : $GroupTwo[2] = "TEXT-2"
#  ===========================================
package Apache::randomlabel;
use Apache::lonnet;
use strict;
use Apache::edit;
use Apache::File();

BEGIN {
  &Apache::lonxml::register('Apache::randomlabel',('randomlabel','labelgroup','location','label'));
}

sub check_int {
    # utility function to do error checking on a integer.
    my ($num,$default) = @_;
    $default = 100 if (! defined($default));
    $num =~ s/\s+//g;  # We dont need no stinkin white space!
    # If it is a real, just grab the integer part.
    ($num,undef) = split (/\./,$num) if ($num =~ /\./); 
    # set to default if what we have left doesn't match anything...
    $num = $default unless ($num =~/^\d+$/);
    return $num;
}

sub start_randomlabel {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  my $result='';
  push (@Apache::lonxml::extlinks, '/res/adm/includes/GLabel.class');
  push (@Apache::lonxml::namespace,'randomlabel');
  my $bgimg= &Apache::lonxml::get_param('bgimg',$parstack,$safeeval);
  if ( $bgimg !~ /^http:/ ) {
    push (@Apache::lonxml::extlinks,$bgimg);
    $bgimg=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$bgimg);
    if ($bgimg =~ /$Apache::lonnet::perlvar{'lonDocRoot'}/) {
      $bgimg=~s/$Apache::lonnet::perlvar{'lonDocRoot'}//;
    } elsif ($bgimg =~ m:^/home/.*/public_html:) {
      $bgimg =~ s:^/home/(.*)/public_html:/~$1:;
    }
    $bgimg='http://'.$ENV{'SERVER_NAME'}.$bgimg;
  }
  my $code = &Apache::lonxml::get_param('code',$parstack,$safeeval);
  my $codebase = &Apache::lonxml::get_param('codebase',$parstack,$safeeval);
  my $w= &check_int(&Apache::lonxml::get_param('width',$parstack,$safeeval));
  my $h= &check_int(&Apache::lonxml::get_param('height',$parstack,$safeeval));
  my $texwidth= &Apache::lonxml::get_param('texwidth',$parstack,$safeeval);
  if (!$code) { $code='GLabel.class'; }
  if (!$codebase) { $codebase='/res/adm/includes/'; }
  $Apache::randomlabel::tlabel_cnt=0;
  $Apache::randomlabel::ilabel_cnt=0;
  if ($target eq 'web') {
    $result.="<applet code=\"$code\" codebase=\"$codebase\" width=\"$w\" height=\"$h\">\n";
    $result.="<param name=\"bgimg\" value=\"$bgimg\">\n";
  } elsif ($target eq 'tex') {
    my $newbgimg = $bgimg;
    $bgimg=~s/(.gif|.jpg)$/.eps/;
    $bgimg= &Apache::lonnet::filelocation($bgimg);
    if (not $ENV{'request.role'}=~/^au\./) {
	$bgimg=~s/http:\/[^\/]*/\/home\/httpd\/html/;
	$bgimg=~s/\/$//;
        #if no eps file try to replicate it
	if (not-e $bgimg) {
	    my $response = &Apache::lonnet::repcopy($bgimg);
            #if replication failed try to find ps file
	    if (not-e $bgimg) {
		$bgimg=~s/\.eps$/\.ps/;
		#if no ps file try to replicate it
		if (not-e $bgimg) {
		    $response = &Apache::lonnet::repcopy($bgimg);
		    #if replication failed try to produce eps file dynamically
		    $bgimg=~s/\.ps$/\.eps/;
		    my $temp_file;
		    my $filename = "/home/httpd/prtspool/$ENV{'user.name'}_$ENV{'user.domain'}_printout.dat";
		    $temp_file = Apache::File->new('>>'.$filename);
		    $newbgimg =~ s/(.*)\/res\//\/home\/httpd\/html\/res\//;
		    print $temp_file "$newbgimg\n";
		    $bgimg =~ m/\/([^\/]+)$/;
		    $bgimg = '/home/httpd/prtspool/'.$1;
		}
	    }
	}
    } else {
	$bgimg=~s/http:\/[^\/]*\/~([^\/]+)/\/home\/$1\/public_html/;
    }
    $bgimg=~s/\/$//;
    my $dirtywidth=$texwidth+5;
    if ($texwidth==90) {
	$result.='\vspace*{2mm}\noindent \parbox{'.$dirtywidth.' mm}{  \noindent \epsfxsize='.$texwidth.' mm \epsffile{'.
	    $bgimg.'}\setlength{\unitlength}{1mm}  \begin{picture}('.$texwidth.','.$texwidth*$h/$w.')(0,-'.$texwidth*$h/$w.')';
    } else {
	$result.='\vspace*{2mm}\noindent \parbox{'.$dirtywidth.' mm}{  \noindent \epsfxsize='.$texwidth.' mm \epsffile{'.
	    $bgimg.'}\setlength{\unitlength}{1mm}  \begin{picture}('.$texwidth.','.$texwidth*$h/$w.')(0,-'.$texwidth*$h/$w.')';
    }
  } elsif ($target eq 'edit') {
    $result.=&Apache::edit::tag_start($target,$token);
    $result.=&Apache::edit::text_arg('Image:','bgimg',$token,75).' ';
    $result.=&Apache::edit::browse('bgimg').' ';
    $result.=&Apache::edit::search('bgimg').'<br />'.
        &Apache::edit::text_arg('Width(pixel):' ,'width'   ,$token,6).
        &Apache::edit::text_arg('Height(pixel):','height'  ,$token,6).
        &Apache::edit::text_arg('TeXWidth(mm):' ,'texwidth',$token,6).
        &Apache::edit::end_row().&Apache::edit::start_spanning_row();     
  } elsif ($target eq 'modified') {
    my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,
						 'bgimg','width','height',
						 'texwidth');
    if ($constructtag) {
      $result = &Apache::edit::rebuild_tag($token);
      $result.=&Apache::edit::handle_insert();
    }
  }
  return $result;
}

sub end_randomlabel {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  my $result='';
  my $count;
  pop @Apache::lonxml::namespace;
  if ($target eq 'web') {
    $count = $Apache::randomlabel::tlabel_cnt;
    if( $count != 0) { $result.= "<param name=\"COUNT\" value=\"$count\">\n"; }
    $count = $Apache::randomlabel::ilabel_cnt;
    if( $count != 0) { $result.= "<param name=\"ICOUNT\" value=\"$count\">\n"; }
    $result .= "</applet>\n<BR />";
  } elsif ($target eq 'tex') {
      $result='\end{picture}\\\\}';
	  @$parstack[-1]=~/\$height\s*=\s*?"(.+)?"/;
      my $one=$1;
	  @$parstack[-1]=~/\$width\s*=\s*?"(.+)?"/;
      my $two=$1;
	  @$parstack[-1]=~/\$texwidth\s*=\s*?"(.+)?"/;
      my $three=$1;
      my $howtoskipback = $three*$one/$two;
      $result.=' \vskip -'.$howtoskipback.' mm ';
  } elsif ($target eq 'edit') {
    $result.=&Apache::edit::end_table;
  }
  return $result;
}

sub start_labelgroup {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  my $result='';
  my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
  my $type = &Apache::lonxml::get_param('type',$parstack,$safeeval);
  $type =~tr/A-Z/a-z/;
  if ($target eq 'web' || $target eq 'tex' || 
      $target eq 'grade' || $target eq 'answer') {
    $Apache::randomlabel::groupname=$name;
    $Apache::randomlabel::type=$type;
    @Apache::randomlabel::xcoord = ();
    @Apache::randomlabel::ycoord = ();
    @Apache::randomlabel::value = ();
    @Apache::randomlabel::label_arr  = ();
    @Apache::randomlabel::decription  = ();
  } elsif ($target eq 'edit') {
    $result.=&Apache::edit::tag_start($target,$token);
    $result.=&Apache::edit::text_arg('Name:','name',$token).
      &Apache::edit::select_arg('Type:','type',['text','image'],$token).
	  &Apache::edit::end_row().&Apache::edit::start_spanning_row();
  } elsif ($target eq 'modified') {
    my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,
						 'name','type');
    if ($constructtag) {
      $result = &Apache::edit::rebuild_tag($token);
      $result.=&Apache::edit::handle_insert();
    }
  }
  return $result;
}

sub add_vars {
  my ($name,$order,$label,$labelorder,$value,$image,$safeeval) = @_;
  my $code = '${'.$name."}{'".($order+1)."'}='".$label."';";
  my $out=Apache::run::run($code,$safeeval);
  if ($value) {
    $code = '${'.$name."}{'value_".($order+1)."'}='".$value."';";
    $out=Apache::run::run($code,$safeeval);
    $code = '${'.$name."}{'labelvalue_".($labelorder+1)."'}='".$value."';";
    $out=Apache::run::run($code,$safeeval);
  }
  if ($image) {
      my $code = '${'.$name."}{'image_".($order+1)."'}='".$image."';";
      my $out=Apache::run::run($code,$safeeval);
  }
  $code = '${'.$name."}{'numlocations'}='".($order+1)."';";
  $out=Apache::run::run($code,$safeeval);
}

# begin to assign labels to locations
sub end_labelgroup {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  my $gname = $Apache::randomlabel::groupname;
  my $type  = $Apache::randomlabel::type;
  my $result='';
  if ($target eq 'web' || $target eq 'answer' || $target eq 'grade') {
    my @idx_arr = (0 .. $#Apache::randomlabel::label_arr);
    &Apache::structuretags::shuffle(\@idx_arr);
    for(0 .. $#Apache::randomlabel::label_arr) {
      my $str;
      my $xstr;
      my $ystr;
      my $label = "$Apache::randomlabel::label_arr[ $idx_arr[$_] ]";
      my $x = $Apache::randomlabel::xcoord[$_];
      my $y = $Apache::randomlabel::ycoord[$_];
      my $value = $Apache::randomlabel::value[$_];
      if( $type eq 'text') {
	&add_vars($gname,$_,$label,$idx_arr[$_],$value,'',$safeeval);
	$str = 'LB'.$Apache::randomlabel::tlabel_cnt;
	$xstr = 'X'.$Apache::randomlabel::tlabel_cnt;
	$ystr = 'Y'.$Apache::randomlabel::tlabel_cnt;
	$Apache::randomlabel::tlabel_cnt += 1;
      } elsif ( $type eq 'image') {
	&add_vars($gname,$_,
		  $Apache::randomlabel::description[$idx_arr[$_]],
		  $idx_arr[$_],$value,$label,$safeeval);
	$str = 'IMG'.$Apache::randomlabel::ilabel_cnt;
	$xstr = 'IX'.$Apache::randomlabel::ilabel_cnt;
	$ystr = 'IY'.$Apache::randomlabel::ilabel_cnt;
	$Apache::randomlabel::ilabel_cnt += 1;
      } else {
	&Apache::lonxml::error('Unknown type of label :'.$type.':');
      }
      if ($target eq 'web') {
	$result .= '<param name="' . $str  . '" value="'.$label.'">';
	$result .= '<param name="' . $xstr . '" value="'.$x.'">';
	$result .= '<param name="' . $ystr . '" value="'.$y.'">'."\n";
      }
    }
  } elsif ($target eq 'tex') {
    my $WX1=0; #  Web x-coord. of upper left corner (ULC)
    my $WY1=0; #  Web y-coord. of (ULC)
    my $wwidth=&Apache::lonxml::get_param('width',$parstack,$safeeval,-2);
    my $wheight=&Apache::lonxml::get_param('height',$parstack,$safeeval,-2);
    my $texwidth=&Apache::lonxml::get_param('texwidth',$parstack,$safeeval,-2);
    my $TX1=0;
    my $TY1=$texwidth*($wheight/$wwidth);
    my $TX2=$texwidth;
    my $TY2=0;


    my $slopex=($wwidth-$WX1)/($TX2-$TX1);
    my $slopey=($wheight-$WY1)/($TY2-($TY1-1.0));
    my $cstx=$wwidth-$slopex*($TX2);
    my $csty=$wheight-$slopey*($TY2);

    my @idx_arr = (0 .. $#Apache::randomlabel::label_arr);
    &Apache::structuretags::shuffle(\@idx_arr);

    &Apache::lonxml::debug("Array is:".$#Apache::randomlabel::label_arr.":");
    for(my $i=0;$i <= $#Apache::randomlabel::label_arr; $i++) {
      my $label = "$Apache::randomlabel::label_arr[ $idx_arr[$i] ]";
      my $x = $Apache::randomlabel::xcoord[$i];
      my $y = $Apache::randomlabel::ycoord[$i];
      my $value = $Apache::randomlabel::value[$i];
      #x latex coordinate
      my $tcX=($x)*($texwidth/$wwidth);
      #y latex coordinate
#      my $ratio=($wwidth > 0 ? $wheight/$wwidth : 1 );
      my $tcY=$TY1-$y*($TY1/$wheight);
      $tcX=sprintf('%.2f',$tcX);
      $tcY=sprintf('%.2f',$tcY);
      $result.='\put('.$tcX.','.$tcY.'){\normalsize \bf '.$label.'}'."\n";
      if( $type eq 'text') {
	&add_vars($gname,$i,$label,$idx_arr[$i],$value,'',$safeeval);
      } elsif ( $type eq 'image') {
	&add_vars($gname,$i,
		  $Apache::randomlabel::description[$idx_arr[$i]],
		  $idx_arr[$i],$value,$label,$safeeval);
      } else {
	&Apache::lonxml::error('Unknown type of label :'.$type.':');
      }
    }
  } elsif ($target eq 'edit') {
    $result.=&Apache::edit::end_table;
  }
  return $result;
}

# <location x="123" y="456" value="some value"/>
sub start_location {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  my $x= &check_int(&Apache::lonxml::get_param('x',$parstack,$safeeval),50);
  my $y= &check_int(&Apache::lonxml::get_param('y',$parstack,$safeeval),50);
  my $value= &Apache::lonxml::get_param('value',$parstack,$safeeval);
  my $result='';
  push(@Apache::randomlabel::xcoord,$x);
  push(@Apache::randomlabel::ycoord,$y);
  push(@Apache::randomlabel::value,$value);
  if ($target eq 'edit') {
    $result.=&Apache::edit::tag_start($target,$token);
    $result.=&Apache::edit::text_arg('X:','x',$token,4).
      &Apache::edit::text_arg('Y:','y',$token,4).
	&Apache::edit::text_arg('Value:','value',$token).
	  &Apache::edit::end_row();
    $result.=&Apache::edit::end_table;
  } elsif ($target eq 'modified') {
    my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,
						 'x','y','value');
    if ($constructtag) {
      $result = &Apache::edit::rebuild_tag($token);
      $result.=&Apache::edit::handle_insert();
    }
  }
  return $result;
}

sub end_location {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  my @result;
  if ($target eq 'edit') { @result=('','no') }
  return @result;
}

# <label>$var_abc</label>
sub start_label {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  my $result='';
  my $type = &Apache::lonxml::get_param('type',$parstack,$safeeval,-2);
  if ($target eq 'web' || $target eq 'tex' || 
      $target eq 'grade' || $target eq 'answer') {
    my $ltext=&Apache::lonxml::get_all_text("/label",$$parser[-1]);
    $ltext=&Apache::run::evaluate($ltext,$safeeval,$$parstack[-1]);
    if ($type eq 'image') {
      &Apache::lonxml::debug("Turning $ltext and $Apache::lonxml::pwd[-1]");
      $ltext="http://$ENV{'SERVER_NAME'}".&Apache::lonnet::hreflocation($Apache::lonxml::pwd[-1],
					   $ltext);
      &Apache::lonxml::debug("into $ltext");
      my $description = &Apache::lonxml::get_param('description',
						   $parstack,$safeeval);
      push(@Apache::randomlabel::description,$description);
    }
    push(@Apache::randomlabel::label_arr,$ltext);
  } elsif ($target eq 'edit') {
    $result.=&Apache::edit::tag_start($target,$token,"$type Label");
    my $text=&Apache::lonxml::get_all_text("/label",$$parser[-1]);
    if ($type eq 'image') {
      $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
      $result.=&Apache::edit::text_arg('Description:','description',$token);
    }
    if ($type eq 'text') { $result.="Label Text:"; }
    if ($type eq 'image') { $result.="Path to image:"; }
    $result.=&Apache::edit::editline('',$text,'',20).
      &Apache::edit::end_table();
  } elsif ($target eq 'modified') {
    my $text=$$parser[-1]->get_text("/label");
    $result = '<label>';
    if ($type eq 'image') {
      my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,
						   'description');
      if ($constructtag) {
	$result = &Apache::edit::rebuild_tag($token);
      } else {
	$result = $token->[4];
      }
    }
    $result.=&Apache::edit::modifiedfield($token);
  }
  return $result;
}

sub end_label {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  my @result;
  if ($target eq 'edit') { @result=('','no') }
  return @result;
}



1;
__END__
 

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