[LON-CAPA-cvs] cvs: loncom /homework radiobuttonresponse.pm

foxr foxr at source.lon-capa.org
Thu Feb 9 19:26:42 EST 2012


foxr		Fri Feb 10 00:26:42 2012 EDT

  Modified files:              
    /loncom/homework	radiobuttonresponse.pm 
  Log:
  bz4492 - Honor horizontal rendering of bubbles and do a bit of tuning of exam
  mode rendering to make stuff look nicer in vert. mode.
  
  
-------------- next part --------------
Index: loncom/homework/radiobuttonresponse.pm
diff -u loncom/homework/radiobuttonresponse.pm:1.154 loncom/homework/radiobuttonresponse.pm:1.155
--- loncom/homework/radiobuttonresponse.pm:1.154	Fri Jan 20 13:26:34 2012
+++ loncom/homework/radiobuttonresponse.pm	Fri Feb 10 00:26:42 2012
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # mutliple choice style responses
 #
-# $Id: radiobuttonresponse.pm,v 1.154 2012/01/20 13:26:34 raeburn Exp $
+# $Id: radiobuttonresponse.pm,v 1.155 2012/02/10 00:26:42 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -33,14 +33,22 @@
 use Apache::lonlocal;
 use Apache::lonnet;
 use Apache::response;
+use Apache::caparesponse;
 
 my $default_bubbles_per_line = 10;
+my @alphabet      = ( 'A' .. 'Z' ); # Foil labels.
+
+
 
 
 BEGIN {
     &Apache::lonxml::register('Apache::radiobuttonresponse',('radiobuttonresponse'));
 }
 
+#---------------------------------------------------------------------------
+#
+#  Generic utility subs.
+
 sub bubble_line_count {
     my ($numfoils, $bubbles_per_line) = @_;
     my $bubble_lines;
@@ -53,6 +61,10 @@
 }
 
 
+
+#------------------------------------------------------------------------------
+#
+#  XML handlers.
 sub start_radiobuttonresponse {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result;
@@ -90,27 +102,30 @@
 						     $safeeval,'max',
 						     'randomize','direction');
 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
-    } elsif ($target eq 'tex') {
-	my $type=&Apache::lonxml::get_param('TeXtype',$parstack,$safeeval,
-					    undef,0);
-	if ($type eq '1') {
-	    $result .= ' \renewcommand{\labelenumi}{\arabic{enumi}.}';
-	} elsif ($type eq 'A') {
-	    $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
-	} elsif ($type eq 'a') {
-	    $result .= ' \renewcommand{\labelenumi}{\alph{enumi}.}';
-	} elsif ($type eq 'i') {
-	    $result .= ' \renewcommand{\labelenumi}{\roman{enumi}.}';
-	} else {
-	    $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
-	}
-        if($env{'form.pdfFormFields'} eq 'yes' && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
-            $result .= '\begin{itemize}';
-        } else {
-            $result .= '\begin{enumerate}';
+
+   } elsif ( $target eq 'tex' ) {
+        my $type =
+          &Apache::lonxml::get_param( 'TeXtype', $parstack, $safeeval, undef,
+            0 );
+        if ( $type eq '1' ) {
+            $result .= ' \renewcommand{\labelenumi}{\arabic{enumi}.}';
+        }
+        elsif ( $type eq 'A' ) {
+            $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
+        }
+        elsif ( $type eq 'a' ) {
+            $result .= ' \renewcommand{\labelenumi}{\alph{enumi}.}';
+        }
+        elsif ( $type eq 'i' ) {
+            $result .= ' \renewcommand{\labelenumi}{\roman{enumi}.}';
         }
-    } elsif ($target eq 'analyze') {
-	my $part_id="$Apache::inputtags::part.$id";
+        else {
+            $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
+        }
+
+    }
+    elsif ( $target eq 'analyze' ) {
+        my $part_id = "$Apache::inputtags::part.$id";
         $Apache::lonhomework::analyze{"$part_id.type"} = 'radiobuttonresponse';
 	push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id);
     }
@@ -120,13 +135,8 @@
 sub end_radiobuttonresponse {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result;
-    if ($target eq 'edit') { $result=&Apache::edit::end_table(); }
-    if ($target eq 'tex' ) {
-        if($env{'form.pdfFormFields'} eq 'yes' and $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
-            $result .= '\end{itemize}';
-        } else {
-            $result .= '\end{enumerate}';
-        }
+    if ( $target eq 'edit' ) { 
+	$result = &Apache::edit::end_table(); 
     }
     &Apache::response::end_response;
     pop @Apache::lonxml::namespace;
@@ -223,6 +233,7 @@
     my $part = $Apache::inputtags::part;
     my $bubbles_per_line = &getbubblesnum($part,$id);
 
+
     if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
 	$target eq 'tex' || $target eq 'analyze') {
 	my $style = $Apache::lonhomework::type;
@@ -285,7 +296,6 @@
     }
     return $result;
 }
-
 sub getbubblesnum {
     my ($part,$id) = @_;
     my $bubbles_per_line;
@@ -328,112 +338,313 @@
 
 }
 
-sub displayallfoils {
-    my ($direction, $target)=@_;
-    my $result;
-    &Apache::lonxml::debug("survey style display");
-    my @names;
-    if ( $Apache::response::foilgroup{'names'} ) {
-	@names= @{ $Apache::response::foilgroup{'names'} };
-    }
 
-    my $temp=0;
-    my $i   =0;
-    my $id=$Apache::inputtags::response['-1'];
-    my $part=$Apache::inputtags::part;
-    my ($lastresponse,$newvariation,$showanswer);
-    if ((($Apache::lonhomework::history{"resource.$part.type"} eq 'randomizetry') ||
-        ($Apache::lonhomework::type eq 'randomizetry')) &&
-        ($Apache::inputtags::status[-1] eq 'CAN_ANSWER')) {
-        if ($env{'form.'.$part.'.rndseed'} ne
-            $Apache::lonhomework::history{"resource.$part.rndseed"}) {
+## 
+# Return the last survey response.  The logic is slightly different than that of 
+# get_last_responses.  TODO: See if there are chunks of code betweenthis and
+# get_last_reponses that are common and can be factored.
+#
+# @param $part - Problem part under consideration.
+# @param $showanswer - True if answers should be shown.
+# @param $id         - Problem id.
+#
+# @return hash reference.
+# @retval reference to the has indexed by answer selection that 
+#         indicates the most recent answer.
+#
+sub get_last_survey_response {
+    my ($part, $showanswer, $id) = @_;
+
+    my $newvariation;
+    my $lastresponse;		# stringified last response.
+
+    if (
+        (
+            (
+                $Apache::lonhomework::history{"resource.$part.type"} eq
+                'randomizetry'
+            )
+            || ( $Apache::lonhomework::type eq 'randomizetry' )
+        )
+        && ( $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
+      )
+    {
+        if ( $env{ 'form.' . $part . '.rndseed' } ne
+            $Apache::lonhomework::history{"resource.$part.rndseed"} )
+        {
             $newvariation = 1;
         }
     }
     $showanswer = &Apache::response::show_answer();
-    unless ((($Apache::lonhomework::history{"resource.$part.type"} eq 'anonsurvey') || ($Apache::lonhomework::history{"resource.$part.type"} eq 'anonsurveycred')) && (defined($env{'form.grade_symb'})) ||
-           ($newvariation && !$showanswer)) {
-        $lastresponse = 
-	    $Apache::lonhomework::history{"resource.$part.$id.submission"};
+    unless (
+        (
+            (
+                $Apache::lonhomework::history{"resource.$part.type"} eq
+                'anonsurvey'
+            )
+            || ( $Apache::lonhomework::history{"resource.$part.type"} eq
+                'anonsurveycred' )
+        )
+        && ( defined( $env{'form.grade_symb'} ) )
+        || ( $newvariation && !$showanswer )
+      )
+    {
+        $lastresponse =
+          $Apache::lonhomework::history{"resource.$part.$id.submission"};
     }
-    if ($direction eq 'horizontal') { $result.='<table><tr>'; }
-    my %lastresponse=&Apache::lonnet::str2hash($lastresponse);
-    if ($showanswer) {
-	foreach my $name (@names) {
-	    if ($Apache::response::foilgroup{$name.'.value'} ne 'unused') {
-		if (($direction eq 'horizontal') && ($target ne 'tex')) {
-		    $result.="<td>";
-		} else {
-		    if ($target eq 'tex') {
-			$result .= '\item \vskip -2mm ';
-		    } else {
-			$result.="<br />";
-		    }
-		}
-		if (defined($lastresponse{$name})) {
-		    if ($target eq 'tex') {
-			$result .= '}';
-		    } else {
-			$result.='<b>';
-		    }
-		}
-		$result .= $Apache::response::foilgroup{$name.'.text'};
-		if (defined($lastresponse{$name}) && ($target ne 'tex')) {
-		    $result.='</b>';
-		}
-		if (($direction eq 'horizontal') && ($target ne 'tex')) { $result.="</td>"; }
+    my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
+   
+
+    return \%lastresponse;
+
+}
+##
+# Removes the names from a foil group that are marked as unused.
+#
+# @param $names - reference to the array of names to filter.
+#
+# @return arrayref
+# @retval reference to the filtered array.
+#
+sub remove_unused {
+    my ($names) = @_;
+    my @result;
+
+    foreach my $name (@{$names}) {
+	if ($Apache::response::foilgroup{$name . '.value'} ne 'unused') {
+	    push(@result, $name);
+	}
+    }
+    return \@result;
+}
+## 
+# Displays all foils in a survey type problem for HTML rendition.
+# TODO: See if there is any logic in this sub that can be shared
+#      with display_foils_html
+#
+# @param $names        - ref to array of names of the foils to display.
+# @param $part         - Problem part number.
+# @param $showanswer   - If true, show the answers.
+# @param $lastresponse - Ref to the last response hash.
+# @param $direction    - Display direction of the radiobuttons.
+#
+# @return string
+# @retval HTML required to display the resource in a browser.
+#
+sub display_survey_html {
+    my ($names, $part, $showanswer, $lastresponse, $direction) = @_;
+    my $result;
+
+    # Figure out a few fragments of html that depend onthe 
+    # orientation of the radiobuttons:
+    # closing_html - HTML to emit at the end of the resource.
+    # pre_foil     - HTML to emit prior to each foil.
+    # post_foil    - HTML to emit following each foil.
+    #
+    #  The opening HTML is just added to the $result now
+    #
+    #  Figuring these outin advance compresses the loop over foils into something
+    #  pretty simple:
+    #
+    # NOTE: There's probably a really cool way to do this with style sheets
+    #       and picking the selector based on the orientation, if someone wants to puzzle
+    #       that out.  In that case, probably the whole thing lives in a <div> and each
+    #       foil lives in a <p>
+    #
+
+
+    my ($opening_html, $closing_html, $pre_foil, $post_foil) = 
+	&html_direction_fragments($direction);
+
+    $result = $opening_html;
+
+    # Different rendering depending on whether answers are shown:
+    # I played with different factorings but this seems the most concise/clear...
+    # although I don't like the $showanswer conditino inside the loop.  Other things I tried
+    #  - two loops..much longer code..no gain in clarity.
+    #  - Using a visitor patttern passing it the rendering code chunklets and
+    #    an anonymous hash reference for state data etc. Very cool but
+    #    quite a bit more code and quite a bit less clear.
+    
+    my $temp = 0;
+    foreach my $name (@{$names}) {
+	$result .= $pre_foil;
+
+	if ($showanswer) {
+	    my $foiltext =  $Apache::response::foilgroup{$name . '.text'};
+
+	    # Bold the prior  response:
+
+	    if (defined($lastresponse->{$name})) {
+		$result .= '<b>' . $foiltext . '</b>';
+	    } else {
+		$result .= $foiltext;
 	    }
+	} else {
+	    $result .= &html_radiobutton(
+		$part, $Apache::inputtags::response['-1'], $name, $lastresponse, $temp
+	     );
 	}
+
+	$result .= $post_foil;
+	$temp++;
+    }
+
+
+    $result .= $closing_html;
+    return $result;
+
+}
+
+##
+#  Generate LaTeX for surveys.
+#  
+#   @param $names - names of the foils to display.
+#   @param $showanswer - flag that is true to display answers.
+#   @param $lastresponse - Reference to a hash the indicates the last response.
+#   @param $direction    - Orientation of foils ('horiztonal' or otherwise).
+#   @param $venv         - LaTeX name for vertical env.
+#
+#   @return string
+#   @retval LaTeX rendering of the survey question.
+
+sub latex_survey {
+    my ($names, $showanswer, $lastresponse, $direction, $venv) = @_;
+
+    my $result;
+    if ($showanswer) {
+	$result .= "\\begin{$venv}";
+	foreach my $name (@{$names}) {
+	    
+	    
+	    $result .= '\item \vskip -2mm ';
+	    
+	    if ( defined( $lastresponse->{$name} ) ) {
+		$result .= '}';
+	    }
+	    $result .= $Apache::response::foilgroup{ $name . '.text' } . ' ';
+	}
+	$result .= "\\end{$venv}";
+
+    } elsif ( $env{'form.pdfFormFields'} eq 'yes'
+	      && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+	$result .= &display_pdf_form($names, $direction, $venv);
     } else {
-	foreach my $name (@names) {
-	    if ($Apache::response::foilgroup{$name.'.value'} ne 'unused') {
-		if ($direction eq 'horizontal') {
-		    $result.="<td>";
-		} else {
-		    if ($target eq 'tex') {
-		        if($env{'form.pdfFormFields'} eq 'yes' && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
-                            my $fieldname = $env{'request.symb'}.'&part_'. $Apache::inputtags::part
-                                            .'&radiobuttonresponse'.'&HWVAL_'.$Apache::inputtags::response['-1'];
-                            $result .= '\item[{'.&Apache::lonxml::print_pdf_radiobutton($fieldname,$temp).'}]'
-                                       .$Apache::response::foilgroup{$name.'.text'}."\n";
-                        } else {
-                            $result .= '\item \vskip -2mm ';
-                        }
-                    } else {
-			$result.="<br />";
-		    }
-		}
-		if ($target eq 'tex') {
-		    if($env{'form.pdfFormFields'} ne 'yes' or $Apache::inputtags::status[-1] ne 'CAN_ANSWER') {
-                        $result .= '$\bigcirc$'.$Apache::response::foilgroup{$name.'.text'}.'\\\\';  #' stupid emacs
-                    }
-		    $i++;
-		} else {
-		    $result .= '<label>';
-		    $result.="<input
-                       onchange=\"javascript:setSubmittedPart('$part');\"
-                       type=\"radio\"
-                       name=\"HWVAL_$Apache::inputtags::response['-1']\"
-                       value=\"$temp\"";
-
-		    if (defined($lastresponse{$name})) { $result .= ' checked="checked"'; }
-		    $result .= ' />'.$Apache::response::foilgroup{$name.'.text'}.
-			'</label>';
+	if ($direction eq 'horizontal') {
+	    my @foil_texts = &get_foil_texts($names);
+	    $result .=  &Apache::caparesponse::make_horizontal_latex_bubbles(
+	    $names, \@foil_texts, '$\bigcirc$');
+	} else {
+	    $result .= "\\begin{$venv}";
+
+	    my $temp = 0;
+	    my $i    = 0;
+	    foreach my $name (@{$names}) {
+
+		$result .= '\item \vskip -2mm ';
+		
+		if ($env{'form.pdfFormFields'} ne 'yes'
+		    or $Apache::inputtags::status[-1] ne 'CAN_ANSWER' )
+		{
+		    $result .=
+			'$\bigcirc$'
+			. $Apache::response::foilgroup{ $name . '.text' }
+		    . '\\\\';    #' stupid emacs
 		}
+		
+		$i++;	    
 		$temp++;
-		if ($target ne 'tex') {
-		    if (($direction eq 'horizontal') && ($target ne 'tex')) { $result.="</td>"; }
-		} else {
-		    $result.='\vskip 0 mm ';
-		}
+		
+		$result .= '\vskip 0 mm ';
 	    }
-	}
+	    $result .= "\\end{$venv}";
+	}	
     }
-    
-    if (($direction eq 'horizontal') && ($target ne 'tex')) { $result.='</tr></table>'; }
     return $result;
 }
+##
+#  Figure out the LaTeX environment in which to wrap the LaTeX vertical output.
+#
+# @return string
+# @retval the environment name.  The LaTeX should be wrapped a 
+#    \begin{retval} \end{retval} pair.
+#
+sub latex_vertical_environment {
+    if ($env{'form.pdfFormFields'} eq 'yes'
+	&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+	return 'itemize';
+    } else {
+	return 'enumerate';
+    }
+}
+
+##
+# Figure out the key html fragments that depend on the rendering direction:
+#
+# @param $direction - 'horizontal' for horizontal direction.
+#
+# @return list
+# @retval (part_start, part_end, foil_start, foil_end)
+# Where:
+#   - part_start is the HTML to emit at the start of the part.
+#   - part_end   is the HTML to emit at the end of the part.
+#   - foil_start is the HTML to emit prior to each foil.
+#   - foil_end is the HTML to emit after each foil
+#
+sub html_direction_fragments {
+    my $direction = shift;
+    if ($direction eq 'horizontal') {
+	return ('<table><tr>', '</tr></table>', '<td>', '</td>');
+    } else {
+	return ('', '<br />', '<br />', '');
+    }
+}
 
+##
+#
+#  Displays all the foils of a problem in a format suitable for
+#   surveys, surveys for credit, anonymous surveys and anonymous surveys for credit.
+#
+#  @param $direction - Display direction of the choices ('horiztonal' or not).
+#  @param $target    - Rendering target.
+#
+#  @return string
+#  @retval Text that renders for the selected target.
+# 
+sub displayallfoils{
+    my ( $direction, $target ) = @_;
+    my $result;
+    &Apache::lonxml::debug("survey style display");
+
+    my @names;
+
+    if ( $Apache::response::foilgroup{'names'} ) {
+        @names = @{ $Apache::response::foilgroup{'names'} };
+    }
+
+
+    my $id   = $Apache::inputtags::response['-1'];
+    my $part = $Apache::inputtags::part;
+    
+    my $showanswer = &Apache::response::show_answer();
+    my $lastresponse = &get_last_survey_response($part, $showanswer, $id);
+    my $used_names = &remove_unused(\@names);
+
+
+    if ($target ne 'tex') {
+	$result .= &display_survey_html(
+	    $used_names, $part, $showanswer, $lastresponse, $direction
+	);
+    } else {	
+
+	my $vertical_env = &latex_vertical_environment();
+	$result .= &latex_survey(
+	    $used_names, $showanswer, $lastresponse, $direction, $vertical_env
+	);
+
+    }
+    return $result;
+}
 
 sub whichfoils {
     my ($max,$randomize)=@_;
@@ -583,152 +794,430 @@
     return ($answer, at whichfalse);
 }
 
-sub displayfoils {
-    my ($target,$answer,$whichfoils,$direction, $bubbles_per_line)=@_;
-    my $result;
+## 
+#  Return a list  of foil texts given foil names.
+#  
+# @param $whichfoils - Reference to a list of foil names.
+#
+# @return array
+# @retval foil texts
+#
+sub get_foil_texts {
+    my ($whichfoils) = @_;
+    my @foil_texts;
+
+    foreach my $name (@{$whichfoils}) {
+	push(@foil_texts, $Apache::response::foilgroup{$name . '.text'});
+    }
+    return @foil_texts;
+}
+
+##
+# Generate the HTML for a single html foil.
+# @param $part           - The part for which the response is being generated.
+# @param $fieldname      - The basename of the radiobutton field
+# @param $name           - The foilname.
+# @param $last_responses - Reference to a hash that holds the most recent
+#                          responses.
+# @param $value          - radiobutton value.
+# 
+# @return text
+# @retval The generated html.
+#
+sub html_radiobutton {
+    my ($part, $fieldname, $name, $last_responses, $value) = @_;
 
-    my $part=$Apache::inputtags::part;
-    my $solved=$Apache::lonhomework::history{"resource.$part.solved"};
-    if ( ($target ne 'tex') &&
-	 &Apache::response::show_answer() ) {
-	if ($direction eq 'horizontal') {
-	    if ($target ne 'tex') {
-		$result.='<table><tr>';
-	    }
+    my $result='<label>';
+    
+    $result .= '<input type="radio"
+                onchange="javascript:setSubmittedPart(' . "'$part');\""
+		. 'name="HWVAL_' . $fieldname . '"'
+		. "value='$value'";
+
+    if (defined($last_responses->{$name})) {
+	$result .= '  checked="checked" ';
+    }
+    $result .= ' />';
+    $result .= $Apache::response::foilgroup{$name . '.text'};
+    $result .= '</label>';
+
+    return $result;
+
+}
+##
+# Return a reference to the last response hash. This hash has exactly
+# one or zero entries.  The one entry is keyed by the foil 'name' of
+# the prior response
+#
+# @param $part - Number of the problem part.
+# 
+# @return reference to a hash.
+# @retval see above.
+#
+sub get_last_response {
+    my ($part) = @_;
+
+    my $id = $Apache::inputtags::response['-1'];
+    my ( $lastresponse, $newvariation );
+    
+    if ((( $Apache::lonhomework::history{"resource.$part.type"} eq  'randomizetry')
+	 || ( $Apache::lonhomework::type eq 'randomizetry' )
+	)
+	&& ( $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
+	)
+    {
+	
+	if ( $env{ 'form.' . $part . '.rndseed' } ne
+	     $Apache::lonhomework::history{"resource.$part.rndseed"} )
+	{
+	    $newvariation = 1;
 	}
-	foreach my $name (@{ $whichfoils }) {
-	    if ($direction eq 'horizontal') {
-		if ($target ne 'tex') { $result.='<td>'; }
-	    }
-	    if ($target ne 'tex') {
-		$result.="<br />";
-	    } else {
-		$result.='\item \vskip -2 mm  ';
-	    }
-	    if ($Apache::response::foilgroup{$name.'.value'} eq 'true') { 
-		if ($target ne 'tex') {
-                    $result.=&mt('Correct:').'<b>';
-                } else {
-                    $result.=&mt('Correct:').' \textbf{';
-                }
+    }
+    unless ($newvariation) {
+	$lastresponse =
+	    $Apache::lonhomework::history{"resource.$part.$id.submission"};
+    }
+    my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
+
+    return \%lastresponse;
+}
+
+##
+# Display foils in html rendition.:
+#
+# @param $whichfoils - Set of foils to display.
+# @param $target     - Rendition target...there are several html targets.
+# @param $direction  - 'horizontal' if layout is horizontal.
+# @param $part       - Part of the problem that's being displayed.
+# @param $show_answer- True if answers should be shown.
+#
+# @return string
+# @retval generated html.
+#
+sub display_foils_html {
+    my ($whichfoils, $target, $direction, $part, $show_answer) = @_;
+    my $result;
+
+
+    # if the answers get shown, we need to label each item as correct or
+    # incorrect.
+
+    my ($opening_html, $finalclose, $item_pretext, $item_posttext) = 
+	&html_direction_fragments($direction);
+
+    $result .= $opening_html;
+
+
+    if ($show_answer) {
+
+	foreach my $name (@{$whichfoils}) {
+
+	    # If the item gets further surrounded by tags, this 
+	    # holds the closures for those tages.
+
+	    my $item_closetag = '';
+
+	    $result .= $item_pretext;
+
+	    # Label each foil as correct or incorrect:
+
+	    if ($Apache::response::foilgroup{$name . '.value'} eq 'true') {
+		$result .= &mt('Correct:') . '<b>';
+		$item_closetag .= '</b>';
+		
 	    } else {
-		$result.=&mt('Incorrect:');
+		$result .= &mt('Incorrect');
 	    }
-	    if ($target eq 'web') { $result.="<label>"; }
-	    $result.=$Apache::response::foilgroup{$name.'.text'};
-	    if ($target eq 'web') { $result.="</label>"; }
-	    if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
-		if ($target ne 'tex') { $result.='</b>';} else {$result.='}';}
-	    }
-	    if ($direction eq 'horizontal') {
-		if ($target ne 'tex') { $result.='</td>'; }
+
+	    # Web rendition encloses the 
+	    # item text in a label tag as well:
+
+	    if ($target eq 'web') {
+		$result .= '<label>';
+		$item_closetag = '</label>' . $item_closetag;
 	    }
+	    $result .= $Apache::response::foilgroup{$name . '.text'};
+	    $result .= $item_closetag;
+	    $result .= $item_posttext;
+	    $result .= "\n";	# make the html a bit more readable.
 	}
-	if ($direction eq 'horizontal') {
-	    if ($target ne 'tex') {
-		$result.='</tr></table>';
-	    }
+
+
+    } else {
+	my $lastresponse = &get_last_response($part);
+	
+	my $item_no = 0;
+	foreach my $name (@{$whichfoils}) {
+	    $result .= $item_pretext;
+	    $result .= &html_radiobutton(
+		$part, $Apache::inputtags::response[-1],
+		$name, $lastresponse, $item_no
+		);
+	    $result .= $item_posttext;
+	    $item_no++;
 	}
+	
+    }
+    $result .= $finalclose;
+
+    return $result;
+}
+##
+#  Display foils in exam mode for latex
+#
+# @param $whichfoils       - Reference to an array that contains the foil names to display
+# @param $bubbles_per_line - Number of bubbles on a line.
+# @param $direction        - Rendering direction 'horizontal' is what we're looking for.
+# @param $venv             - Name of LaTeX environment to use for vertical rendering.
+#
+# @return string
+# @return the latex rendering of the exam problem.
+#
+#
+sub display_latex_exam {
+    my ($whichfoils, $bubbles_per_line, $direction, $venv) = @_;
+    my $result;
+    my $numlines;
+    my $bubble_number = 0;
+    my $line          = 0;
+    my $i             = 0;
+
+    
+    if ($direction eq  'horizontal') {
+
+	# Marshall the display text for each foil and turn things over to
+	# Apache::response::make_horizontal_bubbles:
+
+	my @foil_texts = &get_foil_texts($whichfoils);
+	$result .= &Apache::caparesponse::make_horizontal_latex_bubbles(
+	    $whichfoils, \@foil_texts, '$\bigcirc$');
+
     } else {
-	my @alphabet = ('A'..'Z');
-	my $i = 0;
-	my $bubble_number = 0;
-	my $line = 0;
-	my $temp=0;  
-	my $id=$Apache::inputtags::response['-1'];
-	my $part=$Apache::inputtags::part;
-        my ($lastresponse,$newvariation);
-        if ((($Apache::lonhomework::history{"resource.$part.type"} eq 'randomizetry') ||
-             ($Apache::lonhomework::type eq 'randomizetry')) && 
-        ($Apache::inputtags::status[-1] eq 'CAN_ANSWER')) {
-            if ($env{'form.'.$part.'.rndseed'} ne
-                $Apache::lonhomework::history{"resource.$part.rndseed"}) {
-                $newvariation = 1;
-            }
-        }
-        unless ($newvariation) {
-	    $lastresponse=$Apache::lonhomework::history{"resource.$part.$id.submission"};
-        }
-	my %lastresponse=&Apache::lonnet::str2hash($lastresponse);
-	if ($target ne 'tex' && $direction eq 'horizontal') {
-	    $result.="<table><tr>";
-	}
-        my $numlines;
-        if (($target eq 'tex') && ($Apache::lonhomework::type eq 'exam')) {
-            my $numitems = scalar(@{ $whichfoils });
-            $numlines = int($numitems/$bubbles_per_line);
-            if (($numitems % $bubbles_per_line) != 0) {
-                $numlines ++;
-            }
-            if ($numlines < 1) {
-                $numlines = 1;
-            }
-            if ($numlines > 1) {
-                my $linetext;
-                for (my $i=0; $i<$numlines; $i++) {
-                    $linetext .= $Apache::lonxml::counter+$i.', ';
-                }
-                $linetext =~ s/,\s$//;
-                $result .= '\item[\small {\textbf{'.$linetext.'}}]'.
-                           ' {\footnotesize '.
-                           &mt('(Bubble once in [_1] lines)',$numlines).
-                           '} \hspace*{\fill} \\\\';
-            } else {
-                $result .= '\item[\textbf{'.$Apache::lonxml::counter.'}.]';
-            }
-        }
-	foreach my $name (@{ $whichfoils }) {
-	    if ($target ne 'tex') {
-		if ($direction eq 'horizontal') {
-		    $result.="<td>"; 
-		} else { 
-		    $result.="<br />";
-		} 
-	    }
-	    if ($target ne 'tex') { 
-                $result.= '<label>';
-		$result.=
-		    "<input type=\"radio\"
-                            onchange=\"javascript:setSubmittedPart('$part');\"
-                            name=\"HWVAL_$Apache::inputtags::response['-1']\"
-                            value=\"$temp\"";
-		if (defined($lastresponse{$name})) { $result .= ' checked="checked"'; }
-		$result .= ' />'.$Apache::response::foilgroup{$name.'.text'}."</label>";
+	
+	$result .= '\vskip 2mm \noindent';
+
+	# This section puts out the prefix that tells the user
+	# (if necessary) to only choose one bubble in the next n lines
+	# for problems with more than one line worth of bubbles in the grid sheet:
+	
+	my $numitems = scalar( @{$whichfoils} );
+	$numlines = int( $numitems / $bubbles_per_line );
+	if ( ( $numitems % $bubbles_per_line ) != 0 ) {
+	    $numlines++;
+	}
+	if ( $numlines < 1 ) {
+	    $numlines = 1;
+	}
+	if ( $numlines > 1 ) {
+	    my $linetext;
+	    for ( my $i = 0 ; $i < $numlines ; $i++ ) {
+		$linetext .= $Apache::lonxml::counter + $i . ', ';
+	    }
+	    $linetext =~ s/,\s$//;
+	    $result .=
+		'\small {\textbf{'
+		. $linetext . '}} '
+		. ' {\footnotesize '
+		. &mt( '(Bubble once in [_1] lines)', $numlines )
+		. '} \hspace*{\fill} \\\\';
+	}
+	else {
+	    $result .= '\textbf{' . $Apache::lonxml::counter . '}.';
+	}
+	
+	# Now output the bubbles themselves:
+	
+	foreach my $name (@{$whichfoils}) {
+	    if ( $bubble_number >= $bubbles_per_line ) {
+		$line++;
+		$i             = 0;
+		$bubble_number = 0;
+	    }
+	    my $identifier;
+	    if ( $numlines > 1 ) {
+		$identifier = $Apache::lonxml::counter + $line;
+	    }
+	    my $preindent;
+	    if ($bubble_number > 0) {
+		$preindent = '\hspace*{3 mm}';
+	    }
+	    my $foiltext = $Apache::response::foilgroup{$name . '.text'};
+	    $foiltext =~ s/\\noindent//; # forgive me for I have sinned..
+	    $result .= '{\small \textbf{'
+		. $identifier  .$preindent
+		. $alphabet[$i]
+		. '}}$\bigcirc$'
+		. $foiltext
+	    . '\\\\';    #' stupid emacs -- it thinks it needs that apostrophe to close the quote
+	    
+	    $i++;
+	    $bubble_number++;
+	}
+
+    }	
+
+    return $result;
+    
+}
+
+##
+#  Display latex when exam mode is not on.
+#
+#  @param $whichfoils - The foils to display
+#  @param $direction  - Display direction ('horizontal' is what matters to us).
+#  @param $venv       - Vertical env. to use for vertical rendering.
+#  @param  $vend      - End the vertical environment being used.
+#
+#  @return string
+#  @retval - The LaTeX rendering of the resource.'
+#
+sub display_latex {
+    my ($whichfoils, $direction, $venv) = @_;
+    my $result;
+
+    # how we render depends on the direction.
+    # Vertical is some kind of list environment determined by vbegin/vend.
+    # Horizontal is a table that is generated by 
+    # Apache::caparesponse::make_horizontal_latex_bubbles with an empty string
+    # for the actual bubble text.
+
+    if ($direction eq 'horizontal') {
+	my @foil_texts = &get_foil_texts($whichfoils);
+	$result .= &Apache::caparesponse::make_horizontal_latex_bubbles(
+	    $whichfoils, \@foil_texts, '');
+    } else {
+	$result .= "\\begin{$venv}";
+	foreach my $name (@{$whichfoils}) {
+	    $result .=  '\vspace*{-2 mm}\item '
+		. $Apache::response::foilgroup{ $name . '.text' };
+	}
+	
+	$result .= "\\end{$venv}";
+    }
+    return $result;
+}
+
+
+##
+#  Render foils for a PDF form. This is a variant of tex rednering that provides
+#  sufficient markup that the final PDF is a form that can be filled in online,
+#  or offline.
+#
+# @param $whichfoils - References an array of foils to display in the order in which
+#                     they should be displayed.
+# @param $direction  - Rendering direction.  'horiztonal' means inputs are laid out
+#                      horizontally otherwise they are stacked vertically.
+# @param $venv       - Vertical environment in which to wrap the foils.
+#
+# @return string
+# @retval String containing the rendering of the resource.
+#
+# TODO: Take into account direction!!!
+#
+sub display_pdf_form {
+    my ($whichfoils, $direction, $venv) = @_;
+    my $temp = 0;
+    my $result;
+
+    $result .= "\\begin{$venv}";
+    foreach my $name ( @{$whichfoils} ) {
+	
+	my $fieldname =
+	    $env{'request.symb'} 
+	. '&part_'
+	    . $Apache::inputtags::part
+	    . '&radiobuttonresponse'
+	    . '&HWVAL_'
+	    . $Apache::inputtags::response['-1'];
+	$result .= '\item[{'
+	    . &Apache::lonxml::print_pdf_radiobutton( $fieldname,
+						      $temp )
+	    . '}]'
+	    . $Apache::response::foilgroup{ $name . '.text' }
+	. "\n";
+	
+	$temp++;
+    }
+    $result .= "\\end{$venv}";
+
+    return $result;
+}
+
+
+##
+# Display selected foils:  This is really just a dispatchter to appropriate renderers
+#  
+# @param $target   - Target (e.g. 'tex'...).
+# @param $answer   - True if answers should be shown.
+# @param $whichfoils - Array of foil selectors that indicate which foils shouild be
+#                      rendered, in rendering order.
+# @param $direction- Rendering direction ('horizontal' is the one we look for,
+#                    otherwise foils are rendered one per line vertically.
+# @param $bubbles_per_line - number of exam bubbles per line.
+#
+# @return string
+# @retval The rendered problem.
+
+sub displayfoils {
+    my ($target,$answer,$whichfoils,$direction, $bubbles_per_line)=@_;
+    my $result;
+
+
+    my $part   = $Apache::inputtags::part;
+    my $solved = $Apache::lonhomework::history{"resource.$part.solved"};
+
+    # Show answers html.
+
+    if ( ( $target ne 'tex' )
+        && &Apache::response::show_answer() )
+    {
+
+	$result = &display_foils_html(
+	    $whichfoils, $target, $direction, $part,  1);
+	
+	# other html
+    }  elsif ($target ne 'tex') {
+	    $result = &display_foils_html($whichfoils, $target, $direction, $part,
+					  0, 0);
+
+       # LaTeX rendering:
+    } else {
+
+
+        my $id            = $Apache::inputtags::response['-1'];
+        my $part          = $Apache::inputtags::part;
+	my $numlines;
+	
+	# Decide how to bracket the list of foils:
+
+	my $vertical_env = &latex_vertical_environment();
+
+	# Rendering for latex exams.
+	
+	if ( ( $Apache::lonhomework::type eq 'exam' ) )
+	{
+	    $result .= &display_latex_exam(
+		$whichfoils, $bubbles_per_line, $direction, $vertical_env);
+
+	    $result .= '\vskip 0mm ';
+	    
+	} else {	    
+
+	    # Different rendering for PDF form than for a
+	    # 'regular' answer direction is honored in both of those
+	    #
+
+	    if ( ($env{'form.pdfFormFields'} eq 'yes')
+		    && ($Apache::inputtags::status[-1] eq 'CAN_ANSWER'))
+	    {
+		$result .= &display_pdf_form($whichfoils, $direction, $vertical_env);
 	    } else {
-		if ($Apache::lonhomework::type eq 'exam') {
-		    if($bubble_number >= $bubbles_per_line) {
-			$line++;
-			$i = 0;
-			$bubble_number = 0;
-		    }
-                    my $identifier;
-                    if ($numlines > 1) {
-                        $identifier = $Apache::lonxml::counter+$line;
-                    }
-                    $result .= '{\small \textbf{'.$identifier.$alphabet[$i].'}}$\bigcirc$'.$Apache::response::foilgroup{$name.'.text'}.'\\\\';  #' stupid emacs
-		    $i++;
-		    $bubble_number++;
-		} else {
-                    if($env{'form.pdfFormFields'} eq 'yes' && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
-                        my $fieldname = $env{'request.symb'}.'&part_'. $Apache::inputtags::part
-                                        .'&radiobuttonresponse'.'&HWVAL_'.$Apache::inputtags::response['-1'];
-                        $result .= '\item[{'.&Apache::lonxml::print_pdf_radiobutton($fieldname,$temp).'}]'
-                                   .$Apache::response::foilgroup{$name.'.text'}."\n";
-                    } else { 
-                        $result .= '\vspace*{-2 mm}\item '.$Apache::response::foilgroup{$name.'.text'};
-                    }
-                }
-	    }
-	    if ($target ne 'tex' && $direction eq 'horizontal') {
-		$result.="</td>"; 
+		$result .= &display_latex($whichfoils,  $direction, $vertical_env );
 	    }
-	    $temp++;
-	}
-	if ($target ne 'tex' && $direction eq 'horizontal') {
-	    $result.="</tr></table>";
+	    $result .= '\vskip 0 mm '; 
+       
 	}
     }
-    if ($target ne 'tex') { if ($direction ne 'horizontal') { $result.="<br />";} } else { $result.='\vskip 0 mm '; }
     return $result;
 }
 


More information about the LON-CAPA-cvs mailing list