--- loncom/xml/lonxml.pm	2002/11/13 23:21:07	1.215
+++ loncom/xml/lonxml.pm	2003/03/30 21:58:17	1.243
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # XML Parser Module 
 #
-# $Id: lonxml.pm,v 1.215 2002/11/13 23:21:07 albertel Exp $
+# $Id: lonxml.pm,v 1.243 2003/03/30 21:58:17 www Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -41,7 +41,6 @@
 # 6/1/1 Gerd Kortemeyer
 # 2/21,3/13 Guy
 # 3/29,5/4 Gerd Kortemeyer
-# 5/10 Scott Harrison
 # 5/26 Gerd Kortemeyer
 # 5/27 H. K. Ng
 # 6/2,6/3,6/8,6/9 Gerd Kortemeyer
@@ -101,6 +100,7 @@ use Apache::File();
 use Apache::loncommon();
 use Apache::lonfeedback();
 use Apache::lonmsg();
+use Apache::loncacc();
 
 #==================================================   Main subroutine: xmlparse  
 #debugging control, to turn on debugging modify the correct handler
@@ -144,8 +144,8 @@ $Apache::lonxml::registered=0;
 # a pointer the the Apache request object
 $Apache::lonxml::request='';
 
-# a problem number counter, and check on hether it is used
-$Apache::lonxml::counter=0;
+# a problem number counter, and check on ether it is used
+$Apache::lonxml::counter=1;
 $Apache::lonxml::counter_changed=0;
 
 #internal check on whether to look at style defs
@@ -191,10 +191,18 @@ sub xmlend {
               my $idx;
               for ($idx=1;$idx<=$contrib{'version'};$idx++) {
 		my $hidden=($contrib{'hidden'}=~/\.$idx\./);
-		unless (($hidden) && (!$seeid)) {
+		my $deleted=($contrib{'deleted'}=~/\.$idx\./);
+		unless ((($hidden) && (!$seeid)) || ($deleted)) {
                  my $message=$contrib{$idx.':message'};
                  $message=~s/\n/\<br \/\>/g;
 		 $message=&Apache::lontexconvert::msgtexconverted($message);
+                 if ($contrib{$idx.':attachmenturl'}) {
+                     my ($fname,$ft)
+                        =($contrib{$idx.':attachmenturl'}=~/\/(\w+)\.(\w+)$/);
+		     $message.='<p>Attachment: <a href="'.
+	       &Apache::lonnet::tokenwrapper($contrib{$idx.':attachmenturl'}).
+                     '"><tt>'.$fname.'.'.$ft.'</tt></a>';
+                 }
                  if ($message) {
                   if ($hidden) {
 		      $message='<font color="#888888">'.$message.'</font>';
@@ -225,8 +233,10 @@ sub xmlend {
                           } else {
                              $sender.=' <a href="/adm/feedback?hide='.
 				 $symb.':::'.$idx.'">Hide</a>';
-			  }
-                      }                   
+			  }                     
+                          $sender.=' <a href="/adm/feedback?deldisc='.
+				 $symb.':::'.$idx.'">Delete</a>';
+                      }
                   } else {
                       if ($screenname) {
 			  $sender='<i>'.$screenname.'</i>';
@@ -245,7 +255,7 @@ sub xmlend {
           }
           if ($discussiononly) {
 	      $discussion.=(<<ENDDISCUSS);
-<form action="/adm/feedback" method="post" name="mailform">
+<form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data">
 <input type="submit" name="discuss" value="Post Discussion" />
 <input type="submit" name="anondiscuss" value="Post Anonymous Discussion" />
 <input type="hidden" name="symb" value="$symb" />
@@ -254,6 +264,9 @@ sub xmlend {
 <font size="1">Note: in anonymous discussion, your name is visible only to
 course faculty</font><br />
 <textarea name=comment cols=60 rows=10 wrap=hard></textarea>
+<p>
+Attachment (128 KB max size): <input type="file" name="attachment" />
+</p>
 </form>
 ENDDISCUSS
              $discussion.=&Apache::lonfeedback::generate_preview_button();
@@ -267,7 +280,7 @@ sub tokeninputfield {
     my $defhost=$Apache::lonnet::perlvar{'lonHostID'};
     $defhost=~tr/a-z/A-Z/;
     return (<<ENDINPUTFIELD)
-<script>
+<script type="text/javascript">
     function updatetoken() {
 	var comp=new Array;
         var barcode=unescape(document.tokeninput.barcode.value);
@@ -351,7 +364,7 @@ sub printtokenheader {
     if ($target eq 'web') {
         my %idhash=&Apache::lonnet::idrget($tudom,($tuname));
 	return 
- '<img align="right" src="/cgi-bin/barcode.gif?encode='.$token.'" />'.
+ '<img align="right" src="/cgi-bin/barcode.png?encode='.$token.'" />'.
                'Checked out for '.$plainname.
                '<br />User: '.$tuname.' at '.$tudom.
 	       '<br />ID: '.$idhash{$tuname}.
@@ -373,153 +386,6 @@ sub fontsettings() {
     return $headerstring;
 }
 
-sub registerurl {
-    my $forcereg=shift;
-    my $target = shift;
-    my $result = '';
-    
-    if ($target eq 'edit') {
-        $result .="<script>\n".
-            "if (typeof menu != 'undefined') {menu.currentURL=null;}\n".
-            &Apache::loncommon::browser_and_searcher_javascript().
-                "\n</script>\n";
-    }
-    if ((($ENV{'request.publicaccess'}) || 
-         (!&Apache::lonnet::is_on_map($ENV{'REQUEST_URI'}))) &&
-        (!$forcereg)) {
-	return $result.
-         '<script>function LONCAPAreg(){} function LONCAPAstale(){}</script>';
-    }
-    if ($Apache::lonxml::registered && !$forcereg) { return ''; }
-    $Apache::lonxml::registered=1;
-    my $nothing='';
-    if ($ENV{'browser.type'} eq 'explorer') { $nothing='javascript:void(0);'; }
-    my $newmail='';
-    if (&Apache::lonmsg::newmail()) { 
-       $newmail='menu.setstatus("you have","messages");';
-    }
-    my $timesync='menu.syncclock(1000*'.time.');';
-    if (($ENV{'REQUEST_URI'}!~/^\/(res\/)*adm\//) || ($forcereg)) {
-        my $hwkadd='';
-        if ($ENV{'request.filename'}=~/\.(problem|exam|quiz|assess|survey|form)$/) {
-	    if (&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {
-		$hwkadd.=(<<ENDSUBM);
-                     menu.switchbutton(7,1,'subm.gif','view sub','missions','gocmd("/adm/grades","submission")',
-                     'View user submissions for this assessment resource');
-ENDSUBM
-            }
-	    if (&Apache::lonnet::allowed('mgr',$ENV{'request.course.id'})) {
-		$hwkadd.=(<<ENDGRDS);
-                     menu.switchbutton(7,2,'pgrd.gif','problem','grades','gocmd("/adm/grades","gradingmenu")',
-                     'Modify user grades for this assessment resource');
-ENDGRDS
-            }
-	    if (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'})) {
-		$hwkadd.=(<<ENDPARM);
-                     menu.switchbutton(7,3,'pparm.gif','problem','parms','gocmd("/adm/parmset","set")',
-                     'Modify deadlines, etc, for this assessment resource');
-ENDPARM
-            }
-	}
-	$result = (<<ENDREGTHIS);
-     
-<script language="JavaScript">
-// BEGIN LON-CAPA Internal
-
-    function LONCAPAreg() {
-	  menu=window.open("$nothing","LONCAPAmenu","",false);
-          menu.clearTimeout(menu.menucltim);
-          $timesync
-          $newmail
-	  menu.currentURL=window.location.pathname;
-          menu.reloadURL=window.location.pathname;
-          menu.currentSymb="$ENV{'request.symb'}";
-          menu.reloadSymb="$ENV{'request.symb'}";
-          menu.currentStale=0;
-          menu.clearbut(3,1);
-          menu.switchbutton
-       (6,3,'catalog.gif','catalog','info','catalog_info()');
-          menu.switchbutton
-       (8,1,'eval.gif','evaluate','this','gopost("/adm/evaluate",currentURL)','Provide my evaluation of this resource');
-          menu.switchbutton
-    (8,2,'fdbk.gif','feedback','discuss','gopost("/adm/feedback",currentURL)','Provide feedback messages or contribute to the course discussion about this resource');
-          menu.switchbutton
-     (8,3,'prt.gif','prepare','printout','gopost("/adm/printout",currentURL)','Prepare a printable document');
-          menu.switchbutton
-       (2,1,'back.gif','backward','','gopost("/adm/flip","back:"+currentURL)','Go to the previous resource in the course sequence');
-          menu.switchbutton
-     (2,3,'forw.gif','forward','','gopost("/adm/flip","forward:"+currentURL)','Go to the next resource in the course sequence');
-          menu.switchbutton
-                            (9,1,'sbkm.gif','set','bookmark','set_bookmark()','Set a bookmark for this resource');
-          menu.switchbutton
-                         (9,2,'vbkm.gif','view','bookmark','edit_bookmarks()','Use or edit my bookmark collection');
-          menu.switchbutton
-                               (9,3,'anot.gif','anno-','tations','annotate()','Make notes and annotations about this resource');
-          $hwkadd
-    }
-
-    function LONCAPAstale() {
-	  menu=window.open("$nothing","LONCAPAmenu","",false);
-          menu.currentStale=1;
-          if (menu.reloadURL!='' && menu.reloadURL!= null) { 
-             menu.switchbutton
-             (3,1,'reload.gif','return','location','go(reloadURL)','Return to the last known location in the course sequence');
-	  }
-          menu.clearbut(7,1);
-          menu.clearbut(7,2);
-          menu.clearbut(7,3);
-          menu.menucltim=menu.setTimeout(
- 'clearbut(2,1);clearbut(2,3);clearbut(8,1);clearbut(8,2);clearbut(8,3);'+
- 'clearbut(9,1);clearbut(9,2);clearbut(9,3);clearbut(6,3)',
-			  2000);
-
-      }
-
-// END LON-CAPA Internal
-</script>
-ENDREGTHIS
-
-    } else {
-        $result = (<<ENDDONOTREGTHIS);
-
-<script language="JavaScript">
-// BEGIN LON-CAPA Internal
-
-    function LONCAPAreg() {
-	  menu=window.open("$nothing","LONCAPAmenu","",false);
-          $timesync
-          menu.currentStale=1;
-          menu.clearbut(2,1);
-          menu.clearbut(2,3);
-          menu.clearbut(8,1);
-          menu.clearbut(8,2);
-          menu.clearbut(8,3);
-          if (menu.currentURL) {
-             menu.switchbutton
-              (3,1,'reload.gif','return','location','go(currentURL)');
- 	  } else {
-	      menu.clearbut(3,1);
-          }
-    }
-
-    function LONCAPAstale() {
-    }
-
-// END LON-CAPA Internal
-</script>
-ENDDONOTREGTHIS
-    }
-    return $result;
-}
-
-sub loadevents() {
-    return 'LONCAPAreg();';
-}
-
-sub unloadevents() {
-    return 'LONCAPAstale();';
-}
-
 sub printalltags {
   my $temp;
   foreach $temp (sort keys %Apache::lonxml::alltags) {
@@ -532,6 +398,9 @@ sub xmlparse {
  my ($request,$target,$content_file_string,$safeinit,%style_for_target) = @_;
 
  &setup_globals($request,$target);
+ &Apache::inputtags::initialize_inputtags();
+ &Apache::outputtags::initialize_outputtags();
+ &Apache::edit::initialize_edit();
 #
 # do we have a course style file?
 #
@@ -597,18 +466,22 @@ sub htmlclean {
 }
 
 sub latex_special_symbols {
-    my ($current_token,$stack,$parstack)=@_;
-    $current_token=~s/\\/\\char92 /g;
-    $current_token=~s/\^/\\char94 /g;
-    $current_token=~s/\~/\\char126 /g;
-    $current_token=~s/(&[^a-z\#])/\\$1/g;
-    $current_token=~s/([^&])\#/$1\\#/g;
-    $current_token=~s/(\$|_|{|})/\\$1/g;
-    $current_token=~s/\\char92 /\\texttt{\\char92}/g;
-    $current_token=~s/>/\$>\$/g; #more
-    $current_token=~s/</\$<\$/g; #less
-    if ($current_token=~m/\d%/) {$current_token =~ s/(\d)%/$1\\%/g;} #percent after digit
-    if ($current_token=~m/\s%/) {$current_token =~ s/(\s)%/$1\\%/g;} #persent after space
+    my ($current_token,$stack,$parstack,$where)=@_;
+    if ($where eq 'header') {
+	$current_token =~ s/(\\|_|\^)/ /g;
+	$current_token =~ s/(\$|%|\#|&|\{|\})/\\$1/g;
+    } else {
+	$current_token=~s/\\ /\\char92 /g;
+	$current_token=~s/\^/\\char94 /g;
+	$current_token=~s/\~/\\char126 /g;
+	$current_token=~s/(&[^a-z\#])/\\$1/g;
+	$current_token=~s/([^&])\#/$1\\#/g;
+	$current_token=~s/(\$|_|{|})/\\$1/g;
+	$current_token=~s/\\char92 /\\texttt{\\char92}/g;
+	$current_token=~s/(>|<)/\$$1\$/g; #more or less
+	if ($current_token=~m/\d%/) {$current_token =~ s/(\d)%/$1\\%/g;} #percent after digit
+	if ($current_token=~m/\s%/) {$current_token =~ s/(\s)%/$1\\%/g;} #persent after space
+    }
     return $current_token;
 }
 
@@ -623,8 +496,8 @@ sub inner_xmlparse {
 	if ($metamode<1) {
 	    my $text=$token->[1];
 	    if ($token->[0] eq 'C' && $target eq 'tex') {
-		$text = '%'.$text;
-		$text =~ s/[\n\r]//g;
+		$text = '';
+#		$text = '%'.$text."\n";
 	    }
 	    $result.=$text;
 	}
@@ -702,7 +575,7 @@ sub inner_xmlparse {
       if ($token->[0] eq 'E') { 
 	&end_tag($stack,$parstack,$token);
       }
-    }
+    }	
     if ($#$pars > -1) {
 	pop @$pars;
 	pop @Apache::lonxml::pwd;
@@ -716,7 +589,7 @@ sub inner_xmlparse {
 
   if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {
     $finaloutput=&afterburn($finaloutput);
-  }
+  }	    
   return $finaloutput;
 }
 
@@ -728,6 +601,8 @@ sub callsub {
     my $sub1;
     no strict 'refs';
     my $tag=$token->[1];
+# get utterly rid of extended html tags
+    if ($tag=~/^x\-/i) { return ''; }
     my $space=$Apache::lonxml::alltags{$tag}[-1];
     if (!$space) {
      	$tag=~tr/A-Z/a-z/;
@@ -744,13 +619,13 @@ sub callsub {
     }
     if (!$deleted) {
       if ($space) {
-	&Apache::lonxml::debug("Calling sub $sub in $space $metamode");
+	#&Apache::lonxml::debug("Calling sub $sub in $space $metamode");
 	$sub1="$space\:\:$sub";
 	($currentstring,$nodefault) = &$sub1($target,$token,$tagstack,
 					     $parstack,$parser,$safeeval,
 					     $style);
       } else {
-	&Apache::lonxml::debug("NOT Calling sub $sub in $space $metamode");
+	#&Apache::lonxml::debug("NOT Calling sub $sub in $space $metamode");
 	if ($metamode <1) {
 	  if (defined($token->[4]) && ($metamode < 1)) {
 	    $currentstring = $token->[4];
@@ -762,7 +637,7 @@ sub callsub {
       #    &Apache::lonxml::debug("nodefalt:$nodefault:");
       if ($currentstring eq '' && $nodefault eq '') {
 	if ($target eq 'edit') {
-	  &Apache::lonxml::debug("doing default edit for $token->[1]");
+	  #&Apache::lonxml::debug("doing default edit for $token->[1]");
 	  if ($token->[0] eq 'S') {
 	    $currentstring = &Apache::edit::tag_start($target,$token);
 	  } elsif ($token->[0] eq 'E') {
@@ -930,7 +805,7 @@ sub default_homework_load {
     my ($safeeval)=@_;
     &Apache::lonxml::debug('Loading default_homework');
     my $default=&Apache::lonnet::getfile('/home/httpd/html/res/adm/includes/default_homework.lcpm');
-    if ($default == -1) {
+    if ($default eq -1) {
 	&Apache::lonxml::error("<b>Unable to find <i>default_homework.lcpm</i></b>");
     } else {
 	&Apache::run::run($default,$safeeval);
@@ -1029,7 +904,7 @@ sub increment_counter {
 sub init_counter {
     if (defined($ENV{'form.counter'})) {
 	$Apache::lonxml::counter=$ENV{'form.counter'};
-    } elsif (not defined($Apache::lonxml::counter)) {
+    } else {
 	$Apache::lonxml::counter=1;
 	&store_counter();
     }
@@ -1044,7 +919,9 @@ sub store_counter {
 sub get_all_text {
  my($tag,$pars)= @_;
  &Apache::lonxml::debug("Got a ".ref($pars));
+ my $gotfullstack=1;
  if (ref($pars) ne 'ARRAY') {
+     $gotfullstack=0;
      $pars=[$pars];
  }
  my $depth=0;
@@ -1053,7 +930,8 @@ sub get_all_text {
  if ( $tag =~ m:^/: ) { 
    my $tag=substr($tag,1); 
    #&Apache::lonxml::debug("have:$tag:");
-   while (($depth >=0) && ($#$pars > -1)) {
+   my $top_empty=0;
+   while (($depth >=0) && ($#$pars > -1) && (!$top_empty)) {
      while (($depth >=0) && ($token = $$pars[-1]->get_token)) {
        #&Apache::lonxml::debug("e token:$token->[0]:$depth:$token->[1]:".$#$pars.":".$#Apache::lonxml::pwd);
        if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
@@ -1071,11 +949,21 @@ sub get_all_text {
 	 }
        }
      }
+     if (($depth >=0) && ($#$pars == 0) ) { $top_empty=1; }
      if (($depth >=0) && ($#$pars > 0) ) {
        pop(@$pars);
        pop(@Apache::lonxml::pwd);
      }
    }
+   if ($top_empty && $depth >= 0) {
+       #never found the end tag ran out of text, throw error send back blank
+       &error('Never found end tag for &lt;'.$tag.'&gt;');
+       if ($gotfullstack) {
+	   my $newstring='</'.$tag.'>'.$result;
+	   &Apache::lonxml::newparser($pars,\$newstring);
+       }
+       $result='';
+   }
  } else {
      while ($#$pars > -1) {
 	 while ($token = $$pars[-1]->get_token) {
@@ -1127,7 +1015,7 @@ sub parstring {
   foreach (@{$token->[3]}) {
     unless ($_=~/\W/) {
       my $val=$token->[2]->{$_};
-      $val =~ s/([\%\@\\\"])/\\$1/g;
+      $val =~ s/([\%\@\\\"\'])/\\$1/g;
       #if ($val =~ m/^[\%\@]/) { $val="\\".$val; }
       $temp .= "my \$$_=\"$val\";"
     }
@@ -1181,7 +1069,7 @@ sub afterburn {
         $matchthis=~s/\_+/\\s\+/g;
         $result=~s/($matchthis)/\<a name=\"$anchorname\"\>$1\<\/a\>/s;
         $result.=(<<"ENDSCRIPT");
-<script>
+<script type="text/javascript">
     document.location.hash='$anchorname';
 </script>
 ENDSCRIPT
@@ -1222,6 +1110,13 @@ sub inserteditinfo {
       my ($result,$filecontents)=@_;
       $filecontents = &HTML::Entities::encode($filecontents);
 #      my $editheader='<a href="#editsection">Edit below</a><hr />';
+      my $xml_help = '<table><tr><td>'.
+	  &Apache::loncommon::help_open_topic("Greek_Symbols",'Greek Symbols',
+					      undef,undef,600)
+	      .'</td><td>'.
+          &Apache::loncommon::help_open_topic("Other_Symbols",'Other Symbols',
+					      undef,undef,600)
+	      .'</td></tr></table>';
       my $buttons=(<<BUTTONS);
 <input type="submit" name="attemptclean" 
        value="Save and then attempt to clean HTML" />
@@ -1232,6 +1127,7 @@ BUTTONS
 <hr />
 <a name="editsection" />
 <form method="post">
+$xml_help
 <input type="hidden" name="editmode" value="Edit" />
 $buttons<br />
 <textarea cols="80" rows="40" name="filecont">$filecontents</textarea>
@@ -1301,7 +1197,7 @@ sub handler {
   my %mystyle;
   my $result = '';
   my $filecontents=&Apache::lonnet::getfile($file);
-  if ($filecontents == -1) {
+  if ($filecontents eq -1) {
     $result=(<<ENDNOTFOUND);
 <html>
 <head>
@@ -1417,14 +1313,22 @@ sub get_param_var {
   if ( ! $context ) { $context = -1; }
   my $args ='';
   if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
+  &Apache::lonxml::debug("Args are $args param is $param");
   if ($case_insensitive) {
       if (! ($args=~s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei)) {
 	  return undef;
       }
   } elsif ( $args !~ /my \$\Q$param\E=\"/ ) { return undef; }
   my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
-  if ($value =~ /^[\$\@\%]/) {
-    return &Apache::run::run("return $value",$safeeval,1);
+  &Apache::lonxml::debug("first run is $value");
+  if ($value =~ /^[\$\@\%]\w+$/) {
+      &Apache::lonxml::debug("doing second");
+      my @result=&Apache::run::run("return $value",$safeeval,1);
+      if (!defined($result[0])) {
+	  return $value
+      } else {
+	  if (wantarray) { return @result; } else { return $result[0]; }
+      }
   } else {
     return $value;
   }