Annotation of loncom/homework/structuretags.pm, revision 1.531

1.34      albertel    1: # The LearningOnline Network with CAPA 
                      2: # definition of tags that give a structure to a document
1.74      albertel    3: #
1.531   ! raeburn     4: # $Id: structuretags.pm,v 1.530 2015/02/23 10:40:01 droeschl Exp $
1.74      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.254     www        28: ###
1.54      www        29: 
1.435     jms        30: =pod
                     31: 
                     32: =head1 NAME
                     33: 
                     34: Apache::structuretags
                     35: 
                     36: =head1 SYNOPSIS
                     37: 
                     38: 
                     39: This is part of the LearningOnline Network with CAPA project
                     40: described at http://www.lon-capa.org.
                     41: 
                     42: 
                     43: =head1 NOTABLE SUBROUTINES
                     44: 
                     45: =over
                     46: 
                     47: =item 
                     48: 
                     49: =back
                     50: 
                     51: =cut
                     52: 
1.133     sakharuk   53: 
1.1       albertel   54: package Apache::structuretags; 
                     55: 
                     56: use strict;
                     57: use Apache::lonnet;
1.101     sakharuk   58: use Apache::File();
1.147     www        59: use Apache::lonmenu;
1.210     albertel   60: use Apache::lonlocal;
1.231     sakharuk   61: use Apache::lonxml;
1.434     foxr       62: use Apache::londefdef;
1.338     albertel   63: use Apache::lonenc();
1.500     foxr       64: use Apache::loncommon();
1.267     albertel   65: use Time::HiRes qw( gettimeofday tv_interval );
1.356     www        66: use lib '/home/httpd/lib/perl/';
                     67: use LONCAPA;
                     68:  
1.78      harris41   69: BEGIN {
1.469     www        70:     &Apache::lonxml::register('Apache::structuretags',('block','languageblock','translated','instructorcomment','while','randomlist','problem','library','web','tex','part','preduedate','postanswerdate','solved','notsolved','problemtype','startpartmarker','startouttext','endpartmarker','endouttext','simpleeditbutton','definetag'));
1.10      albertel   71: }
                     72: 
1.500     foxr       73: 
                     74: #---------------------------------------------------------------------------------
                     75: # 
                     76: #  This section of code deals with hyphenation management.
                     77: #  We must do three things:
                     78: #  - keep track fo the desired languages to alter the header.
                     79: #  - provide hyphenation selection as needed by each language that appears in the
                     80: #    text.
                     81: #  - Provide the header text needed to make available the desired hyphenations.
                     82: #
                     83: #
                     84: 
                     85: # Hash whose keys are the languages encountered in the document/resource.
                     86: #
                     87: 
                     88: my %languages_required;
                     89: ##
                     90: #   Given a language selection as input returns a chunk of LaTeX that
                     91: #   selects the required hyphenator.
                     92: #
                     93: #  @param language - the language being selected.
                     94: #  @return string
                     95: #  @retval The LaTeX needed to select the hyphenation appropriate to the language. 
                     96: #   
                     97: sub select_hyphenation {
                     98:     my $language  = shift;
                     99: 
                    100:     $language = &Apache::loncommon::latexlanguage($language); # Translate -> latex language.
                    101: 
                    102:     # If there is no latex language there's not much we can do:
                    103: 
                    104:     if ($language) {
                    105: 	&require_language($language);
                    106: 	my $babel_hyphenation = "\\selectlanguage{$language}";
                    107: 	
                    108: 	return $babel_hyphenation;
                    109:     } else {
                    110: 	return '';
                    111:     }
                    112: }
                    113: ##
                    114: # Selects hyphenation based on the current problem metadata.
                    115: # This requires that
                    116: # - There is a language metadata item set for the problem.
                    117: # - The language has a latex/babel hyphenation.
                    118: #
                    119: # @note: Uses &Apache::lonxml::request to locate the Uri associated with
                    120: #        this problem.
                    121: # @return string (possibly empty).
                    122: # @retval If not empty an appropriate \selectlanguage{} directive.
                    123: #
                    124: sub select_metadata_hyphenation {
                    125:     my $uri      = $Apache::lonxml::request->uri;
                    126:     my $language = &Apache::lonnet::metadata($uri, 'language'); 
                    127:     my $latex_language = &Apache::loncommon::latexhyphenation($language);
                    128:     if ($latex_language) {
                    129: 	return '\selectlanguage{'.$latex_language."}\n";
                    130:     }
                    131:     return '';			# no latex hyphenation or no lang metadata.
                    132: }
                    133: 
                    134: 
                    135: ##
                    136: #  Clears the set of languages required by the document being rendered.
                    137: #
                    138: sub clear_required_languages {
                    139:     %languages_required = ();
                    140: }
                    141: ##
                    142: # Allows an external client of this module to register a need for a language:
                    143: #
                    144: # @param LaTeX language required:
                    145: #
                    146: sub require_language {
                    147:     my $language = shift;
                    148:     $languages_required{$language} = 1;
                    149: }
                    150: 
                    151: ##
                    152: # Provides the header for babel that indicates the languages
                    153: # the document requires.
                    154: # @return string
                    155: # @retval \usepackage[lang1,lang2...]{babel}
                    156: # @retval ''   if there are no languages_required.
                    157: sub languages_header {
                    158:     my $header    ='';
                    159:     my @languages = (keys(%languages_required));
                    160: 
                    161:     # Only generate the header if there are languages:
                    162: 
                    163:     if (scalar @languages) {
                    164: 	my $language_list = join(',', (@languages));
                    165: 	$header  = '\usepackage['.$language_list."]{babel}\n";
                    166:     }
                    167:     return $header;
                    168: }
                    169: 
                    170: #----------------------------------------------------------------------------------
                    171: 
1.10      albertel  172: sub start_web {
1.326     albertel  173:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.383     albertel  174:     if ($target ne 'edit' && $target ne 'modified') {
                    175: 	my $bodytext=&Apache::lonxml::get_all_text("/web",$parser,$style);
                    176: 	if ($target eq 'web' || $target eq 'webgrade') {
                    177: 	    return $bodytext;
                    178: 	}
                    179:     } elsif ($target eq "edit" ) {
                    180: 	my $bodytext = 
                    181: 	    &Apache::lonxml::get_all_text_unbalanced("/web",$parser);
                    182: 	my $result = &Apache::edit::tag_start($target,$token);
                    183: 	$result .= &Apache::edit::editfield($token->[1],$bodytext,'',80,1);
                    184: 	return $result;
                    185:     } elsif ( $target eq "modified" ) {
                    186: 	return $token->[4].&Apache::edit::modifiedfield("/web",$parser);
1.159     albertel  187:     }
                    188:     return '';
1.10      albertel  189: }
                    190: 
                    191: sub end_web {
1.44      ng        192:     return '';
1.10      albertel  193: }
                    194: 
                    195: sub start_tex {
1.326     albertel  196:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.198     sakharuk  197:     my $result='';
1.383     albertel  198:     if ($target ne 'edit' && $target ne 'modified') {
                    199: 	my $bodytext=&Apache::lonxml::get_all_text("/tex",$parser,$style);
                    200: 	if ($target eq 'tex') {
1.434     foxr      201: 	    
                    202: 	    # If inside a table, occurrences of \\ must be removed;
                    203: 	    # else the table blows up.
                    204: 
                    205: 	    if (&Apache::londefdef::is_inside_of($tagstack, "table")) {
                    206: 		$bodytext =~ s/\\\\//g;
                    207: 	    }
1.432     foxr      208: 	    return $bodytext.'{}';
1.383     albertel  209: 	}
                    210:     } elsif ($target eq "edit" ) {
                    211: 	my $bodytext = 
                    212: 	    &Apache::lonxml::get_all_text_unbalanced("/tex",$parser);
                    213: 	my $result = &Apache::edit::tag_start($target,$token);
                    214: 	$result .= &Apache::edit::editfield($token->[1],$bodytext,'',80,1);
                    215: 	return $result;
                    216:     } elsif ( $target eq "modified" ) {
                    217: 	return $token->[4].&Apache::edit::modifiedfield("/tex",$parser);
1.159     albertel  218:     }
1.198     sakharuk  219:     return $result;;
1.10      albertel  220: }
                    221: 
                    222: sub end_tex {
1.44      ng        223:     return '';
1.9       albertel  224: }
                    225: 
1.400     albertel  226: sub homework_js {
1.531   ! raeburn   227:     my ($postsubmit,$timeout);
        !           228:     if (($env{'request.course.id'}) && ($env{'request.state'} ne 'construct')) {
        !           229:         my $crstype;
        !           230:         if (&Apache::loncommon::course_type() eq 'Community') {
        !           231:             $crstype = 'community';
        !           232:         } else {
        !           233:             if ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) {
        !           234:                 $crstype = 'official';
        !           235:             } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.textbook'}) {
        !           236:                 $crstype = 'textbook';
        !           237:             } else {
        !           238:                 $crstype = 'unofficial';
        !           239:             }
        !           240:         }
        !           241:         $postsubmit = $env{'course.'.$env{'request.course.id'}.'.internal.postsubmit'};
        !           242:         if ($postsubmit eq '') {
        !           243:             my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
        !           244:             $postsubmit = $domdefs{'postsubmit'};
        !           245:             unless ($postsubmit eq 'off') {
        !           246:                 $timeout = $domdefs{$crstype.'postsubtimeout'};
        !           247:             }
        !           248:         } elsif ($postsubmit eq '0') {
        !           249:             $postsubmit = 'off';
        !           250:         } elsif ($postsubmit eq '1') {
        !           251:             $postsubmit = 'on';
        !           252:             $timeout = $env{'course.'.$env{'request.course.id'}.'.internal.postsubtimeout'};
        !           253:             if ($timeout eq '') {
        !           254:                 my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
        !           255:                 $timeout = $domdefs{$crstype.'postsubtimeout'};
        !           256:             }
        !           257:         }
        !           258:         if ($timeout eq '') {
        !           259:             $timeout = 60;
        !           260:         }
        !           261:     } else {
        !           262:         my %domdefs = &Apache::lonnet::get_domain_defaults($env{'request.role.domain'});
        !           263:         $postsubmit = $domdefs{'postsubmit'};
        !           264:         unless ($postsubmit eq 'off') {
        !           265:             $timeout = 60;
        !           266:         }
        !           267:     }
        !           268:     my $jstimeout = 0;
        !           269:     if ($timeout) {
        !           270:         $jstimeout = 1000 * $timeout;
        !           271:     }
1.400     albertel  272:     return &Apache::loncommon::resize_textarea_js().
1.527     golterma  273:                 &Apache::loncommon::colorfuleditor_js().
1.416     raeburn   274:            &setmode_javascript().
1.531   ! raeburn   275: 	<<"JS";
1.400     albertel  276: <script type="text/javascript">
1.483     raeburn   277: // <![CDATA[
1.494     raeburn   278: function setSubmittedPart (part,prefix) {
                    279:     if (typeof(prefix) == 'undefined') {
                    280:         this.document.lonhomework.submitted.value="part_"+part;
                    281:     } else {
                    282:         for (var i=0;i<this.document.lonhomework.elements.length;i++) {
                    283:             if (this.document.lonhomework.elements[i].name == prefix+'submitted') {
                    284:                 this.document.lonhomework.elements[i].value="part_"+part;
                    285:             }
                    286:         }
                    287:     }
1.400     albertel  288: }
                    289: 
                    290: function image_response_click (which, e) {
                    291:     init_geometry();
                    292:     if (!e) { e = window.event; } //IE
                    293:     var input_element = document.lonhomework.elements[which];
1.401     albertel  294:     var token_element = document.lonhomework.elements[which+'_token'];
1.400     albertel  295:     var token = token_element.value;
1.401     albertel  296:     var img_element   = document.getElementById(which+'_imageresponse');
1.400     albertel  297:     var x= e.clientX-getX(img_element)+Geometry.getHorizontalScroll();
                    298:     var y= e.clientY-getY(img_element)+Geometry.getVerticalScroll();
                    299:     var click = x+':'+y;
                    300:     input_element.value = click;
1.485     raeburn   301:     img_element.src = '/adm/randomlabel.png?token='+token+'&clickdata='+click;
1.400     albertel  302: }
1.520     raeburn   303: 
                    304: var submithandled = 0;
1.521     raeburn   305: var keypresshandled = 0;
1.531   ! raeburn   306: var postsubmit = '$postsubmit';
1.520     raeburn   307: 
1.531   ! raeburn   308: \$(document).ready(function(){
        !           309:   if (postsubmit != 'off') {    
        !           310:     \$(document).keypress(function(event){
1.521     raeburn   311:         var keycode = (event.keyCode ? event.keyCode : event.which);
                    312:         if ((keycode == '13') && (keypresshandled == 0)) {
1.531   ! raeburn   313:             if ( \$( document.activeElement ).hasClass("LC_textline") ) {
1.521     raeburn   314:                 keypresshandled = 1;
1.531   ! raeburn   315:                 var idsArray = \$( document.activeElement ).attr("id").split(/HWVAL_/);
1.521     raeburn   316:                 if (idsArray.length) {
                    317:                     event.preventDefault();
                    318:                     var itemsArray = idsArray[1].split(/_/);
                    319:                     var buttonId = idsArray[0]+'submit_'+itemsArray[0];
1.531   ! raeburn   320:                     \$("#"+buttonId).trigger("click");
1.521     raeburn   321:                 }
                    322:             }
                    323:         }
                    324:     });
                    325: 
1.531   ! raeburn   326:     \$(document).delegate('form :submit', 'click', function( event ) {
        !           327:         if ( \$( this ).hasClass( "LC_hwk_submit" ) ) {
1.520     raeburn   328:             var buttonId = this.id;
1.531   ! raeburn   329:             var timeout = $jstimeout;
1.520     raeburn   330:             if (submithandled == 0) {
                    331:                 submithandled = 1;
1.531   ! raeburn   332:                 \$( "#msg_"+buttonId ).css({"display": "inline","background-color": "#87cefa",
1.521     raeburn   333:                                            "color": "black","padding": "2px"}) ;
1.531   ! raeburn   334:                 if (( \$(this.form).id == "LC_page" ) && (\$('input[name="all_submit"]').length )) {
1.522     raeburn   335:                     if (buttonId != "all_submit") {
1.531   ! raeburn   336:                         \$( ".LC_status_"+buttonId ).hide();
1.522     raeburn   337:                         if (( "#"+buttonId+"_pressed" ).length) {
1.531   ! raeburn   338:                             \$( "#"+buttonId+"_pressed" ).val( "1" );
1.522     raeburn   339:                         }
1.520     raeburn   340:                     }
1.522     raeburn   341:                 } else {
1.531   ! raeburn   342:                     \$( ".LC_status_"+buttonId ).hide();
1.520     raeburn   343:                 }
1.531   ! raeburn   344:                 \$(this.form).submit();
        !           345:                 \$( ".LC_hwk_submit" ).prop( "disabled", true);
        !           346:                 \$( ".LC_textline" ).prop( "readonly", "readonly");
1.520     raeburn   347:                 event.preventDefault();
1.531   ! raeburn   348: 
        !           349:                 if (timeout > 0) {
        !           350:                     setTimeout(function(){
        !           351:                                        \$( "#msg_"+buttonId ).css({"display": "none"});
        !           352:                                        if (( \$(this.form).id == "LC_page" ) && (\$('input[name="all_submit"]').length )) {
        !           353:                                            if (buttonId != "all_submit") {
        !           354:                                                if (( "#"+buttonId+"_pressed" ).length) {
        !           355:                                                    \$( "#"+buttonId+"_pressed" ).val( "" );
        !           356:                                                }
        !           357:                                            }
        !           358:                                        }
        !           359:                                        \$( ".LC_hwk_submit" ).prop( "disabled", false);
        !           360:                                        \$( ".LC_textline" ).prop( "readonly", false);
        !           361:                                        submithandled = 0;
        !           362:                                        keypresshandled = 0;
        !           363:                                      }, timeout);
        !           364:                 }
1.520     raeburn   365:                 return true;
                    366:             }
                    367:         }
                    368:     });
1.531   ! raeburn   369:   }
1.520     raeburn   370: });
                    371: 
1.483     raeburn   372: // ]]>
1.400     albertel  373: </script>
                    374: JS
                    375: }
                    376: 
1.416     raeburn   377: sub setmode_javascript {
                    378:     return <<"ENDSCRIPT";
                    379: <script type="text/javascript">
1.485     raeburn   380: // <![CDATA[
1.416     raeburn   381: function setmode(form,probmode) {
                    382:     form.problemmode.value = probmode;
                    383:     form.submit();
                    384: }
1.485     raeburn   385: // ]]>
1.416     raeburn   386: </script>
                    387: ENDSCRIPT
                    388: }
                    389: 
1.48      albertel  390: sub page_start {
1.345     albertel  391:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$name,
                    392: 	$extra_head)=@_;
1.159     albertel  393:     my %found;
1.207     albertel  394:     foreach my $taginside (@$tagstack) {
1.159     albertel  395: 	foreach my $taglookedfor ('html','body','form') {
                    396: 	    if ($taginside =~ /^$taglookedfor$/i) {$found{$taglookedfor} = 1;}
                    397: 	}
                    398:     }
                    399: 
1.343     albertel  400:     if ($target eq 'tex') {
                    401: 	return
                    402: 	    &Apache::londefdef::start_html($target,$token,$tagstack,
                    403: 					   $parstack,$parser,$safeeval);
                    404:     }
                    405: 
1.474     raeburn   406:     $extra_head .= &homework_js().
                    407:                    &Apache::lonhtmlcommon::dragmath_js("EditMathPopup");
                    408:     if (&Apache::lonhtmlcommon::htmlareabrowser()) {
                    409:         my %textarea_args = (
                    410:                                 dragmath => 'math',
                    411:                               );
                    412:         $extra_head .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args);
1.425     raeburn   413:     }
1.478     raeburn   414:     my $is_task = ($env{'request.uri'} =~ /\.task$/);
1.528     raeburn   415:     my ($needs_upload,$partlist);
1.495     raeburn   416:     my ($symb)= &Apache::lonnet::whichuser();
                    417:     my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
1.478     raeburn   418:     if ($is_task) {
1.495     raeburn   419:         $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js();
1.493     raeburn   420:     } else {
                    421:         if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.uploadedfiletypes") ne '') {
1.495     raeburn   422:             unless ($env{'request.state'} eq 'construct') {
                    423:                 my $navmap = Apache::lonnavmaps::navmap->new();
                    424:                 if (ref($navmap)) {
                    425:                     my $mapres = $navmap->getResourceByUrl($map);
1.496     raeburn   426:                     my $is_page;
                    427:                     if (ref($mapres)) {
                    428:                         $is_page = $mapres->is_page();
                    429:                     }
                    430:                     unless ($is_page) {
1.495     raeburn   431:                         $needs_upload = 1;
                    432:                     }
1.528     raeburn   433:                     if ((ref($tagstack) eq 'ARRAY') && ($tagstack->[-1] eq 'problem')) {
                    434:                         my $res = $navmap->getBySymb($symb);
                    435:                         if (ref($res)) {
                    436:                             $partlist = $res->parts();
                    437:                         }
                    438:                     }
1.495     raeburn   439:                 }
                    440:             }
1.493     raeburn   441:         } else {
                    442:             unless ($env{'request.state'} eq 'construct') {
                    443:                 my $navmap = Apache::lonnavmaps::navmap->new();
                    444:                 if (ref($navmap)) {
1.495     raeburn   445:                     my $mapres = $navmap->getResourceByUrl($map);
1.496     raeburn   446:                     my $is_page;
                    447:                     if (ref($mapres)) {
                    448:                         $is_page = $mapres->is_page();
                    449:                     }
1.528     raeburn   450:                     if ($is_page) {
                    451:                         if ((ref($tagstack) eq 'ARRAY') && ($tagstack->[-1] eq 'problem')) {
                    452:                             my $res = $navmap->getBySymb($symb);
                    453:                             if (ref($res)) {
                    454:                                 $partlist = $res->parts();
                    455:                             }
                    456:                         }
                    457:                     } else {
1.495     raeburn   458:                         my $res = $navmap->getBySymb($symb);
                    459:                         if (ref($res)) {
1.528     raeburn   460:                             $partlist = $res->parts();
1.495     raeburn   461:                             if (ref($partlist) eq 'ARRAY') {
                    462:                                 foreach my $part (@{$partlist}) {
                    463:                                     my @types = $res->responseType($part);
                    464:                                     my @ids = $res->responseIds($part);
                    465:                                     for (my $i=0; $i < scalar(@ids); $i++) {
                    466:                                         if ($types[$i] eq 'essay') {
                    467:                                             my $partid = $part.'_'.$ids[$i];
                    468:                                             if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {
                    469:                                                 $needs_upload = 1;
                    470:                                                 last;
                    471:                                             }
1.493     raeburn   472:                                         }
                    473:                                     }
                    474:                                 }
1.495     raeburn   475:                             } 
                    476:                         }
1.493     raeburn   477:                     }
                    478:                 }
                    479:             }
                    480:         }
1.495     raeburn   481:         if ($needs_upload) {
                    482:             $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js();
                    483:         }
1.478     raeburn   484:     }
1.425     raeburn   485: 
1.344     albertel  486:     my %body_args;
                    487:     if (defined($found{'html'})) {
                    488: 	$body_args{'skip_phases'}{'head'}=1;
                    489:     } else {
1.343     albertel  490: 	
1.345     albertel  491: 	$extra_head .= &Apache::lonhtmlcommon::spellheader();
1.343     albertel  492: 
1.379     albertel  493: 	$extra_head .= &Apache::londefdef::generate_css_links();
                    494: 
1.384     albertel  495: 	if ($env{'request.state'} eq 'construct') {
1.343     albertel  496: 	    $extra_head.=&Apache::edit::js_change_detection().
                    497: 		"<script type=\"text/javascript\">\n".
                    498: 		"if (typeof swmenu != 'undefined') {swmenu.currentURL=null;}\n".
                    499: 		&Apache::loncommon::browser_and_searcher_javascript().
                    500:                 "\n</script>\n";
1.525     raeburn   501:             if ($target eq 'edit') {
                    502:                 $extra_head .= &Apache::edit::js_update_linknum();
                    503:             }
1.343     albertel  504: 	}
1.159     albertel  505:     }
1.343     albertel  506: 
1.446     bisitz    507:     my $pageheader = '';
1.344     albertel  508:     if (defined($found{'body'})) {
                    509: 	$body_args{'skip_phases'}{'body'}=1;
                    510:     } elsif (!defined($found{'body'}) 
                    511: 	     && $env{'request.state'} eq 'construct') {
1.343     albertel  512: 	if ($target eq 'web' || $target eq 'edit') {
1.513     raeburn   513:         # Breadcrumbs for Authoring Space
1.450     bisitz    514:         &Apache::lonhtmlcommon::clear_breadcrumbs();
                    515:         &Apache::lonhtmlcommon::add_breadcrumb({
1.513     raeburn   516:             'text'  => 'Authoring Space',
1.497     raeburn   517:             'href'  => &Apache::loncommon::authorspace($env{'request.uri'}),
1.450     bisitz    518:         });
1.460     droeschl  519:         # breadcrumbs (and tools) will be created 
                    520:         # in start_page->bodytag->innerregister
                    521: 
1.450     bisitz    522: # FIXME Where are we?
                    523: #        &Apache::lonhtmlcommon::add_breadcrumb({
                    524: #            'text'  => 'Problem Editing', # 'Problem Testing'
                    525: #            'href'  => '',
                    526: #        });
1.460     droeschl  527:         $pageheader =&Apache::loncommon::head_subbox(
1.446     bisitz    528:                 &Apache::loncommon::CSTR_pageheader());
1.297     albertel  529: 	}
1.272     albertel  530:     } elsif (!defined($found{'body'})) {
1.343     albertel  531: 	my %add_entries;
1.159     albertel  532: 	my $background=&Apache::lonxml::get_param('background',$parstack,
                    533: 						  $safeeval);
1.343     albertel  534: 	if ($background ne '' ) {
                    535: 	    $add_entries{'background'} = $background;
                    536: 	}
1.344     albertel  537: 
1.290     albertel  538: 	my $bgcolor=&Apache::lonxml::get_param('bgcolor',$parstack,
                    539: 					       $safeeval);
1.446     bisitz    540:         if ($bgcolor eq '' ) { $bgcolor = '#FFFFFF'; }
1.344     albertel  541: 
1.446     bisitz    542:         $body_args{'bgcolor'}        = $bgcolor;
                    543:         # $body_args{'no_title'}       = 1;
                    544:         $body_args{'force_register'} = 1;
                    545:         $body_args{'add_entries'}    = \%add_entries;
1.466     droeschl  546:         if ( $env{'request.state'} eq   'construct') {
1.446     bisitz    547:             $body_args{'only_body'}  = 1;
1.518     raeburn   548:         } elsif ($target eq 'web') {
                    549:             $body_args{'print_suppress'} = 1;
1.446     bisitz    550:         }
1.344     albertel  551:     }
1.365     albertel  552:     $body_args{'no_auto_mt_title'} = 1;
1.344     albertel  553:     my $page_start = &Apache::loncommon::start_page($name,$extra_head,
                    554: 						    \%body_args);
1.446     bisitz    555:     $page_start .= $pageheader;
1.462     raeburn   556:     if (!defined($found{'body'}) 
                    557: 	&& $env{'request.state'} ne 'construct'
                    558: 	&& ($target eq 'web' || $target eq 'webgrade')) {
                    559: 
                    560: 	my ($symb,undef,undef,undef,$publicuser)= &Apache::lonnet::whichuser();
                    561:         if ($symb eq '' && !$publicuser) {
                    562:             $page_start .= '<p class="LC_info">'
                    563:                           .&mt('Browsing resource, all submissions are temporary.')
                    564:                           .'</p>';
1.457     bisitz    565:         }
1.344     albertel  566:     }
                    567: 
1.409     albertel  568:     if (!defined($found{'body'}) && $env{'request.state'} ne 'construct') {
1.343     albertel  569: 	$page_start .= &Apache::lonxml::message_location();
1.159     albertel  570:     }
                    571:     my $form_tag_start;
                    572:     if (!defined($found{'form'})) {
1.337     albertel  573: 	$form_tag_start='<form name="lonhomework" enctype="multipart/form-data" method="post" action="';
1.465     raeburn   574: 	my $uri = &Apache::loncommon::inhibit_menu_check(
1.455     droeschl  575:                 &Apache::lonenc::check_encrypt($env{'request.uri'}));
1.464     raeburn   576:         $uri = &HTML::Entities::encode($uri,'<>&"');
1.327     albertel  577: 	$form_tag_start.=$uri.'" ';
                    578: 	if ($target eq 'edit') {
                    579: 	    $form_tag_start.=&Apache::edit::form_change_detection();
                    580: 	}
1.493     raeburn   581:         my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();
                    582:         my ($path,$multiresp) = 
                    583:             &Apache::loncommon::get_turnedin_filepath($symb,$uname,$udom);
1.495     raeburn   584:         if (($is_task) || ($needs_upload)) {
                    585:             $form_tag_start .= ' onsubmit="return file_submission_check(this,'."'$path','$multiresp'".');"';
1.478     raeburn   586:         }
1.368     albertel  587: 	$form_tag_start.='>'."\n";
1.355     albertel  588: 
                    589: 	if ($symb =~ /\S/) {
                    590: 	    $symb=
                    591: 		&HTML::Entities::encode(&Apache::lonenc::check_encrypt($symb));
                    592: 	    $form_tag_start.=
1.368     albertel  593: 		"\t".'<input type="hidden" name="symb" value="'.$symb.'" />'."\n";
1.355     albertel  594: 	}
1.159     albertel  595:     }
1.528     raeburn   596:     return ($page_start,$form_tag_start,$partlist);
1.105     albertel  597: }
                    598: 
1.141     matthew   599: #use Time::HiRes();
1.105     albertel  600: sub get_resource_name {
1.159     albertel  601:     my ($parstack,$safeeval)=@_;
1.388     foxr      602:     my $name;
1.204     albertel  603:     if (defined($Apache::lonhomework::name)) {
1.388     foxr      604: 	$name = $Apache::lonhomework::name;
                    605:     } else {
                    606: 	my ($symb)=&Apache::lonnet::whichuser();
1.392     albertel  607: 	$name=&Apache::lonnet::gettitle($symb);
1.388     foxr      608: 	if ($name eq '') {
                    609: 	    $name=&Apache::lonnet::EXT('resource.title');
                    610: 	    if ($name eq 'con_lost') { $name = ''; }
                    611: 	}
                    612: 	if ($name!~/\S+/) {
                    613: 	    $name=$env{'request.uri'};
                    614: 	    $name=~s-.*/([^/]+)$-$1-;
                    615: 	}
                    616: 	# The name has had html tags escaped:
                    617:        
                    618: 	$name=~s/&lt;/</gs;
                    619: 	$name=~s/&gt;/>/gs;
                    620: 
                    621: 	$Apache::lonhomework::name=$name;
1.204     albertel  622:     }
1.159     albertel  623:     return $name;
1.105     albertel  624: }
                    625: 
                    626: sub setup_rndseed {
1.528     raeburn   627:     my ($safeeval,$target,$probpartlist)=@_;
1.367     albertel  628:     my ($symb)=&Apache::lonnet::whichuser();
1.479     raeburn   629:     my ($questiontype,$set_safespace,$rndseed);
                    630:     if ($target eq 'analyze') {
                    631:         $questiontype = $env{'form.grade_questiontype'};
                    632:     }
                    633:     unless (defined($questiontype)) {
                    634:         $questiontype = $Apache::lonhomework::type;
                    635:     }
1.333     albertel  636:     if ($env{'request.state'} eq "construct" 
                    637: 	|| $symb eq '' 
                    638: 	|| $Apache::lonhomework::type eq 'practice'
                    639: 	|| $Apache::lonhomework::history{'resource.CODE'}) {
1.316     www       640: 	&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.317     albertel  641: 						['rndseed']);
1.284     albertel  642: 	$rndseed=$env{'form.rndseed'};
1.159     albertel  643: 	if (!$rndseed) {
1.162     albertel  644: 	    $rndseed=$Apache::lonhomework::history{'rndseed'};
                    645: 	    if (!$rndseed) {
                    646: 		$rndseed=time;
                    647: 	    }
1.284     albertel  648: 	    $env{'form.rndseed'}=$rndseed;
1.162     albertel  649: 	}
1.479     raeburn   650:         if (($env{'request.state'} eq "construct") && 
                    651:             ($Apache::lonhomework::type eq 'randomizetry')) {
                    652:             my $tries = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.tries"};
                    653:             if ($tries) {
                    654:                 $rndseed += $tries;
                    655:             }
1.480     raeburn   656:             $env{'form.'.$Apache::inputtags::part.'.rndseed'}=$rndseed;
1.479     raeburn   657:         }
1.374     albertel  658: 	if ( ($env{'form.resetdata'} eq &mt('New Problem Variation')
                    659: 	      && $env{'form.submitted'} eq 'yes')  ||
1.284     albertel  660: 	    $env{'form.newrandomization'} eq &mt('New Randomization')) {
1.190     albertel  661: 	    srand(time);
                    662: 	    $rndseed=int(rand(2100000000));
1.284     albertel  663: 	    $env{'form.rndseed'}=$rndseed;
                    664: 	    delete($env{'form.resetdata'});
                    665: 	    delete($env{'form.newrandomization'});
1.159     albertel  666: 	}
1.488     www       667:         $rndseed=~s/\,/\:/g;
                    668:         $rndseed=~s/[^\w\d\:\-]//g;
1.489     www       669: 	if (defined($rndseed)) {
                    670:             my ($c1,$c2)=split(/\:/,$rndseed);
                    671:             unless ($c2) { $c2=0; }
                    672:             unless (($c1==int($c1)) && ($c2==int($c2))) {
                    673: 	       $rndseed=join(':',&Apache::lonnet::digest($rndseed));
                    674:             }
1.187     albertel  675:         }
1.247     albertel  676:         if ($Apache::lonhomework::history{'resource.CODE'}) {
                    677: 	   $rndseed=&Apache::lonnet::rndseed();
                    678: 	}
1.479     raeburn   679:         $set_safespace = 1;
                    680:     } elsif ($questiontype eq 'randomizetry') {
                    681:         if ($target eq 'analyze') {
                    682:             if (defined($env{'form.grade_rndseed'})) {
                    683:                 $rndseed = $env{'form.grade_rndseed'};
                    684:             }
                    685:         }
                    686:         unless (($target eq 'analyze') && (defined($rndseed))) {
                    687:             $rndseed=&Apache::lonnet::rndseed();
1.528     raeburn   688:             my $partfortries = $Apache::inputtags::part;
                    689:             if (ref($probpartlist) eq 'ARRAY') {
                    690:                 if ((@{$probpartlist} == 1) && ($probpartlist->[0] ne $Apache::inputtags::part)) {
                    691:                     $partfortries = $probpartlist->[0];
                    692:                 }
                    693:             }
                    694:             my $curr_try = $Apache::lonhomework::history{"resource.$partfortries.tries"};
1.479     raeburn   695:             if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
                    696:                 $curr_try ++;
                    697:             }
                    698:             if ($rndseed =~/^(\d+)[,:](\d+)$/) {
                    699:                 $rndseed = $1;
                    700:             }
                    701:             if ($curr_try) {
1.528     raeburn   702:                 my $reqtries = &Apache::lonnet::EXT("resource.$partfortries.randomizeontries");
1.479     raeburn   703:                 if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {
                    704:                     my $inc = int(($curr_try-1)/$reqtries);
                    705:                     $rndseed += $inc;
                    706:                 } else {
                    707:                     $rndseed += $curr_try;
                    708:                 }
                    709:             }
                    710:         }
                    711:         $set_safespace = 1;
1.528     raeburn   712:         if ($target eq 'grade') {
                    713:             $Apache::lonhomework::rawrndseed = $rndseed;
                    714:         }
1.479     raeburn   715:     }
                    716:     if ($set_safespace) {
                    717:         if ($safeeval) {
                    718:             &Apache::lonxml::debug("Setting rndseed to $rndseed");
                    719:             &Apache::run::run('$external::randomseed="'.$rndseed.'";',$safeeval);
                    720:         }
                    721:     }
                    722:     unless (($env{'request.state'} eq "construct") || ($symb eq '')) {
                    723:         $env{'form.'.$Apache::inputtags::part.'.rndseed'}=$rndseed;
1.159     albertel  724:     }
                    725:     return $rndseed;
1.105     albertel  726: }
                    727: 
1.268     albertel  728: sub remember_problem_state {
                    729:     return '
1.284     albertel  730:        <input type="hidden" name="problemstate" value="'.$env{'form.problemstate'}.'" />
                    731:        <input type="hidden" name="problemtype" value="'.$env{'form.problemtype'}.'" />
                    732:        <input type="hidden" name="problemstatus" value="'.$env{'form.problemstatus'}.'" />';
1.268     albertel  733: }
                    734: 
1.487     www       735: sub problem_edit_action_button {
                    736:     my ($name,$action,$accesskey,$text,$flag)=@_;
                    737:     my $actionscript="setmode(this.form,'$action')";
                    738:     return "\n<input type='button' name='$name' accesskey='$accesskey' value='".&mt($text)."'".
                    739:            ($flag?&Apache::edit::submit_ask_anyway($actionscript):&Apache::edit::submit_dont_ask($actionscript))." />";
                    740: }
                    741: 
1.423     www       742: sub problem_edit_buttons {
1.487     www       743:    my ($mode)=@_;
                    744: # Buttons that do not save
                    745:    my $result='<div class="LC_edit_problem_discards">'.
                    746:               &problem_edit_action_button('subdiscview','discard','d','Discard Edits and View',1);
                    747:    if ($mode eq 'editxml') {
                    748:        $result.=&problem_edit_action_button('subedit','edit','e','Edit',1);
                    749:        $result.=&problem_edit_action_button('subundo','undoxml','u','Undo',1);
                    750:        $result.=&Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1);
                    751:    } else {
                    752:        $result.=&problem_edit_action_button('subeditxml','editxml','x','EditXML',1);
                    753:        $result.=&problem_edit_action_button('subundo','undo','u','Undo',1);
                    754:    }
                    755:    $result.="\n</div>";
                    756: # Buttons that save
                    757:    $result.='<div class="LC_edit_problem_saves">';
                    758:    if ($mode eq 'editxml') {
                    759:        $result.=&problem_edit_action_button('subsaveedit','saveeditxml','s','Save and EditXML');
                    760:        $result.=&problem_edit_action_button('subsaveview','saveviewxml','v','Save and View');
                    761:    } else {
                    762:        $result.=&problem_edit_action_button('subsaveedit','saveedit','s','Save and Edit');
                    763:        $result.=&problem_edit_action_button('subsaveview','saveview','v','Save and View');
                    764:    }
                    765:    $result.="\n</div>\n";
                    766:    return $result;
1.423     www       767: }
                    768: 
1.527     golterma  769: sub insert_menu_datastructure {
                    770: 
                    771: 	my $template_menu = &template_dropdown_datastructure();
                    772: 	my $responseblock_menu = &responseblock_dropdown_datastructure();
                    773: 	my $conditional_scripting = &conditional_scripting_datastructure();
                    774: 	my $misc = &misc_datastructure();
                    775: 	
                    776: 	my @menu = ($template_menu, $responseblock_menu, $conditional_scripting, $misc);
                    777: 	return \@menu;
                    778: 
                    779: }
                    780: 
                    781: sub template_dropdown_datastructure {
                    782:     # gathering the all templates and their path, title, category and help topic
                    783:     my @templates = &Apache::lonhomework::get_template_list('problem');
                    784:     # template category => title
                    785:     my %tmplthash = ();
                    786:     # template title => path
                    787:     my %tmpltcontent = ();
                    788: 	
                    789:     foreach my $template (@templates){
                    790:         # put in hash if the template is not empty
                    791:         unless ($template->[1] eq ''){
                    792:             push(@{$tmplthash{$template->[2]}}, $template->[1]);
                    793:             push(@{$tmpltcontent{$template->[1]}},$template->[0]);
                    794:         }
                    795:     }
                    796: 
                    797: 	my $catList = [];
                    798:     foreach my $cat (sort keys %tmplthash) {
                    799: 		my $catItems = [];
                    800:         foreach my $title (sort @{$tmplthash{$cat}}) {
                    801:             my $path = $tmpltcontent{$title}->[0];
                    802:             my $code;
                    803:             open(FH, "<$path");
                    804:             while(<FH>){
                    805:                 $code.= $_ unless $_ =~ /(<problem>)|(<\/problem>)/;
                    806:             }
                    807:             close(FH);
                    808: 
                    809: 			if ($code ne '') {				
                    810: 				my $href = 'javascript:insertText(\'' . &convert_for_js(&HTML::Entities::encode($code)) . '\')';
                    811: 				my $currItem = [$href, $title, undef];
                    812: 				push @{$catItems}, $currItem;
                    813: 			}
                    814:         }
                    815: 		push @{$catList}, [$catItems, $cat, undef];
                    816:     }
                    817: 
                    818: 	my $templDropdown = [$catList, &mt("Complete Problem Templates"), undef];
                    819:     return $templDropdown;
                    820: }
                    821: 
                    822: sub responseblock_dropdown_datastructure {
                    823: 	
                    824: 	my $mathCat = [
                    825: 		[
                    826: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_formularesponse())) . "\')", &mt("Formula Response"), undef],
                    827: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_functionplotresponse())) . "\')", &mt("Function Plot Response"), undef],
                    828: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_mathresponse())) . "\')", &mt("Math Response"), undef],
                    829: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_numericalresponse())) . "\')", &mt("Numerical Response"), undef]
                    830: 		], 
                    831: 		&mt("Math"), 
                    832: 		undef
                    833: 	];
                    834: 
                    835: 	my $miscCat = [		
                    836: 		[
                    837:             ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_imageresponse())) . "\')", &mt("Click on Image"), undef],
                    838:             ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_customresponse())) . "\')", &mt("Custom Response"), undef],
                    839:             ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_externalresponse())) . "\')", &mt("External Response"), undef],
                    840:             ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_matchresponse())) . "\')", &mt("Match Response"), undef],
                    841:             ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_radiobuttonresponse())) . "\')", &mt("One out of N Statement"), undef],
                    842:             ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_optionresponse())) . "\')", &mt("Optionresponse"), undef], 
                    843: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_rankresponse())) . "\')", &mt("Rank Values"), undef]
                    844: 		],
                    845: 		&mt("Misc"),
                    846: 		undef
                    847: 	];
                    848: 
                    849: 	my $chemCat = [
                    850: 		[
                    851: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_reactionresponse())) . "\')", &mt("Chemical Reaction"), undef],
                    852: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicresponse())) . "\')", &mt("Organic Structure"), undef]
                    853: 		],
                    854: 		&mt("Chemical"),
                    855: 		undef
                    856: 	];
                    857: 
                    858: 	my $textCat = [
                    859: 		[
                    860: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_stringresponse())) . "\')", &mt("String Response"), undef],
                    861: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_essayresponse())) . "\')", &mt("Essay"), undef]
                    862: 		],
                    863: 		&mt("Text"),
                    864: 		undef
                    865: 	];
                    866: 
                    867: 	my $cats = [[$mathCat, $miscCat, $chemCat, $textCat], &mt("Response Types"), undef];
                    868: 	return $cats;
                    869: }
                    870: 
                    871: 
                    872: sub conditional_scripting_datastructure {
                    873: # TODO: corresponding routines should be used for the javascript:insertText parts
                    874: # instead of the placeholder routine default_xml_tag with the tags
                    875: # e.g. &default_xml_tag("postanswerdate") should be replaced with a routine which
                    876: # returns the corresponding content for this case
                    877: 
                    878: #TODO translated is currently temporarily here, another solution should be found where the
                    879: # needed string can be retrieved
                    880: 
                    881: 	my $translatedTag = '
                    882: <translated>
                    883:     <lang which="en"></lang>
                    884:     <lang which="default"></lang>
                    885: </translated>';
                    886: 
                    887: 	my $cat = [
                    888: 		[
                    889: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode($translatedTag)) . "\')", &mt("Translated Tag"), undef],
                    890: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("block"))) . "\')", &mt("Conditional Block"), undef],
                    891: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("postanswerdate"))) . "\')", &mt("After Answer Block"), undef],
                    892: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("preduedate"))) . "\')", &mt("Before Due Date Block"), undef],
                    893: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("solved"))) . "\')", &mt("Block For After Solved"), undef],
                    894: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("notsolved"))) . "\')", &mt("Block For When Not Solved"), undef]
                    895: 		],
                    896: 		&mt("Contitional Scripting"),
                    897: 		undef
                    898: 	];
                    899: 
                    900: 	return $cat;
                    901: }
                    902: 
                    903: sub misc_datastructure {
                    904: 	
                    905: 	my $graphicalCat = [
                    906: 		[
                    907: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_img())) . "\')", &mt("Image"), undef],
                    908: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::lonplot::insert_gnuplot())) . "\')", &mt("GNU Plot"), undef],
                    909: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicstructure())) . "\')", &mt("Organic Structure"), undef]
                    910: 		],
                    911: 		"Graphical",
                    912: 		undef
                    913: 	];
                    914: 
                    915: 	my $advancedCat = [
                    916: 		[
                    917: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_script())) . "\')", &mt("Script Block"), undef],
                    918: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("allow"))) . "\')", &mt("File Dependencies"), undef],
                    919: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("import"))) . "\')", &mt("Import a File"), undef],
                    920: 			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::londefdef::insert_meta())) . "\')", &mt("Custom Metadata"), undef]
                    921: 		],
                    922: 		"advanced",
                    923: 		undef
                    924: 	];
                    925: 	
                    926: 	my $cats = [[$graphicalCat, $advancedCat], &mt("misc"), undef];
                    927: 	return $cats;
                    928: }
                    929: 
                    930: # helper routine for the datastructure building subroutines
                    931: sub default_xml_tag {
                    932: 	my ($tag) = @_;
                    933: 	return "\n<$tag></$tag>";
                    934: }
                    935: 
                    936: 
                    937: sub helpmenu_datastructure {
                    938: 
                    939: 	my $width = 500;
                    940: 	my $height = 600;
                    941: 
                    942: 	my $helpers = [
                    943: 		['Problem_LON-CAPA_Functions', &mt('Script Functions')],
                    944: 		['Greek_Symbols', &mt('Greek Symbols')],
                    945:  		['Other_Symbols', &mt('Other Symbols')],
                    946: 		['Authoring_Output_Tags', &mt('Output Tags')],
                    947: 		['Authoring_Multilingual_Problems', 
                    948: 			&mt('How to create problems in different languages')]
                    949: 	];
                    950: 
                    951: 	my $help_structure = [];
                    952: 
                    953: 	foreach my $count (0..(scalar(@{$helpers})-1)) {
                    954: 		my $filename = $helpers->[$count]->[0];
                    955: 		my $title = $helpers->[$count]->[1];
                    956: 		my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename.hlp',$width,$height,'yes');");
                    957: 		push @{$help_structure}, [$href, $title, undef];
                    958: 	}
                    959: 
                    960: 	return $help_structure;
                    961: }
                    962: 
                    963: # we need substitution to not break javascript code
                    964: sub convert_for_js {
                    965:     my $return = shift;
                    966:         $return =~ s|script|ESCAPEDSCRIPT|g;
1.530     droeschl  967:         $return =~ s|\\|\\\\|g;
1.527     golterma  968:         $return =~ s|\n|\\r\\n|g;
                    969:         $return =~ s|'|\\'|g;
                    970: 		$return =~ s|&#39;|\\&#39;|g;
                    971:     return $return;
                    972: }
                    973: 
1.423     www       974: sub problem_edit_header {
1.527     golterma  975:     my ($mode)=@_;
                    976:     my $return = '<input type="hidden" name="submitted" value="edit" />'.
1.487     www       977: 	&remember_problem_state('edit').'
1.527     golterma  978:         <div class="LC_edit_problem_header">
                    979:         <div class="LC_edit_problem_header_title">
                    980:         '.&mt('Problem Editing').$mode.&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'
                    981:         </div><div class="LC_edit_actionbar" id="actionbar">'.
                    982:         '<input type="hidden" name="problemmode" value="saveedit" />'.
                    983:         &problem_edit_buttons();
                    984: 
                    985:     $return.='<hr style="clear:both;visibility:hidden;" />
                    986:     </div></div>'
                    987:     .&Apache::lonxml::message_location();
                    988:     $return .= '<link rel="stylesheet" href="/adm/codemirror/codemirror-combined.css" />
                    989:     <script type="text/javascript" src="/adm/codemirror/codemirror-compressed-colorful.js"></script>';
                    990: 
                    991:     $return .= '<script type="text/javascript" src="/adm/jQuery/addons/jquery-scrolltofixed.js"></script>
                    992:         <script type="text/javascript">
                    993:             // unless internet explorer
                    994:             if (!(window.navigator.appName == "Microsoft Internet Explorer" && (document.documentMode || document.compatMode))){
                    995:                 $(document).ready(
                    996:                     function() {
                    997:                         $(\'.LC_edit_actionbar\').scrollToFixed(
                    998:                             {
                    999:                                 fixed: function(){
                   1000:                                     $(this).find(\'.LC_edit_actionbar\').css(\'height\', \'31px\');
                   1001:                                 }
                   1002:                             }
                   1003:                         );
                   1004:                     }
                   1005:                 );
                   1006:             }
                   1007:         </script>
                   1008:         <table id="LC_edit_problem_colorful" border="0" width="100%"><tr><td bgcolor="#F8F8F8">';
                   1009:     return $return;
1.105     albertel 1010: }
                   1011: 
                   1012: sub problem_edit_footer {
1.527     golterma 1013:     my $resource = $env{'request.ambiguous'};
1.412     albertel 1014:     return '</td></tr></table><br />
                   1015: <div class="LC_edit_problem_footer">
1.453     bisitz   1016:   <hr />'.
1.423     www      1017: &problem_edit_buttons().'
1.459     bisitz   1018:   <hr style="clear:both;" />
1.527     golterma 1019:   <script type="text/javascript">
                   1020:       restoreState("'.$resource.'");
                   1021:       restoreScrollPosition("'.$resource.'");
                   1022:   </script>
1.412     albertel 1023: </div>
                   1024: '.
1.342     albertel 1025:     "\n</form>\n".&Apache::loncommon::end_page();
1.105     albertel 1026: }
                   1027: 
1.235     albertel 1028: sub option {
                   1029:     my ($value,$name) = @_;
                   1030:     my $result ="<option value='".$value."' ";
1.284     albertel 1031:     if ($env{'form.'.$name} eq $value) {
1.235     albertel 1032: 	$result.=" selected='on' ";
                   1033:     }
                   1034:     $result.='>';
                   1035:     return $result;
                   1036: }
                   1037: 
1.105     albertel 1038: sub problem_web_to_edit_header {
1.159     albertel 1039:     my ($rndseed)=@_;
1.406     albertel 1040:     my $result .= '<div class="LC_edit_problem_header">';
                   1041: 
                   1042:     if (!$Apache::lonhomework::parsing_a_task) {
                   1043: 	$result .= 
                   1044: 	    '<div class="LC_edit_problem_header_title">'.
                   1045: 	    &mt('Problem Testing').
                   1046: 	    &Apache::loncommon::help_open_topic('Problem_Editor_Testing_Area').
                   1047: 	    '</div>';
                   1048:     } else {
                   1049: 	$result .= 
                   1050: 	    '<div class="LC_edit_problem_header_title">'.
                   1051: 	    &mt('Task Testing').
                   1052: 	    '</div>';
                   1053:     }
                   1054:     
1.315     albertel 1055:     my $show_all_foils_text = 
                   1056: 	($Apache::lonhomework::parsing_a_task) ?
1.452     bisitz   1057: 	&mt('Show All Instances')
                   1058: 	: &mt('Show All Foils');
1.315     albertel 1059: 
1.452     bisitz   1060:     my $show_all= '<span class="LC_nobreak"><label for="showallfoils">'
                   1061:                  .'<input type="checkbox" name="showallfoils"';
1.440     bisitz   1062:     if (defined($env{'form.showallfoils'})) { $show_all.=' checked="checked"'; }
1.452     bisitz   1063:     $show_all.= ' /> '.$show_all_foils_text
                   1064:                .'</label></span>';
1.406     albertel 1065: 
                   1066: 
1.384     albertel 1067: 
1.406     albertel 1068:     $result .= '<div class="LC_edit_problem_header_status_row">';
1.313     albertel 1069:     if (!$Apache::lonhomework::parsing_a_task) {
                   1070: 	$result.="
1.406     albertel 1071: <div class='LC_edit_problem_header_row1'>
                   1072: <span class=\"LC_nobreak\">
1.405     albertel 1073: ".&mt("Problem Status:")."
1.235     albertel 1074: <select name='problemstate'>
1.270     albertel 1075:   <option value=''></option>
1.235     albertel 1076:   ".&option('CLOSED'               ,'problemstate').&mt("Closed")."</option>
                   1077:   ".&option('CAN_ANSWER'           ,'problemstate').&mt("Answerable")."</option>
                   1078:   ".&option('CANNOT_ANSWER_tries'  ,'problemstate').&mt("Open with full tries")."</option>
                   1079:   ".&option('CANNOT_ANSWER_correct','problemstate').&mt("Open and correct")."</option>
                   1080:   ".&option('SHOW_ANSWER'          ,'problemstate').&mt("Show Answer")."</option>
                   1081: </select>
1.406     albertel 1082: </span>
                   1083: <span class=\"LC_nobreak\">
1.405     albertel 1084: ".&mt("Problem Type:")."
1.235     albertel 1085: <select name='problemtype'>
1.270     albertel 1086:   <option value=''></option>
1.509     bisitz   1087:   ".&option('exam'   ,'problemtype').&mt("Bubblesheet Exam Problem")."</option>
1.428     raeburn  1088:   ".&option('problem','problemtype').&mt("Homework Problem")."</option>
1.242     albertel 1089:   ".&option('survey' ,'problemtype').&mt("Survey Question")."</option>
1.465     raeburn  1090:   ".&option('surveycred' ,'problemtype').&mt("Survey Question (with credit)")."</option>
                   1091:   ".&option('anonsurvey' ,'problemtype').&mt("Anonymous Survey Question")."</option>
                   1092:   ".&option('anonsurveycred' ,'problemtype').&mt("Anonymous Survey Question (with credit)")."</option>
1.428     raeburn  1093:   ".&option('practice' ,'problemtype').&mt("Practice Problem")."</option>
1.479     raeburn  1094:   ".&option('randomizetry' ,'problemtype').&mt("New Randomization Each Try")."</option>
1.235     albertel 1095: </select>
1.406     albertel 1096: </span>
                   1097: $show_all
                   1098: </div>
                   1099: <div class='LC_edit_problem_header_row2'>
                   1100: <span class=\"LC_nobreak\">
1.405     albertel 1101: ".&mt("Feedback Mode:")."
1.235     albertel 1102: <select name='problemstatus'>
                   1103:   <option value=''></option>
1.242     albertel 1104:   ".&option('yes','problemstatus').&mt("Show Feedback")."</option>
1.517     bisitz   1105:   ".&option('no', 'problemstatus').&mt("Don't Show Incorrect/Correct Feedback")."</option>
1.405     albertel 1106:   ".&option('no_feedback_ever', 'problemstatus').&mt("Don't Show Any Feedback")."</option>
1.235     albertel 1107: </select>
1.406     albertel 1108: </span>
                   1109: ";
                   1110: 
1.376     albertel 1111:     } elsif ($Apache::lonhomework::parsing_a_task) {
                   1112: 	$result.="
1.406     albertel 1113: <div class='LC_edit_problem_header_row1'>
                   1114: <span class=\"LC_nobreak\">
1.405     albertel 1115: ".&mt("Problem Status:")."
1.376     albertel 1116: <select name='problemstate'>
                   1117:   <option value=''></option>
                   1118:   ".&option('CLOSED'               ,'problemstate').&mt("Closed")."</option>
                   1119:   ".&option('CAN_ANSWER'           ,'problemstate').&mt("Answerable")."</option>
                   1120:   ".&option('WEB_GRADE'            ,'problemstate').&mt("Criteria Grading")."</option>
                   1121:   ".&option('SHOW_ANSWER'          ,'problemstate').&mt("Show Feedback")."</option>
                   1122: </select>
1.406     albertel 1123: </span>
                   1124: $show_all
                   1125: ";
                   1126:     }
                   1127:     $result.='
                   1128:        <span class="LC_nobreak">
                   1129:        '.&mt('Apply style file: ').'
                   1130:          <input type="text" name="style_file" value="'.&HTML::Entities::encode($env{'construct.style'},'"<>&').'" />
                   1131:          <a href="javascript:openbrowser(\'lonhomework\',\'style_file\',\'sty\')">'.&mt('Select').'</a>
                   1132:        </span>
1.422     www      1133:      </div>
                   1134:      <div class="LC_edit_problem_header_row1">'.
                   1135:        &Apache::lonxml::renderingoptions().'
1.406     albertel 1136:      </div>
                   1137:      <input type="submit" name="changeproblemmode" value="'.&mt("Change View").'" />
                   1138:      <input type="submit" name="clear_style_file" accesskey="d" value="'.&mt('Show Default View').'" />
                   1139:      <input type="submit" name="resetdata" accesskey="r" value="'.&mt('Reset Submissions').'" />
                   1140:    </div>
1.453     bisitz   1141:    <hr />
1.406     albertel 1142:    <div class="LC_edit_problem_header_randomize_row">
                   1143:      <input type="submit" name="newrandomization" accesskey="a" value="'.&mt('New Randomization').'" />
                   1144:      <input type="submit" name="changerandseed" value="'.&mt('Change Random Seed To:').'" />
1.488     www      1145:      <input type="text" name="rndseed" size="24" value="'.
1.406     albertel 1146: 	       $rndseed.'"
                   1147:              onchange="javascript:document.lonhomework.changerandseed.click()" />';
                   1148: 
                   1149:     if (!$Apache::lonhomework::parsing_a_task) {
                   1150: 	my $numtoanalyze=$env{'form.numtoanalyze'};
                   1151: 	if (!$numtoanalyze) { $numtoanalyze=20; }
1.408     albertel 1152: 	$result .= '<span class="LC_nobreak">'.
                   1153: 	    &mt('[_1] for [_2] versions.',
1.416     raeburn  1154: 		'<input type="button" name="submitmode" value="'.&mt('Calculate answers').'" '.
1.419     bisitz   1155:                 'onclick="javascript:setmode(this.form,'."'calcanswers'".')" />'
                   1156:                ,'<input type="text" name="numtoanalyze" value="'.
1.408     albertel 1157: 		$numtoanalyze.'" size="5" />').
                   1158: 		&Apache::loncommon::help_open_topic("Analyze_Problem",'',undef,undef,300).
                   1159: 		'</span>';
                   1160: 						    
1.313     albertel 1161:     }
1.406     albertel 1162: 
                   1163:     $result.='
                   1164:    </div>
1.453     bisitz   1165:    <hr />
1.447     bisitz   1166:    <div>';
1.416     raeburn  1167:     $result.='<input type="hidden" name="problemmode" value="view" />';
                   1168:     $result .= '<input type="button" name="submitmode" accesskey="e" value="'.&mt('Edit').'" '.
                   1169:                'onclick="javascript:setmode(this.form,'."'edit'".')" />';
                   1170:     $result .= '<input type="button" name="submitmode" accesskey="x" value="'.&mt('EditXML').'" '.
                   1171:                'onclick="javascript:setmode(this.form,'."'editxml'".')" />';
1.408     albertel 1172:     $result.='
                   1173:    </div>
1.453     bisitz   1174:    <hr />
1.409     albertel 1175:    '.&Apache::lonxml::message_location().'
1.406     albertel 1176: </div>';
1.159     albertel 1177:     return $result;
1.48      albertel 1178: }
                   1179: 
1.65      albertel 1180: sub initialize_storage {
1.357     albertel 1181:     my ($given_symb) = @_;
1.353     albertel 1182:     undef(%Apache::lonhomework::results);
                   1183:     undef(%Apache::lonhomework::history);
1.357     albertel 1184:     my ($symb,$courseid,$domain,$name) = 
1.367     albertel 1185: 	&Apache::lonnet::whichuser($given_symb);
1.353     albertel 1186:     
                   1187:     # anonymous users (CODEd exams) have no data
                   1188:     if ($name eq 'anonymous' 
                   1189: 	&& !defined($domain)) {
                   1190: 	return;
                   1191:     }
                   1192: 
1.333     albertel 1193:     if ($env{'request.state'} eq 'construct' 
                   1194: 	|| $symb eq ''
                   1195: 	|| $Apache::lonhomework::type eq 'practice') {
                   1196: 	
                   1197: 	my $namespace = $symb || $env{'request.uri'};
                   1198: 	if ($env{'form.resetdata'} eq &mt('Reset Submissions') ||
1.374     albertel 1199: 	    ($env{'form.resetdata'} eq &mt('New Problem Variation')
                   1200: 	     && $env{'form.submitted'} eq 'yes') ||
1.333     albertel 1201: 	    $env{'form.newrandomization'} eq &mt('New Randomization')) {
                   1202: 	    &Apache::lonnet::tmpreset($namespace,'',$domain,$name);
                   1203: 	    &Apache::lonxml::debug("Attempt reset");
                   1204: 	}
1.159     albertel 1205: 	%Apache::lonhomework::history=
1.333     albertel 1206: 	    &Apache::lonnet::tmprestore($namespace,'',$domain,$name);
1.526     raeburn  1207: 	my ($temp)=keys(%Apache::lonhomework::history) ;
1.159     albertel 1208: 	&Apache::lonxml::debug("Return message of $temp");
                   1209:     } else {
                   1210: 	%Apache::lonhomework::history=
                   1211: 	    &Apache::lonnet::restore($symb,$courseid,$domain,$name);
                   1212:     }
1.353     albertel 1213: 
1.159     albertel 1214:     #ignore error conditions
1.526     raeburn  1215:     my ($temp)=keys(%Apache::lonhomework::history);
1.159     albertel 1216:     if ($temp =~ m/^error:.*/) { %Apache::lonhomework::history=(); }
1.65      albertel 1217: }
                   1218: 
1.435     jms      1219: =pod
                   1220: 
                   1221: =item finalize_storage()
                   1222: 
1.524     raeburn  1223: 	Stores away the result hash to a student's environment;
1.523     raeburn  1224: 	checks form.grade_ for specific values, otherwise stores
                   1225: 	to the running user's environment.
1.524     raeburn  1226: 
                   1227:         &check_correctness_changes() is called in two circumstances
                   1228:         in which the results hash is to be stored permanently, for
                   1229:         grading triggered by a student's submission, where feedback on
                   1230:         correctness is to be provided to the student. 
                   1231: 
                   1232:         1. Immediately prior to storing the results hash
                   1233: 
                   1234:         To handle the case where a student's submission (and award) were 
                   1235:         stored after history was retrieved in &initialize_storage(), e.g.,
                   1236:         if a student submitted answers in quick succession (e.g., from 
                   1237:         multiple tabs).  &Apache::inputtags::hidealldata() is called for
                   1238:         any parts with out-of-order storage (i.e., correct then incorrect,
                   1239:         where awarded >= 1 when correct).
                   1240: 
                   1241:         2. Immediately after storing the results hash
                   1242: 
                   1243:         To handle the case where lond on the student's homeserver returns
                   1244:         delay:N -- where N is the number of transactions between the last
                   1245:         retrieved in &initialize_storage() and the last stored immediately
                   1246:         before permanent storage of the current transaction via 
                   1247:         lond::store_handler().  &Apache::grades::makehidden() is called  
                   1248:         for any parts with out-of-order storage (i.e., correct then incorrect,
                   1249:         where awarded >= 1 when correct).
                   1250: 
                   1251: 	Will call &store_aggregates() to increment totals for attempts, 
                   1252:         students, and corrects, if running user has student role.
                   1253: 
1.435     jms      1254: =cut
                   1255: 
                   1256: 
1.65      albertel 1257: sub finalize_storage {
1.357     albertel 1258:     my ($given_symb) = @_;
1.159     albertel 1259:     my $result;
1.289     albertel 1260:     if (%Apache::lonhomework::results) {
1.323     albertel 1261: 	my @remove = grep(/^INTERNAL_/,keys(%Apache::lonhomework::results));
                   1262: 	delete(@Apache::lonhomework::results{@remove});
1.357     albertel 1263: 	my ($symb,$courseid,$domain,$name) = 
1.367     albertel 1264: 	    &Apache::lonnet::whichuser($given_symb);
1.333     albertel 1265: 	if ($env{'request.state'} eq 'construct' 
                   1266: 	    || $symb eq ''
                   1267: 	    || $Apache::lonhomework::type eq 'practice') {
                   1268: 	    my $namespace = $symb || $env{'request.uri'};
1.284     albertel 1269: 	    $Apache::lonhomework::results{'rndseed'}=$env{'form.rndseed'};
1.159     albertel 1270: 	    $result=&Apache::lonnet::tmpstore(\%Apache::lonhomework::results,
1.333     albertel 1271: 					      $namespace,'',$domain,$name);
1.159     albertel 1272: 	    &Apache::lonxml::debug('Construct Store return message:'.$result);
                   1273: 	} else {
1.524     raeburn  1274:             my ($laststore,$checkedparts,@parts,%postcorrect);
                   1275:             if (($env{'user.name'} eq $name) && ($env{'user.domain'} eq $domain) &&
                   1276:                 (!$Apache::lonhomework::scantronmode) && (!defined($env{'form.grade_symb'})) &&
                   1277:                 (!defined($env{'form.grade_courseid'}))) {
                   1278:                 if ($Apache::lonhomework::history{'version'}) {
                   1279:                     $laststore = $Apache::lonhomework::history{'version'}.'='.
                   1280:                                  $Apache::lonhomework::history{'timestamp'};
                   1281:                 } else {
                   1282:                     $laststore = '0=0';
                   1283:                 }
                   1284:                 my %record = &Apache::lonnet::restore($symb,$courseid,$domain,$name);
                   1285:                 if ($record{'version'}) {
                   1286:                     my ($newversion,$oldversion,$oldtimestamp);
                   1287:                     if ($Apache::lonhomework::history{'version'}) {
                   1288:                         $oldversion = $Apache::lonhomework::history{'version'};
                   1289:                         $oldtimestamp = $Apache::lonhomework::history{'timestamp'};
                   1290:                     } else {
                   1291:                         $oldversion = 0;
                   1292:                         $oldtimestamp = 0;
                   1293:                     }
                   1294:                     if ($record{'version'} > $oldversion) {
                   1295:                         if ($record{'timestamp'} >= $oldtimestamp) {
                   1296:                             $laststore = $record{'version'}.'='.$record{'timestamp'};
                   1297:                             $newversion = $record{'version'} + 1;
                   1298:                             $checkedparts = 1;
                   1299:                             foreach my $key (keys(%Apache::lonhomework::results)) {
                   1300:                                 if ($key =~ /^resource\.([^\.]+)\.solved$/) {
                   1301:                                     my $part = $1;
                   1302:                                     if ($Apache::lonhomework::results{$key} eq 'incorrect_attempted') {
                   1303:                                         push(@parts,$part);
                   1304:                                     }
                   1305:                                 }
                   1306:                             }
                   1307:                             if (@parts) {
                   1308:                                 my @parts_to_hide = &check_correctness_changes($symb,$courseid,$domain,$name,
                   1309:                                                                                \%record,\@parts,$newversion,
                   1310:                                                                                $oldversion);
                   1311:                                 if (@parts_to_hide) {
                   1312:                                     foreach my $part (@parts_to_hide) {
                   1313:                                         $postcorrect{$part} = 1;
                   1314:                                         &Apache::inputtags::hidealldata($part);
                   1315:                                     }
                   1316:                                 }
                   1317:                             }
                   1318:                         }
                   1319:                     }
                   1320:                 }
                   1321:             }
1.159     albertel 1322: 	    $result=&Apache::lonnet::cstore(\%Apache::lonhomework::results,
1.524     raeburn  1323: 					    $symb,$courseid,$domain,$name,$laststore);
                   1324:             if ($result =~ /^delay\:(\d+)$/) {
                   1325:                 my $numtrans = $1;
                   1326:                 my ($oldversion) = split(/=/,$laststore);
                   1327:                 if ($numtrans) {
                   1328:                     my $newversion = $oldversion + 1 + $numtrans;
                   1329:                     my @possparts;
                   1330:                     if ($checkedparts) {
                   1331:                         foreach my $part (@parts) {
                   1332:                             unless ($postcorrect{$part}) {
                   1333:                                 push(@possparts,$part);
                   1334:                             }
                   1335:                         }
                   1336:                     } else {
                   1337:                         foreach my $key (keys(%Apache::lonhomework::results)) {
                   1338:                             if ($key =~ /^resource\.([^\.]+)\.solved$/) {
                   1339:                                 my $part = $1;
                   1340:                                 unless ($postcorrect{$part}) {
                   1341:                                     if ($Apache::lonhomework::results{$key} eq 'incorrect_attempted') {
                   1342:                                         push(@possparts,$part);
                   1343:                                     }
                   1344:                                 }
                   1345:                             }
                   1346:                         }
                   1347:                     }
                   1348:                     if (@possparts) {
                   1349:                         my %newrecord = &Apache::lonnet::restore($symb,$courseid,$domain,$name);
                   1350:                         my @parts_to_hide = &check_correctness_changes($symb,$courseid,$domain,$name,
                   1351:                                                                        \%newrecord,\@possparts,$newversion,
                   1352:                                                                        $oldversion);
                   1353:                         if (@parts_to_hide) {
                   1354:                             my $partslist = join(',',@parts_to_hide);
                   1355:                             &Apache::grades::makehidden($newversion,$partslist,\%newrecord,$symb,$domain,$name,1);
                   1356:                         }
                   1357:                     }
                   1358:                 }
                   1359:             }
1.159     albertel 1360: 	    &Apache::lonxml::debug('Store return message:'.$result);
1.470     raeburn  1361:             &store_aggregates($symb,$courseid);
1.159     albertel 1362: 	}
1.323     albertel 1363:     } else {
                   1364: 	&Apache::lonxml::debug('Nothing to store');
1.67      albertel 1365:     }
1.159     albertel 1366:     return $result;
1.65      albertel 1367: }
                   1368: 
1.435     jms      1369: =pod
                   1370: 
1.524     raeburn  1371: =item check_correctness_changes()
                   1372: 
                   1373:         For all parts for which current results contain a solved status
                   1374:         of "incorrect_attempted", check if there was a transaction in which  
                   1375:         solved was set to "correct_by_student" in the time since the last 
                   1376:         transaction (retrieved when &initialize_storage() was called i.e., 
                   1377:         when &start_problem() was called), unless:
                   1378:         (a) questiontype parameter is set to survey or anonymous survey (+/- credit)
                   1379:         (b) problemstatus is set to no or no_feedback_ever
                   1380:         If such a transaction exists, and did not occur after "reset status" 
                   1381:         by a user with grading privileges, then the current transaction is an
                   1382:         example of an out-of-order transaction (i.e., incorrect occurring after
                   1383:         correct).  Accordingly, the current transaction should be hidden.
                   1384: 
                   1385: =cut
                   1386: 
                   1387: 
                   1388: sub check_correctness_changes {
                   1389:     my ($symb,$courseid,$domain,$name,$record,$parts,$newversion,$oldversion) = @_;
                   1390:     my @parts_to_hide;
                   1391:     unless ((ref($record) eq 'HASH') && (ref($parts) eq 'ARRAY')) {
                   1392:         return @parts_to_hide;
                   1393:     }
                   1394:     if (@{$parts}) {
                   1395:         my $usec;
                   1396:         if (($env{'user.name'} eq $name) && ($env{'user.domain'} eq $domain) &&
                   1397:             ($env{'request.course.id'} eq $courseid)) {
                   1398:             $usec = $env{'request.course.sec'};
                   1399:         } else {
                   1400:             $usec = &Apache::lonnet::getsection($domain,$name,$courseid);
                   1401:         }
                   1402:         foreach my $id (@{$parts}) {
                   1403:             next if (($Apache::lonhomework::results{'resource.'.$id.'.type'} =~ /survey/) ||
                   1404:                      (&Apache::lonnet::EXT("resource.$id.problemstatus",$symb,
                   1405:                                            $domain,$name,$usec,undef,$courseid) =~ /^no/));
                   1406:             my $reset;
                   1407:             for (my $i=$newversion-1; $i>=$oldversion; $i--) {
                   1408:                 if (($record->{$i.':resource.'.$id.'.regrader'}) &&
                   1409:                     ($record->{$i.':resource.'.$id.'.tries'} eq '') &&
                   1410:                     ($record->{$i.':resource.'.$id.'.award'} eq '')) {
                   1411:                     $reset = 1;
                   1412:                 } elsif (($record->{$i.":resource.$id.solved"} eq 'correct_by_student') &&
                   1413:                          ($record->{$i.":resource.$id.awarded"} >= 1)) {
                   1414:                     unless ($reset) {
                   1415:                         push(@parts_to_hide,$id);
                   1416:                         last;
                   1417:                     }
                   1418:                 }
                   1419:             }
                   1420:         }
                   1421:     }
                   1422:     return @parts_to_hide;
                   1423: }
                   1424: 
                   1425: =pod
                   1426: 
1.435     jms      1427: item store_aggregates()
                   1428: 
                   1429: 	Sends hash of values to be incremented in nohist_resourcetracker.db
                   1430: 	for the course. Increments total number of attempts, unique students 
                   1431: 	and corrects for each part for an instance of a problem, as appropriate.
                   1432: 	
                   1433: =cut
                   1434: 
1.285     raeburn  1435: sub store_aggregates {
                   1436:     my ($symb,$courseid) = @_;
1.479     raeburn  1437:     my (%aggregate,%anoncounter,%randtrycounter);
1.286     albertel 1438:     my @parts;
1.288     albertel 1439:     my $cdomain = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   1440:     my $cname = $env{'course.'.$env{'request.course.id'}.'.num'};
1.286     albertel 1441:     foreach my $key (keys(%Apache::lonhomework::results)) {
1.287     albertel 1442:         if ($key =~ /resource\.([^\.]+)\.tries/) {
1.286     albertel 1443:             push(@parts, $1);
1.285     raeburn  1444:         }
                   1445:     }
1.286     albertel 1446:     foreach my $part (@parts) {
1.470     raeburn  1447:         if ($env{'request.role'} =~/^st/) {
                   1448:             if ($Apache::lonhomework::results{'resource.'.$part.'.award'}
                   1449: 	        eq 'APPROX_ANS' ||
                   1450: 	        $Apache::lonhomework::results{'resource.'.$part.'.award'}
                   1451: 	        eq 'EXACT_ANS') {
                   1452:                 $aggregate{$symb."\0".$part."\0correct"} = 1;
                   1453:             }
                   1454:             if ($Apache::lonhomework::results{'resource.'.$part.'.tries'} == 1) {
                   1455:                 $aggregate{$symb."\0".$part."\0users"} = 1;
                   1456:             } else {
                   1457:                 my (undef,$last_reset) = &Apache::grades::get_last_resets($symb,$env{'request.course.id'},[$part]); 
                   1458:                 if ($last_reset) {
                   1459:                     if (&Apache::grades::get_num_tries(\%Apache::lonhomework::history,$last_reset,$part) == 0) {
                   1460:                         $aggregate{$symb."\0".$part."\0users"} = 1;
                   1461:                     }
                   1462:                 }
                   1463:             }
                   1464:             $aggregate{$symb."\0".$part."\0attempts"} = 1;
1.285     raeburn  1465:         }
1.470     raeburn  1466:         if (($Apache::lonhomework::results{'resource.'.$part.'.type'} eq 'anonsurvey') || 
1.479     raeburn  1467:             ($Apache::lonhomework::results{'resource.'.$part.'.type'} eq 'anonsurveycred') ||
                   1468:             ($Apache::lonhomework::results{'resource.'.$part.'.type'} eq 'randomizetry')) {
                   1469:             if ($Apache::lonhomework::results{'resource.'.$part.'.type'} eq 'randomizetry') {
                   1470:                 $randtrycounter{$symb."\0".$part} = 1;
                   1471:             } else {
                   1472:                 $anoncounter{$symb."\0".$part} = 1;
                   1473:             }
1.470     raeburn  1474:             my $needsrelease = $Apache::lonnet::needsrelease{'parameter:type:'.$Apache::lonhomework::results{'resource.'.$part.'.type'}};
                   1475:             if ($needsrelease) {   
                   1476:                 my $curr_required = $env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'};
                   1477:                 if ($curr_required eq '') {
1.471     raeburn  1478:                     &Apache::lonnet::update_released_required($needsrelease);
1.470     raeburn  1479:                 } else {
                   1480:                     my ($currmajor,$currminor) = split(/\./,$curr_required);
                   1481:                     my ($needsmajor,$needsminor) = split(/\./,$needsrelease);
                   1482:                     if (($currmajor < $needsmajor) || ($currmajor == $needsmajor && $currminor < $needsminor)) {
1.471     raeburn  1483:                         &Apache::lonnet::update_released_required($needsrelease);
1.470     raeburn  1484:                     }
1.292     raeburn  1485:                 }
                   1486:             }
1.285     raeburn  1487:         }
                   1488:     }
1.526     raeburn  1489:     if (keys(%aggregate) > 0) {
1.289     albertel 1490: 	&Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
1.292     raeburn  1491:                             $cdomain,$cname);
                   1492:     }
1.472     raeburn  1493:     if (keys(%anoncounter) > 0) {
1.481     raeburn  1494:         &Apache::lonnet::cput('nohist_anonsurveys',\%anoncounter,
                   1495:                               $cdomain,$cname);
1.472     raeburn  1496:     }
1.479     raeburn  1497:     if (keys(%randtrycounter) > 0) {
1.481     raeburn  1498:         &Apache::lonnet::cput('nohist_randomizetry',\%randtrycounter,
                   1499:                               $cdomain,$cname);
1.479     raeburn  1500:     }
1.292     raeburn  1501: }
1.289     albertel 1502: 
1.65      albertel 1503: sub checkout_msg {
1.211     albertel 1504:     my %lt=&Apache::lonlocal::texthash( 
                   1505: 		'resource'=>'The resource needs to be checked out',
                   1506: 		'id_expln'=>'As a resource gets checked out, a unique timestamped ID is given to it, and a permanent record is left in the system.',
                   1507:                 'warning'=>'Checking out resources is subject to course policies, and may exclude future credit even if done erroneously.',
1.509     bisitz   1508:                 'checkout'=>'Check out Bubblesheet Exam for Viewing',
                   1509: 		'checkout?'=>'Check out Bubblesheet Exam?');
1.352     albertel 1510:     my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});
1.159     albertel 1511:     return (<<ENDCHECKOUT);
1.211     albertel 1512: <h2>$lt{'resource'}</h2>
                   1513:     <p>$lt{'id_expln'}</p>
1.449     bisitz   1514: <p class="LC_warning">$lt{'warning'}</p>
1.444     bisitz   1515: <form name="checkout" method="post" action="$uri">
1.91      albertel 1516: <input type="hidden" name="doescheckout" value="yes" />
1.514     bisitz   1517: <input type="button" name="checkoutbutton" value="$lt{'checkout'}" onclick="javascript:if (confirm('$lt{'checkout?'}')) { document.checkout.submit(); }" />
1.65      albertel 1518: </form>
                   1519: ENDCHECKOUT
                   1520: }
                   1521: 
1.252     albertel 1522: sub firstaccess_msg {
1.253     albertel 1523:     my ($time,$symb)=@_;
1.414     albertel 1524:     my $result;
                   1525:     my @interval=&Apache::lonnet::EXT("resource.0.interval");
                   1526:     if ($interval[1] eq 'map') {
                   1527: 	my ($map)=&Apache::lonnet::decode_symb($symb);
                   1528: 	my $foldertitle=&Apache::lonnet::gettitle($map);
                   1529:     
                   1530: 	&Apache::lonxml::debug("map is $map title is $foldertitle");
1.504     golterma 1531: 	$result .= "<h2>".&mt('The resources in "[_1]" are open for a limited time.',$foldertitle)."</h2>"
                   1532:                              .'<p>'.&mt('Once you click the "Show Resource" button below you have [_2] to complete all resources "[_1]".'
                   1533:                              ,$foldertitle,$time)."</p>";
1.414     albertel 1534:     } elsif ($interval[1] eq 'course') {
                   1535: 	my $course = $env{'course.'.$env{'request.course.id'}.'.description'};
1.504     golterma 1536:         $result .= "<h2>".&mt('The resources in "[_1]" are open for a limited time.',$course)."</h2>"
1.505     golterma 1537:                              .'<p>'.&mt('Once you click the "Show Resource" button below you have [_2] to complete all resources "[_1]".'
1.504     golterma 1538:                              ,$course,$time)."</p>";
1.414     albertel 1539:     } else {
                   1540: 	my $title=&Apache::lonnet::gettitle($symb);
1.504     golterma 1541:         $result .= "<h2>".&mt('This resource "[_1]" is open for a limited time.',$title)."</h2>"
                   1542:                              .'<p>'.&mt('Once you click the "Show Resource" button below you have [_2] to complete this resource "[_1]".'
                   1543:                              ,$title,$time)."</p>";
1.414     albertel 1544:     }
1.352     albertel 1545:     my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});
1.418     bisitz   1546:     my $buttontext = &mt('Show Resource');
                   1547:     my $timertext = &mt('Start Timer?');
1.414     albertel 1548:     $result .= (<<ENDCHECKOUT);
1.444     bisitz   1549: <form name="markaccess" method="post" action="$uri">
1.252     albertel 1550: <input type="hidden" name="markaccess" value="yes" />
1.514     bisitz   1551: <input type="button" name="accessbutton" value="$buttontext" onclick="javascript:if (confirm('$timertext')) { document.markaccess.submit(); }" />
1.252     albertel 1552: </form>
                   1553: ENDCHECKOUT
1.414     albertel 1554:     return $result;
1.252     albertel 1555: }
                   1556: 
1.204     albertel 1557: sub init_problem_globals {
                   1558:     my ($type)=@_;
                   1559:     #initialize globals
1.308     foxr     1560:     #   For problems, we start out in part 0 (outside a <part> tag).
                   1561:     #   and part 0 is used to describe the main body of the <problem>
                   1562:     #
1.204     albertel 1563:     if ($type eq 'problem') {
                   1564: 	$Apache::inputtags::part='0';
                   1565: 	@Apache::inputtags::partlist=('0');
1.405     albertel 1566: 	&Apache::lonhomework::set_show_problem_status(&get_problem_status('0'));
1.266     albertel 1567: 	$Apache::lonhomework::ignore_response_errors=0;
1.308     foxr     1568: 
1.266     albertel 1569:     } elsif ($type eq 'library') {
1.204     albertel 1570: 	$Apache::inputtags::part='';
                   1571: 	@Apache::inputtags::partlist=();
1.405     albertel 1572: 	&Apache::lonhomework::reset_show_problem_status();
1.266     albertel 1573: 	$Apache::lonhomework::ignore_response_errors=1;
1.308     foxr     1574: 
1.304     albertel 1575:     } elsif ($type eq 'Task') {
                   1576: 	$Apache::inputtags::part='0';
                   1577: 	@Apache::inputtags::partlist=('0');
1.405     albertel 1578: 	&Apache::lonhomework::reset_show_problem_status();
1.304     albertel 1579: 	$Apache::lonhomework::ignore_response_errors=1;
1.204     albertel 1580:     }
1.477     www      1581:     @Apache::functionplotresponse::callscripts=();
1.204     albertel 1582:     @Apache::inputtags::responselist = ();
                   1583:     @Apache::inputtags::importlist = ();
                   1584:     @Apache::inputtags::previous=();
                   1585:     @Apache::inputtags::previous_version=();
                   1586:     $Apache::structuretags::printanswer='No';
                   1587:     @Apache::structuretags::whileconds=();
                   1588:     @Apache::structuretags::whilebody=();
                   1589:     @Apache::structuretags::whileline=();
                   1590:     $Apache::lonhomework::scantronmode=0;
                   1591:     undef($Apache::lonhomework::name);
1.358     albertel 1592:     undef($Apache::lonhomework::default_type);
                   1593:     undef($Apache::lonhomework::type);
1.204     albertel 1594: }
                   1595: 
                   1596: sub reset_problem_globals {
                   1597:     my ($type)=@_;
                   1598:     undef(%Apache::lonhomework::history);
                   1599:     undef(%Apache::lonhomework::results);
                   1600:     undef($Apache::inputtags::part);
1.498     raeburn  1601:     if ($type eq 'Task') {
                   1602:         undef($Apache::inputtags::slot_name);
1.528     raeburn  1603:     } elsif ($type eq 'problem') {
                   1604:         undef($Apache::lonhomework::rawrndseed);
1.498     raeburn  1605:     }
1.208     albertel 1606: #don't undef this, lonhomework.pm takes care of this, we use this to 
                   1607: #detect if we try to do 2 problems in one file
                   1608: #   undef($Apache::lonhomework::parsing_a_problem);
1.204     albertel 1609:     undef($Apache::lonhomework::name);
1.358     albertel 1610:     undef($Apache::lonhomework::default_type);
                   1611:     undef($Apache::lonhomework::type);
                   1612:     undef($Apache::lonhomework::scantronmode);
                   1613:     undef($Apache::lonhomework::ignore_response_errors);
1.477     www      1614:     undef(@Apache::functionplotresponse::callscripts);
1.405     albertel 1615:     &Apache::lonhomework::reset_show_problem_status();
1.204     albertel 1616: }
                   1617: 
1.241     albertel 1618: sub set_problem_state {
1.240     albertel 1619:     my ($part)=@_;
1.284     albertel 1620:     if ($env{'form.problemstate'} eq 'CANNOT_ANSWER_correct') {
1.240     albertel 1621: 	$Apache::lonhomework::history{"resource.$part.solved"}=
                   1622: 	    'correct_by_student';
                   1623:     }
                   1624: }
                   1625: 
1.241     albertel 1626: sub get_problem_status {
                   1627:     my ($part)=@_;
1.267     albertel 1628:     my $problem_status;
1.284     albertel 1629:     if ($env{'request.state'} eq 'construct' &&
                   1630: 	defined($env{'form.problemstatus'})) {
                   1631: 	$problem_status=$env{'form.problemstatus'};
1.267     albertel 1632:     } else {
                   1633: 	$problem_status=&Apache::lonnet::EXT("resource.$part.problemstatus");
                   1634: 	&Apache::lonxml::debug("problem status for $part is $problem_status");
1.284     albertel 1635: 	&Apache::lonxml::debug("env probstat is ".$env{'form.problemstatus'});
1.241     albertel 1636:     }
                   1637:     return $problem_status;
                   1638: }
                   1639: 
1.9       albertel 1640: sub start_problem {
1.326     albertel 1641:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.19      albertel 1642: 
1.311     foxr     1643:     # We'll use the redirection to fix up printing of duedates.
1.321     albertel 1644:     if (!$Apache::lonxml::metamode) {
                   1645: 	&Apache::lonxml::startredirection();
                   1646:     }
1.311     foxr     1647: 
1.308     foxr     1648:     # Problems don't nest and we don't allow more than one <problem> in
                   1649:     # a .problem file.
                   1650:     #
1.184     albertel 1651:     if ( $Apache::inputtags::part ne '' ||
                   1652: 	 $Apache::lonhomework::parsing_a_problem) {
                   1653: 	&Apache::lonxml::error('Only one &lt;problem&gt; allowed in a .problem file');
1.326     albertel 1654: 	#my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser,$style);
1.159     albertel 1655: 	return '';
                   1656:     }
1.184     albertel 1657: 
                   1658:     $Apache::lonhomework::parsing_a_problem=1;
1.204     albertel 1659:     &init_problem_globals('problem');
1.166     albertel 1660: 
1.284     albertel 1661:     if (defined($env{'scantron.maxquest'})) {
1.166     albertel 1662: 	$Apache::lonhomework::scantronmode=1;
                   1663:     }
1.161     albertel 1664: 
1.159     albertel 1665:     if ($target ne 'analyze') {
1.415     raeburn  1666:         my $type = &Apache::lonnet::EXT('resource.0.type');
                   1667: 	$Apache::lonhomework::type=$type;
1.284     albertel 1668: 	if (($env{'request.state'} eq 'construct') &&
1.410     albertel 1669: 	    $env{'form.problemtype'} =~ /\S/) {
1.284     albertel 1670: 	    $Apache::lonhomework::type=$env{'form.problemtype'};
1.237     albertel 1671: 	}
1.332     albertel 1672: 	&Apache::lonxml::debug("Found this to be of type :$Apache::lonhomework::type:");
1.159     albertel 1673:     }
1.164     albertel 1674:     if ($Apache::lonhomework::type eq '' ) {
1.284     albertel 1675: 	my $uri=$env{'request.uri'};
1.159     albertel 1676: 	if ($uri=~/\.(\w+)$/) {
                   1677: 	    $Apache::lonhomework::type=$1;
                   1678: 	    &Apache::lonxml::debug("Using type of $1");
                   1679: 	} else {
                   1680: 	    $Apache::lonhomework::type='problem';
                   1681: 	    &Apache::lonxml::debug("Using default type, problem, :$uri:");
                   1682: 	}
1.87      albertel 1683:     }
1.301     albertel 1684:     $Apache::lonhomework::default_type = $Apache::lonhomework::type;
1.58      www      1685: 
1.363     albertel 1686:     &initialize_storage();
1.389     albertel 1687:     if ($target ne 'analyze'
                   1688:        	&& $env{'request.state'} eq 'construct') {
                   1689: 	&set_problem_state('0');
                   1690:     }
                   1691: 
1.366     albertel 1692:     if ($target eq 'web') {
                   1693: 	&Apache::lonxml::debug(" grading history ");
                   1694: 	&Apache::lonhomework::showhash(%Apache::lonhomework::history);
                   1695:     }
1.363     albertel 1696: 
1.159     albertel 1697:     #added vars to the scripting enviroment
1.213     albertel 1698:     my $expression='$external::part=\''.$Apache::inputtags::part.'\';';
1.248     albertel 1699:     $expression.='$external::type=\''.$Apache::lonhomework::type.'\';';
1.24      albertel 1700:     &Apache::run::run($expression,$safeeval);
1.159     albertel 1701:     my $status;
                   1702:     my $accessmsg;
1.508     raeburn  1703:     my $resource_due;
1.159     albertel 1704: 
1.343     albertel 1705:     my $name= &get_resource_name($parstack,$safeeval);
1.528     raeburn  1706:     my ($result,$form_tag_start,$slot_name,$slot,$probpartlist);
1.506     raeburn  1707: 
                   1708:     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
                   1709:         $target eq 'tex') {
                   1710:         if ($env{'form.markaccess'}) {
                   1711:             my @interval=&Apache::lonnet::EXT("resource.0.interval");
1.519     raeburn  1712:             &Apache::lonnet::set_first_access($interval[1],$interval[0]);
1.506     raeburn  1713:         }
                   1714: 
                   1715:         ($status,$accessmsg,$slot_name,$slot) =
                   1716:             &Apache::lonhomework::check_slot_access('0','problem');
                   1717:         push (@Apache::inputtags::status,$status);
                   1718:     }
                   1719: 
1.354     albertel 1720:     if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex'
                   1721: 	|| $target eq 'edit') {
1.528     raeburn  1722: 	($result,$form_tag_start,$probpartlist) =
1.350     albertel 1723: 	    &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval,
                   1724: 			$name);
1.528     raeburn  1725:     } elsif (($target eq 'grade') && ($Apache::lonhomework::type eq 'randomizetry')) {
                   1726:         my ($symb)= &Apache::lonnet::whichuser();
                   1727:         my $navmap = Apache::lonnavmaps::navmap->new();
                   1728:         if (ref($navmap)) {
                   1729:             my $res = $navmap->getBySymb($symb);
                   1730:             if (ref($res)) {
                   1731:                 $probpartlist = $res->parts();
                   1732:             }
                   1733:         }
1.350     albertel 1734:     }
                   1735: 
1.284     albertel 1736:     if ($target eq 'tex' and $env{'request.symb'} =~ m/\.page_/) {$result='';}
1.159     albertel 1737: 
1.479     raeburn  1738:     if ($target eq 'analyze') { my $rndseed=&setup_rndseed($safeeval,$target); }
1.159     albertel 1739:     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
                   1740: 	$target eq 'tex') {
1.479     raeburn  1741: 
1.159     albertel 1742: 	#handle rand seed in construction space
1.528     raeburn  1743: 	my $rndseed=&setup_rndseed($safeeval,$target,$probpartlist);
                   1744:         if (($target eq 'grade') && &Apache::response::submitted()) {
                   1745:             if ($Apache::lonhomework::type eq 'randomizetry') {
1.529     raeburn  1746:                 $Apache::lonhomework::results{'resource.0.rndseed'}=$rndseed;
1.528     raeburn  1747:             } else {
                   1748:                 my @parts;
                   1749:                 if (ref($probpartlist) eq 'ARRAY') {
                   1750:                     @parts = @{$probpartlist};
                   1751:                 }
                   1752:                 unless (@parts) {
1.529     raeburn  1753:                     $Apache::lonhomework::results{'resource.0.rndseed'}=$Apache::lonhomework::rawrndseed;
1.528     raeburn  1754:                 }
                   1755:             }
                   1756:         }
1.367     albertel 1757: 	my ($symb)=&Apache::lonnet::whichuser();
1.479     raeburn  1758: 
1.333     albertel 1759: 	if ($env{'request.state'} ne "construct" && 
                   1760: 	    ($symb eq '' || $Apache::lonhomework::type eq 'practice')) {
1.162     albertel 1761: 	    $form_tag_start.='<input type="hidden" name="rndseed" value="'.
1.462     raeburn  1762: 		$rndseed.'" />'.
                   1763: 		    '<input type="submit" name="resetdata"
                   1764:                              value="'.&mt('New Problem Variation').'" />';
1.334     albertel 1765: 	    if (exists($env{'form.username'})) {
                   1766: 		$form_tag_start.=
1.164     albertel 1767: 		    '<input type="hidden" name="username"
1.284     albertel 1768:                              value="'.$env{'form.username'}.'" />';
1.334     albertel 1769: 	    }
1.462     raeburn  1770: 	    if ($env{'request.role.adv'}) {
                   1771: 		$form_tag_start.= ' <label class="LC_nobreak">'
                   1772:                          .'<input type="checkbox" name="showallfoils"';
                   1773: 		if (defined($env{'form.showallfoils'})) {
                   1774: 		    $form_tag_start.=' checked="checked"';
                   1775: 		}
                   1776:                 $form_tag_start.= ' /> '
                   1777:                                  .&mt('Show All Foils')
                   1778:                                  .'</label>';
                   1779: 	    }
1.417     www      1780:             if ($Apache::lonhomework::type eq 'practice') {
1.428     raeburn  1781:                 $form_tag_start.=&practice_problem_header();
1.417     www      1782:             }
1.462     raeburn  1783: 	    $form_tag_start.='<hr />';
1.479     raeburn  1784:         } elsif (($env{'request.state'} ne "construct") &&
                   1785:                  ($Apache::lonhomework::type eq 'randomizetry') &&
                   1786:                  ($status eq 'CAN_ANSWER')) {
                   1787:             my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
                   1788:             my $problemstatus = &get_problem_status($Apache::inputtags::part);
                   1789:             $form_tag_start.=&randomizetry_problem_header($problemstatus,$reqtries);
                   1790:         }
1.324     albertel 1791: 
1.159     albertel 1792: 	my $expression='$external::datestatus="'.$status.'";';
                   1793: 	$expression.='$external::gradestatus="'.$Apache::lonhomework::history{"resource.0.solved"}.'";';
                   1794: 	&Apache::run::run($expression,$safeeval);
                   1795: 	&Apache::lonxml::debug("Got $status");
1.324     albertel 1796: 
1.159     albertel 1797: 	if (( $status eq 'CLOSED' ) ||
                   1798: 	    ( $status eq 'UNCHECKEDOUT') ||
1.252     albertel 1799: 	    ( $status eq 'NOT_YET_VIEWED') ||
1.159     albertel 1800: 	    ( $status eq 'BANNED') ||
1.216     albertel 1801: 	    ( $status eq 'UNAVAILABLE') ||
1.324     albertel 1802: 	    ( $status eq 'NOT_IN_A_SLOT') ||
1.499     raeburn  1803:             ( $status eq 'NOTRESERVABLE') ||
                   1804:             ( $status eq 'RESERVABLE') ||
                   1805:             ( $status eq 'RESERVABLE_LATER') ||
1.216     albertel 1806: 	    ( $status eq 'INVALID_ACCESS')) {
1.326     albertel 1807: 	    my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser,
                   1808: 						       $style);
1.159     albertel 1809: 	    if ( $target eq "web" ) {
1.343     albertel 1810: 		my $msg;
1.159     albertel 1811: 		if ($status eq 'UNAVAILABLE') {
1.504     golterma 1812: 		    $msg.='<p class="LC_error">'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'</p>';
1.441     raeburn  1813:                 } elsif ($status eq 'NOT_IN_A_SLOT') {
1.504     golterma 1814:                     $msg.='<p class="LC_warning">'.&mt('You are not currently signed up to work at this time and/or place.').'</p>';
1.499     raeburn  1815:                 } elsif (($status eq 'RESERVABLE') || ($status eq 'RESERVABLE_LATER') ||
                   1816:                          ($status eq 'NOTRESERVABLE')) {
1.504     golterma 1817:                     $msg.='<p class="LC_warning">'.&mt('Access requires reservation to work at specific time/place.').'</p>';
1.253     albertel 1818: 		} elsif ($status ne 'NOT_YET_VIEWED') {
1.504     golterma 1819: 		    $msg.='<p class="LC_warning">'.&mt('Not open to be viewed').'</p>';
1.499     raeburn  1820:                 }
1.216     albertel 1821: 		if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') {
1.393     www      1822: 		    $msg.=&mt('The problem ').$accessmsg;
1.159     albertel 1823: 		} elsif ($status eq 'UNCHECKEDOUT') {
1.343     albertel 1824: 		    $msg.=&checkout_msg();
1.252     albertel 1825: 		} elsif ($status eq 'NOT_YET_VIEWED') {
1.253     albertel 1826: 		    $msg.=&firstaccess_msg($accessmsg,$symb);
1.325     albertel 1827: 		} elsif ($status eq 'NOT_IN_A_SLOT') {
1.441     raeburn  1828: 		    $msg.=&Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work");
1.499     raeburn  1829:                 } elsif ($status eq 'RESERVABLE') {
                   1830:                     $msg.=&mt('Available to make a reservation.').' '.&mt('Reservation window closes [_1].',
                   1831:                               &Apache::lonnavmaps::timeToHumanString($accessmsg,'end')).
                   1832:                           '<br />'.
                   1833:                           &Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work");
                   1834:                 } elsif ($status eq 'RESERVABLE_LATER') {
                   1835:                     $msg.=&mt('Window to make a reservation will open [_1].',
                   1836:                               &Apache::lonnavmaps::timeToHumanString($accessmsg,'start'));
                   1837:                 } elsif ($status eq 'NOTRESERVABLE') {
                   1838:                     $msg.=&mt('Not available to make a reservation.');  
1.159     albertel 1839: 		}
                   1840: 		$result.=$msg.'<br />';
                   1841: 	    } elsif ($target eq 'tex') {
1.332     albertel 1842: 		my $startminipage = ($env{'form.problem_split'}=~/yes/i)? ''
                   1843: 		                    : '\begin{minipage}{\textwidth}';
1.443     foxr     1844: 		$result.='\noindent \vskip 1 mm '.
1.332     albertel 1845: 		    $startminipage.'\vskip 0 mm';
1.159     albertel 1846: 		if ($status eq 'UNAVAILABLE') {
1.211     albertel 1847: 		    $result.=&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'\vskip 0 mm ';
1.159     albertel 1848: 		} else {
1.211     albertel 1849: 		    $result.=&mt('Problem is not open to be viewed. It')." $accessmsg \\vskip 0 mm ";
1.159     albertel 1850: 		}
                   1851: 	    }
1.324     albertel 1852: 	} elsif ($status eq 'NEEDS_CHECKIN') {
1.326     albertel 1853: 	    my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser,
                   1854: 						       $style);
1.324     albertel 1855: 	    if ($target eq 'web') {
1.375     albertel 1856: 		$result .= 
                   1857: 		    &Apache::bridgetask::proctor_validation_screen($slot);
1.324     albertel 1858: 	    } elsif ($target eq 'grade') {
                   1859: 		&Apache::bridgetask::proctor_check_auth($slot_name,$slot,
                   1860: 							'problem');
                   1861: 	    }
1.159     albertel 1862: 	} elsif ($target eq 'web') {
1.508     raeburn  1863: 	    if ($status eq 'CAN_ANSWER') {
                   1864:                 $resource_due = &Apache::lonhomework::due_date(0, $env{'request.symb'});
                   1865:                 if ($slot_name ne '') {
                   1866:                     my $checked_in =
                   1867:                         $Apache::lonhomework::history{'resource.0.checkedin'};
                   1868:                     if ($checked_in eq '') {
                   1869:                         # unproctored slot access, self checkin
                   1870:                         &Apache::bridgetask::check_in('problem',undef,undef,
                   1871:                                                       $slot_name);
                   1872:                         $checked_in =
                   1873:                             $Apache::lonhomework::results{"resource.0.checkedin"};
                   1874:                     }
                   1875:                     if ((ref($slot) eq 'HASH') && ($checked_in ne '')) {
                   1876:                         if ($slot->{'starttime'} < time()) {
                   1877:                             if (!$resource_due) {
                   1878:                                 $resource_due = $slot->{'endtime'};
                   1879:                             } elsif ($slot->{'endtime'} < $resource_due) {
                   1880:                                 $resource_due = $slot->{'endtime'};
                   1881:                             }
                   1882:                         }
                   1883:                     }
                   1884:                 }
                   1885:                 if ($resource_due) {
                   1886:                     my $time_left = $resource_due - time();
                   1887:                     if ($resource_due && ($time_left > 0) && ($target eq 'web')) {
                   1888:                         $result .= &Apache::lonhtmlcommon::set_due_date($resource_due);
                   1889:                     }
                   1890:                 }
                   1891:             }
1.368     albertel 1892: 	    $result.="\n $form_tag_start \t".	
1.227     albertel 1893: 	      '<input type="hidden" name="submitted" value="yes" />';
                   1894: 	    # create a page header and exit
1.284     albertel 1895: 	    if ($env{'request.state'} eq "construct") {
                   1896: 		$result.= &problem_web_to_edit_header($env{'form.rndseed'});
1.428     raeburn  1897:                 if ($Apache::lonhomework::type eq 'practice') {
                   1898:                     $result.= '<input type="submit" name="resetdata" '.
                   1899:                               'value="'.&mt('New Problem Variation').'" />'.
                   1900:                               &practice_problem_header().'<hr />';
                   1901:                 }
1.227     albertel 1902: 	    }
                   1903: 	    # if we are viewing someone else preserve that info
1.284     albertel 1904: 	    if (defined $env{'form.grade_symb'}) {
1.227     albertel 1905: 		foreach my $field ('symb','courseid','domain','username') {
                   1906: 		    $result .= '<input type="hidden" name="grade_'.$field.
1.284     albertel 1907: 			'" value="'.$env{"form.grade_$field"}.'" />'."\n";
1.159     albertel 1908: 		}
1.479     raeburn  1909:                 foreach my $field ('trial','questiontype') {
                   1910:                     if ($env{"form.grade_$field"} ne '') {
                   1911:                         $result .= '<input type="hidden" name="grade_'.$field.
                   1912:                             '" value="'.$env{"form.grade_$field"}.'" />'."\n";
                   1913:                     }
                   1914:                 }
1.159     albertel 1915: 	    }
1.490     raeburn  1916:             if ($env{'form.grade_imsexport'}) {
                   1917:                 $result = '';
                   1918:             }
1.159     albertel 1919: 	} elsif ($target eq 'tex') {
1.319     foxr     1920: 	    $result .= 'INSERTTEXFRONTMATTERHERE';
1.500     foxr     1921: 	    $result .= &select_metadata_hyphenation();
                   1922: 	    
1.319     foxr     1923: 
1.99      sakharuk 1924: 	}
1.159     albertel 1925:     } elsif ($target eq 'edit') {
1.343     albertel 1926: 	$result .= $form_tag_start.&problem_edit_header();
1.226     albertel 1927: 	$Apache::lonxml::warnings_error_header=
                   1928: 	    &mt("Editor Errors - these errors might not effect the running of the problem, but they will likely cause problems with further use of the Edit mode. Please use the EditXML mode to fix these errors.")."<br />";
1.159     albertel 1929: 	my $temp=&Apache::edit::insertlist($target,$token);
                   1930: 	$result.=$temp;
                   1931:     } elsif ($target eq 'modified') {
                   1932: 	$result=$token->[4];
                   1933:     } else {
                   1934: 	# page_start returned a starting result, delete it if we don't need it
                   1935: 	$result = '';
1.99      sakharuk 1936:     }
1.159     albertel 1937:     return $result;
1.9       albertel 1938: }
                   1939: 
                   1940: sub end_problem {
1.159     albertel 1941:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.321     albertel 1942:     my $result;
1.310     foxr     1943: 
1.321     albertel 1944:     if (!$Apache::lonxml::metamode) {
                   1945: 	$result = &Apache::lonxml::endredirection(); #started in &start_problem
1.329     albertel 1946: 	$Apache::lonxml::post_evaluate=0;
1.321     albertel 1947:     }
1.319     foxr     1948: 
                   1949:     if ($target eq 'tex') {
1.321     albertel 1950: 	# Figure out the front matter and replace the
                   1951: 	# INSERTTEXFRONTMATTERHERE in result with it.  note that we do
                   1952: 	# this in end_problem because whether or not we display due
                   1953: 	# dates depends on whether due dates have already been
                   1954: 	# displayed in the problem parts.
                   1955: 
1.319     foxr     1956: 	my $frontmatter   = '';
                   1957: 	my $startminipage = '';
                   1958: 	if (not $env{'form.problem_split'}=~/yes/) {
                   1959: 	    $startminipage = '\begin{minipage}{\textwidth}';
                   1960: 	}
                   1961: 	my $id = $Apache::inputtags::part;
                   1962: 	my $weight = &Apache::lonnet::EXT("resource.$id.weight");
                   1963: 	my $packages=&Apache::lonnet::metadata($env{'request.uri'},'packages');
1.526     raeburn  1964: 	my @packages = split(/,/,$packages);
1.319     foxr     1965: 	my $allow_print_points = 0;
                   1966: 	foreach my $partial_key (@packages) {
                   1967: 	    if ($partial_key=~m/^part_0$/) {
                   1968: 		$allow_print_points=1;
                   1969: 	    }
                   1970: 	}
                   1971: 	my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries");
                   1972: 	if (defined($maxtries) && $maxtries < 0) { $allow_print_points=0; }
                   1973: 	if (lc($env{'course.'.$env{'request.course.id'}.
                   1974: 			'.disableexampointprint'}) eq 'yes') {
                   1975: 	    $allow_print_points=0;
                   1976: 	}
                   1977: 	my $name_of_resourse= &Apache::lonxml::latex_special_symbols(&get_resource_name($parstack,$safeeval),'header');
1.443     foxr     1978: 	my $begin_doc=' \typeout{STAMPOFPASSEDRESOURCESTART Resource <h2>"'.$name_of_resourse.'"</h2> located in <br /><small><b>'.$env{'request.uri'}.'</b></small><br /> STAMPOFPASSEDRESOURCEEND} \noindent ';
1.500     foxr     1979: 	&clear_required_languages();
1.319     foxr     1980: 	my $toc_line='\vskip 1 mm\noindent '.$startminipage.
                   1981: 	    '\addcontentsline{toc}{subsection}{'.$name_of_resourse.'}';
                   1982: 	
                   1983: 	#  Figure out what the due date is and if we need to print
                   1984: 	#  it in the problem header.  We have been logging the
                   1985: 	#  last due date written to file. 
                   1986: 	
                   1987: 	my $duetime = &Apache::lonnet::EXT("resource.$id.duedate"); 
                   1988: 	my $duedate = POSIX::strftime("%c",localtime($duetime));
1.448     bisitz   1989:         my $duedate_text = &mt('Due date: [_1]'
                   1990:                               ,&Apache::lonlocal::locallocaltime($duetime));
1.319     foxr     1991: 	my $temp_file;
                   1992: 	my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";
                   1993: 	
                   1994: 	# Figure out what the last printed due date is or set it
                   1995: 	# to the epoch if no duedates have been printed.
                   1996: 	
                   1997: 	my $due_file_content = 0;      #   If the file does not yet exist, time is the epoch.
                   1998: 	if (-e $filename) {
                   1999: 	    $temp_file = Apache::File->new($filename);
                   2000: 	    my @due_file      = <$temp_file>;
                   2001: 	    $due_file_content = $due_file[$#due_file];
                   2002: 	    chomp $due_file_content;
                   2003: 	} 
                   2004: 	
                   2005: 	# We display the due date iff it is not the same as the last
                   2006: 	# duedate in problem header ($due_file_content), and
                   2007: 	# none of our parts displayed a duedate.
                   2008: 	#
                   2009: 	my $parts_with_displayduedate;
                   2010: 	if (defined $Apache::outputtags::showonce{'displayduedate'}) {
                   2011: 	    $parts_with_displayduedate = 
                   2012: 		scalar(@{$Apache::outputtags::showonce{'displayduedate'}});
                   2013: 	} else {
                   2014: 	    $parts_with_displayduedate = 0;
                   2015: 	}
                   2016: 	if (($due_file_content != $duetime) && ($parts_with_displayduedate == 0) ) {
                   2017: 	    $temp_file = Apache::File->new('>'.$filename);
                   2018: 	    print $temp_file "$duetime\n";
                   2019: 	    if (not $env{'request.symb'} =~ m/\.page_/) {
                   2020: 		if(not $duedate=~m/1969/ and $Apache::lonhomework::type ne 'exam') {
                   2021: 		    $frontmatter .= $begin_doc.
1.448     bisitz   2022: 			'\textit{'.$duedate_text.'} '.$toc_line;
1.319     foxr     2023: 		} else {
                   2024: 		    $frontmatter.= $begin_doc.$toc_line;
1.463     foxr     2025: 		    if ($Apache::lonhomework::type eq 'exam' and $allow_print_points==1) { 
1.492     christia 2026: 			$frontmatter .= '\fbox{\textit{'.&mt('[quant,_1,pt,pt]',$weight ).'}}';
1.463     foxr     2027: 		    }
1.319     foxr     2028: 		}
                   2029: 	    } else {
1.448     bisitz   2030: 		$frontmatter .= '\vskip 1mm\textit{'.$duedate_text.'} \\\\\\\\'.$startminipage;
1.319     foxr     2031: 	    }
                   2032: 	} else {
                   2033: 	    if (not $env{'request.symb'} =~ m/\.page_/) {
                   2034: 		$frontmatter .= $begin_doc.$toc_line;
1.463     foxr     2035: 		if (($Apache::lonhomework::type eq 'exam') and ($allow_print_points==1)) { 
1.492     christia 2036: 		    $frontmatter .= '\fbox{\textit{'.&mt('[quant,_1,pt,pt]',$weight ).'}}';
1.463     foxr     2037: 		}
1.319     foxr     2038: 	    } else {
1.381     albertel 2039: 		$frontmatter .= '\vskip 1mm \\\\\\\\'.$startminipage;
1.319     foxr     2040: 	    }
                   2041: 	}
                   2042: 	$result =~ s/INSERTTEXFRONTMATTERHERE/$frontmatter/;
                   2043:     }
                   2044: 
1.159     albertel 2045:     my $status=$Apache::inputtags::status['-1'];
                   2046:     if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
                   2047: 	$target eq 'tex') {
1.249     albertel 2048: 	if ( $target eq 'grade' && $Apache::inputtags::part eq '0') {
1.159     albertel 2049: 	    # if part is zero, no <part>s existed, so we need to the grading
1.249     albertel 2050: 	    if ($status eq 'CAN_ANSWER' ||$Apache::lonhomework::scantronmode) {
                   2051: 		&Apache::inputtags::grade;
1.324     albertel 2052: 	    } elsif ($status eq 'NEEDS_CHECKIN') {
                   2053: 		# no need to grade, and don't want to hide data
1.249     albertel 2054: 	    } else {
                   2055: 		# move any submission data to .hidden
                   2056: 		&Apache::inputtags::hidealldata($Apache::inputtags::part);
                   2057: 	    }
1.159     albertel 2058: 	} elsif ( ($target eq 'web' || $target eq 'tex') &&
                   2059: 		  $Apache::inputtags::part eq '0' &&
1.490     raeburn  2060: 		  $status ne 'UNCHECKEDOUT' && $status ne 'NOT_YET_VIEWED'
                   2061:                   && !$env{'form.grade_imsexport'}) {
1.159     albertel 2062: 	    # if part is zero, no <part>s existed, so we need show the current
                   2063: 	    # grading status
                   2064: 	    my $gradestatus = &Apache::inputtags::gradestatus($Apache::inputtags::part,$target);
                   2065: 	    $result.= $gradestatus;
                   2066: 	}
                   2067: 	if (
1.284     albertel 2068: 	    (($target eq 'web') && ($env{'request.state'} ne 'construct')) ||
1.159     albertel 2069: 	    ($target eq 'answer') || ($target eq 'tex')
                   2070: 	   ) {
1.490     raeburn  2071: 	    if (($target ne 'tex') &&
                   2072: 		($env{'form.answer_output_mode'} ne 'tex') && 
                   2073:                 (!$env{'form.grade_imsexport'})) {
1.254     www      2074: 		$result.="</form>";
1.159     albertel 2075: 	    }
                   2076: 	    if ($target eq 'web') {
1.507     raeburn  2077:                 #
                   2078:                 # Closing </body></html> not added by end_page().
                   2079:                 # Added separately at end of this routine, after added
                   2080:                 # <script></script> so document will be valid xhtml.
                   2081:                 #
                   2082: 		$result.= &Apache::loncommon::end_page({'discussion' => 1,
                   2083: 							'notbody'    => 1});
1.159     albertel 2084: 	    } elsif ($target eq 'tex') {
1.178     sakharuk 2085: 		my $endminipage = '';
1.284     albertel 2086: 		if (not $env{'form.problem_split'}=~/yes/) {
1.178     sakharuk 2087: 		    $endminipage = '\end{minipage}';
                   2088: 		}
1.284     albertel 2089:                 if ($env{'form.print_discussions'} eq 'yes') {
1.263     sakharuk 2090: 		    $result.=&Apache::lonxml::xmlend($target,$parser);
1.159     albertel 2091: 		} else {
1.262     sakharuk 2092: 		    $result .= '\keephidden{ENDOFPROBLEM}\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}';
1.284     albertel 2093: 		    if (not $env{'request.symb'} =~ m/\.page_/) {
1.262     sakharuk 2094: 			$result .= $endminipage.'\end{document} ';
                   2095: 		    } else {
1.382     albertel 2096: 			$result .= $endminipage;
1.262     sakharuk 2097: 		    }
1.159     albertel 2098: 		}
                   2099: 	    }
                   2100: 	}
1.476     www      2101:         if ($target eq 'web') {
                   2102:            $result.=&Apache::functionplotresponse::init_script();
                   2103:         }
1.159     albertel 2104: 	if ($target eq 'grade') {
                   2105: 	    &Apache::lonhomework::showhash(%Apache::lonhomework::results);
                   2106: 	    &finalize_storage();
                   2107: 	}
1.284     albertel 2108: 	if ($target eq 'answer' && ($env{'request.state'} eq 'construct')
                   2109: 	    && $env{'form.answer_output_mode'} ne 'tex') {
1.346     albertel 2110: 	    $result.=&Apache::loncommon::end_page({'discussion' => 1});
1.294     albertel 2111: 	                        # normally we get it from above, but in CSTR
1.172     albertel 2112: 	                        # we always show answer mode too.
1.159     albertel 2113: 	}
                   2114:     } elsif ($target eq 'meta') {
                   2115: 	if ($Apache::inputtags::part eq '0') {
1.179     albertel 2116: 	    @Apache::inputtags::response=();
1.159     albertel 2117: 	    $result=&Apache::response::mandatory_part_meta;
                   2118: 	}
1.215     albertel 2119: 	$result.=&Apache::response::meta_part_order();
1.258     albertel 2120: 	$result.=&Apache::response::meta_response_order();
1.159     albertel 2121:     } elsif ($target eq 'edit') {
                   2122: 	&Apache::lonxml::debug("in end_problem with $target, edit");
1.314     albertel 2123: 	$result .= &problem_edit_footer();
1.320     albertel 2124:     } elsif ($target eq 'modified') {
                   2125: 	 $result .= $token->[2];
1.159     albertel 2126:     }
1.155     albertel 2127: 
1.284     albertel 2128:     if ($env{'request.state'} eq 'construct' && $target eq 'web') {
1.177     albertel 2129: 	&Apache::inputtags::check_for_duplicate_ids();
                   2130:     }
1.204     albertel 2131: 
                   2132:     &reset_problem_globals('problem');
1.159     albertel 2133: 
1.502     foxr     2134:     #
                   2135:     # This shouild be just above the return so that the
                   2136:     # time put in the javascript is as late as possible in the
                   2137:     # computation:
                   2138:     #
                   2139:     if ($target eq 'web') {
                   2140:         $result .= &Apache::lonhtmlcommon::set_compute_end_time();
1.507     raeburn  2141:         #
                   2142:         # Closing tags delayed so any <script></script> tags 
                   2143:         # not in head can appear inside body, for valid xhtml.
                   2144:         # 
                   2145:         $result .= "</body>\n</html>";
1.502     foxr     2146:     }
1.159     albertel 2147:     return $result;
1.48      albertel 2148: }
                   2149: 
1.108     albertel 2150: 
1.48      albertel 2151: sub start_library {
1.159     albertel 2152:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.343     albertel 2153:     my ($result,$form_tag_start);
1.371     albertel 2154:     if ($#$tagstack eq 0 && $$tagstack[0] eq 'library') {
1.244     albertel 2155: 	&init_problem_globals('library');
                   2156: 	$Apache::lonhomework::type='problem';
                   2157:     }
1.159     albertel 2158:     if ($target eq 'edit') {
1.343     albertel 2159: 	($result,$form_tag_start)=
                   2160: 	    &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval,
                   2161: 			'Edit');
                   2162: 	$result.=$form_tag_start.&problem_edit_header();
1.159     albertel 2163: 	my $temp=&Apache::edit::insertlist($target,$token);
                   2164: 	$result.=$temp;
                   2165:     } elsif ($target eq 'modified') {
                   2166: 	$result=$token->[4];
1.340     albertel 2167:     } elsif (($target eq 'web' || $target eq 'webgrade')
1.371     albertel 2168: 	     && ($#$tagstack eq 0 && $$tagstack[0] eq 'library')
1.340     albertel 2169: 	     && $env{'request.state'} eq "construct" ) {
1.159     albertel 2170: 	my $name=&get_resource_name($parstack,$safeeval);
1.343     albertel 2171: 	($result,$form_tag_start)=
                   2172: 	    &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval,
                   2173: 			$name);
1.479     raeburn  2174: 	my $rndseed=&setup_rndseed($safeeval,$target);
1.343     albertel 2175: 	$result.=" \n $form_tag_start".	
1.159     albertel 2176: 		  '<input type="hidden" name="submitted" value="yes" />';
                   2177: 	$result.=&problem_web_to_edit_header($rndseed);
1.428     raeburn  2178:         if ($Apache::lonhomework::type eq 'practice') {
                   2179:             $result.= '<input type="submit" name="resetdata" '.
                   2180:                       'value="'.&mt('New Problem Variation').'" />'.
                   2181:                       &practice_problem_header().'<hr />';
                   2182:         }
1.159     albertel 2183:     }
                   2184:     return $result;
1.48      albertel 2185: }
                   2186: 
                   2187: sub end_library {
1.159     albertel 2188:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2189:     my $result='';
                   2190:     if ($target eq 'edit') {
                   2191: 	$result=&problem_edit_footer();
1.371     albertel 2192:     } elsif ($target eq 'web' 
                   2193: 	     && ($#$tagstack eq 0 && $$tagstack[0] eq 'library') 
                   2194: 	     && $env{'request.state'} eq "construct") {
1.349     albertel 2195: 	$result.='</form>'.&Apache::loncommon::end_page({'discussion' => 1});
1.159     albertel 2196:     }
1.371     albertel 2197:     if ( $#$tagstack eq 0 && $$tagstack[0] eq 'library') {
                   2198: 	&reset_problem_globals('library');
                   2199:     }
1.159     albertel 2200:     return $result;
1.197     www      2201: }
                   2202: 
                   2203: sub start_definetag {
1.326     albertel 2204:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.197     www      2205: 
                   2206:     my $result;
                   2207: 
                   2208:     my $name = $token->[2]->{'name'};
1.326     albertel 2209:     my $skip=&Apache::lonxml::get_all_text("/definetag",$parser,$style);
1.396     albertel 2210:     if ($target eq 'web') {
                   2211: 	if ($name=~/^\//) {
                   2212: 	    $result=
                   2213: 		'<br /><table class="LC_sty_end"><tr><th>'.
                   2214: 		&mt('END [_1]'.'<tt>'.$name.'</tt>').'</th></tr>';
                   2215: 	} else {
                   2216: 	    $result=
                   2217: 		'<br /><table class="LC_sty_begin"><tr><th>'.
                   2218: 		&mt('BEGIN [_1]'.'<tt>'.$name.'</tt>').'</th></tr>';
                   2219: 	}
                   2220: 	$skip = &HTML::Entities::encode($skip, '<>&"');
                   2221: 	$result.='<tr><td><pre>'.$skip.'</pre></td></tr></table>';
1.197     www      2222:     }
                   2223:     return $result;
                   2224: }
                   2225: 
                   2226: sub end_definetag {
                   2227:     return '';
1.1       albertel 2228: }
                   2229: 
                   2230: sub start_block {
1.201     albertel 2231:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.131     albertel 2232: 
                   2233:     my $result;
1.1       albertel 2234: 
1.339     albertel 2235:     if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer'  ||
                   2236: 	$target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
1.159     albertel 2237: 	my $code = $token->[2]->{'condition'};
1.385     albertel 2238: 	if (defined($code) && $code ne '') {
1.137     albertel 2239: 	    if (!$Apache::lonxml::default_homework_loaded) {
                   2240: 		&Apache::lonxml::default_homework_load($safeeval);
                   2241: 	    }
1.131     albertel 2242: 	    $result = &Apache::run::run($code,$safeeval);
                   2243: 	    &Apache::lonxml::debug("block :$code: returned :$result:");
                   2244: 	} else {
                   2245: 	    $result='1';
                   2246: 	}
                   2247: 	if ( ! $result ) {
1.201     albertel 2248: 	    my $skip=&Apache::lonxml::get_all_text("/block",$parser,$style);
1.131     albertel 2249: 	    &Apache::lonxml::debug("skipping ahead :$skip: $$parser[-1]");
                   2250: 	}
                   2251: 	$result='';
                   2252:     } elsif ($target eq 'edit') {
                   2253: 	$result .=&Apache::edit::tag_start($target,$token);
                   2254: 	$result .=&Apache::edit::text_arg('Test Condition:','condition',
                   2255: 					  $token,40);
                   2256: 	$result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
                   2257:     } elsif ($target eq 'modified') {
                   2258: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                   2259: 						     $safeeval,'condition');
                   2260: 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
1.38      albertel 2261:     }
1.131     albertel 2262:     return $result;
1.1       albertel 2263: }
                   2264: 
                   2265: sub end_block {
1.167     www      2266:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2267:     my $result;
                   2268:     if ($target eq "edit") {
                   2269: 	$result.= &Apache::edit::tag_end($target,$token,'');
                   2270:     }
                   2271:     return $result;
                   2272: }
1.500     foxr     2273: #
                   2274: #  <languageblock [include='lang1,lang2...'] [exclude='lang1,lang2...']>
                   2275: #  ...
                   2276: #  </languageblock>
                   2277: #
                   2278: #   This declares the intent to provide content that can be rendered in the
                   2279: #   set of languages in the include specificatino but not in the exclude
                   2280: #   specification.  If a currently preferred language is in the include list
                   2281: #   the content in the <languageblock>...</languageblock> is rendered
                   2282: #   If the currently preferred language is in the exclude list,
                   2283: #   the content in the <languageblock>..></languageblock is not rendered.
                   2284: #
                   2285: #   Pathalogical case handling:
                   2286: #     - Include specified, without the preferred language but exclude  specified
                   2287: #       also without the preferred langauge results in rendering the block.
                   2288: #     - Exclude specified without include and excluden not containing a 
                   2289: #       preferred language renders the block.
                   2290: #     - Include and exclude both specifying the preferred language does not
                   2291: #       render the block.
                   2292: #     - If neither include/exclude is specified, the block gets rendered.
                   2293: #
                   2294: #  This tag has no effect when target is in {edit, modified}
                   2295: #
1.167     www      2296: sub start_languageblock {
1.201     albertel 2297:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.167     www      2298: 
1.500     foxr     2299:     my $result = '';
1.167     www      2300: 
1.339     albertel 2301:     if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
                   2302: 	$target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
1.201     albertel 2303: 	my $include = $token->[2]->{'include'};
                   2304: 	my $exclude = $token->[2]->{'exclude'};
1.436     raeburn  2305:         my @preferred_languages=&Apache::lonlocal::preferred_languages();
1.500     foxr     2306: 
                   2307:         # This should not even happen, since we should at least have the server language
                   2308: 
                   2309:         if (!$preferred_languages[0]) { 
                   2310: 	    $preferred_languages[0]='en'; 
                   2311: 	}
                   2312: 
                   2313:         # Now loop over all languages in order of preference
                   2314: 
                   2315: 	my $render;
1.398     www      2316:         foreach my $preferred_language (@preferred_languages) {
1.500     foxr     2317: 
                   2318: 	    # If neither include/nor exlude is present the block is going
                   2319: 	    # to get rendered.
                   2320: 
1.399     www      2321:            my $found=0;
1.500     foxr     2322:            $render=1;
                   2323: 
                   2324: 	   #  If include is specified,  don't render the block
                   2325: 	   #  unless the preferred language is included in the set.
                   2326: 
1.398     www      2327: 	   if ($include) {
1.500     foxr     2328:               $render=0;
1.398     www      2329:               foreach my $included_language (split(/\,/,$include)) {
                   2330:                  if ($included_language eq $preferred_language) {
1.500     foxr     2331:                     $render=1; 
1.399     www      2332:                     $found=1; 
1.500     foxr     2333: 		    last;	# Only need to find the first.
1.398     www      2334:                  }
                   2335:               }
                   2336: 	   }
1.500     foxr     2337:            # Do we have an exclude argument?
                   2338: 	   # If so, and one of the languages matches a preferred language
                   2339: 	   # inhibit rendering the block.  Note that in the pathalogical case the
                   2340: 	   # author has specified a preferred language in both the include and exclude
                   2341: 	   # attribte exclude is preferred.  
                   2342: 
1.398     www      2343:            if ($exclude) {
1.500     foxr     2344:               $render=1;
1.398     www      2345:               foreach my $excluded_language (split(/\,/,$exclude)) {
                   2346:                  if ($excluded_language eq $preferred_language) {
1.500     foxr     2347:                     $render=0;
1.399     www      2348:                     $found=1;
1.500     foxr     2349: 		    last;	# Only need to find the first.
1.398     www      2350:                  }
                   2351:               }
                   2352: 	   }
1.500     foxr     2353:            if ($found) { 
                   2354: 	       last; 		# Done on any match of include or exclude.
                   2355: 	   }
1.398     www      2356:         }
1.500     foxr     2357: 	# If $render not true skip the entire block until </languageblock>
                   2358: 	#
                   2359: 
                   2360: 	if ( ! $render ) {
1.201     albertel 2361: 	    my $skip=&Apache::lonxml::get_all_text("/languageblock",$parser,
                   2362: 						   $style);
                   2363: 	    &Apache::lonxml::debug("skipping ahead :$skip: $$parser[-1]");
                   2364: 	}
1.500     foxr     2365: 	# If $render is true, we've not skipped the contents of the <languageglock>
                   2366: 	# and the normal loncapa processing flow will render it as a matter of course.
                   2367: 
1.167     www      2368:     } elsif ($target eq 'edit') {
                   2369: 	$result .=&Apache::edit::tag_start($target,$token);
1.211     albertel 2370: 	$result .=&Apache::edit::text_arg(&mt('Include Language:'),'include',
1.167     www      2371: 					  $token,40);
1.211     albertel 2372: 	$result .=&Apache::edit::text_arg(&mt('Exclude Language:'),'exclude',
1.167     www      2373: 					  $token,40);
                   2374: 	$result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
                   2375:     } elsif ($target eq 'modified') {
                   2376: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
1.168     albertel 2377: 						     $safeeval,'include',
                   2378: 						     'exclude');
1.167     www      2379: 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
                   2380:     }
                   2381:     return $result;
                   2382: }
                   2383: 
                   2384: sub end_languageblock {
1.170     www      2385:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2386:     my $result;
1.201     albertel 2387:     if ($target eq "edit") {
1.170     www      2388: 	$result.= &Apache::edit::tag_end($target,$token,'');
                   2389:     }
                   2390:     return $result;
                   2391: }
1.500     foxr     2392: #  languagblock specific tags:
                   2393: {
                   2394:     # For chunks of a resource that has translations, this hash contains
                   2395:     # the translations available indexed by language name.
                   2396:     #
                   2397: 
                   2398:     my %available_texts;       
1.170     www      2399: 
1.500     foxr     2400:     # <translated> starts a block of a resource that has multiple translations.
                   2401:     # See the <lang> tag as well.
                   2402:     # When </translated> is encountered if there is a translation for the 
                   2403:     # currently preferred language, that is rendered inthe web/tex/webgrade
                   2404:     # targets.  Otherwise, the default text is rendered.
                   2405:     #
                   2406:     # Note that <lang> is only registered for the duration of the 
                   2407:     #  <translated>...</translated> block 
                   2408:     #
                   2409:     # Pathalogical case handling:
                   2410:     #   - If there is no <lang> that specifies a 'default' and there is no
                   2411:     #     translation that matches a preferred language, nothing is rendered.
                   2412:     #   - Nested <translated>...</translated> might be linguistically supported by
                   2413:     #     XML due to the stack nature of tag registration(?) however the rendered
                   2414:     #     output will be incorrect because there is only one %available_texts
                   2415:     #     has and end_translated clears it.
                   2416:     #   - Material outside of a <lang>...</lang> block within the
                   2417:     #     <translated>...<translated> block won't render either e.g.:
                   2418:     #    <translated>
                   2419:     #      The following will be in your preferred langauge:
                   2420:     #      <lang which='en'>
                   2421:     #         This section in english
                   2422:     #      </lang>
                   2423:     #      <lang which='sgeiso'>
                   2424:     #         Hier es ist auf Deutsch.
                   2425:     #      </lang>
                   2426:     #      <lang which='sfriso'>
                   2427:     #         En Francais
                   2428:     #      </lang>
                   2429:     #    </translated>
                   2430:     #
                   2431:     #    The introductory text prior to the first <lang> tag is not rendered.
                   2432:     #
1.397     albertel 2433:     sub start_translated {
                   2434: 	my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
                   2435: 	&Apache::lonxml::register('Apache::structuretags',('lang'));
                   2436: 	undef(%available_texts);
                   2437:     }
                   2438:     
                   2439:     sub end_translated {
                   2440: 	my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
                   2441: 	my $result;
                   2442: 	#show the translation on viewable targets
                   2443: 	if ($target eq 'web'     || $target eq 'tex' || $target eq 'webgrade'||
                   2444: 	    # or non-viewable targets, if it's embedded in something that
                   2445: 	    # wants the output
                   2446: 	    (($target eq 'answer' || $target eq 'analyze'|| $target eq 'grade')
                   2447: 	     && &Apache::lonxml::in_redirection() ) ) {
                   2448: 	    my @possibilities = keys(%available_texts);
                   2449: 	    my $which = 
                   2450: 		&Apache::loncommon::languages(\@possibilities) || 'default';
1.500     foxr     2451: 	    if ($target eq 'tex') {
                   2452: 		$result = &select_hyphenation($which);
                   2453: 	    }
                   2454: 	    $result .= $available_texts{$which};
                   2455: 	    if ($target eq 'tex') {
                   2456: 		$result .= &select_metadata_hyphenation(); # Restore original language.
                   2457: 	    }
1.397     albertel 2458: 	}
                   2459: 	undef(%available_texts);
                   2460: 	&Apache::lonxml::deregister('Apache::structuretags',('lang'));
                   2461: 	return $result;
                   2462:     }
                   2463: 
1.500     foxr     2464:     # <lang [which='language-name'] [other='lang1,lang2...']>  
                   2465:     #  Specifies that the block contained within it is a translation 
                   2466:     #  for a specific language specified by the 'which' attribute. The
                   2467:     #   'other' attribute can be used by itself or in conjunction with
                   2468:     #   which to specify this tag _may_ be used as a translation for some
                   2469:     #   list of languages. e.g.:  <lang which='senisoUS' other='senisoCA,senisoAU,seniso'>
                   2470:     #   specifying that the block provides a translation for US (primary)
                   2471:     #   Canadian, Australian and UK Englush.
                   2472:     #   
                   2473:     # Comment: this seems a bit silly why not just support a list of languages
                   2474:     #           e.g. <lang which='l1,l2...'> and ditch the other attribute?
                   2475:     #
                   2476:     #  Effect:
                   2477:     #    The material within the <lang>..</lang> block is stored in the
                   2478:     #    specified set of $available_texts hash entries, the appropriate one
                   2479:     #    is selected at </translated> time.
                   2480:     #
                   2481:     #  Pathalogical case handling:
                   2482:     #    If a language occurs multiple times within a <translated> block,
                   2483:     #    only the last one is rendered e.g.:
                   2484:     #
                   2485:     #    <translated>
                   2486:     #       <lang which='senisoUS', other='senisoCA,senisoAU,seniso'>
                   2487:     #          Red green color blindness is quite common affecting about 7.8% of 
                   2488:     #          the male population, but onloy about .65% of the female population.
                   2489:     #       </lang>
                   2490:     #          Red green colour blindness is quite common affecting about 7.8% of 
                   2491:     #          the male population, but onloy about .65% of the female population.
                   2492:     #       <lang which='seniso', other='senisoCA,senisoAU'>
                   2493:     #     </translated>
                   2494:     #
                   2495:     #    renders the correct spelling of color (colour) for people who have specified
                   2496:     #    a preferred language that is one of the British Commonwealth languages
                   2497:     #    even though those are also listed as valid selections for the US english
                   2498:     #    <lang> block.
                   2499:     #
1.397     albertel 2500:     sub start_lang {
                   2501: 	my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
                   2502: 	if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
                   2503: 	    $target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
                   2504: 	    &Apache::lonxml::startredirection();
                   2505: 	}
                   2506: 	return '';
                   2507:     }
                   2508: 
                   2509:     sub end_lang {
                   2510: 	my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
                   2511: 	if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
                   2512: 	    $target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
                   2513: 	    my $result = &Apache::lonxml::endredirection();
                   2514: 	    my $which = &Apache::lonxml::get_param('which',$parstack,
                   2515: 						   $safeeval);
1.431     raeburn  2516:             if ($which=~/\w/) {
                   2517:                 $available_texts{$which} = $result;
                   2518:             }
                   2519:             my $otherlangs = &Apache::lonxml::get_param('other',$parstack,
                   2520:                                                         $safeeval);
                   2521:             foreach my $language (split(/\s*\,\s*/,$otherlangs)) {
                   2522:                 if ($language=~/\w/) {
                   2523:                     $available_texts{$language} = $result;
                   2524:                 }
1.427     bisitz   2525:             }
                   2526: 
1.397     albertel 2527: 	}
                   2528: 	return '';
                   2529:     }
1.500     foxr     2530: }				# end langauge block specific tags.
                   2531: 
1.397     albertel 2532: 
1.170     www      2533: sub start_instructorcomment {
1.201     albertel 2534:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.170     www      2535: 
                   2536:     my $result;
                   2537: 
1.339     albertel 2538:     if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
                   2539: 	$target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
1.468     raeburn  2540:         $result=($env{'request.role'}=~/^(in|cc|co|au|ca|li)/);
1.284     albertel 2541: 	if ( (! $result) or ($env{'form.instructor_comments'} eq 'hide')) {
1.201     albertel 2542: 	    my $skip=&Apache::lonxml::get_all_text("/instructorcomment",
                   2543: 						   $parser,$style);
1.170     www      2544: 	    &Apache::lonxml::debug("skipping ahead :$skip: $$parser[-1]");
                   2545: 	}
                   2546: 	$result='';
                   2547:     } elsif ($target eq 'edit') {
                   2548: 	$result .=&Apache::edit::tag_start($target,$token);
                   2549: 	$result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
                   2550:     }
                   2551:     return $result;
                   2552: }
                   2553: 
                   2554: sub end_instructorcomment {
1.159     albertel 2555:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.160     albertel 2556:     my $result;
                   2557:     if ($target eq "edit") {
                   2558: 	$result.= &Apache::edit::tag_end($target,$token,'');
                   2559:     }
                   2560:     return $result;
1.4       tsai     2561: }
                   2562: 
                   2563: sub start_while {
1.326     albertel 2564:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.159     albertel 2565: 
1.160     albertel 2566:     my $result;
1.339     albertel 2567:     if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
                   2568: 	$target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
1.160     albertel 2569: 	my $code = $token->[2]->{'condition'};
1.4       tsai     2570: 
1.160     albertel 2571: 	push( @Apache::structuretags::whileconds, $code);
                   2572: 	if (!$Apache::lonxml::default_homework_loaded) {
                   2573: 	    &Apache::lonxml::default_homework_load($safeeval);
                   2574: 	}
                   2575: 	my $result = &Apache::run::run($code,$safeeval);
1.326     albertel 2576: 	my $bodytext=&Apache::lonxml::get_all_text("/while",$parser,$style);
1.160     albertel 2577: 	push( @Apache::structuretags::whilebody, $bodytext);
1.161     albertel 2578: 	push( @Apache::structuretags::whileline, $token->[5]);
                   2579: 	&Apache::lonxml::debug("s code $code got -$result-");
1.160     albertel 2580: 	if ( $result ) {
                   2581: 	    &Apache::lonxml::newparser($parser,\$bodytext);
                   2582: 	}
                   2583:     } elsif ($target eq 'edit') {
                   2584: 	$result .=&Apache::edit::tag_start($target,$token);
1.211     albertel 2585: 	$result .=&Apache::edit::text_arg(&mt('Test Condition:'),'condition',
1.160     albertel 2586: 					  $token,40);
                   2587: 	$result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
                   2588:     } elsif ($target eq 'modified') {
                   2589: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                   2590: 						     $safeeval,'condition');
                   2591: 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
1.159     albertel 2592:     }
1.160     albertel 2593:     return $result;
1.4       tsai     2594: }
                   2595: 
                   2596: sub end_while {
1.159     albertel 2597:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.160     albertel 2598:     my $result;
                   2599: 
1.339     albertel 2600:     if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
                   2601: 	$target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
1.160     albertel 2602: 	my $code = pop(@Apache::structuretags::whileconds);
                   2603: 	my $bodytext = pop(@Apache::structuretags::whilebody);
1.161     albertel 2604: 	my $line = pop(@Apache::structuretags::whileline);
                   2605: 	my $return = &Apache::run::run($code,$safeeval);
                   2606: 	my $starttime=time;
                   2607: 	my $error=0;
                   2608: 	while ($return) {
                   2609: 	    if (time-$starttime >
                   2610: 		$Apache::lonnet::perlvar{'lonScriptTimeout'}) {
1.378     albertel 2611: 		$return = 0; $error=1; next;
1.161     albertel 2612: 	    }
                   2613: 	    $result.=&Apache::scripttag::xmlparse($bodytext);
1.380     albertel 2614: 	    if ($target eq 'grade' || $target eq 'answer' ||
                   2615: 		$target eq 'analyze') {
                   2616: 		# grade/answer/analyze should produce no output but if we
                   2617: 		# are redirecting, the redirecter should know what to do
                   2618: 		# with the output
                   2619: 		if (!$Apache::lonxml::redirection) { undef($result); }
                   2620: 	    }
1.161     albertel 2621: 	    $return = &Apache::run::run($code,$safeeval);
                   2622: 	}
1.516     bisitz   2623:         if ($error) {
                   2624:             &Apache::lonxml::error(
                   2625:                 '<pre>'
                   2626:                .&mt('Code ran too long. It ran for more than [_1] seconds.',
                   2627:                         $Apache::lonnet::perlvar{'lonScriptTimeout'})
                   2628:                .&mt('This occurred while running &lt;while&gt; on line [_1].',
                   2629:                         $line)
                   2630:                .'</pre>');
                   2631:         }
1.160     albertel 2632:     } elsif ($target eq "edit") {
                   2633: 	$result.= &Apache::edit::tag_end($target,$token,'');
1.159     albertel 2634:     }
1.160     albertel 2635:     return $result;
1.1       albertel 2636: }
1.6       tsai     2637: 
1.160     albertel 2638: # <randomlist show="1">
1.6       tsai     2639: #  <tag1>..</tag1>
                   2640: #  <tag2>..</tag2>
                   2641: #  <tag3>..</tag3>
1.160     albertel 2642: #  ...
1.6       tsai     2643: # </randomlist>
                   2644: sub start_randomlist {
1.326     albertel 2645:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.159     albertel 2646:     my $result;
1.339     albertel 2647:     if ($target eq 'answer' || $target eq 'grade'   || $target eq 'web' ||
                   2648: 	$target eq 'tex'    || $target eq 'analyze' || $target eq 'webgrade') {
1.331     albertel 2649: 	my $body= &Apache::lonxml::get_all_text("/randomlist",$parser);
1.305     albertel 2650: 	my $b_parser= HTML::LCParser->new(\$body);
                   2651: 	$b_parser->xml_mode(1);
                   2652: 	$b_parser->marked_sections(1);
1.159     albertel 2653: 	my $b_tok;
                   2654: 	my @randomlist;
                   2655: 	my $list_item;
                   2656: 	while($b_tok = $b_parser->get_token() ) {
                   2657: 	    if($b_tok->[0] eq 'S') { # start tag
                   2658: 		# get content of the tag until matching end tag
                   2659: 		# get all text upto the matching tag
                   2660: 		# and push the content into @randomlist
                   2661: 		$list_item = &Apache::lonxml::get_all_text('/'.$b_tok->[1],
                   2662: 							   $b_parser);
                   2663: 		$list_item = "$b_tok->[4]"."$list_item"."</$b_tok->[1]>";
                   2664: 		push(@randomlist,$list_item);
                   2665: 		#  print "<br /><b>START-TAG $b_tok->[1], $b_tok->[4],
                   2666:                 #         $list_item</b>";
                   2667: 	    }
                   2668: 	    if($b_tok->[0] eq 'T') { # text
                   2669: 		# what to do with text in between tags?
                   2670: 		#  print "<b>TEXT $b_tok->[1]</b><br />";
                   2671: 	    }
                   2672: 	    # if($b_tok->[0] eq 'E') { # end tag, should not happen
                   2673: 	    #  print "<b>END-TAG $b_tok->[1]</b><br />";
                   2674: 	    # }
                   2675: 	}
1.303     albertel 2676: 	if (@randomlist) {
                   2677: 	    my @idx_arr = (0 .. $#randomlist);
                   2678: 	    &Apache::structuretags::shuffle(\@idx_arr);
                   2679: 	    my $bodytext = '';
                   2680: 	    my $show=$#randomlist;
                   2681: 	    my $showarg=&Apache::lonxml::get_param('show',$parstack,$safeeval);
                   2682: 	    $showarg--;
                   2683: 	    if ( ($showarg >= 0) && ($showarg < $show) ) { $show = $showarg; }
1.439     raeburn  2684:             if (($target eq 'analyze') && ($env{'form.check_parts_withrandomlist'})) {
                   2685:                 my @currlist;
                   2686:                 my $part = $Apache::inputtags::part;
                   2687:                 if ($part ne '') {
                   2688:                     if (ref($Apache::lonhomework::analyze{'parts_withrandomlist'}) eq 'ARRAY') {
                   2689:                         my @currlist = @{$Apache::lonhomework::analyze{'parts_withrandomlist'}};
                   2690:                         if (!(grep(/^\Q$part\E$/,@currlist))) {
                   2691:                             push(@{$Apache::lonhomework::analyze{'parts_withrandomlist'}},$part);
                   2692:                         }
                   2693:                     } else {
                   2694:                         push(@{$Apache::lonhomework::analyze{'parts_withrandomlist'}},$part);
                   2695:                     }
                   2696:                 }
                   2697:             }
1.526     raeburn  2698: 	    for my $i (0 .. $show) {
                   2699: 		$bodytext .= "$randomlist[ $idx_arr[$i] ]";
1.303     albertel 2700: 	    }
                   2701: 	    &Apache::lonxml::newparser($parser,\$bodytext);
1.159     albertel 2702: 	}
                   2703:     } elsif ($target eq 'edit' ) {
                   2704: 	$result .=&Apache::edit::tag_start($target,$token);
                   2705: 	$result .=&Apache::edit::text_arg('Maximum Tags to Show:','show',
                   2706: 					   $token,5);
                   2707: 	$result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
                   2708:     } elsif ($target eq 'modified' ) {
                   2709: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                   2710: 						     $safeeval,'show');
                   2711: 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
                   2712:     }
                   2713:     return $result;
1.7       tsai     2714: }
                   2715: 
                   2716: sub shuffle {
                   2717:     my $a=shift;
                   2718:     my $i;
1.303     albertel 2719:     if (ref($a) eq 'ARRAY' && @$a) {
1.251     albertel 2720: 	&Apache::response::pushrandomnumber();
1.159     albertel 2721: 	for($i=@$a;--$i;) {
                   2722: 	    my $j=int(&Math::Random::random_uniform() * ($i+1));
                   2723: 	    next if $i == $j;
                   2724: 	    @$a[$i,$j] = @$a[$j,$i];
                   2725: 	}
1.251     albertel 2726: 	&Apache::response::poprandomnumber();
1.7       tsai     2727:     }
1.6       tsai     2728: }
                   2729: 
                   2730: sub end_randomlist {
1.159     albertel 2731:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2732:     my $result;
                   2733:     if ($target eq 'edit' ) {
                   2734: 	$result=&Apache::edit::tag_end($target,$token,
                   2735: 				       'End Randomly Parsed Block');
                   2736:     }
                   2737:     return $result;
1.6       tsai     2738: }
                   2739: 
1.283     albertel 2740: sub ordered_show_check {
                   2741:     my $last_part=$Apache::inputtags::partlist[-2];
                   2742:     my $in_order=
                   2743: 	&Apache::lonnet::EXT('resource.'.$Apache::inputtags::part.'.ordered');
                   2744:     my $in_order_show=1;
                   2745:     if ($last_part ne '0' && lc($in_order) eq 'yes') {
                   2746: 	$in_order_show=&Apache::response::check_status($last_part);
                   2747:     }
                   2748:     return $in_order_show;
                   2749: }
                   2750: 
1.469     www      2751: 
                   2752: sub start_startpartmarker {
                   2753:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2754:     my $result='';
                   2755:     if ($target eq 'edit') {
                   2756:         $result=&Apache::edit::tag_start($target,$token);
                   2757:         $result.=&mt('Marker for the start of a part. Place end marker below to wrap in-between tags into a new part.').'</td></tr>';
                   2758:         $result.=&Apache::edit::end_table();
                   2759: 
                   2760:     } 
                   2761:     return $result;
                   2762: }
                   2763: 
                   2764: sub end_startpartmarker {
                   2765:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2766:     my @result;
                   2767:     if ($target eq 'edit') { $result[1]='no'; }
                   2768:     return @result;
                   2769: }
                   2770: 
                   2771: sub start_endpartmarker {
                   2772:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2773:     my $result='';
                   2774:     if ($target eq 'edit') {
                   2775:         $result=&Apache::edit::tag_start($target,$token);
                   2776:         $result.=&mt('Marker for the end of a part. Place start marker above to wrap in-between tags into a new part.').'</td></tr>';
                   2777:         $result.=&Apache::edit::end_table();
                   2778: 
                   2779:     }
                   2780:     return $result;
                   2781: }
                   2782: 
                   2783: sub end_endpartmarker {
                   2784:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2785:     my @result;
                   2786:     if ($target eq 'edit') { $result[1]='no'; }
                   2787:     return @result;
                   2788: }
                   2789: 
                   2790: 
                   2791: 
                   2792: 
                   2793: 
1.11      albertel 2794: sub start_part {
1.326     albertel 2795:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.321     albertel 2796:     if (!$Apache::lonxml::metamode) {
                   2797: 	&Apache::lonxml::startredirection(); # we'll use redirection to fix up 
                   2798: 	                                     # duedates.
                   2799:     }
1.159     albertel 2800:     my $result='';
1.386     albertel 2801:     my $id= &Apache::lonxml::get_id($parstack,$safeeval);
1.159     albertel 2802:     $Apache::inputtags::part=$id;
1.177     albertel 2803:     push(@Apache::inputtags::partlist,$id);
                   2804:     @Apache::inputtags::response=();
1.159     albertel 2805:     @Apache::inputtags::previous=();
                   2806:     @Apache::inputtags::previous_version=();
1.405     albertel 2807:     &Apache::lonhomework::set_show_problem_status(&get_problem_status($id));
1.403     albertel 2808:     &Apache::response::reset_params();
                   2809: 
1.159     albertel 2810:     my $hidden=&Apache::loncommon::check_if_partid_hidden($Apache::inputtags::part);
1.259     albertel 2811:     my $newtype=&Apache::lonnet::EXT("resource.$id.type");
                   2812:     if ($newtype) { $Apache::lonhomework::type=$newtype; }
1.528     raeburn  2813:     if ($Apache::lonhomework::type eq 'randomizetry') {
                   2814:         my $rndseed=&setup_rndseed($safeeval,$target);
                   2815:         if (($target eq 'grade') && &Apache::response::submitted()) {
1.529     raeburn  2816:             $Apache::lonhomework::results{"resource.$id.rndseed"}=$rndseed;
1.528     raeburn  2817:         }
                   2818:     } elsif (($target eq 'grade') && &Apache::response::submitted()) {
1.529     raeburn  2819:         $Apache::lonhomework::results{"resource.$id.rndseed"}=$Apache::lonhomework::rawrndseed;
1.528     raeburn  2820:     }
1.283     albertel 2821:     my $in_order_show=&ordered_show_check();
1.214     albertel 2822:     my $expression='$external::part=\''.$Apache::inputtags::part.'\';';
1.259     albertel 2823:     $expression.='$external::type=\''.$Apache::lonhomework::type.'\';';
1.209     albertel 2824:     &Apache::run::run($expression,$safeeval);
1.159     albertel 2825: 
                   2826:     if ($target eq 'meta') {
1.224     www      2827: 	my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval);
                   2828: 	return &Apache::response::mandatory_part_meta.
                   2829: 	       &Apache::response::meta_parameter_write('display','string',$display,'Part Description');
1.159     albertel 2830:     } elsif ($target eq 'web' || $target eq 'grade' ||
                   2831: 	     $target eq 'answer' || $target eq 'tex') {
1.283     albertel 2832: 	if ($hidden || !$in_order_show) {
1.326     albertel 2833: 	    my $bodytext=&Apache::lonxml::get_all_text("/part",$parser,$style);
1.159     albertel 2834: 	} else {
                   2835: 	    my ($status,$accessmsg) = &Apache::lonhomework::check_access($id);
                   2836: 	    push (@Apache::inputtags::status,$status);
                   2837: 	    my $expression='$external::datestatus="'.$status.'";';
                   2838: 	    $expression.='$external::gradestatus="'.$Apache::lonhomework::history{"resource.$id.solved"}.'";';
                   2839: 	    &Apache::run::run($expression,$safeeval);
1.284     albertel 2840: 	    if ($env{'request.state'} eq 'construct') {
1.241     albertel 2841: 		&set_problem_state($Apache::inputtags::part); 
1.240     albertel 2842: 	    }
1.216     albertel 2843: 	    if (( $status eq 'CLOSED' ) ||
                   2844: 		( $status eq 'UNCHECKEDOUT') ||
1.252     albertel 2845: 		( $status eq 'NOT_YET_VIEWED') ||
1.216     albertel 2846: 		( $status eq 'BANNED') ||
                   2847: 		( $status eq 'UNAVAILABLE') ||
                   2848: 		( $status eq 'INVALID_ACCESS')) {
1.326     albertel 2849: 		my $bodytext=&Apache::lonxml::get_all_text("/part",$parser,
                   2850: 							   $style);
1.159     albertel 2851: 		if ( $target eq "web" ) {
1.211     albertel 2852: 		    $result="<br />".&mt('Part is not open to be viewed. It')." $accessmsg<br />";
1.159     albertel 2853: 		} elsif ( $target eq 'tex' ) {
1.284     albertel 2854: 		    if (not $env{'form.problem_split'}=~/yes/) {
1.211     albertel 2855: 			$result="\\end{minipage}\\vskip 0 mm ".&mt('Part is not open to be viewed. It')." $accessmsg \\\\\\begin{minipage}{\\textwidth}";
1.195     sakharuk 2856: 		    } else {
1.211     albertel 2857: 			$result="\\vskip 0 mm ".&mt('Part is not open to be viewed. It')." $accessmsg \\\\";
1.195     sakharuk 2858: 		    }
1.159     albertel 2859: 		}
                   2860: 	    } else {
                   2861: 		if ($target eq 'tex') {
1.284     albertel 2862: 		    if (not $env{'form.problem_split'}=~/yes/) {
1.264     sakharuk 2863: 			if ($$tagstack[-2] eq 'td') {
1.388     foxr     2864: 			    $result.='\noindent \begin{minipage}{\textwidth}\noindent';
1.264     sakharuk 2865: 			} else {
                   2866: 			    $result.='\noindent \end{minipage}\vskip 0 mm \noindent \begin{minipage}{\textwidth}\noindent';
                   2867: 			}
1.195     sakharuk 2868: 		    }
1.159     albertel 2869: 		    my $weight = &Apache::lonnet::EXT("resource.$id.weight");
1.284     albertel 2870: 		    my $allkeys=&Apache::lonnet::metadata($env{'request.uri'},'packages');
1.526     raeburn  2871: 		    my @allkeys = split(/,/,$allkeys);
1.222     sakharuk 2872: 		    my $allow_print_points = 0;
                   2873: 		    foreach my $partial_key (@allkeys) {
1.230     albertel 2874: 			if ($partial_key=~m/^part_(.*)$/) {
1.222     sakharuk 2875: 			    if ($1 ne '0') {$allow_print_points=1;}
                   2876: 			}
                   2877: 		    }
1.275     albertel 2878: 		    my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries");
                   2879: 		    if (defined($maxtries) && $maxtries < 0) {
                   2880: 			$allow_print_points=0;
                   2881: 		    }
1.302     albertel 2882: 		    if (lc($env{'course.'.$env{'request.course.id'}.
                   2883: 				    '.disableexampointprint'}) eq 'yes') {
                   2884: 			$allow_print_points=0;
                   2885: 		    }
1.463     foxr     2886: 		    if (($Apache::lonhomework::type eq 'exam') && ($allow_print_points)) { 
1.492     christia 2887: 			$result .= '\vskip 10mm\fbox{\textit{'.&mt('[quant,_1,pt,pt]',$weight ).'}}';
1.463     foxr     2888: 
                   2889: 		    }
1.233     www      2890: 		} elsif ($target eq 'web') {
1.479     raeburn  2891:                     if ($status eq 'CAN_ANSWER') {
                   2892:                         my $problemstatus = &get_problem_status($Apache::inputtags::part); 
                   2893:                         my $probrandomize = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[0].type");
                   2894:                         my $probrandtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[0].randomizeontries");
                   2895:                         my $num = scalar(@Apache::inputtags::partlist)-1;
                   2896:                         if ($probrandomize eq 'randomizetry') {
                   2897:                             if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") ne 'randomizetry') {
                   2898:                                 $result .= &randomizetry_part_header($problemstatus,'none',$num);
                   2899:                             } else {
                   2900:                                 my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
                   2901:                                 if ($probrandtries ne $reqtries) {
                   2902:                                     $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);
                   2903:                                 }
                   2904:                             }
                   2905:                         } elsif (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") eq 'randomizetry') {
                   2906:                             my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
                   2907:                             $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);
                   2908:                         }
                   2909:                     }
1.475     raeburn  2910: 		    $result.='<a name="'.&escape($Apache::inputtags::part).'" ></a>';
1.159     albertel 2911: 		}
                   2912: 	    }
                   2913: 	}
                   2914:     } elsif ($target eq 'edit') {
                   2915: 	$result.=&Apache::edit::tag_start($target,$token);
                   2916: 	$result.=&Apache::edit::text_arg('Part ID:','id',$token).
                   2917: 	    &Apache::loncommon::help_open_topic("Part_Tag_Edit_Help").
1.224     www      2918: 	    '&nbsp;&nbsp;'.
                   2919: &Apache::edit::text_arg('Displayed Part Description:','display',$token).
1.159     albertel 2920: 		&Apache::edit::end_row().&Apache::edit::start_spanning_row();
                   2921:     } elsif ($target eq 'modified') {
                   2922: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
1.225     albertel 2923: 						     $safeeval,'id','display');
1.159     albertel 2924: 	if ($constructtag) {
1.225     albertel 2925: 	    #limiting ids to only letters numbers, and space
1.224     www      2926: 	    $token->[2]->{'id'}=~s/[^A-Za-z0-9 ]//gs;
1.159     albertel 2927: 	    $result = &Apache::edit::rebuild_tag($token);
                   2928: 	}
                   2929:     }
                   2930:     return $result;
1.11      albertel 2931: }
                   2932: 
                   2933: sub end_part {
1.159     albertel 2934:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2935:     &Apache::lonxml::debug("in end_part $target ");
                   2936:     my $status=$Apache::inputtags::status['-1'];
                   2937:     my $hidden=&Apache::loncommon::check_if_partid_hidden($Apache::inputtags::part);
1.283     albertel 2938:     my $in_order_show=&ordered_show_check();
1.321     albertel 2939:     my $result;
                   2940:     if (!$Apache::lonxml::metamode) {
                   2941: 	$result = &Apache::lonxml::endredirection(); # started in &start_part
1.329     albertel 2942: 	$Apache::lonxml::post_evaluate=0;
1.321     albertel 2943:     }
1.312     albertel 2944:     if ($target eq 'grade') {
1.249     albertel 2945: 	if (($status eq 'CAN_ANSWER' || $Apache::lonhomework::scantronmode) &&
1.283     albertel 2946: 	    !$hidden && $in_order_show) {
1.311     foxr     2947: 	    $result.=&Apache::inputtags::grade;
1.249     albertel 2948: 	} else {
                   2949: 	    # move any submission data to .hidden
                   2950: 	    &Apache::inputtags::hidealldata($Apache::inputtags::part);
                   2951: 	}
1.283     albertel 2952:     } elsif (($target eq 'web' || $target eq 'tex') &&
                   2953: 	     !$hidden && $in_order_show) {
1.159     albertel 2954: 	my $gradestatus=&Apache::inputtags::gradestatus($Apache::inputtags::part,
                   2955: 							$target);
1.490     raeburn  2956: 	if (($Apache::lonhomework::type eq 'exam' && $target eq 'tex') ||
                   2957:              ($env{'form.grade_imsexport'})) {
1.212     albertel 2958: 	    $gradestatus='';
                   2959: 	}
1.311     foxr     2960: 	$result.=$gradestatus;
1.265     sakharuk 2961: 	if ($$tagstack[-2] eq 'td' and $target eq 'tex') {$result.='\end{minipage}';} 
1.181     albertel 2962:     } elsif ($target eq 'edit') {
1.311     foxr     2963: 	$result.=&Apache::edit::end_table();
1.322     albertel 2964:     } elsif ($target eq 'modified') {
                   2965: 	 $result .= $token->[2];
1.159     albertel 2966:     }
                   2967:     pop @Apache::inputtags::status;
                   2968:     $Apache::inputtags::part='';
1.295     albertel 2969:     $Apache::lonhomework::type = $Apache::lonhomework::default_type;
1.159     albertel 2970:     return $result;
1.11      albertel 2971: }
1.1       albertel 2972: 
1.25      albertel 2973: sub start_preduedate {
1.326     albertel 2974:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.339     albertel 2975:     if ($target eq 'web' || $target eq 'grade'    || $target eq 'answer' ||
                   2976: 	$target eq 'tex' || $target eq 'webgrade') {
1.236     albertel 2977: 	&Apache::lonxml::debug("State in preduedate is ". $Apache::inputtags::status['-1']);
1.300     albertel 2978: 	if (!$Apache::lonhomework::scantronmode &&
                   2979: 	    $Apache::inputtags::status['-1'] ne 'CAN_ANSWER' &&
1.236     albertel 2980: 	    $Apache::inputtags::status['-1'] ne 'CANNOT_ANSWER') {
                   2981: 	    &Apache::lonxml::debug("Wha? ". ($Apache::inputtags::status['-1'] ne 'SHOW_ANSWER'));
1.326     albertel 2982: 	    &Apache::lonxml::get_all_text("/preduedate",$parser,$style);
1.159     albertel 2983: 	}
1.24      albertel 2984:     }
1.159     albertel 2985:     return '';
1.24      albertel 2986: }
                   2987: 
1.25      albertel 2988: sub end_preduedate {
1.159     albertel 2989:     return '';
1.24      albertel 2990: }
                   2991: 
1.369     foxr     2992: # In all the modes where <postanswerdate> text is 
                   2993: # displayable,  all we do is eat up the text between the start/stop
                   2994: # tags if the conditions are not right to display it.
1.25      albertel 2995: sub start_postanswerdate {
1.326     albertel 2996:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.370     foxr     2997:     my $pav = &Apache::lonnet::allowed('pav', $env{'request.course.id'}) ||
                   2998: 	&Apache::lonnet::allowed('pav',
                   2999: 			   $env{'request.course.id'}.'/'.$env{'request.course.sec'});
1.369     foxr     3000:     if ($target eq 'web' || $target eq 'grade' || $target eq 'webgrade' ||
1.370     foxr     3001: 	$target eq 'tex' ) {
1.300     albertel 3002: 	if ($Apache::lonhomework::scantronmode ||
1.370     foxr     3003: 	    $Apache::inputtags::status['-1'] ne 'SHOW_ANSWER' ||
                   3004: 	    (($target eq 'tex') && !$pav)) {
1.326     albertel 3005: 	    &Apache::lonxml::get_all_text("/postanswerdate",$parser,$style);
1.159     albertel 3006: 	}
                   3007:     }
                   3008:     return '';
1.24      albertel 3009: }
                   3010: 
1.25      albertel 3011: sub end_postanswerdate {
1.159     albertel 3012:     return '';
1.24      albertel 3013: }
                   3014: 
1.25      albertel 3015: sub start_notsolved {
1.326     albertel 3016:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.159     albertel 3017:     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
1.339     albertel 3018: 	$target eq 'tex' || $target eq 'webgrade') {
1.159     albertel 3019: 	my $gradestatus=$Apache::lonhomework::history{"resource.$Apache::inputtags::part.solved"};
                   3020: 	&Apache::lonxml::debug("not solved has :$gradestatus:");
1.239     albertel 3021: 	if ($gradestatus =~ /^correct/ &&
                   3022: 	    &Apache::response::show_answer()) {
1.159     albertel 3023: 	    &Apache::lonxml::debug("skipping");
1.326     albertel 3024: 	    &Apache::lonxml::get_all_text("/notsolved",$parser,$style);
1.159     albertel 3025: 	}
1.24      albertel 3026:     }
1.159     albertel 3027:     return '';
1.24      albertel 3028: }
                   3029: 
1.25      albertel 3030: sub end_notsolved {
1.159     albertel 3031:     return '';
1.24      albertel 3032: }
                   3033: 
                   3034: sub start_solved {
1.326     albertel 3035:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.159     albertel 3036:     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
                   3037: 	$target eq 'tex') {
                   3038: 	my $gradestatus=$Apache::lonhomework::history{"resource.$Apache::inputtags::part.solved"};
1.239     albertel 3039: 	if ($gradestatus !~ /^correct/ ||
                   3040: 	    !&Apache::response::show_answer()) {
1.326     albertel 3041: 	    &Apache::lonxml::get_all_text("/solved",$parser,$style);
1.159     albertel 3042: 	}
1.24      albertel 3043:     }
1.159     albertel 3044:     return '';
1.24      albertel 3045: }
                   3046: 
                   3047: sub end_solved {
1.248     albertel 3048:     return '';
                   3049: }
                   3050: 
                   3051: sub start_problemtype {
1.326     albertel 3052:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.248     albertel 3053:     my $result;
1.339     albertel 3054:     if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
                   3055: 	$target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
1.248     albertel 3056: 	my $mode=lc(&Apache::lonxml::get_param('mode',$parstack,$safeeval));
                   3057: 	if (!defined($mode)) { $mode='show'; }
                   3058: 	my $for=&Apache::lonxml::get_param('for',$parstack,$safeeval);
                   3059: 	my $found=0;
                   3060: 	foreach my $type (split(',',$for)) {
                   3061: 	    if ($Apache::lonhomework::type eq lc($type)) { $found=1; }
                   3062: 	}
                   3063: 	if ($mode eq 'show' && !$found) {
1.326     albertel 3064: 	    &Apache::lonxml::get_all_text("/problemtype",$parser,$style);
1.248     albertel 3065: 	}
                   3066: 	if ($mode eq 'hide' && $found) {
1.326     albertel 3067: 	    &Apache::lonxml::get_all_text("/problemtype",$parser,$style);
1.248     albertel 3068: 	}
                   3069:     } elsif ($target eq 'edit') {
                   3070: 	$result .=&Apache::edit::tag_start($target,$token);
                   3071: 	$result.=&Apache::edit::select_arg('Mode:','mode',
                   3072: 					   [['show','Show'],
                   3073: 					    ['hide','Hide']]
                   3074: 					   ,$token);
                   3075: 	$result .=&Apache::edit::checked_arg('When used as type(s):','for',
1.511     bisitz   3076: 					     [ ['exam','Bubblesheet Exam/Quiz Problem'],
1.248     albertel 3077: 					       ['survey','Survey'],
1.465     raeburn  3078:                                                ['surveycred','Survey (with credit)'],
                   3079:                                                ['anonsurvey','Anonymous Survey'],
                   3080:                                                ['anonsurveycred','Anonymous Survey (with credit)'],
1.428     raeburn  3081: 					       ['problem','Homework Problem'],
1.479     raeburn  3082:                                                ['practice','Practice Problem'],
                   3083:                                                ['randomizetry','New Randomization Each Try'] ]
1.248     albertel 3084: 					     ,$token);
                   3085: 	$result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
                   3086:     } elsif ($target eq 'modified') {
                   3087: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                   3088: 						     $safeeval,'mode','for');
                   3089: 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
                   3090:     }
                   3091:     return $result;
                   3092: }
                   3093: 
                   3094: sub end_problemtype {
1.159     albertel 3095:     return '';
1.24      albertel 3096: }
1.34      albertel 3097: 
                   3098: sub start_startouttext {
1.159     albertel 3099:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   3100:     my @result=(''.'');
                   3101:     if ($target eq 'edit' || $target eq 'modified' ) { @result=('','no'); }
1.404     albertel 3102:     
                   3103:     my $nesting = 
                   3104: 	&Apache::lonxml::set_state('outtext',
                   3105: 				   &Apache::lonxml::get_state('outtext')+1);
                   3106:     if ($nesting > 1 && $env{'request.state'} eq 'construct') {
                   3107: 	&Apache::lonxml::error("Nesting of &lt;startouttext /&gt; not allowed, on line ".$token->[5]);
                   3108:     }
1.159     albertel 3109:     return (@result);
1.34      albertel 3110: }
1.159     albertel 3111: 
1.34      albertel 3112: sub end_startouttext {
1.326     albertel 3113:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.159     albertel 3114:     my $result='';
                   3115:     my $text='';
                   3116:     if ($target eq 'edit') {
1.424     foxr     3117: 	my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth;
1.326     albertel 3118: 	$text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);
1.527     golterma 3119:         $result.=&Apache::edit::start_table($token)."<tr><td>".&Apache::loncommon::insert_folding_button()
                   3120:                  ." ".&mt('Text Block')."</td>"
1.438     bisitz   3121:                  .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
1.437     raeburn  3122:                  .&Apache::edit::deletelist($target,$token)
1.474     raeburn  3123:                  .'</span></td>'
1.515     golterma 3124: 	         .'<td><span id="math_'.$areaid.'">'
1.474     raeburn  3125: 		 .&Apache::lonhtmlcommon::dragmath_button($areaid,1)
1.512     bisitz   3126: 		 .'</span></td>'
1.474     raeburn  3127: 		 .'<td>'
                   3128: 		 .&Apache::edit::insertlist($target,$token)
                   3129: 		 .'</td>'
1.515     golterma 3130: 	         .'<td class="LC_edit_problem_latexhelper">' .
1.474     raeburn  3131: 	         &Apache::loncommon::helpLatexCheatsheet().
1.159     albertel 3132: 		 &Apache::edit::end_row().
1.362     albertel 3133:                  &Apache::edit::start_spanning_row()."\n".
1.255     www      3134: 		 &Apache::edit::editfield($token->[1],$text,"",80,8,1);
1.159     albertel 3135:     }
                   3136:     if ($target eq 'modified') {
1.219     albertel 3137: 	$result='<startouttext />'.&Apache::edit::modifiedfield("endouttext",$parser);
1.159     albertel 3138:     }
                   3139:     if ($target eq 'tex') {
                   3140: 	$result .= '\noindent ';
                   3141:     }
                   3142:     return $result;
1.34      albertel 3143: }
1.159     albertel 3144: 
1.34      albertel 3145: sub start_endouttext {
1.159     albertel 3146:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   3147:     my $result='';
                   3148:     if ($target eq "edit" ) { $result="</td></tr>".&Apache::edit::end_table()."\n"; }
                   3149:     if ($target eq "modified") {
                   3150: 	$result='<endouttext />'.
1.377     albertel 3151: 	    &Apache::edit::handle_insertafter('startouttext');
                   3152:     }
1.404     albertel 3153: 
                   3154:     my $nesting = 
                   3155: 	&Apache::lonxml::set_state('outtext',
                   3156: 				   &Apache::lonxml::get_state('outtext')-1);
                   3157:     if ($nesting < 0 && $env{'request.state'} eq 'construct') {
                   3158: 	&Apache::lonxml::error(" Extraneous &lt;endouttext /&gt; not allowed on line ".$token->[5]);
                   3159: 	&Apache::lonxml::set_state('outtext', 0);
                   3160:     }
1.159     albertel 3161:     return $result;
1.34      albertel 3162: }
1.159     albertel 3163: 
1.34      albertel 3164: sub end_endouttext {
1.159     albertel 3165:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   3166:     my @result=('','');
                   3167:     if ($target eq "edit" || $target eq 'modified') { @result=('','no'); }
                   3168:     return (@result);
1.34      albertel 3169: }
1.159     albertel 3170: 
1.45      albertel 3171: sub delete_startouttext {
1.326     albertel 3172:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
                   3173:     #  my $text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);
1.159     albertel 3174:     my $text=$$parser['-1']->get_text("/endouttext");
                   3175:     my $ntoken=$$parser['-1']->get_token();
                   3176:     &Apache::lonxml::debug("Deleting :$text: and :$ntoken->[0]:$ntoken->[1]:$ntoken->[2]: for startouttext");
                   3177:     &Apache::lonxml::end_tag($tagstack,$parstack,$ntoken);
                   3178:     # Deleting 2 parallel tag pairs, but we need the numbers later to look like
                   3179:     # they did the last time round
                   3180:     &Apache::lonxml::increasedepth($ntoken);
                   3181:     &Apache::lonxml::decreasedepth($ntoken);
                   3182:     return 1;
1.193     www      3183: }
                   3184: 
                   3185: sub start_simpleeditbutton {
                   3186:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   3187:     my $result='';
1.284     albertel 3188:     if (($env{'form.simple_edit_button'} ne 'off') &&
1.273     albertel 3189: 	($target eq 'web') &&
1.330     albertel 3190:         (&Apache::lonnet::allowed('mdc',$env{'request.course.id'}))) {
1.284     albertel 3191:         my $url=$env{'request.noversionuri'};
1.193     www      3192:         $url=~s/\?.*$//;
1.367     albertel 3193: 	my ($symb) = &Apache::lonnet::whichuser();
1.451     bisitz   3194: #       Warning makes more sense and is more important on edit screen
1.442     bisitz   3195: #       $result='<p class="LC_warning">'
                   3196: #              .&mt('Note: it can take up to 10 minutes for changes to take effect for all users.')
                   3197: #              .&Apache::loncommon::help_open_topic('Caching')
                   3198: #              .'</p>';
1.486     www      3199:         $result.=&Apache::loncommon::head_subbox(
                   3200:                  &Apache::lonhtmlcommon::start_funclist()
1.451     bisitz   3201:                 .&Apache::lonhtmlcommon::add_item_funclist(
                   3202:                      '<a href="'.$url.'/smpedit?symb='.&escape($symb).'">'
                   3203:                     .&mt('Edit').'</a>')
1.486     www      3204:                 .&Apache::lonhtmlcommon::end_funclist());
1.442     bisitz   3205: 
1.193     www      3206:     }
                   3207:     return $result;
                   3208: }
                   3209: 
                   3210: sub end_simpleeditbutton {
                   3211:     return '';
1.45      albertel 3212: }
1.34      albertel 3213: 
1.428     raeburn  3214: sub practice_problem_header {
                   3215:     return '<span class="LC_info"><h3>'.&mt('Practice Problem').'</h3></span>'.
                   3216:            '<span class="LC_info">'.&mt('Submissions are not permanently recorded').
                   3217:            '</span>';
                   3218: }
                   3219: 
1.479     raeburn  3220: sub randomizetry_problem_header {
                   3221:     my ($problemstatus,$reqtries) = @_;
                   3222:     my ($header,$text);
                   3223:     if ($reqtries > 1) {
                   3224:         $header = &mt('New Problem Variation After Every [quant,_1,Try,Tries]',$reqtries);
                   3225:         if (($problemstatus eq 'no') ||
                   3226:             ($problemstatus eq 'no_feedback_ever')) {
                   3227:             $text = &mt('A new variation will be generated after every [quant,_1,try,tries], until the tries limit is reached.',$reqtries);
                   3228:         } else {
                   3229:             $text = &mt('A new variation will be generated after every [quant,_1,try,tries], until correct or tries limit is reached.',$reqtries);
                   3230:         }
                   3231:     } else {
                   3232:         $header = &mt('New Problem Variation Each Try');
                   3233:         if (($problemstatus eq 'no') ||
                   3234:             ($problemstatus eq 'no_feedback_ever')) {
                   3235:             $text = &mt('A new variation will be generated after each try until the tries limit is reached.');
                   3236: 
                   3237:         } else {
                   3238:             $text = &mt('A new variation will be generated after each try until correct or tries limit is reached.');
                   3239:         }
                   3240:     }
                   3241:     return '<span class="LC_info"><h3>'.$header.'</h3></span>'.
                   3242:            '<span class="LC_info">'.$text.'</span><hr />';
                   3243: }
                   3244: 
                   3245: sub randomizetry_part_header {
                   3246:     my ($problemstatus,$reqtries,$num) = @_;
                   3247:     my ($header,$text);
                   3248:     if ($reqtries eq 'none') {
                   3249:         $header = &mt('No Question Variation');
                   3250:         $text = &mt('For this question there will no new variation after a try.');
                   3251:     } elsif ($reqtries > 1) {
                   3252:         $header = &mt('New Question Variation After Every [quant,_1,Try,Tries]',$reqtries);
                   3253:         if (($problemstatus eq 'no') ||
                   3254:             ($problemstatus eq 'no_feedback_ever')) {
                   3255:             $text = &mt('For this question a new variation will be generated after every [quant,_1,try,tries], until the tries limit is reached.',$reqtries);
                   3256:         } else {
                   3257:             $text = &mt('For this question a new variation will be generated after every [quant,_1,try,tries], until correct or tries limit is reached.',$reqtries);
                   3258:         }
                   3259:     } else {
                   3260:         $header = &mt('New Question Variation For Each Try');
                   3261:         if (($problemstatus eq 'no') ||
                   3262:             ($problemstatus eq 'no_feedback_ever')) {
                   3263:             $text =  &mt('For this question a new variation will be generated after each try until the tries limit is reached.');
                   3264:         } else {
                   3265:             $text = &mt('For this question a new variation will be generated after each try until correct or tries limit is reached.');
                   3266:         }
                   3267:     }
                   3268:     my $output;
                   3269:     if ($num > 1) {
                   3270:         $output .= '<hr />';
                   3271:     }
                   3272:     $output .=  '<span class="LC_info"><h4>'.$header.'</h4></span>'.
                   3273:                   '<span class="LC_info">'.$text.'</span><br /><br />';
                   3274:     return $output;
                   3275: }
                   3276: 
1.1       albertel 3277: 1;
                   3278: __END__
1.435     jms      3279: 
                   3280: =pod
                   3281: 
                   3282: =back
                   3283: 
                   3284: =cut

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