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.

    1: # The LearningOnline Network with CAPA
    2: # random labelling tool
    3: #
    4: # $Id: randomlabel.pm,v 1.36 2002/08/27 18:21:27 sakharuk Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: # 7/20/2001 Isaac Tsai, initial syntax
   29: # 8/10/2001 Isaac Tsai, 
   30: # 8/30/2001 Isaac Tsai, 
   31: # SYNTAX:
   32: # <randomlabel bgimg="URL" width="12" height="45" texwidth="50">
   33: #    <labelgroup name="GroupOne" type="image">
   34: #      <location x="123" y="456" />
   35: #      <location x="321" y="654" />
   36: #      <location x="213" y="546" />
   37: #      <label description="TEXT-1">IMG-URL</label>
   38: #      <label description="TEXT-2">IMG-URL</label>
   39: #      <label description="TEXT-3">IMG-URL</label>
   40: #    </labelgroup>
   41: #    <labelgroup name="GroupTwo" type="text">
   42: #      <location x="12" y="45" />
   43: #      <location x="32" y="65" />
   44: #      <location x="21" y="54" />
   45: #      <label>TEXT-1</label>
   46: #      <label>TEXT-2</label>
   47: #      <label>TEXT-3</label>
   48: #    </labelgroup>
   49: #   </randomlabel>
   50: #  ===========================================
   51: #  side effect:
   52: #    location (123,456): $GroupOne[0] = 2  # images give out indexes
   53: #             (321,654): $GroupOne[1] = 1
   54: #             (213,546): $GroupOne[2] = 0
   55: #    location (12,45)  : $GroupTwo[0] = "TEXT-3"
   56: #             (32,65)  : $GroupTwo[1] = "TEXT-1"
   57: #             (21,54)  : $GroupTwo[2] = "TEXT-2"
   58: #  ===========================================
   59: package Apache::randomlabel;
   60: use Apache::lonnet;
   61: use strict;
   62: use Apache::edit;
   63: use Apache::File();
   64: 
   65: BEGIN {
   66:   &Apache::lonxml::register('Apache::randomlabel',('randomlabel','labelgroup','location','label'));
   67: }
   68: 
   69: sub check_int {
   70:     # utility function to do error checking on a integer.
   71:     my ($num,$default) = @_;
   72:     $default = 100 if (! defined($default));
   73:     $num =~ s/\s+//g;  # We dont need no stinkin white space!
   74:     # If it is a real, just grab the integer part.
   75:     ($num,undef) = split (/\./,$num) if ($num =~ /\./); 
   76:     # set to default if what we have left doesn't match anything...
   77:     $num = $default unless ($num =~/^\d+$/);
   78:     return $num;
   79: }
   80: 
   81: sub start_randomlabel {
   82:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   83:   my $result='';
   84:   push (@Apache::lonxml::extlinks, '/res/adm/includes/GLabel.class');
   85:   push (@Apache::lonxml::namespace,'randomlabel');
   86:   my $bgimg= &Apache::lonxml::get_param('bgimg',$parstack,$safeeval);
   87:   if ( $bgimg !~ /^http:/ ) {
   88:     push (@Apache::lonxml::extlinks,$bgimg);
   89:     $bgimg=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$bgimg);
   90:     if ($bgimg =~ /$Apache::lonnet::perlvar{'lonDocRoot'}/) {
   91:       $bgimg=~s/$Apache::lonnet::perlvar{'lonDocRoot'}//;
   92:     } elsif ($bgimg =~ m:^/home/.*/public_html:) {
   93:       $bgimg =~ s:^/home/(.*)/public_html:/~$1:;
   94:     }
   95:     $bgimg='http://'.$ENV{'SERVER_NAME'}.$bgimg;
   96:   }
   97:   my $code = &Apache::lonxml::get_param('code',$parstack,$safeeval);
   98:   my $codebase = &Apache::lonxml::get_param('codebase',$parstack,$safeeval);
   99:   my $w= &check_int(&Apache::lonxml::get_param('width',$parstack,$safeeval));
  100:   my $h= &check_int(&Apache::lonxml::get_param('height',$parstack,$safeeval));
  101:   my $texwidth= &Apache::lonxml::get_param('texwidth',$parstack,$safeeval);
  102:   if (!$code) { $code='GLabel.class'; }
  103:   if (!$codebase) { $codebase='/res/adm/includes/'; }
  104:   $Apache::randomlabel::tlabel_cnt=0;
  105:   $Apache::randomlabel::ilabel_cnt=0;
  106:   if ($target eq 'web') {
  107:     $result.="<applet code=\"$code\" codebase=\"$codebase\" width=\"$w\" height=\"$h\">\n";
  108:     $result.="<param name=\"bgimg\" value=\"$bgimg\">\n";
  109:   } elsif ($target eq 'tex') {
  110:     my $newbgimg = $bgimg;
  111:     $bgimg=~s/(.gif|.jpg)$/.eps/;
  112:     $bgimg= &Apache::lonnet::filelocation($bgimg);
  113:     if (not $ENV{'request.role'}=~/^au\./) {
  114: 	$bgimg=~s/http:\/[^\/]*/\/home\/httpd\/html/;
  115: 	$bgimg=~s/\/$//;
  116:         #if no eps file try to replicate it
  117: 	if (not-e $bgimg) {
  118: 	    my $response = &Apache::lonnet::repcopy($bgimg);
  119:             #if replication failed try to find ps file
  120: 	    if (not-e $bgimg) {
  121: 		$bgimg=~s/\.eps$/\.ps/;
  122: 		#if no ps file try to replicate it
  123: 		if (not-e $bgimg) {
  124: 		    $response = &Apache::lonnet::repcopy($bgimg);
  125: 		    #if replication failed try to produce eps file dynamically
  126: 		    $bgimg=~s/\.ps$/\.eps/;
  127: 		    my $temp_file;
  128: 		    my $filename = "/home/httpd/prtspool/$ENV{'user.name'}_$ENV{'user.domain'}_printout.dat";
  129: 		    $temp_file = Apache::File->new('>>'.$filename);
  130: 		    $newbgimg =~ s/(.*)\/res\//\/home\/httpd\/html\/res\//;
  131: 		    print $temp_file "$newbgimg\n";
  132: 		    $bgimg =~ m/\/([^\/]+)$/;
  133: 		    $bgimg = '/home/httpd/prtspool/'.$1;
  134: 		}
  135: 	    }
  136: 	}
  137:     } else {
  138: 	$bgimg=~s/http:\/[^\/]*\/~([^\/]+)/\/home\/$1\/public_html/;
  139:     }
  140:     $bgimg=~s/\/$//;
  141:     my $dirtywidth=$texwidth+5;
  142:     if ($texwidth==90) {
  143: 	$result.='\vspace*{2mm}\noindent \parbox{'.$dirtywidth.' mm}{  \noindent \epsfxsize='.$texwidth.' mm \epsffile{'.
  144: 	    $bgimg.'}\setlength{\unitlength}{1mm}  \begin{picture}('.$texwidth.','.$texwidth*$h/$w.')(0,-'.$texwidth*$h/$w.')';
  145:     } else {
  146: 	$result.='\vspace*{2mm}\noindent \parbox{'.$dirtywidth.' mm}{  \noindent \epsfxsize='.$texwidth.' mm \epsffile{'.
  147: 	    $bgimg.'}\setlength{\unitlength}{1mm}  \begin{picture}('.$texwidth.','.$texwidth*$h/$w.')(0,-'.$texwidth*$h/$w.')';
  148:     }
  149:   } elsif ($target eq 'edit') {
  150:     $result.=&Apache::edit::tag_start($target,$token);
  151:     $result.=&Apache::edit::text_arg('Image:','bgimg',$token,75).' ';
  152:     $result.=&Apache::edit::browse('bgimg').' ';
  153:     $result.=&Apache::edit::search('bgimg').'<br />'.
  154:         &Apache::edit::text_arg('Width(pixel):' ,'width'   ,$token,6).
  155:         &Apache::edit::text_arg('Height(pixel):','height'  ,$token,6).
  156:         &Apache::edit::text_arg('TeXWidth(mm):' ,'texwidth',$token,6).
  157:         &Apache::edit::end_row().&Apache::edit::start_spanning_row();     
  158:   } elsif ($target eq 'modified') {
  159:     my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,
  160: 						 'bgimg','width','height',
  161: 						 'texwidth');
  162:     if ($constructtag) {
  163:       $result = &Apache::edit::rebuild_tag($token);
  164:       $result.=&Apache::edit::handle_insert();
  165:     }
  166:   }
  167:   return $result;
  168: }
  169: 
  170: sub end_randomlabel {
  171:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  172:   my $result='';
  173:   my $count;
  174:   pop @Apache::lonxml::namespace;
  175:   if ($target eq 'web') {
  176:     $count = $Apache::randomlabel::tlabel_cnt;
  177:     if( $count != 0) { $result.= "<param name=\"COUNT\" value=\"$count\">\n"; }
  178:     $count = $Apache::randomlabel::ilabel_cnt;
  179:     if( $count != 0) { $result.= "<param name=\"ICOUNT\" value=\"$count\">\n"; }
  180:     $result .= "</applet>\n<BR />";
  181:   } elsif ($target eq 'tex') {
  182:       $result='\end{picture}\\\\}';
  183: 	  @$parstack[-1]=~/\$height\s*=\s*?"(.+)?"/;
  184:       my $one=$1;
  185: 	  @$parstack[-1]=~/\$width\s*=\s*?"(.+)?"/;
  186:       my $two=$1;
  187: 	  @$parstack[-1]=~/\$texwidth\s*=\s*?"(.+)?"/;
  188:       my $three=$1;
  189:       my $howtoskipback = $three*$one/$two;
  190:       $result.=' \vskip -'.$howtoskipback.' mm ';
  191:   } elsif ($target eq 'edit') {
  192:     $result.=&Apache::edit::end_table;
  193:   }
  194:   return $result;
  195: }
  196: 
  197: sub start_labelgroup {
  198:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  199:   my $result='';
  200:   my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
  201:   my $type = &Apache::lonxml::get_param('type',$parstack,$safeeval);
  202:   $type =~tr/A-Z/a-z/;
  203:   if ($target eq 'web' || $target eq 'tex' || 
  204:       $target eq 'grade' || $target eq 'answer') {
  205:     $Apache::randomlabel::groupname=$name;
  206:     $Apache::randomlabel::type=$type;
  207:     @Apache::randomlabel::xcoord = ();
  208:     @Apache::randomlabel::ycoord = ();
  209:     @Apache::randomlabel::value = ();
  210:     @Apache::randomlabel::label_arr  = ();
  211:     @Apache::randomlabel::decription  = ();
  212:   } elsif ($target eq 'edit') {
  213:     $result.=&Apache::edit::tag_start($target,$token);
  214:     $result.=&Apache::edit::text_arg('Name:','name',$token).
  215:       &Apache::edit::select_arg('Type:','type',['text','image'],$token).
  216: 	  &Apache::edit::end_row().&Apache::edit::start_spanning_row();
  217:   } elsif ($target eq 'modified') {
  218:     my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,
  219: 						 'name','type');
  220:     if ($constructtag) {
  221:       $result = &Apache::edit::rebuild_tag($token);
  222:       $result.=&Apache::edit::handle_insert();
  223:     }
  224:   }
  225:   return $result;
  226: }
  227: 
  228: sub add_vars {
  229:   my ($name,$order,$label,$labelorder,$value,$image,$safeeval) = @_;
  230:   my $code = '${'.$name."}{'".($order+1)."'}='".$label."';";
  231:   my $out=Apache::run::run($code,$safeeval);
  232:   if ($value) {
  233:     $code = '${'.$name."}{'value_".($order+1)."'}='".$value."';";
  234:     $out=Apache::run::run($code,$safeeval);
  235:     $code = '${'.$name."}{'labelvalue_".($labelorder+1)."'}='".$value."';";
  236:     $out=Apache::run::run($code,$safeeval);
  237:   }
  238:   if ($image) {
  239:       my $code = '${'.$name."}{'image_".($order+1)."'}='".$image."';";
  240:       my $out=Apache::run::run($code,$safeeval);
  241:   }
  242:   $code = '${'.$name."}{'numlocations'}='".($order+1)."';";
  243:   $out=Apache::run::run($code,$safeeval);
  244: }
  245: 
  246: # begin to assign labels to locations
  247: sub end_labelgroup {
  248:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  249:   my $gname = $Apache::randomlabel::groupname;
  250:   my $type  = $Apache::randomlabel::type;
  251:   my $result='';
  252:   if ($target eq 'web' || $target eq 'answer' || $target eq 'grade') {
  253:     my @idx_arr = (0 .. $#Apache::randomlabel::label_arr);
  254:     &Apache::structuretags::shuffle(\@idx_arr);
  255:     for(0 .. $#Apache::randomlabel::label_arr) {
  256:       my $str;
  257:       my $xstr;
  258:       my $ystr;
  259:       my $label = "$Apache::randomlabel::label_arr[ $idx_arr[$_] ]";
  260:       my $x = $Apache::randomlabel::xcoord[$_];
  261:       my $y = $Apache::randomlabel::ycoord[$_];
  262:       my $value = $Apache::randomlabel::value[$_];
  263:       if( $type eq 'text') {
  264: 	&add_vars($gname,$_,$label,$idx_arr[$_],$value,'',$safeeval);
  265: 	$str = 'LB'.$Apache::randomlabel::tlabel_cnt;
  266: 	$xstr = 'X'.$Apache::randomlabel::tlabel_cnt;
  267: 	$ystr = 'Y'.$Apache::randomlabel::tlabel_cnt;
  268: 	$Apache::randomlabel::tlabel_cnt += 1;
  269:       } elsif ( $type eq 'image') {
  270: 	&add_vars($gname,$_,
  271: 		  $Apache::randomlabel::description[$idx_arr[$_]],
  272: 		  $idx_arr[$_],$value,$label,$safeeval);
  273: 	$str = 'IMG'.$Apache::randomlabel::ilabel_cnt;
  274: 	$xstr = 'IX'.$Apache::randomlabel::ilabel_cnt;
  275: 	$ystr = 'IY'.$Apache::randomlabel::ilabel_cnt;
  276: 	$Apache::randomlabel::ilabel_cnt += 1;
  277:       } else {
  278: 	&Apache::lonxml::error('Unknown type of label :'.$type.':');
  279:       }
  280:       if ($target eq 'web') {
  281: 	$result .= '<param name="' . $str  . '" value="'.$label.'">';
  282: 	$result .= '<param name="' . $xstr . '" value="'.$x.'">';
  283: 	$result .= '<param name="' . $ystr . '" value="'.$y.'">'."\n";
  284:       }
  285:     }
  286:   } elsif ($target eq 'tex') {
  287:     my $WX1=0; #  Web x-coord. of upper left corner (ULC)
  288:     my $WY1=0; #  Web y-coord. of (ULC)
  289:     my $wwidth=&Apache::lonxml::get_param('width',$parstack,$safeeval,-2);
  290:     my $wheight=&Apache::lonxml::get_param('height',$parstack,$safeeval,-2);
  291:     my $texwidth=&Apache::lonxml::get_param('texwidth',$parstack,$safeeval,-2);
  292:     my $TX1=0;
  293:     my $TY1=$texwidth*($wheight/$wwidth);
  294:     my $TX2=$texwidth;
  295:     my $TY2=0;
  296: 
  297: 
  298:     my $slopex=($wwidth-$WX1)/($TX2-$TX1);
  299:     my $slopey=($wheight-$WY1)/($TY2-($TY1-1.0));
  300:     my $cstx=$wwidth-$slopex*($TX2);
  301:     my $csty=$wheight-$slopey*($TY2);
  302: 
  303:     my @idx_arr = (0 .. $#Apache::randomlabel::label_arr);
  304:     &Apache::structuretags::shuffle(\@idx_arr);
  305: 
  306:     &Apache::lonxml::debug("Array is:".$#Apache::randomlabel::label_arr.":");
  307:     for(my $i=0;$i <= $#Apache::randomlabel::label_arr; $i++) {
  308:       my $label = "$Apache::randomlabel::label_arr[ $idx_arr[$i] ]";
  309:       my $x = $Apache::randomlabel::xcoord[$i];
  310:       my $y = $Apache::randomlabel::ycoord[$i];
  311:       my $value = $Apache::randomlabel::value[$i];
  312:       #x latex coordinate
  313:       my $tcX=($x)*($texwidth/$wwidth);
  314:       #y latex coordinate
  315: #      my $ratio=($wwidth > 0 ? $wheight/$wwidth : 1 );
  316:       my $tcY=$TY1-$y*($TY1/$wheight);
  317:       $tcX=sprintf('%.2f',$tcX);
  318:       $tcY=sprintf('%.2f',$tcY);
  319:       $result.='\put('.$tcX.','.$tcY.'){\normalsize \bf '.$label.'}'."\n";
  320:       if( $type eq 'text') {
  321: 	&add_vars($gname,$i,$label,$idx_arr[$i],$value,'',$safeeval);
  322:       } elsif ( $type eq 'image') {
  323: 	&add_vars($gname,$i,
  324: 		  $Apache::randomlabel::description[$idx_arr[$i]],
  325: 		  $idx_arr[$i],$value,$label,$safeeval);
  326:       } else {
  327: 	&Apache::lonxml::error('Unknown type of label :'.$type.':');
  328:       }
  329:     }
  330:   } elsif ($target eq 'edit') {
  331:     $result.=&Apache::edit::end_table;
  332:   }
  333:   return $result;
  334: }
  335: 
  336: # <location x="123" y="456" value="some value"/>
  337: sub start_location {
  338:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  339:   my $x= &check_int(&Apache::lonxml::get_param('x',$parstack,$safeeval),50);
  340:   my $y= &check_int(&Apache::lonxml::get_param('y',$parstack,$safeeval),50);
  341:   my $value= &Apache::lonxml::get_param('value',$parstack,$safeeval);
  342:   my $result='';
  343:   push(@Apache::randomlabel::xcoord,$x);
  344:   push(@Apache::randomlabel::ycoord,$y);
  345:   push(@Apache::randomlabel::value,$value);
  346:   if ($target eq 'edit') {
  347:     $result.=&Apache::edit::tag_start($target,$token);
  348:     $result.=&Apache::edit::text_arg('X:','x',$token,4).
  349:       &Apache::edit::text_arg('Y:','y',$token,4).
  350: 	&Apache::edit::text_arg('Value:','value',$token).
  351: 	  &Apache::edit::end_row();
  352:     $result.=&Apache::edit::end_table;
  353:   } elsif ($target eq 'modified') {
  354:     my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,
  355: 						 'x','y','value');
  356:     if ($constructtag) {
  357:       $result = &Apache::edit::rebuild_tag($token);
  358:       $result.=&Apache::edit::handle_insert();
  359:     }
  360:   }
  361:   return $result;
  362: }
  363: 
  364: sub end_location {
  365:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  366:   my @result;
  367:   if ($target eq 'edit') { @result=('','no') }
  368:   return @result;
  369: }
  370: 
  371: # <label>$var_abc</label>
  372: sub start_label {
  373:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  374:   my $result='';
  375:   my $type = &Apache::lonxml::get_param('type',$parstack,$safeeval,-2);
  376:   if ($target eq 'web' || $target eq 'tex' || 
  377:       $target eq 'grade' || $target eq 'answer') {
  378:     my $ltext=&Apache::lonxml::get_all_text("/label",$$parser[-1]);
  379:     $ltext=&Apache::run::evaluate($ltext,$safeeval,$$parstack[-1]);
  380:     if ($type eq 'image') {
  381:       &Apache::lonxml::debug("Turning $ltext and $Apache::lonxml::pwd[-1]");
  382:       $ltext="http://$ENV{'SERVER_NAME'}".&Apache::lonnet::hreflocation($Apache::lonxml::pwd[-1],
  383: 					   $ltext);
  384:       &Apache::lonxml::debug("into $ltext");
  385:       my $description = &Apache::lonxml::get_param('description',
  386: 						   $parstack,$safeeval);
  387:       push(@Apache::randomlabel::description,$description);
  388:     }
  389:     push(@Apache::randomlabel::label_arr,$ltext);
  390:   } elsif ($target eq 'edit') {
  391:     $result.=&Apache::edit::tag_start($target,$token,"$type Label");
  392:     my $text=&Apache::lonxml::get_all_text("/label",$$parser[-1]);
  393:     if ($type eq 'image') {
  394:       $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
  395:       $result.=&Apache::edit::text_arg('Description:','description',$token);
  396:     }
  397:     if ($type eq 'text') { $result.="Label Text:"; }
  398:     if ($type eq 'image') { $result.="Path to image:"; }
  399:     $result.=&Apache::edit::editline('',$text,'',20).
  400:       &Apache::edit::end_table();
  401:   } elsif ($target eq 'modified') {
  402:     my $text=$$parser[-1]->get_text("/label");
  403:     $result = '<label>';
  404:     if ($type eq 'image') {
  405:       my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,
  406: 						   'description');
  407:       if ($constructtag) {
  408: 	$result = &Apache::edit::rebuild_tag($token);
  409:       } else {
  410: 	$result = $token->[4];
  411:       }
  412:     }
  413:     $result.=&Apache::edit::modifiedfield($token);
  414:   }
  415:   return $result;
  416: }
  417: 
  418: sub end_label {
  419:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  420:   my @result;
  421:   if ($target eq 'edit') { @result=('','no') }
  422:   return @result;
  423: }
  424: 
  425: 
  426: 
  427: 1;
  428: __END__
  429:  

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