[LON-CAPA-cvs] cvs: rat / lonpage.pm loncom/homework structuretags.pm loncom/interface lonhtmlcommon.pm

raeburn raeburn at source.lon-capa.org
Wed Jul 27 23:14:09 EDT 2011


raeburn		Thu Jul 28 03:14:09 2011 EDT

  Modified files:              
    /loncom/homework	structuretags.pm 
    /loncom/interface	lonhtmlcommon.pm 
    /rat	lonpage.pm 
  Log:
  - Bug 6459.
   - Overwriting previously submitted file in "turned_in" portfolio.
     - Prompt to confirm overwrite now supported for resources in .page.
     - &file_delchk_js() and &file_overwritechk_js() routines in structuretags.pm
       moved to a consolidated routine: &file_submissionchk_js() in lonhtmlcommon.pm
       to facilitate re-use.
     - Calls to &file_overwritechk_js() omitted from individual resources if 
       enclosing map is .page.  Single call from lonpage.pm instead (with
       refs to hashes with information about paths and numbers of response items
       in resources in .page included there.
     - Pop-up confirmations for overwrite and/or deletions supported for both
       "Submit Answer" and "Submit All" button presses.
     - Triggers for multiple response items aggregated into one pop-up
       for overwrites, and one for deletions (if applicable).
  - Generation of pop-up to confirm deletions in a .task now uses same mechanism
    (separate file_delchk_js() eliminated).`
  
  
-------------- next part --------------
Index: loncom/homework/structuretags.pm
diff -u loncom/homework/structuretags.pm:1.494 loncom/homework/structuretags.pm:1.495
--- loncom/homework/structuretags.pm:1.494	Thu Jul 28 02:53:38 2011
+++ loncom/homework/structuretags.pm	Thu Jul 28 03:13:58 2011
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: structuretags.pm,v 1.494 2011/07/28 02:53:38 raeburn Exp $
+# $Id: structuretags.pm,v 1.495 2011/07/28 03:13:58 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -172,166 +172,6 @@
 ENDSCRIPT
 }
 
-sub file_delchk_js {
-    my $delfilewarn = &mt('You have indicated you wish to remove some files previously included in your submission.').'\\n'.
-                      &mt('Continue submission with these files removed?');
-    return <<"ENDSCRIPT";
-<script type="text/javascript">
-// <![CDATA[
-function file_deletion_check(formname,uploadid) {
-    var elemnum = formname.elements.length;
-    if (elemnum == 0) {
-        return true;
-    }
-    var alluploads = new Array();
-    if ((uploadid != '') && (uploadid != undefined)) {
-        alluploads.push(uploadid);
-    } else {
-        var uploadstr = /^HWFILE.+\$/;
-        for (var i=0; i<formname.elements.length; i++) {
-            var id = formname.elements[i].id;
-            if (id != '') {
-                if (uploadstr.test(id)) {
-                    if (formname.elements[i].type == 'file') {
-                        alluploads.push(id);
-                    }
-                }
-            }
-        }
-    }
-    for (var i=0; i<alluploads.length; i++) {
-        var delstr = new RegExp('^'+alluploads[i]+'_\\\\d+_delete\$');
-        var delboxes = new Array();
-        for (var j=0; j<formname.elements.length; j++) {
-            var id = formname.elements[j].id;
-            if (id != '') {
-                if (delstr.test(id)) {
-                    if (formname.elements[j].type == 'checkbox') {
-                        if (formname.elements[j].checked) {
-                            delboxes.push(id);
-                        }
-                    }
-                }
-            }
-        }
-        if (delboxes.length > 0) {
-            if (!confirm("$delfilewarn")) {
-                for (var j=0; j<delboxes.length; j++) {
-                    formname.elements[delboxes[j]].checked = false;
-                }
-                return false;
-            }
-        }
-    }
-    return true;
-}
-// ]]>
-</script>
-ENDSCRIPT
-}
-
-sub file_overwritechk_js {
-    my $overwritewarn = &mt('File(s) you uploaded for your submission will overwrite existing file(s) submitted for this item').'\\n'.
-                      &mt('Continue submission and overwrite the file(s)?');
-    return <<"ENDSCRIPT";
-<script type="text/javascript">
-// <![CDATA[
-function file_overwrite_check(formname,path,multiresp) {
-    var elemnum = formname.elements.length;
-    if (elemnum == 0) {
-        return true;
-    }
-    var alluploads = new Array();
-    var uploaded = new Array();
-    var uploadstr = /^HWFILE.+\$/;
-    var fnametrim = /[^\\/\\\\]+\$/;
-    for (var i=0; i<formname.elements.length; i++) {
-        var id = formname.elements[i].id;
-        if (id != '') {
-            if (uploadstr.test(id)) {
-                if (formname.elements[i].type == 'file') {
-                    alluploads.push(id);
-                    if ((formname.elements[i].value != undefined) &&
-                        (formname.elements[i].value != '')) {
-                        uploaded.push(id);
-                    }
-                }
-            }
-        }
-    }
-    for (var i=0; i<alluploads.length; i++) {
-        var delstr = new RegExp("^"+alluploads[i]+"_\\\\d+_delete\$");
-        var delboxes = new Array();
-        for (var j=0; j<formname.elements.length; j++) {
-            var id = formname.elements[j].id;
-            if (id != '') {
-                if (delstr.test(id)) {
-                    if (formname.elements[j].type == 'checkbox') {
-                        delboxes.push(id);
-                    }
-                }
-            }
-        }
-        var overwrites = new Array();
-        if (delboxes.length > 0) {
-            if ((formname.elements[alluploads[i]].value != undefined) &&
-                (formname.elements[alluploads[i]].value != '')) {
-                var filepath = formname.elements[alluploads[i]].value;
-                var newfilename = fnametrim.exec(filepath);
-                if (newfilename != null) {
-                    var filename = String(newfilename);
-                    var nospaces = filename.replace(/\\s+/g,'_');
-                    var nospecials = nospaces.replace(/[^\\/\\w\\.\\-]/g,'');
-                    var cleanfilename = nospecials.replace(/\\.(\\d+\\.)/g,"_\$1");
-                    if (cleanfilename != '') {
-                        var fullpath = path+"/"+cleanfilename;
-                        if (multiresp == 1) {
-                            var partid = String(alluploads[i]);
-                            var subdir = partid.replace(/^HWFILE/,'');
-                            if (subdir != "" && subdir != undefined) {
-                                fullpath = path+"/"+subdir+"/"+cleanfilename;
-                            }
-                        }
-                        for (var k=0; k<delboxes.length; k++) {
-                            if (fullpath == formname.elements[delboxes[k]].value) {
-                                var id = formname.elements[delboxes[k]].id;
-                                if (id != '') {
-                                    if (!formname.elements[delboxes[k]].checked) {
-                                        overwrites.push(id);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            if (overwrites.length > 0) {
-                if (confirm("$overwritewarn")) {
-                    var delcheck = file_deletion_check(formname,alluploads[i]);
-                    if (delcheck == false) {
-                        return false;
-                    }
-                } else {
-                    for (var n=0; n<overwrites.length; n++) {
-                        formname.elements[overwrites[n]].value = "";
-                    }
-                    return false;
-                }
-            } else {
-                var delcheck = file_deletion_check(formname);
-                if (delcheck == false) {
-                    return false;
-                }
-            }
-        }
-    }
-    return true;
-}
-// ]]>
-</script>
-ENDSCRIPT
-}
-
 sub page_start {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$name,
 	$extra_head)=@_;
@@ -358,42 +198,53 @@
     }
     my $is_task = ($env{'request.uri'} =~ /\.task$/);
     my $needs_upload;
+    my ($symb)= &Apache::lonnet::whichuser();
+    my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
     if ($is_task) {
-        $extra_head .= &file_delchk_js();
+        $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js();
     } else {
         if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.uploadedfiletypes") ne '') {
-            $needs_upload = 1;
+            unless ($env{'request.state'} eq 'construct') {
+                my $navmap = Apache::lonnavmaps::navmap->new();
+                if (ref($navmap)) {
+                    my $mapres = $navmap->getResourceByUrl($map);
+                    unless ($mapres->is_page()) {
+                        $needs_upload = 1;
+                    }
+                }
+            }
         } else {
             unless ($env{'request.state'} eq 'construct') {
-                my ($symb)= &Apache::lonnet::whichuser();
                 my $navmap = Apache::lonnavmaps::navmap->new();
                 if (ref($navmap)) {
-                    my $res = $navmap->getBySymb($symb);
-                    if (ref($res)) {
-                        my $partlist = $res->parts();
-                        if (ref($partlist) eq 'ARRAY') {
-                            foreach my $part (@{$partlist}) {
-                                my @types = $res->responseType($part);
-                                my @ids = $res->responseIds($part);
-                                for (my $i=0; $i < scalar(@ids); $i++) {
-                                    if ($types[$i] eq 'essay') {
-                                        my $partid = $part.'_'.$ids[$i];
-                                        if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {
-                                            $needs_upload = 1;
-                                            last;
+                    my $mapres = $navmap->getResourceByUrl($map);
+                    unless ($mapres->is_page()) {
+                        my $res = $navmap->getBySymb($symb);
+                        if (ref($res)) {
+                            my $partlist = $res->parts();
+                            if (ref($partlist) eq 'ARRAY') {
+                                foreach my $part (@{$partlist}) {
+                                    my @types = $res->responseType($part);
+                                    my @ids = $res->responseIds($part);
+                                    for (my $i=0; $i < scalar(@ids); $i++) {
+                                        if ($types[$i] eq 'essay') {
+                                            my $partid = $part.'_'.$ids[$i];
+                                            if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {
+                                                $needs_upload = 1;
+                                                last;
+                                            }
                                         }
                                     }
                                 }
-                            }
-                        } 
+                            } 
+                        }
                     }
                 }
             }
         }
-    }
-    if ($needs_upload) {
-        $extra_head .= &file_overwritechk_js()."\n".
-                       &file_delchk_js();
+        if ($needs_upload) {
+            $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js();
+        }
     }
 
     my %body_args;
@@ -489,10 +340,8 @@
         my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();
         my ($path,$multiresp) = 
             &Apache::loncommon::get_turnedin_filepath($symb,$uname,$udom);
-        if ($is_task) {
-            $form_tag_start .= ' onsubmit="return file_deletion_check(this);"';
-        } elsif ($needs_upload) {
-            $form_tag_start .= ' onsubmit="return file_overwrite_check(this,'."'$path','$multiresp'".');"';
+        if (($is_task) || ($needs_upload)) {
+            $form_tag_start .= ' onsubmit="return file_submission_check(this,'."'$path','$multiresp'".');"';
         }
 	$form_tag_start.='>'."\n";
 
Index: loncom/interface/lonhtmlcommon.pm
diff -u loncom/interface/lonhtmlcommon.pm:1.290 loncom/interface/lonhtmlcommon.pm:1.291
--- loncom/interface/lonhtmlcommon.pm:1.290	Fri Jun  3 13:00:39 2011
+++ loncom/interface/lonhtmlcommon.pm	Thu Jul 28 03:14:04 2011
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common html routines
 #
-# $Id: lonhtmlcommon.pm,v 1.290 2011/06/03 13:00:39 www Exp $
+# $Id: lonhtmlcommon.pm,v 1.291 2011/07/28 03:14:04 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2338,6 +2338,247 @@
 ##############################################
 ##############################################
 
+sub file_submissionchk_js {
+    my ($turninpaths,$multiples) = @_;
+    my $overwritewarn = &mt('File(s) you uploaded for your submission will overwrite existing file(s) submitted for this item').'\\n'.
+                      &mt('Continue submission and overwrite the file(s)?');
+    my $delfilewarn = &mt('You have indicated you wish to remove some files previously included in your submission.').'\\n'.
+                      &mt('Continue submission with these files removed?');
+    my ($turninpathtext,$multtext);
+    if (ref($turninpaths) eq 'HASH') {
+        foreach my $key (sort(keys(%{$turninpaths}))) {
+            $turninpathtext .= "    if (prefix == '$key') {\n".
+                               "        return '$turninpaths->{$key}';\n".
+                               "    }\n";
+        }
+    }
+    $turninpathtext .= "    return '';\n";
+    if (ref($multiples) eq 'HASH') {
+        foreach my $key (sort(keys(%{$multiples}))) {
+            $multtext .= "    if (prefix == '$key') {\n".
+                         "        return '$multiples->{$key}';\n".
+                         "    }\n";
+        }
+    }
+    $multtext .= "    return '';\n";
+    return <<"ENDSCRIPT";
+<script type="text/javascript">
+// <![CDATA[
+
+function file_submission_check(formname,path,multiresp) {
+    var elemnum = formname.elements.length;
+    if (elemnum == 0) {
+        return true;
+    }
+    var alloverwrites = [];
+    var alldelconfirm = [];
+    var result = [];
+    var submitter;
+    var subprefix;
+    var allsub = getIndexByName(formname,'all_submit');
+    if (allsub == -1) {
+        var idx = getIndexByName(formname,'submitted');
+        if (idx != -1) {
+            var subval = String(formname.elements[idx].value);
+            submitter = subval.replace(/^part_/,'');
+            result = overwritten_check(formname,path,multiresp,submitter);
+            alloverwrites.push.apply(alloverwrites,result['overwrite']);
+            alldelconfirm.push.apply(alldelconfirm,result['delete']);
+        }
+    } else {
+        if (formname.elements[allsub].type == 'submit') {
+            var partsub = /^\\d+\\.\\d+_submit_.+\$/;
+            var allprefixes = [];
+            var allparts = [];
+            for (var i=0; i<formname.elements.length; i++) {
+                if (formname.elements[i].type == 'submit') {
+                    var elemname = formname.elements[i].name;
+                    var subname = String(elemname);
+                    var savesub = String(elemname);
+                    if (partsub.test(subname)) {
+                        var prefix = subname.replace(/_submit_.+\$/,'');
+                        if (allprefixes.indexOf(prefix) == -1) {
+                            allprefixes.push(prefix);
+                            allparts[prefix] = [];
+                        }
+                        var part = savesub.replace(/^\\d+\\.\\d+_submit_/,'');
+                        allparts[prefix].push(part);
+                    }
+                }
+            }
+            for (var k=0; k<allprefixes.length; k++) {
+                var idx = getIndexByName(formname,allprefixes[k]+'_submitted');
+                if (idx > -1) {
+                    if (formname.elements[idx].value != 'yes') {
+                        submitterval = formname.elements[idx].value;
+                        submitter = submitterval.replace(/^part_/,'');
+                        subprefix = allprefixes[k];
+                        result = overwritten_check(formname,path,multiresp,submitter,subprefix);
+                        alloverwrites.push.apply(alloverwrites,result['overwrite']);
+                        alldelconfirm.push.apply(alldelconfirm,result['delete']);
+                        break;
+                    }
+                }
+            }
+            if (submitter == '' || submitter == undefined) {
+                for (var m=0; m<allprefixes.length; m++) {
+                    for (var n=0; n<allparts[allprefixes[m]].length; n++) {
+                        var result = overwritten_check(formname,path,multiresp,allparts[allprefixes[m]][n],allprefixes[m]);
+                        alloverwrites.push.apply(alloverwrites,result['overwrite']);
+                        alldelconfirm.push.apply(alldelconfirm,result['delete']);
+                    }
+                }
+            }
+        }
+    }
+    if (alloverwrites.length > 0) {
+        if (!confirm("$overwritewarn")) {
+            for (var n=0; n<alloverwrites.length; n++) {
+                formname.elements[alloverwrites[n]].value = "";
+            }
+            return false;
+        }
+    }
+    if (alldelconfirm.length > 0) {
+        if (!confirm("$delfilewarn")) {
+            for (var p=0; p<alldelconfirm.length; p++) {
+                formname.elements[alldelconfirm[p]].checked = false;
+            }
+            return false;
+        }
+    }
+    return true;
+}
+
+function getIndexByName(formname,item) {
+    for (var i=0;i<formname.elements.length;i++) {
+        if (formname.elements[i].name == item) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+function overwritten_check(formname,path,multiresp,part,prefix) {
+    var result = [];
+    result['overwrite'] = [];
+    result['delete'] = [];
+    var elemnum = formname.elements.length;
+    if (elemnum == 0) {
+        return result;
+    }
+    var uploadstr;
+    var deletestr;
+    if ((prefix != undefined) && (prefix != '')) {
+        var prepend = prefix+'_';
+        uploadstr = new RegExp("^"+prepend+"HWFILE"+part+".+\$");
+        deletestr = new RegExp("^"+prepend+"HWFILE"+part+".+_\\\\d+_delete\$");
+        multiresp = check_for_multiples(prepend);
+        path = check_for_turninpath(prepend);
+    } else {
+        uploadstr = new RegExp("^HWFILE"+part+".+\$");
+        deletestr = new RegExp("^HWFILE"+part+".+_\\\\d+_delete\$");
+    }
+    var alluploads = [];
+    var allchecked = [];
+    var allskipdel = [];
+    var fnametrim = /[^\\/\\\\]+\$/;
+    for (var i=0; i<formname.elements.length; i++) {
+        var id = formname.elements[i].id;
+        if (id != '') {
+            if (uploadstr.test(id)) {
+                if (formname.elements[i].type == 'file') {
+                    alluploads.push(id);
+                } else {
+                    if (deletestr.test(id)) {
+                        if (formname.elements[i].type == 'checkbox') {
+                            if (formname.elements[i].checked) {
+                                allchecked.push(id);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    for (var j=0; j<alluploads.length; j++) {
+        var delstr = new RegExp("^"+alluploads[j]+"_\\\\d+_delete\$");
+        var delboxes = [];
+        for (var k=0; k<formname.elements.length; k++) {
+            var id = formname.elements[k].id;
+            if ((id != '') && (id != undefined)) {
+                if (delstr.test(id)) {
+                    if (formname.elements[k].type == 'checkbox') {
+                        delboxes.push(id);
+                    }
+                }
+            }
+        }
+        if (delboxes.length > 0) {
+            if ((formname.elements[alluploads[j]].value != undefined) &&
+                (formname.elements[alluploads[j]].value != '')) {
+                var filepath = formname.elements[alluploads[j]].value;
+                var newfilename = fnametrim.exec(filepath);
+                if (newfilename != null) {
+                    var filename = String(newfilename);
+                    var nospaces = filename.replace(/\\s+/g,'_');
+                    var nospecials = nospaces.replace(/[^\\/\\w\\.\\-]/g,'');
+                    var cleanfilename = nospecials.replace(/\\.(\\d+\\.)/g,"_\$1");
+                    if (cleanfilename != '') {
+                        var fullpath = path+"/"+cleanfilename;
+                        if (multiresp == 1) {
+                            var partid = String(alluploads[i]);
+                            var subdir = partid.replace(/^\\d*.?\\d*_?HWFILE/,'');
+                            if (subdir != "" && subdir != undefined) {
+                                fullpath = path+"/"+subdir+"/"+cleanfilename;
+                            }
+                        }
+                        for (var m=0; m<delboxes.length; m++) {
+                            if (fullpath == formname.elements[delboxes[m]].value) {
+                                if (formname.elements[delboxes[m]].checked) {
+                                    allskipdel.push(delboxes[m]);
+                                } else {
+                                    result['overwrite'].push(alluploads[j]);
+                                }
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    if (allchecked.length > 0) {
+        if (allskipdel.length > 0) {
+            for (var n=0; n<allchecked.length; n++) {
+                if (allskipdel.indexOf(allchecked[n]) == -1) {
+                    result['delete'].push(allchecked[n]);
+                }
+            }
+        } else {
+            result['delete'].push.apply(result['delete'],allchecked);
+        }
+    }
+    return result;
+}
+
+function check_for_multiples(prefix) {
+$multtext
+}
+
+function check_for_turninpath(prefix) {
+$turninpathtext
+}
+
+// ]]>
+</script>
+
+ENDSCRIPT
+}
+
+##############################################
+##############################################
+
 # javascript_valid_email
 #
 # Generates javascript to validate an e-mail address.
Index: rat/lonpage.pm
diff -u rat/lonpage.pm:1.95 rat/lonpage.pm:1.96
--- rat/lonpage.pm:1.95	Thu Jul 28 02:53:33 2011
+++ rat/lonpage.pm	Thu Jul 28 03:14:09 2011
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Page Handler
 #
-# $Id: lonpage.pm,v 1.95 2011/07/28 02:53:33 raeburn Exp $
+# $Id: lonpage.pm,v 1.96 2011/07/28 03:14:09 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -214,6 +214,10 @@
                   my $lcm=1;
                   my $contents=0;
                   my $nforms=0;
+                  my $nuploads=0;
+                  my %turninpaths;
+                  my %multiresps;
+                  my $turninparent;
                   
                   my %ssibody=();
                   my %ssibgcolor=();
@@ -352,8 +356,21 @@
 				  $nforms++;
                                   $output=~s/\<form[^\>]*\>//gsi;
                                   $output=~s/\<\/form[^\>]*\>//gsi;
+                                  if ($output=~/\<input[^\>]+name\s*=\s*[\'\"]*HWFILE/) {
+                                      $nuploads++;
+                                  }
                                   $output=~
 				      s/\<((?:input|select|button|textarea)[^\>]+)name\s*\=\s*[\'\"]*([^\'\"]+)[\'\"]*([^\>]*)\>/\<$1 name="$prefix$2" $3\>/gsi;
+                                  if ($nuploads) {
+                                      $output=~
+                                          s/\<(input[^\>]+name=\"\Q$prefix\EHWFILE[^\>]+)\s*id\s*\=\s*[\'\"]*([^\'\"]+)[\'\"]*([^\)]*)\>/\<$1 id="$prefix$2" $3\>/gsi;
+                                       ($turninpaths{$prefix},$multiresps{$prefix}) = 
+                                           &Apache::loncommon::get_turnedin_filepath($symb,$env{'user.name'},$env{'user.domain'});
+                                       if ($turninparent eq '') {
+                                           $turninparent = $turninpaths{$prefix};
+                                           $turninparent =~ s{(/[^/]+)$}{}; 
+                                       }
+                                  }
                                   $output=~
                                       s/\<((?:input|select)[^\>]+\Qjavascript:setSubmittedPart\E)\(\s*[\'\"]([^\'\"]+)[\'\"]*\s*\)/\<$1('$2','$prefix')/gsi;
                               }
@@ -403,15 +420,27 @@
 				  $allscript.
 				  "\n</script>\n";
 			  }
+                          if (($nforms) && ($nuploads)) {
+                              $allscript .= &Apache::lonhtmlcommon::file_submissionchk_js(\%turninpaths,\%multiresps);
+                          }
 # ------------------------------------------------------------------ Start body
 			  $r->print(&Apache::loncommon::start_page(undef,$allscript,
 								   {'force_register' => 1,
 								    'bgcolor'        => '#ffffff',}));
 # ------------------------------------------------------------------ Start form
 			  if ($nforms) {
-			      $r->print('<form name="lonhomework" method="post"  enctype="multipart/form-data" action="'.
+			      my $fmtag = '<form name="lonhomework" method="post"  enctype="multipart/form-data"';
+                              if ($nuploads) {
+                                  my $multi;
+                                  if ($nuploads > 1) {
+                                      $multi = 1;
+                                  }
+                                  $fmtag .= 'onsubmit="return file_submission_check(this,'."'$turninparent','$multi'".');"';
+                              }
+                              $fmtag .= ' action="'.
 					&Apache::lonenc::check_encrypt($requrl)
-					.'">');
+					.'">';
+                              $r->print($fmtag);
 			  }
 		      } elsif (($target eq 'tex') || ($target eq 'tex_answer')) {
 			  #  I think this is not needed as the header


More information about the LON-CAPA-cvs mailing list