--- loncom/homework/grades.pm	2014/01/30 19:11:05	1.717
+++ loncom/homework/grades.pm	2014/08/25 20:23:01	1.724
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.717 2014/01/30 19:11:05 bisitz Exp $
+# $Id: grades.pm,v 1.724 2014/08/25 20:23:01 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -330,6 +330,8 @@ sub cleanRecord {
     my $grayFont = '<span class="LC_internal_info">';
     if ($response =~ /^(option|rank)$/) {
 	my %answer=&Apache::lonnet::str2hash($answer);
+        my @answer = %answer;
+        %answer = map {&HTML::Entities::encode($_, '"<>&')}  @answer;
 	my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"});
 	my ($toprow,$bottomrow);
 	foreach my $foil (@$order) {
@@ -346,6 +348,8 @@ sub cleanRecord {
 	    $bottomrow.'</tr></table></blockquote>';
     } elsif ($response eq 'match') {
 	my %answer=&Apache::lonnet::str2hash($answer);
+        my @answer = %answer;
+        %answer = map {&HTML::Entities::encode($_, '"<>&')}  @answer;
 	my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"});
 	my @items=&Apache::lonnet::str2array($record->{$version."resource.$partid.$respid.submissionitems"});
 	my ($toprow,$middlerow,$bottomrow);
@@ -368,6 +372,8 @@ sub cleanRecord {
 	    $bottomrow.'</tr></table></blockquote>';
     } elsif ($response eq 'radiobutton') {
 	my %answer=&Apache::lonnet::str2hash($answer);
+        my @answer = %answer;
+        %answer = map {&HTML::Entities::encode($_, '"<>&')}  @answer;
 	my ($toprow,$bottomrow);
 	my $correct = 
 	    &get_radiobutton_correct_foil($partid,$respid,$symb,$uname,$udom,$type,$trial,$rndseed);
@@ -400,10 +406,11 @@ sub cleanRecord {
 	    $env{'form.kwstyle'}  = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';
 	    $env{'form.'.$symb} = 1; # so that we don't have to read it from disk for multiple sub of the same prob.
 	}
-	$answer =~ s-\n-<br />-g;
-	return '<br /><br /><blockquote><tt>'.&keywords_highlight($answer).'</tt></blockquote>';
+	return '<br /><br /><blockquote><tt>'.&keywords_highlight(&HTML::Entities::encode($answer, '"<>&')).'</tt></blockquote>';
+
     } elsif ( $response eq 'organic') {
-	my $result='Smile representation: "<tt>'.$answer.'</tt>"';
+        my $result=&mt('Smile representation: [_1]',
+                           '"<tt>'.&HTML::Entities::encode($answer, '"<>&').'</tt>"');
 	my $jme=$record->{$version."resource.$partid.$respid.molecule"};
 	$result.=&Apache::chemresponse::jme_img($jme,$answer,400);
 	return $result;
@@ -442,8 +449,9 @@ sub cleanRecord {
 	$answer = 
 	    &Apache::loncommon::format_previous_attempt_value('submission',
 							      $answer);
+	return $answer;
     }
-    return $answer;
+    return &HTML::Entities::encode($answer, '"<>&');
 }
 
 #-- A couple of common js functions
@@ -1432,6 +1440,15 @@ INNERJS
                 txtc => 'Text Color',
                 font => 'Font Size',
                 fnst => 'Font Style',
+                col1 => 'red',
+                col2 => 'green',
+                col3 => 'blue',
+                siz1 => 'normal',
+                siz2 => '+1',
+                siz3 => '+2',
+                sty1 => 'normal',
+                sty2 => 'italic',
+                sty3 => 'bold',
              );
     $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT));
 
@@ -1595,25 +1612,34 @@ INNERJS
     var redsel = "";
     var grnsel = "";
     var blusel = "";
-    if (kwclr=="red")   {var redsel="checked"};
-    if (kwclr=="green") {var grnsel="checked"};
-    if (kwclr=="blue")  {var blusel="checked"};
+    var txtcol1 = "$lt{'col1'}";
+    var txtcol2 = "$lt{'col2'}";
+    var txtcol3 = "$lt{'col3'}";
+    var txtsiz1 = "$lt{'siz1'}";
+    var txtsiz2 = "$lt{'siz2'}";
+    var txtsiz3 = "$lt{'siz3'}";
+    var txtsty1 = "$lt{'sty1'}";
+    var txtsty2 = "$lt{'sty2'}";
+    var txtsty3 = "$lt{'sty3'}";
+    if (kwclr=="red")   {var redsel="checked='checked'"};
+    if (kwclr=="green") {var grnsel="checked='checked'"};
+    if (kwclr=="blue")  {var blusel="checked='checked'"};
     var sznsel = "";
     var sz1sel = "";
     var sz2sel = "";
-    if (kwsize=="0")  {var sznsel="checked"};
-    if (kwsize=="+1") {var sz1sel="checked"};
-    if (kwsize=="+2") {var sz2sel="checked"};
+    if (kwsize=="0")  {var sznsel="checked='checked'"};
+    if (kwsize=="+1") {var sz1sel="checked='checked'"};
+    if (kwsize=="+2") {var sz2sel="checked='checked'"};
     var synsel = "";
     var syisel = "";
     var sybsel = "";
-    if (kwstyle=="")    {var synsel="checked"};
-    if (kwstyle=="<i>") {var syisel="checked"};
-    if (kwstyle=="<b>") {var sybsel="checked"};
+    if (kwstyle=="")    {var synsel="checked='checked'"};
+    if (kwstyle=="<i>") {var syisel="checked='checked'"};
+    if (kwstyle=="<b>") {var sybsel="checked='checked'"};
     highlightCentral();
-    highlightbody('red','red',redsel,'0','normal',sznsel,'','normal',synsel);
-    highlightbody('green','green',grnsel,'+1','+1',sz1sel,'<i>','italic',syisel);
-    highlightbody('blue','blue',blusel,'+2','+2',sz2sel,'<b>','bold',sybsel);
+    highlightbody('red',txtcol1,redsel,'0',txtsiz1,sznsel,'',txtsty1,synsel);
+    highlightbody('green',txtcol2,grnsel,'+1',txtsiz2,sz1sel,'<i>',txtsty2,syisel);
+    highlightbody('blue',txtcol3,blusel,'+2',txtsiz3,sz2sel,'<b>',txtsty3,sybsel);
     highlightend();
     return;
   }
@@ -1631,31 +1657,29 @@ INNERJS
     hDoc.$docopen;
     hDoc.write('$start_page_highlight_central');
     hDoc.write("<form action=\\"inactive\\" name=\\"hlCenter\\">");
-    hDoc.write("<h3><span class=\\"LC_info\\">&nbsp;$lt{'kehi'}<\\/span><\\/h3><br /><br />");
+    hDoc.write("<h1>$lt{'kehi'}<\\/h1>");
 
-    hDoc.write('<table border="0" width="100%"><tr><td bgcolor="#777777">');
-    hDoc.write('<table border="0" width="100%"><tr bgcolor="#DDFFFF">');
-    hDoc.write("<td><b>$lt{'txtc'}<\\/b><\\/td><td><b>$lt{'font'}<\\/b><\\/td><td><b>$lt{'fnst'}<\\/td><\\/tr>");
+    hDoc.write('<table border="0" width="100%"><tr style="background-color:#A1D676">');
+    hDoc.write("<th>$lt{'txtc'}<\\/th><th>$lt{'font'}<\\/th><th>$lt{'fnst'}<\\/th><\\/tr>");
   }
 
   function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) { 
     var hDoc = hwdWin.document;
-    hDoc.write("<tr bgcolor=\\"#ffffdd\\">");
+    hDoc.write("<tr>");
     hDoc.write("<td align=\\"left\\">");
-    hDoc.write("<input name=\\"kwdclr\\" type=\\"radio\\" value=\\""+clrval+"\\" "+clrsel+">&nbsp;"+clrtxt+"<\\/td>");
+    hDoc.write("<input name=\\"kwdclr\\" type=\\"radio\\" value=\\""+clrval+"\\" "+clrsel+" \\/>&nbsp;"+clrtxt+"<\\/td>");
     hDoc.write("<td align=\\"left\\">");
-    hDoc.write("<input name=\\"kwdsize\\" type=\\"radio\\" value=\\""+szval+"\\" "+szsel+">&nbsp;"+sztxt+"<\\/td>");
+    hDoc.write("<input name=\\"kwdsize\\" type=\\"radio\\" value=\\""+szval+"\\" "+szsel+" \\/>&nbsp;"+sztxt+"<\\/td>");
     hDoc.write("<td align=\\"left\\">");
-    hDoc.write("<input name=\\"kwdstyle\\" type=\\"radio\\" value=\\""+syval+"\\" "+sysel+">&nbsp;"+sytxt+"<\\/td>");
+    hDoc.write("<input name=\\"kwdstyle\\" type=\\"radio\\" value=\\""+syval+"\\" "+sysel+" \\/>&nbsp;"+sytxt+"<\\/td>");
     hDoc.write("<\\/tr>");
   }
 
   function highlightend() { 
     var hDoc = hwdWin.document;
-    hDoc.write("<\\/table>");
-    hDoc.write("<\\/td><\\/tr><\\/table>&nbsp;");
-    hDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:updateChoice(1)\\">&nbsp;&nbsp;");
-    hDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />");
+    hDoc.write("<\\/table><br \\/>");
+    hDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:updateChoice(1)\\" \\/>&nbsp;&nbsp;");
+    hDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\" \\/><br /><br />");
     hDoc.write("<\\/form>");
     hDoc.write('$end_page_highlight_central');
     hDoc.close();
@@ -2045,6 +2069,7 @@ sub submission {
         if (1) {
 
             my %lt = &Apache::lonlocal::texthash(
+                          keyh => 'Keyword Highlighting for Essays',
                           keyw => 'Keyword Options',
                           list => 'List',
                           past => 'Paste Selection to List',
@@ -2053,13 +2078,18 @@ sub submission {
 #
 # Print out the keyword options line
 #
-	    $request->print(<<KEYWORDS);
-<br /><b>$lt{'keyw'}:</b>&nbsp;
-<a href="javascript:keywords(document.SCORE);" target="_self">$lt{'list'}</a>&nbsp; &nbsp;
-<a href="#" onmousedown="javascript:getSel(); return false"
- class="page">$lt{'past'}</a>&nbsp; &nbsp;
-<a href="javascript:kwhighlight();" target="_self">$lt{'high'}</a><br /><br />
-KEYWORDS
+	    $request->print(
+                '<div class="LC_columnSection">'
+               .'<fieldset><legend>'.$lt{'keyh'}.'</legend>'
+               .&Apache::lonhtmlcommon::funclist_from_array(
+                    ['<a href="javascript:keywords(document.SCORE);" target="_self">'.$lt{'list'}.'</a>',
+                     '<a href="#" onmousedown="javascript:getSel(); return false"
+ class="page">'.$lt{'past'}.'</a>',
+                     '<a href="javascript:kwhighlight();" target="_self">'.$lt{'high'}.'</a>'],
+                    {legend => $lt{'keyw'}})
+               .'</fieldset></div>'
+            );
+
 #
 # Load the other essays for similarity check
 #
@@ -2196,7 +2226,7 @@ KEYWORDS
 	    foreach my $submission (@$string) {
 		my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);
 		if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
-		my ($ressub,$hide,$subval) = split(/:/,$submission,3);
+		my ($ressub,$hide,$draft,$subval) = split(/:/,$submission,4);
 		# Similarity check
                 my $similar='';
                 my ($type,$trial,$rndseed);
@@ -2265,9 +2295,17 @@ KEYWORDS
                     if ($hide eq 'anon') {
                         $lastsubonly.='<br /><b>'.&mt('Anonymous Survey').'</b>'; 
                     } else {
-             	        $lastsubonly.='<br /><b>'.&mt('Submitted Answer:').' </b>'.
+             	        $lastsubonly.='<br /><b>'.&mt('Submitted Answer:').' </b>';
+                        if ($draft) {
+                            $lastsubonly.= ' <span class="LC_warning">'.&mt('Draft Copy').'</span>';
+                        }
+                        $subval =
 			    &cleanRecord($subval,$responsetype,$symb,$partid,
 					 $respid,\%record,$order,undef,$uname,$udom,$type,$trial,$rndseed);
+                        if ($responsetype eq 'essay') {
+                            $subval =~ s{\n}{<br />}g;
+                        }
+                        $lastsubonly.=$subval."\n";
                     }
 	            if ($similar) {$lastsubonly.="<br /><br />$similar\n";}
 		    $lastsubonly.='</div>';
@@ -2280,6 +2318,7 @@ KEYWORDS
     if ($env{'form.lastSub'} eq 'datesub') {
         my ($parts,$handgrade,$responseType) = &response_type($symb,\$res_error);
 	$request->print(&displaySubByDates($symb,\%record,$parts,$responseType,$checkIcon,$uname,$udom));
+  
     } 
     if ($env{'form.lastSub'} =~ /^(last|all)$/) {
         $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
@@ -2513,10 +2552,9 @@ sub get_last_submission {
                 }
             }
 	    my ($partid,$foo) = split(/submission$/,$key);
-	    my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ?
-		'<span class="LC_warning">'.&mt('Draft Copy').'</span> ' : '';
+	    my $draft  = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ? 1 : 0;
 	    #push(@string, join(':', $key, $hide, $draft.$lasthash{$key}));
-            push(@string, join(':', $key, $hide, $draft.(
+            push(@string, join(':', $key, $hide, $draft, (
                 ref($lasthash{$key}) eq 'ARRAY' ?
                     join(',', @{$lasthash{$key}}) : $lasthash{$key}) ));
 	}
@@ -2743,7 +2781,10 @@ sub processHandGrade {
 		next;
 	    }
 	    if ($errorflag eq 'not_allowed') {
-		$request->print("<span class=\"LC_warning\">Not allowed to modify grades for $uname:$udom</span>");
+		$request->print(
+                    '<span class="LC_error">'
+                   .&mt('Not allowed to modify grades for [_1]',"$uname:$udom")
+                   .'</span>');
 		$ctr++;
 		next;
 	    }
@@ -6583,7 +6624,7 @@ sub scantron_warning_screen {
 	$scantron_config{'CODEstart'} &&
 	$scantron_config{'CODElength'}) {
 	$CODElist=$env{'form.scantron_CODElist'};
-	if ($env{'form.scantron_CODElist'} eq '') { $CODElist='<span class="LC_warning">None</span>'; }
+	if ($env{'form.scantron_CODElist'} eq '') { $CODElist='<span class="LC_warning">'.&mt('None').'</span>'; }
 	$CODElist=
 	    '<tr><td><b>'.&mt('List of CODES to validate against:').'</b></td><td><tt>'.
 	    $env{'form.scantron_CODElist'}.'</tt></td></tr>';
@@ -8216,7 +8257,7 @@ sub hand_bubble_option {
         return &mt('The sequence to be graded contains response types which are handgraded.').'<p>'.
                &mt('If you have already graded these by bubbling sheets to indicate points awarded, [_1]what point value is assigned to a filled last bubble in each row?','<br />').
                '<label><input type="radio" name="scantron_lastbubblepoints" value="'.$bubbles_per_row.'" checked="checked" />'.&mt('[quant,_1,point]',$bubbles_per_row).'</label>&nbsp;'.&mt('or').'&nbsp;'.
-               '<label><input type="radio" name="scantron_lastbubblepoints" value="0"/>0 points</label></p>';
+               '<label><input type="radio" name="scantron_lastbubblepoints" value="0" />'.&mt('0 points').'</label></p>';
     }
     return;
 }
@@ -8879,7 +8920,7 @@ sub scantron_download_scantron_data {
     &Apache::lonnet::allowuploaded('/adm/grades',$skipped);
     $r->print('
     <p>
-	'.&mt('[_1]Original[_2] file as uploaded by the bubblesheet office.',
+	'.&mt('[_1]Original[_2] file as uploaded by the bubblesheet scanning office.',
 	      '<a href="'.$orig.'">','</a>').'
     </p>
     <p>
@@ -9050,14 +9091,14 @@ sub checkscantron_results {
 '<td>'.&mt('Bubblesheet').'</td><td>'.$showscandata.'</td><td rowspan="2">'.$last.'</td><td rowspan="2">'.$pid.'</td>'."\n".
 '</tr>'."\n".
 '<tr class="'.$css_class.'">'."\n".
-'<td>Submissions</td><td>'.$showrecord.'</td></tr>'."\n";
+'<td>'.&mt('Submissions').'</td><td>'.$showrecord.'</td></tr>'."\n";
                     $passed ++;
                 } else {
                     my $css_class = ($failed % 2)?'LC_odd_row':'LC_even_row';
                     $badstudents .= '<tr class="'.$css_class.'"><td>'.&mt('Bubblesheet').'</td><td><span class="LC_nobreak">'.$scandata{$pid}.'</span></td><td rowspan="2">'.$last.'</td><td rowspan="2">'.$pid.'</td>'."\n".
 '</tr>'."\n".
 '<tr class="'.$css_class.'">'."\n".
-'<td>Submissions</td><td><span class="LC_nobreak">'.$record{$pid}.'</span></td>'."\n".
+'<td>'.&mt('Submissions').'</td><td><span class="LC_nobreak">'.$record{$pid}.'</span></td>'."\n".
 '</tr>'."\n";
                     $failed ++;
                 }