Diff for /loncom/homework/Attic/lonproblem.pm between versions 1.4 and 1.5

version 1.4, 2001/08/06 18:35:51 version 1.5, 2001/08/06 20:33:23
Line 1 Line 1
 # The LON-CAPA problem handler  # The LearningOnline Network with CAPA
 #  
 # Problem Handler  # Problem Handler
 #  #
 # 12/15-01/21,01/24 Gerd Kortemeyer  # 12/15-01/21,01/24 Gerd Kortemeyer
 # 4/12 Guy Albertelli  
 # 8/6 Scott Harrison  
   
 package Apache::lonproblem;  package Apache::lonproblem;
   
Line 14  use Safe; Line 11  use Safe;
 use Apache::File;  use Apache::File;
   
 # ================================================================ Main Handler  # ================================================================ Main Handler
   
 sub handler {  sub handler {
     my $r=shift;    my $r=shift;
     my @parsecontents;    my @parsecontents;
     my $parsestring;    my $parsestring;
     my $outstring;    my $outstring;
         
     {    {
  my $fh=Apache::File->new($r->filename);      my $fh=Apache::File->new($r->filename);
  @parsecontents=<$fh>;      @parsecontents=<$fh>;
     }    }
         
     $parsestring=join('',@parsecontents);    $parsestring=join('',@parsecontents);
         
     print "<form>";    print "<form>";
         
     &xmlparse($r,$parsestring,'web');    &xmlparse($r,$parsestring,'web');
         
     print "\n---------------\n";    print "\n---------------\n";
     print "<form>";    print "<form>";
     &xmlparse($r,$parsestring,'edit');    &xmlparse($r,$parsestring,'edit');
     $outstring=xmlparse($parsestring,'modified');    $outstring=xmlparse($parsestring,'modified');
     print "\n---------------\n$outstring\n";    print "\n---------------\n$outstring\n";
     return 1; #change to ok    return 1; #change to ok
 }  }
   
   # =============================================================================
 # ============================================================= Parsing Routine  # ============================================================= Parsing Routine
 # Takes $parsestring and $target  # Takes $parsestring and $target
   # =============================================================================
   
 sub xmlparse {  sub xmlparse {
       
     my ($r,$parsestring,$target) = @_;    my ($r,$parsestring,$target) = @_;
       
     my $safeeval   = new Safe 'Script';    my $safeeval   = new Safe 'Script';
       
     my $parsereval = new Safe 'Parser';    my $parsereval = new Safe 'Parser';
       
     my $parser=HTML::TokeParser->new(\$parsestring);  
       
     my $outtext='';    my $parser=HTML::TokeParser->new(\$parsestring);
     
     my $outtext='';
       
 # ---------------------------------------------------------------- Handled tags  # ---------------------------------------------------------------- Handled tags
   
     my %toptoplevel  = ( 'problem'    => 'Problem',    my %toptoplevel  = ( 'problem'    => 'Problem',
  'entryform'  => 'Entry Form',         'entryform'  => 'Entry Form',
  'survey'     => 'Survey',         'survey'     => 'Survey',
  'graded'     => 'Manually Graded' );         'graded'     => 'Manually Graded' );
       
       
 # --------------------------------------------------------------- Toplevel Tags  # --------------------------------------------------------------- Toplevel Tags
   
     my %topleveltags = ( 'block'   => 'Condition Block',    my %topleveltags = ( 'block'   => 'Condition Block',
  'part'    => 'Problem Part',         'part'    => 'Problem Part',
  'include' => 'Include Section',         'include' => 'Include Section',
  'answer'  => 'Answerfield',         'answer'  => 'Answerfield',
  'script'  => 'Script',          'script'  => 'Script', 
  'outtext' => 'Text Block' );         'outtext' => 'Text Block' );
     
 # ---------------------------------------------------------- Preregistered Tags  # ---------------------------------------------------------- Preregistered Tags
   
     my %includetags  = ( 'scriptlib' => 'Script Library',    my %includetags  = ( 'scriptlib' => 'Script Library',
  'parserlib' => 'Parser Library' );         'parserlib' => 'Parser Library' );
 # -------------------------------------------------------------Answer type Tags  # -------------------------------------------------------------Answer type Tags
   
     my %answertags   = ( 'capaanswer' => 'CAPA Standard Answers');    my %answertags   = ( 'capaanswer' => 'CAPA Standard Answers');
   
 # -------------------------------------------------------------------- All Tags  # -------------------------------------------------------------------- All Tags
   
   
     my %xmltags      = ( %includetags, %topleveltags, %toptoplevel,     my %xmltags      = ( %includetags, %topleveltags, %toptoplevel, %answertags );
  %answertags );  
       
     my $toplevel     = '';    my $toplevel     = '';
     my $above        = '';    my $above        = '';
       
 # --------------------------------------------------- Depth counter for editing  # --------------------------------------------------- Depth counter for editing
   
     my @depthcounter = ();    my @depthcounter=();
     my $depth = -1;    my $depth=-1;
     my $olddepth = -1;    my $olddepth=-1;
   
 # ----------------------------------------------------------------------- Stack  # ----------------------------------------------------------------------- Stack
   
     my @stack = ('');    my @stack=('');
   
 # -------------------------------------------------------------- Init $saveeval  # -------------------------------------------------------------- Init $saveeval
       
     &init_safeeval($safeeval);    &init_safeeval($safeeval);
   
 # ---------------------------------------------------------- Parse $parsestring  # ---------------------------------------------------------- Parse $parsestring
   
     my $token;    my $token;
   
     while ($token = $parser->get_token) {    while ($token=$parser->get_token) {n
 # =============================================================================  # =============================================================================
  if ($token->[0] eq 'S') {      if ($token->[0] eq 'S') {
 # =================================================================== Start Tag  # =================================================================== Start Tag
 # --------------------------------------------------------------- Depth Counter  # --------------------------------------------------------------- Depth Counter
     if (defined($xmltags{$token->[1]})) {        if (defined($xmltags{$token->[1]})) {
  if ($depth<$olddepth-1) {   if ($depth<$olddepth-1) {
     $#depthcounter--;    $#depthcounter--;
     $olddepth=$depth;    $olddepth=$depth;
  }   }
  $depth++;   $depth++;
  $depthcounter[$depth]++;   $depthcounter[$depth]++;
  if ($depthcounter[$depth] == 1) {   if ($depthcounter[$depth]==1) {
     $olddepth = $depth;    $olddepth=$depth;
  }   }
     }          }  
 # -----------------------------------------------------------------------------  # -----------------------------------------------------------------------------
   
   
     if ($target eq 'web') {        if ($target eq 'web') {
  my $sub = "start_$token->[1]";   my $sub="start_$token->[1]";
  {   {
     no strict 'refs';    no strict 'refs';
     if (defined (&$sub)) {     if (defined (&$sub)) { 
  &$sub($r,$token,$parser,$safeeval,\@stack);       &$sub($r,$token,$parser,$safeeval,\@stack); 
     } else {    } else {
  $stack[$#stack] .= $token->[4];      $stack[$#stack].=$token->[4];
     }    }
  }   }
     }        }
               
     if ($target eq 'edit') {        if ($target eq 'edit') {
  my $depthlabel = join('_',@depthcounter);   my $depthlabel=join('_',@depthcounter);
  if (defined($xmltags{$token->[1]})) {   if (defined($xmltags{$token->[1]})) {
     if (defined($topleveltags{$token->[1]})) {    if (defined($topleveltags{$token->[1]})) {
  &insertmenu($r,$xmltags{$token->[1]},      &insertmenu($r,$xmltags{$token->[1]},
     $depthlabel,\%topleveltags);   $depthlabel,\%topleveltags);
  $toplevel = $token->[1];      $toplevel=$token->[1];
     } else {    } else {
  if ($toplevel eq 'answer') {      if ($toplevel eq 'answer') {
     &insertmenu($r,$xmltags{$token->[1]},        &insertmenu($r,$xmltags{$token->[1]},
  $depthlabel,\%answertags);    $depthlabel,\%answertags);
  }  
     }  
     my $sub = "start_edit_$token->[1]";  
     {  
  no strict 'refs';  
  if (defined (&$sub)) {   
     &$sub($r,$token,$parser,$xmltags{$token->[1]},  
   $depthlabel,$above,\%answertypes,\@stack);   
  }  
     }   
  } else {  
     $stack[$#stack] .= $token->[4];  
  }  
     }      }
         }
     if ($target eq 'modified') {    my $sub="start_edit_$token->[1]";
     {
       no strict 'refs';
       if (defined (&$sub)) { 
         &$sub($r,$token,$parser,$xmltags{$token->[1]},
       $depthlabel,$above,\%answertypes,\@stack); 
     }      }
         } 
    } else {
     $stack[$#stack].=$token->[4];
    }
         }
         
         if ($target eq 'modified') {
         }
   
 # =============================================================================  # =============================================================================
  } elsif ($token->[0] eq 'E') {      } elsif ($token->[0] eq 'E') {
 # ===================================================================== End Tag  # ===================================================================== End Tag
   
     if ($target eq 'web') {        if ($target eq 'web') {
  my $sub = "end_$token->[1]";   my $sub="end_$token->[1]";
  {   {
     no strict 'refs';    no strict 'refs';
     if (defined (&$sub)) {     if (defined (&$sub)) { 
  &$sub($r,$token,$parser,$safeeval,\@stack);      &$sub($r,$token,$parser,$safeeval,\@stack);
     } else {    } else {
  $stack[$#stack] .= $token->[2];      $stack[$#stack].=$token->[2];
     }    }
  }   }
     }        }
             
     if ($target eq 'edit') {        if ($target eq 'edit') {
  if (defined($xmltags{$token->[1]})) {   if (defined($xmltags{$token->[1]})) {
     my $sub = "end_edit_$token->[1]";    my $sub="end_edit_$token->[1]";
     {    {
  no strict 'refs';      no strict 'refs';
  if (defined (&$sub)) {       if (defined (&$sub)) { 
     &$sub($r,$token,$above,\@stack);         &$sub($r,$token,$above,\@stack); 
  }  
     }   
  }   
     }  
       
     if ($target eq 'modified') {  
     }      }
     } 
    } 
         }
         
         if ($target eq 'modified') {
         }
 # --------------------------------------------------------------- Depth Counter  # --------------------------------------------------------------- Depth Counter
     if (defined($xmltags{$token->[1]})) { $depth--; }        if (defined($xmltags{$token->[1]})) { $depth--; }
 # -----------------------------------------------------------------------------  # -----------------------------------------------------------------------------
 # =============================================================================  # =============================================================================
  } elsif ($token->[0] eq 'T') {      } elsif ($token->[0] eq 'T') {
 # ================================================================= Parsed Text  # ================================================================= Parsed Text
     $stack[$#stack] .= $token->[1];        $stack[$#stack].=$token->[1];
  }  
     }      }
         }
     return $outtext;  
     return $outtext;
 }  }
 # =============================================================================  # =============================================================================
   
Line 216  sub xmlparse { Line 216  sub xmlparse {
 # ------------------------------------------------- Helper Routines for Editing  # ------------------------------------------------- Helper Routines for Editing
   
 sub rawprint {  sub rawprint {
   my ($r,$data) = @_;    my ($r,$data)=@_;
   $r->print($data);    $r->print($data);
 }  }
   
 sub insertmenu {  sub insertmenu {
     my ($r,$description,$depthlabel,$xmltagsref) = @_;    my ($r,$description,$depthlabel,$xmltagsref)=@_;
     &rawprint($r,'<br><table bgcolor="#DDDD33" width="100%"><tr><td>');    &rawprint($r,'<br><table bgcolor="#DDDD33" width="100%"><tr><td>');
     &rawprint($r,"\n".'<select name="mod_menu_'.$depthlabel.'">'."\n");    &rawprint($r,"\n".'<select name="mod_menu_'.$depthlabel.'">'."\n");
     &rawprint($r,'<option value="no_changes" selected>(no changes)</option>');    &rawprint($r,'<option value="no_changes" selected>(no changes)</option>');
     &rawprint($r,"\n".
       '<option value="delete">Delete '.$description.
       ' Below</option>');
     my $key;
     foreach $key (keys %$xmltagsref) {
     &rawprint($r,"\n".      &rawprint($r,"\n".
       '<option value="delete">Delete '.$description.        '<option value="insert_'.$key.'">Insert '.
       ' Below</option>');        $$xmltagsref{$key}.'</option>');
     my $key;    }
     foreach $key (keys %$xmltagsref) {    &rawprint($r,"\n".'</select></td></tr></table><br>'."\n");
  &rawprint($r,"\n".  
   '<option value="insert_'.$key.'">Insert '.  
   $$xmltagsref{$key}.'</option>');  
     }  
     &rawprint($r,"\n".'</select></td></tr></table><br>'."\n");  
 }  }
   
 # =============================================================================  # =============================================================================
Line 244  sub insertmenu { Line 244  sub insertmenu {
 # -------------------------------------------- Initialize routines in $safeeval  # -------------------------------------------- Initialize routines in $safeeval
   
 sub init_safeeval {  sub init_safeeval {
     my $safeeval = shift;    my $safeeval=shift;
     my $initprg =<<'ENDINIT';     my $initprg=<<'ENDINIT'; 
   
 # -------------------------------------------- Initializations inside $safeeval  # -------------------------------------------- Initializations inside $safeeval
   
     $e = 25;    $e=25;
     $c = 20;    $c=20;
   
   ENDINIT    ENDINIT
 # ---------------------------------------------------------------- Execute that  # ---------------------------------------------------------------- Execute that
Line 260  sub init_safeeval { Line 260  sub init_safeeval {
 # ----------------------------------------------- Routines that use Safe Spaces  # ----------------------------------------------- Routines that use Safe Spaces
   
 sub printout {  sub printout {
     my ($r,$data,$safespace) = @_;    my ($r,$data,$safespace)=@_;
     $r->print($safespace->reval('return qq('.$data.');'));    $r->print($safespace->reval('return qq('.$data.');'));
 }  }
   
 sub runfile {  sub runfile {
     my ($r,$filename,$safespace) = @_;    my ($r,$filename,$safespace)=@_;
     my $includefile;    my $includefile;
     if ($filename =~ /^\//) {    if ($filename=~/^\//) {
  $includefile = $filename;      $includefile=$filename;
     } else {    } else {
  $includefile = $r->dir_config('lonIncludes');      $includefile=$r->dir_config('lonIncludes');
  $includefile .= '/'.$filename;      $includefile.='/'.$filename;
     }    }
     if (-e $includefile) {    if (-e $includefile) {
  $safespace->rdo($includefile);      $safespace->rdo($includefile);
     }       }   
 }  }
   
 sub run {  sub run {
     my ($expression,$safespace) = @_;    my ($expression,$safespace)=@_;
     $safespace->reval($expression);       $safespace->reval($expression);   
 }  }
   
 sub booleanexpr {  sub booleanexpr {
     my ($expression,$safespace) = @_;    my ($expression,$safespace)=@_;
     return $safespace->reval('return '.$expression.';');    return $safespace->reval('return '.$expression.';');
 }  }
   
   
Line 294  sub booleanexpr { Line 294  sub booleanexpr {
 # =============================================================================  # =============================================================================
   
 sub start_block {  sub start_block {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     if (!booleanexpr($token->[2]{'condition'},$safeeval)) {    if (!booleanexpr($token->[2]{'condition'},$safeeval)) {
  my $blockdepth = 0;      my $blockdepth=0;
  my $nexttoken;      my $nexttoken;
  while ($nexttoken=$parser->get_tag()) {       while ($nexttoken=$parser->get_tag()) { 
     if ($nexttoken->[0] eq 'block') { $blockdepth++ };        if ($nexttoken->[0] eq 'block') { $blockdepth++ };
     if ($nexttoken->[0] eq '/block') {        if ($nexttoken->[0] eq '/block') {
  if ($blockdepth == 0) {    if ($blockdepth==0) { 
     return;     return; 
  } else {   } else {
     $blockdepth--;    $blockdepth--;
  }  
     }  
  }   }
         }
     }      }
     return;    }
     return;
 }  }
   
 sub start_script {  sub start_script {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     $stackref->[$#$stackref+1] = '';    $stackref->[$#$stackref+1]='';
 }  }
   
 sub end_script {  sub end_script {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     &run($stackref->[$#$stackref],$safeeval);    &run($stackref->[$#$stackref],$safeeval);
     $#$stackref--;    $#$stackref--;
 }  }
   
 sub start_outtext {  sub start_outtext {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     $stackref->[$#$stackref+1] = '';    $stackref->[$#$stackref+1]='';
 }  }
   
 sub end_outtext {  sub end_outtext {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     &printout($r,$stackref->[$#$stackref],$safeeval);    &printout($r,$stackref->[$#$stackref],$safeeval);
     $#$stackref--;    $#$stackref--;
 }  }
   
 sub start_inlinetext {  sub start_inlinetext {
     &start_outtext(@_);    &start_outtext(@_);
 }  }
   
 sub end_inlinetext {  sub end_inlinetext {
     &end_outtext(@_);    &end_outtext(@_);
 }  }
   
 sub start_scriptlib {  sub start_scriptlib {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     &runfile($r,$parser->get_text('/scriptlib'),$safeeval);    &runfile($r,$parser->get_text('/scriptlib'),$safeeval);
 }  }
   
 sub start_parserlib {  sub start_parserlib {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     &runfile($r,$parser->get_text('/parserlib'),$parsereval);    &runfile($r,$parser->get_text('/parserlib'),$parsereval);
 }  }
   
   
 sub start_answer {  sub start_answer {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     $stackref->[$#$stackref+1] = '<answer>::'.    $stackref->[$#$stackref+1]='<answer>::'.
  join(':',map{$_.':'.$token->[2]->{$_}} @{$token->[3]});         join(':',map{$_.':'.$token->[2]->{$_}} @{$token->[3]});   
     $stackref->[$#$stackref+1] = '';    $stackref->[$#$stackref+1]='';
 }  }
   
 sub end_answer {  sub end_answer {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     my @itemtexts;    my @itemtexts;
     my @itemargs;    my @itemargs;
     my $stackpointer = $#$stackref;    my $stackpointer=$#$stackref;
     while (($stackref->[$stackpointer] !~ '<answer>::') &&    while (($stackref->[$stackpointer]!~'<answer>::') && ($stackpointer>0)) { 
    ($stackpointer > 0)) {       $stackpointer--; 
  $stackpointer--;     }
     }    my %answerargs=split(/:/,$stackref->[$stackpointer]);
     my %answerargs=split(/:/,$stackref->[$stackpointer]);  
 }  }
   
 sub start_item {  sub start_item {
     my ($r,$token,$parser,$safeeval,$stackref) = @_;    my ($r,$token,$parser,$safeeval,$stackref)=@_;
     $stackref->[$#$stackref+1] = '<item>::'.    $stackref->[$#$stackref+1]='<item>::'.
  join(':',map{$_.':'.$token->[2]->{$_}} @{$token->[3]});         join(':',map{$_.':'.$token->[2]->{$_}} @{$token->[3]});   
     $stackref->[$#$stackref+1]='';    $stackref->[$#$stackref+1]='';
 }  }
   
 sub end_item {}  sub end_item {}
Line 386  sub end_item {} Line 385  sub end_item {}
 # =============================================================================  # =============================================================================
   
 sub start_edit_outtext {  sub start_edit_outtext {
     my ($r,$token,$parser,$description,$depthlabel,$above,$answertyperef,    my ($r,$token,$parser,$description,$depthlabel,$above,$answertyperef,
  $stackref) = @_;        $stackref)=@_;
     &rawprint($r,"\n<h3>$description</h3>".    &rawprint($r,"\n<h3>$description</h3>".
       '<textarea rows="10" cols="80" name="data_'.$depthlabel.'">');      '<textarea rows="10" cols="80" name="data_'.$depthlabel.'">');
     $stackref->[$#$stackref+1] = '';    $stackref->[$#$stackref+1]='';
 }  }
   
 sub end_edit_outtext {  sub end_edit_outtext {
     my ($r,$token,$above,$stackref) = @_;    my ($r,$token,$above,$stackref)=@_;
     &rawprint($r,$stackref->[$#$stackref]."</textarea>\n");       &rawprint($r,$stackref->[$#$stackref]."</textarea>\n");   
     $#$stackref--;    $#$stackref--;
 }  }
   
 sub start_edit_script {  sub start_edit_script {
     &start_edit_outtext(@_);    &start_edit_outtext(@_);
 }  }
   
 sub end_edit_script {  sub end_edit_script {
     &end_edit_outtext(@_);    &end_edit_outtext(@_);
 }  }
   
 sub start_edit_inlinetext {  sub start_edit_inlinetext {
     &start_edit_outtext(@_);    &start_edit_outtext(@_);
 }  }
   
 sub end_edit_inlinetext {  sub end_edit_inlinetext {
     &end_edit_inlinetext(@_);    &end_edit_inlinetext(@_);
 }  }
   
 sub start_edit_block {  sub start_edit_block {
     my ($r,$token,$parser,$description,$depthlabel,$above,$answertyperef,    my ($r,$token,$parser,$description,$depthlabel,$above,$answertyperef,
  $stackref) = @_;        $stackref)=@_;
     my $bgcolor = $depthlabel;    my $bgcolor=$depthlabel;
     $bgcolor =~ s/\_//g;    $bgcolor=~s/\_//g;
     $bgcolor = substr(length($bgcolor),-1,1);    $bgcolor=substr(length($bgcolor),-1,1);
     $bgcolor =~ tr/1-5/A-E/;    $bgcolor=~tr/1-5/A-E/;
     $bgcolor = $bgcolor.'FFF'.$bgcolor.'A';    $bgcolor=$bgcolor.'FFF'.$bgcolor.'A';
     &rawprint($r,"\n".'<br><table border="2" cellpadding="10" bgcolor="#'.    &rawprint($r,"\n".'<br><table border="2" cellpadding="10" bgcolor="#'.
       $bgcolor.      $bgcolor.
       '" width="100%"><tr><td><h3>'.$description.'</h3>');      '" width="100%"><tr><td><h3>'.$description.'</h3>');
 }  }
   
 sub end_edit_block {  sub end_edit_block {
     my ($r,$token,$above,$stackref) = @_;    my ($r,$token,$above,$stackref)=@_;
     &rawprint($r,"\n".'</td></tr></table><br>');    &rawprint($r,"\n".'</td></tr></table><br>');
 }  }
   
 sub start_edit_answer {  sub start_edit_answer {
     my ($r,$token,$parser,$description,$depthlabel,$above,$answertyperef,    my ($r,$token,$parser,$description,$depthlabel,$above,$answertyperef,
  $stackref) = @_;        $stackref)=@_;
     start_edit_block(@_);    start_edit_block(@_);
     $above = $token->[2]{'type'};    $above=$token->[2]{'type'};
     &rawprint($r,"\n".'<select name="mod_type_'.$depthlabel.'">');    &rawprint($r,"\n".'<select name="mod_type_'.$depthlabel.'">');
     my $key;    my $key;
     foreach $key (keys %$answertyperef) {    foreach $key (keys %$answertyperef) {
  &rawprint($r,"\n".'<option value="'.$key.'"');      &rawprint($r,"\n".'<option value="'.$key.'"');
  if ($above eq $key) { &rawprint($r,' selected'); }      if ($above eq $key) { &rawprint($r,' selected'); }
  &rawprint($r,'>'.$$answertyperef{$key}.'</option>');      &rawprint($r,'>'.$$answertyperef{$key}.'</option>');
     }    }
     &rawprint($r,"\n".'</select>'."\n");    &rawprint($r,"\n".'</select>'."\n");
 }  }
   
 sub end_edit_answer {  sub end_edit_answer {
     my ($r,$token,$above,$stackref)=@_;    my ($r,$token,$above,$stackref)=@_;
     end_edit_block(@_);    end_edit_block(@_);
 }  }
   
 sub start_edit_include {  sub start_edit_include {
     start_edit_block(@_);    start_edit_block(@_);
 }  }
   
 sub end_edit_include {  sub end_edit_include {
     end_edit_block(@_);    end_edit_block(@_);
 }  }
   
 sub start_edit_problem {  sub start_edit_problem {
     start_edit_block(@_);    start_edit_block(@_);
 }  }
   
 sub end_edit_problem {  sub end_edit_problem {
     end_edit_block(@_);    end_edit_block(@_);
 }  }
   
 1;  1;
   
 __END__  __END__
       
   

Removed from v.1.4  
changed lines
  Added in v.1.5


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