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

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

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