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

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

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