--- loncom/homework/structuretags.pm 2007/11/13 23:01:05 1.411 +++ loncom/homework/structuretags.pm 2013/06/05 15:37:26 1.512.2.3 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # definition of tags that give a structure to a document # -# $Id: structuretags.pm,v 1.411 2007/11/13 23:01:05 albertel Exp $ +# $Id: structuretags.pm,v 1.512.2.3 2013/06/05 15:37:26 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -27,6 +27,29 @@ # ### +=pod + +=head1 NAME + +Apache::structuretags + +=head1 SYNOPSIS + + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + + +=head1 NOTABLE SUBROUTINES + +=over + +=item + +=back + +=cut + package Apache::structuretags; @@ -36,15 +59,116 @@ use Apache::File(); use Apache::lonmenu; use Apache::lonlocal; use Apache::lonxml; +use Apache::londefdef; use Apache::lonenc(); +use Apache::loncommon(); use Time::HiRes qw( gettimeofday tv_interval ); use lib '/home/httpd/lib/perl/'; use LONCAPA; BEGIN { - &Apache::lonxml::register('Apache::structuretags',('block','languageblock','translated','instructorcomment','while','randomlist','problem','library','web','tex','part','preduedate','postanswerdate','solved','notsolved','problemtype','startouttext','endouttext','simpleeditbutton','definetag')); + &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')); +} + + +#--------------------------------------------------------------------------------- +# +# This section of code deals with hyphenation management. +# We must do three things: +# - keep track fo the desired languages to alter the header. +# - provide hyphenation selection as needed by each language that appears in the +# text. +# - Provide the header text needed to make available the desired hyphenations. +# +# + +# Hash whose keys are the languages encountered in the document/resource. +# + +my %languages_required; +## +# Given a language selection as input returns a chunk of LaTeX that +# selects the required hyphenator. +# +# @param language - the language being selected. +# @return string +# @retval The LaTeX needed to select the hyphenation appropriate to the language. +# +sub select_hyphenation { + my $language = shift; + + $language = &Apache::loncommon::latexlanguage($language); # Translate -> latex language. + + # If there is no latex language there's not much we can do: + + if ($language) { + &require_language($language); + my $babel_hyphenation = "\\selectlanguage{$language}"; + + return $babel_hyphenation; + } else { + return ''; + } +} +## +# Selects hyphenation based on the current problem metadata. +# This requires that +# - There is a language metadata item set for the problem. +# - The language has a latex/babel hyphenation. +# +# @note: Uses &Apache::lonxml::request to locate the Uri associated with +# this problem. +# @return string (possibly empty). +# @retval If not empty an appropriate \selectlanguage{} directive. +# +sub select_metadata_hyphenation { + my $uri = $Apache::lonxml::request->uri; + my $language = &Apache::lonnet::metadata($uri, 'language'); + my $latex_language = &Apache::loncommon::latexhyphenation($language); + if ($latex_language) { + return '\selectlanguage{'.$latex_language."}\n"; + } + return ''; # no latex hyphenation or no lang metadata. } + +## +# Clears the set of languages required by the document being rendered. +# +sub clear_required_languages { + %languages_required = (); +} +## +# Allows an external client of this module to register a need for a language: +# +# @param LaTeX language required: +# +sub require_language { + my $language = shift; + $languages_required{$language} = 1; +} + +## +# Provides the header for babel that indicates the languages +# the document requires. +# @return string +# @retval \usepackage[lang1,lang2...]{babel} +# @retval '' if there are no languages_required. +sub languages_header { + my $header =''; + my @languages = (keys(%languages_required)); + + # Only generate the header if there are languages: + + if (scalar @languages) { + my $language_list = join(',', (@languages)); + $header = '\usepackage['.$language_list."]{babel}\n"; + } + return $header; +} + +#---------------------------------------------------------------------------------- + sub start_web { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; if ($target ne 'edit' && $target ne 'modified') { @@ -74,7 +198,14 @@ sub start_tex { if ($target ne 'edit' && $target ne 'modified') { my $bodytext=&Apache::lonxml::get_all_text("/tex",$parser,$style); if ($target eq 'tex') { - return $bodytext.' '; + + # If inside a table, occurrences of \\ must be removed; + # else the table blows up. + + if (&Apache::londefdef::is_inside_of($tagstack, "table")) { + $bodytext =~ s/\\\\//g; + } + return $bodytext.'{}'; } } elsif ($target eq "edit" ) { my $bodytext = @@ -94,10 +225,20 @@ sub end_tex { sub homework_js { return &Apache::loncommon::resize_textarea_js(). + &setmode_javascript(). <<'JS'; JS } +sub setmode_javascript { + return <<"ENDSCRIPT"; + +ENDSCRIPT +} + sub page_start { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$name, $extra_head)=@_; @@ -133,7 +288,72 @@ sub page_start { $parstack,$parser,$safeeval); } - $extra_head .= &homework_js(); + $extra_head .= &homework_js(). + &Apache::lonhtmlcommon::dragmath_js("EditMathPopup"); + if (&Apache::lonhtmlcommon::htmlareabrowser()) { + my %textarea_args = ( + dragmath => 'math', + ); + $extra_head .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args); + } + my $is_task = ($env{'request.uri'} =~ /\.task$/); + my $needs_upload; + my ($symb)= &Apache::lonnet::whichuser(); + my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb); + if ($is_task) { + $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js(); + } else { + if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.uploadedfiletypes") ne '') { + unless ($env{'request.state'} eq 'construct') { + my $navmap = Apache::lonnavmaps::navmap->new(); + if (ref($navmap)) { + my $mapres = $navmap->getResourceByUrl($map); + my $is_page; + if (ref($mapres)) { + $is_page = $mapres->is_page(); + } + unless ($is_page) { + $needs_upload = 1; + } + } + } + } else { + unless ($env{'request.state'} eq 'construct') { + my $navmap = Apache::lonnavmaps::navmap->new(); + if (ref($navmap)) { + my $mapres = $navmap->getResourceByUrl($map); + my $is_page; + if (ref($mapres)) { + $is_page = $mapres->is_page(); + } + unless ($is_page) { + my $res = $navmap->getBySymb($symb); + if (ref($res)) { + my $partlist = $res->parts(); + if (ref($partlist) eq 'ARRAY') { + foreach my $part (@{$partlist}) { + my @types = $res->responseType($part); + my @ids = $res->responseIds($part); + for (my $i=0; $i < scalar(@ids); $i++) { + if ($types[$i] eq 'essay') { + my $partid = $part.'_'.$ids[$i]; + if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') { + $needs_upload = 1; + last; + } + } + } + } + } + } + } + } + } + } + if ($needs_upload) { + $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js(); + } + } my %body_args; if (defined($found{'html'})) { @@ -153,14 +373,28 @@ sub page_start { } } + my $pageheader = ''; if (defined($found{'body'})) { $body_args{'skip_phases'}{'body'}=1; } elsif (!defined($found{'body'}) && $env{'request.state'} eq 'construct') { if ($target eq 'web' || $target eq 'edit') { - if ($env{'environment.remote'} ne 'off') { - $body_args{'only_body'} = 1; - } + # Breadcrumbs for Authoring Space + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb({ + 'text' => 'Authoring Space', + 'href' => &Apache::loncommon::authorspace($env{'request.uri'}), + }); + # breadcrumbs (and tools) will be created + # in start_page->bodytag->innerregister + +# FIXME Where are we? +# &Apache::lonhtmlcommon::add_breadcrumb({ +# 'text' => 'Problem Editing', # 'Problem Testing' +# 'href' => '', +# }); + $pageheader =&Apache::loncommon::head_subbox( + &Apache::loncommon::CSTR_pageheader()); } } elsif (!defined($found{'body'})) { my %add_entries; @@ -172,48 +406,53 @@ sub page_start { my $bgcolor=&Apache::lonxml::get_param('bgcolor',$parstack, $safeeval); - if ($bgcolor eq '' ) { $bgcolor = '#FFFFFF'; } + if ($bgcolor eq '' ) { $bgcolor = '#FFFFFF'; } - $body_args{'bgcolor'} = $bgcolor; - $body_args{'no_title'} = 1; - $body_args{'force_register'} = 1; - $body_args{'add_entries'} = \%add_entries; - if ($env{'environment.remote'} eq 'off' - && $env{'request.state'} eq 'construct') { - $body_args{'only_body'} = 1; - } + $body_args{'bgcolor'} = $bgcolor; + # $body_args{'no_title'} = 1; + $body_args{'force_register'} = 1; + $body_args{'add_entries'} = \%add_entries; + if ( $env{'request.state'} eq 'construct') { + $body_args{'only_body'} = 1; + } } $body_args{'no_auto_mt_title'} = 1; my $page_start = &Apache::loncommon::start_page($name,$extra_head, \%body_args); - + $page_start .= $pageheader; if (!defined($found{'body'}) && $env{'request.state'} ne 'construct' && ($target eq 'web' || $target eq 'webgrade')) { my ($symb,undef,undef,undef,$publicuser)= &Apache::lonnet::whichuser(); - if ($symb eq '' && !$publicuser) { - my $help = &Apache::loncommon::help_open_topic("Ambiguous_Reference"); - $help=&mt("Browsing resource, all submissions are temporary.")."
"; - $page_start .= $help; - } + if ($symb eq '' && !$publicuser) { + $page_start .= '

' + .&mt('Browsing resource, all submissions are temporary.') + .'

'; + } } if (!defined($found{'body'}) && $env{'request.state'} ne 'construct') { $page_start .= &Apache::lonxml::message_location(); } - my $form_tag_start; if (!defined($found{'form'})) { $form_tag_start='
1)) { + my $inc = int(($curr_try-1)/$reqtries); + $rndseed += $inc; + } else { + $rndseed += $curr_try; + } + } + } + $set_safespace = 1; + } + if ($set_safespace) { + if ($safeeval) { + &Apache::lonxml::debug("Setting rndseed to $rndseed"); + &Apache::run::run('$external::randomseed="'.$rndseed.'";',$safeeval); + } + } + unless (($env{'request.state'} eq "construct") || ($symb eq '')) { + $env{'form.'.$Apache::inputtags::part.'.rndseed'}=$rndseed; } return $rndseed; } @@ -299,34 +590,64 @@ sub remember_problem_state { '; } +sub problem_edit_action_button { + my ($name,$action,$accesskey,$text,$flag)=@_; + my $actionscript="setmode(this.form,'$action')"; + return "\n"; +} + +sub problem_edit_buttons { + my ($mode)=@_; +# Buttons that do not save + my $result='
'. + &problem_edit_action_button('subdiscview','discard','d','Discard Edits and View',1); + if ($mode eq 'editxml') { + $result.=&problem_edit_action_button('subedit','edit','e','Edit',1); + $result.=&problem_edit_action_button('subundo','undoxml','u','Undo',1); + $result.=&Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1); + } else { + $result.=&problem_edit_action_button('subeditxml','editxml','x','EditXML',1); + $result.=&problem_edit_action_button('subundo','undo','u','Undo',1); + } + $result.="\n
"; +# Buttons that save + $result.='
'; + if ($mode eq 'editxml') { + $result.=&problem_edit_action_button('subsaveedit','saveeditxml','s','Save and EditXML'); + $result.=&problem_edit_action_button('subsaveview','saveviewxml','v','Save and View'); + } else { + $result.=&problem_edit_action_button('subsaveedit','saveedit','s','Save and Edit'); + $result.=&problem_edit_action_button('subsaveview','saveview','v','Save and View'); + } + $result.="\n
\n"; + return $result; +} + sub problem_edit_header { return ''. - &Apache::structuretags::remember_problem_state().' + &remember_problem_state('edit').'
'.&mt('Problem Editing').&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').' -
-
- - - - -
-
- - -
-
+
'. +''. +&problem_edit_buttons().' +
'.&Apache::lonxml::message_location().' '. - '
'; + '
'; } sub problem_edit_footer { - return '

- '. - &Apache::lonhtmlcommon::htmlareaselectactive(&Apache::lonhtmlcommon::get_htmlareafields()). + return '

+ +'. "\n
\n".&Apache::loncommon::end_page(); } @@ -359,12 +680,14 @@ sub problem_web_to_edit_header { my $show_all_foils_text = ($Apache::lonhomework::parsing_a_task) ? - &mt(' Show All Instances') - : &mt(' Show All Foils'); + &mt('Show All Instances') + : &mt('Show All Foils'); - my $show_all= ''; + my $show_all= ''; @@ -388,8 +711,13 @@ sub problem_web_to_edit_header { $show_all @@ -422,7 +750,6 @@ $show_all $show_all "; } - $result.=' '.&mt('Apply style file: ').' @@ -430,15 +757,18 @@ $show_all '.&mt('Select').' +
'. + &Apache::lonxml::renderingoptions().' +
-
+
- '; @@ -447,8 +777,9 @@ $show_all if (!$numtoanalyze) { $numtoanalyze=20; } $result .= ''. &mt('[_1] for [_2] versions.', - '', - '' + ,''). &Apache::loncommon::help_open_topic("Analyze_Problem",'',undef,undef,300). ''; @@ -457,12 +788,16 @@ $show_all $result.='
-
'; - $result.=''; - $result .= ''; - $result .= ''; +
+
'; + $result.=''; + $result .= ''; + $result .= ''; $result.='
+
'.&Apache::lonxml::message_location().'
'; return $result; @@ -507,12 +842,19 @@ sub initialize_storage { if ($temp =~ m/^error:.*/) { %Apache::lonhomework::history=(); } } -# -------------------------------------------------------------finalize_storage -# Stores away the result has to a student's environment -# checks form.grade_ for specific values, other wises stores -# to the running users environment -# Will increment totals for attempts, students, and corrects -# if running user has student role. +=pod + +=item finalize_storage() + + Stores away the result has to a student's environment + checks form.grade_ for specific values, other wises stores + to the running users environment + Will increment totals for attempts, students, and corrects + if running user has student role. + +=cut + + sub finalize_storage { my ($given_symb) = @_; my $result; @@ -533,9 +875,7 @@ sub finalize_storage { $result=&Apache::lonnet::cstore(\%Apache::lonhomework::results, $symb,$courseid,$domain,$name); &Apache::lonxml::debug('Store return message:'.$result); - if ($env{'request.role'} =~/^st/) { - &store_aggregates($symb,$courseid); - } + &store_aggregates($symb,$courseid); } } else { &Apache::lonxml::debug('Nothing to store'); @@ -543,13 +883,19 @@ sub finalize_storage { return $result; } -# -------------------------------------------------------------store_aggregates -# Sends hash of values to be incremented in nohist_resourcetracker.db -# for the course. Increments total number of attempts, unique students -# and corrects for each part for an instance of a problem, as appropriate. +=pod + +item store_aggregates() + + Sends hash of values to be incremented in nohist_resourcetracker.db + for the course. Increments total number of attempts, unique students + and corrects for each part for an instance of a problem, as appropriate. + +=cut + sub store_aggregates { my ($symb,$courseid) = @_; - my %aggregate; + my (%aggregate,%anoncounter,%randtrycounter); my @parts; my $cdomain = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cname = $env{'course.'.$env{'request.course.id'}.'.num'}; @@ -559,28 +905,60 @@ sub store_aggregates { } } foreach my $part (@parts) { - if ($Apache::lonhomework::results{'resource.'.$part.'.award'} - eq 'APPROX_ANS' || - $Apache::lonhomework::results{'resource.'.$part.'.award'} - eq 'EXACT_ANS') { - $aggregate{$symb."\0".$part."\0correct"} = 1; + if ($env{'request.role'} =~/^st/) { + if ($Apache::lonhomework::results{'resource.'.$part.'.award'} + eq 'APPROX_ANS' || + $Apache::lonhomework::results{'resource.'.$part.'.award'} + eq 'EXACT_ANS') { + $aggregate{$symb."\0".$part."\0correct"} = 1; + } + if ($Apache::lonhomework::results{'resource.'.$part.'.tries'} == 1) { + $aggregate{$symb."\0".$part."\0users"} = 1; + } else { + my (undef,$last_reset) = &Apache::grades::get_last_resets($symb,$env{'request.course.id'},[$part]); + if ($last_reset) { + if (&Apache::grades::get_num_tries(\%Apache::lonhomework::history,$last_reset,$part) == 0) { + $aggregate{$symb."\0".$part."\0users"} = 1; + } + } + } + $aggregate{$symb."\0".$part."\0attempts"} = 1; } - if ($Apache::lonhomework::results{'resource.'.$part.'.tries'} == 1) { - $aggregate{$symb."\0".$part."\0users"} = 1; - } else { - my (undef,$last_reset) = &Apache::grades::get_last_resets($symb,$env{'request.course.id'},[$part]); - if ($last_reset) { - if (&Apache::grades::get_num_tries(\%Apache::lonhomework::history,$last_reset,$part) == 0) { - $aggregate{$symb."\0".$part."\0users"} = 1; + if (($Apache::lonhomework::results{'resource.'.$part.'.type'} eq 'anonsurvey') || + ($Apache::lonhomework::results{'resource.'.$part.'.type'} eq 'anonsurveycred') || + ($Apache::lonhomework::results{'resource.'.$part.'.type'} eq 'randomizetry')) { + if ($Apache::lonhomework::results{'resource.'.$part.'.type'} eq 'randomizetry') { + $randtrycounter{$symb."\0".$part} = 1; + } else { + $anoncounter{$symb."\0".$part} = 1; + } + my $needsrelease = $Apache::lonnet::needsrelease{'parameter:type:'.$Apache::lonhomework::results{'resource.'.$part.'.type'}}; + if ($needsrelease) { + my $curr_required = $env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'}; + if ($curr_required eq '') { + &Apache::lonnet::update_released_required($needsrelease); + } else { + my ($currmajor,$currminor) = split(/\./,$curr_required); + my ($needsmajor,$needsminor) = split(/\./,$needsrelease); + if (($currmajor < $needsmajor) || ($currmajor == $needsmajor && $currminor < $needsminor)) { + &Apache::lonnet::update_released_required($needsrelease); + } } } } - $aggregate{$symb."\0".$part."\0attempts"} = 1; } if (keys (%aggregate) > 0) { &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate, $cdomain,$cname); } + if (keys(%anoncounter) > 0) { + &Apache::lonnet::cput('nohist_anonsurveys',\%anoncounter, + $cdomain,$cname); + } + if (keys(%randtrycounter) > 0) { + &Apache::lonnet::cput('nohist_randomizetry',\%randtrycounter, + $cdomain,$cname); + } } sub checkout_msg { @@ -594,10 +972,8 @@ sub checkout_msg { return (<$lt{'resource'}

$lt{'id_expln'}

- -

$lt{'warning'}

-
-
+

$lt{'warning'}

+
@@ -606,17 +982,37 @@ ENDCHECKOUT sub firstaccess_msg { my ($time,$symb)=@_; - my ($map)=&Apache::lonnet::decode_symb($symb); - my $foldertitle=&Apache::lonnet::gettitle($map); - &Apache::lonxml::debug("map is $map title is $foldertitle"); + my $result; + my @interval=&Apache::lonnet::EXT("resource.0.interval"); + if ($interval[1] eq 'map') { + my ($map)=&Apache::lonnet::decode_symb($symb); + my $foldertitle=&Apache::lonnet::gettitle($map); + + &Apache::lonxml::debug("map is $map title is $foldertitle"); + $result .= "

".&mt('The resources in "[_1]" are open for a limited time.',$foldertitle)."

" + .'

'.&mt('Once you click the "Show Resource" button below you have [_2] to complete all resources "[_1]".' + ,$foldertitle,$time)."

"; + } elsif ($interval[1] eq 'course') { + my $course = $env{'course.'.$env{'request.course.id'}.'.description'}; + $result .= "

".&mt('The resources in "[_1]" are open for a limited time.',$course)."

" + .'

'.&mt('Once you click the "Show Resource" button below you have [_2] to complete all resources "[_1]".' + ,$course,$time)."

"; + } else { + my $title=&Apache::lonnet::gettitle($symb); + $result .= "

".&mt('This resource "[_1]" is open for a limited time.',$title)."

" + .'

'.&mt('Once you click the "Show Resource" button below you have [_2] to complete this resource "[_1]".' + ,$title,$time)."

"; + } my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'}); - return (<The resources in "$foldertitle" are open for a limited time. Once you click the 'Show Resource' button below you have $time to complete all resources "$foldertitle". -
+ my $buttontext = &mt('Show Resource'); + my $timertext = &mt('Start Timer?'); + $result .= (< - + ENDCHECKOUT + return $result; } sub init_problem_globals { @@ -643,6 +1039,7 @@ sub init_problem_globals { &Apache::lonhomework::reset_show_problem_status(); $Apache::lonhomework::ignore_response_errors=1; } + @Apache::functionplotresponse::callscripts=(); @Apache::inputtags::responselist = (); @Apache::inputtags::importlist = (); @Apache::inputtags::previous=(); @@ -662,6 +1059,9 @@ sub reset_problem_globals { undef(%Apache::lonhomework::history); undef(%Apache::lonhomework::results); undef($Apache::inputtags::part); + if ($type eq 'Task') { + undef($Apache::inputtags::slot_name); + } #don't undef this, lonhomework.pm takes care of this, we use this to #detect if we try to do 2 problems in one file # undef($Apache::lonhomework::parsing_a_problem); @@ -670,6 +1070,7 @@ sub reset_problem_globals { undef($Apache::lonhomework::type); undef($Apache::lonhomework::scantronmode); undef($Apache::lonhomework::ignore_response_errors); + undef(@Apache::functionplotresponse::callscripts); &Apache::lonhomework::reset_show_problem_status(); } @@ -721,7 +1122,8 @@ sub start_problem { } if ($target ne 'analyze') { - $Apache::lonhomework::type=&Apache::lonnet::EXT('resource.0.type'); + my $type = &Apache::lonnet::EXT('resource.0.type'); + $Apache::lonhomework::type=$type; if (($env{'request.state'} eq 'construct') && $env{'form.problemtype'} =~ /\S/) { $Apache::lonhomework::type=$env{'form.problemtype'}; @@ -757,9 +1159,23 @@ sub start_problem { &Apache::run::run($expression,$safeeval); my $status; my $accessmsg; + my $resource_due; my $name= &get_resource_name($parstack,$safeeval); - my ($result,$form_tag_start); + my ($result,$form_tag_start,$slot_name,$slot); + + if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' || + $target eq 'tex') { + if ($env{'form.markaccess'}) { + my @interval=&Apache::lonnet::EXT("resource.0.interval"); + &Apache::lonnet::set_first_access($interval[1]); + } + + ($status,$accessmsg,$slot_name,$slot) = + &Apache::lonhomework::check_slot_access('0','problem'); + push (@Apache::inputtags::status,$status); + } + if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex' || $target eq 'edit') { ($result,$form_tag_start) = @@ -769,26 +1185,14 @@ sub start_problem { if ($target eq 'tex' and $env{'request.symb'} =~ m/\.page_/) {$result='';} - if ($target eq 'analyze') { my $rndseed=&setup_rndseed($safeeval); } + if ($target eq 'analyze') { my $rndseed=&setup_rndseed($safeeval,$target); } if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' || $target eq 'tex') { - #handle exam checkout - if ($Apache::lonhomework::type eq 'exam') { - my $token= - $Apache::lonhomework::history{"resource.0.outtoken"}; - if (($env{'form.doescheckout'}) && (!$token)) { - $token=&Apache::lonxml::maketoken(); - $Apache::lonhomework::history{"resource.0.outtoken"}= - $token; - } - $result.=&Apache::lonxml::printtokenheader($target,$token); - } - if ($env{'form.markaccess'}) { - &Apache::lonnet::set_first_access('map'); - } + #handle rand seed in construction space - my $rndseed=&setup_rndseed($safeeval); + my $rndseed=&setup_rndseed($safeeval,$target); my ($symb)=&Apache::lonnet::whichuser(); + if ($env{'request.state'} ne "construct" && ($symb eq '' || $Apache::lonhomework::type eq 'practice')) { $form_tag_start.=''; } if ($env{'request.role.adv'}) { - $form_tag_start.= - ' '; } + if ($Apache::lonhomework::type eq 'practice') { + $form_tag_start.=&practice_problem_header(); + } $form_tag_start.='
'; - } - - ($status,$accessmsg,my $slot_name,my $slot) = - &Apache::lonhomework::check_slot_access('0','problem'); - push (@Apache::inputtags::status,$status); + } elsif (($env{'request.state'} ne "construct") && + ($Apache::lonhomework::type eq 'randomizetry') && + ($status eq 'CAN_ANSWER')) { + my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries"); + my $problemstatus = &get_problem_status($Apache::inputtags::part); + $form_tag_start.=&randomizetry_problem_header($problemstatus,$reqtries); + } my $expression='$external::datestatus="'.$status.'";'; $expression.='$external::gradestatus="'.$Apache::lonhomework::history{"resource.0.solved"}.'";'; @@ -827,16 +1237,24 @@ sub start_problem { ( $status eq 'BANNED') || ( $status eq 'UNAVAILABLE') || ( $status eq 'NOT_IN_A_SLOT') || + ( $status eq 'NOTRESERVABLE') || + ( $status eq 'RESERVABLE') || + ( $status eq 'RESERVABLE_LATER') || ( $status eq 'INVALID_ACCESS')) { my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser, $style); if ( $target eq "web" ) { my $msg; if ($status eq 'UNAVAILABLE') { - $msg.='

'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'

'; + $msg.='

'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'

'; + } elsif ($status eq 'NOT_IN_A_SLOT') { + $msg.='

'.&mt('You are not currently signed up to work at this time and/or place.').'

'; + } elsif (($status eq 'RESERVABLE') || ($status eq 'RESERVABLE_LATER') || + ($status eq 'NOTRESERVABLE')) { + $msg.='

'.&mt('Access requires reservation to work at specific time/place.').'

'; } elsif ($status ne 'NOT_YET_VIEWED') { - $msg.='

'.&mt('Not open to be viewed').'

'; - } + $msg.='

'.&mt('Not open to be viewed').'

'; + } if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') { $msg.=&mt('The problem ').$accessmsg; } elsif ($status eq 'UNCHECKEDOUT') { @@ -844,13 +1262,23 @@ sub start_problem { } elsif ($status eq 'NOT_YET_VIEWED') { $msg.=&firstaccess_msg($accessmsg,$symb); } elsif ($status eq 'NOT_IN_A_SLOT') { - $msg.=&Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work."); + $msg.=&Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work"); + } elsif ($status eq 'RESERVABLE') { + $msg.=&mt('Available to make a reservation.').' '.&mt('Reservation window closes [_1].', + &Apache::lonnavmaps::timeToHumanString($accessmsg,'end')). + '
'. + &Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work"); + } elsif ($status eq 'RESERVABLE_LATER') { + $msg.=&mt('Window to make a reservation will open [_1].', + &Apache::lonnavmaps::timeToHumanString($accessmsg,'start')); + } elsif ($status eq 'NOTRESERVABLE') { + $msg.=&mt('Not available to make a reservation.'); } $result.=$msg.'
'; } elsif ($target eq 'tex') { my $startminipage = ($env{'form.problem_split'}=~/yes/i)? '' : '\begin{minipage}{\textwidth}'; - $result.='\begin{document}\noindent \vskip 1 mm '. + $result.='\noindent \vskip 1 mm '. $startminipage.'\vskip 0 mm'; if ($status eq 'UNAVAILABLE') { $result.=&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'\vskip 0 mm '; @@ -869,18 +1297,45 @@ sub start_problem { 'problem'); } } elsif ($target eq 'web') { - if ($status eq 'CAN_ANSWER' - && $slot_name ne '' - && $Apache::lonhomework::history{'resource.0.checkedin'} eq '') { - # unproctored slot access, self checkin - &Apache::bridgetask::check_in('problem',undef,undef, - $slot_name); - } + if ($status eq 'CAN_ANSWER') { + $resource_due = &Apache::lonhomework::due_date(0, $env{'request.symb'}); + if ($slot_name ne '') { + my $checked_in = + $Apache::lonhomework::history{'resource.0.checkedin'}; + if ($checked_in eq '') { + # unproctored slot access, self checkin + &Apache::bridgetask::check_in('problem',undef,undef, + $slot_name); + $checked_in = + $Apache::lonhomework::results{"resource.0.checkedin"}; + } + if ((ref($slot) eq 'HASH') && ($checked_in ne '')) { + if ($slot->{'starttime'} < time()) { + if (!$resource_due) { + $resource_due = $slot->{'endtime'}; + } elsif ($slot->{'endtime'} < $resource_due) { + $resource_due = $slot->{'endtime'}; + } + } + } + } + if ($resource_due) { + my $time_left = $resource_due - time(); + if ($resource_due && ($time_left > 0) && ($target eq 'web')) { + $result .= &Apache::lonhtmlcommon::set_due_date($resource_due); + } + } + } $result.="\n $form_tag_start \t". ''; # create a page header and exit if ($env{'request.state'} eq "construct") { $result.= &problem_web_to_edit_header($env{'form.rndseed'}); + if ($Apache::lonhomework::type eq 'practice') { + $result.= ''. + &practice_problem_header().'
'; + } } # if we are viewing someone else preserve that info if (defined $env{'form.grade_symb'}) { @@ -888,9 +1343,20 @@ sub start_problem { $result .= ''."\n"; } + foreach my $field ('trial','questiontype') { + if ($env{"form.grade_$field"} ne '') { + $result .= ''."\n"; + } + } } + if ($env{'form.grade_imsexport'}) { + $result = ''; + } } elsif ($target eq 'tex') { $result .= 'INSERTTEXFRONTMATTERHERE'; + $result .= &select_metadata_hyphenation(); + } } elsif ($target eq 'edit') { @@ -946,7 +1412,8 @@ sub end_problem { $allow_print_points=0; } my $name_of_resourse= &Apache::lonxml::latex_special_symbols(&get_resource_name($parstack,$safeeval),'header'); - my $begin_doc='\begin{document} \typeout{STAMPOFPASSEDRESOURCESTART Resource

"'.$name_of_resourse.'"

located in
'.$env{'request.uri'}.'
STAMPOFPASSEDRESOURCEEND} \noindent '; + my $begin_doc=' \typeout{STAMPOFPASSEDRESOURCESTART Resource

"'.$name_of_resourse.'"

located in
'.$env{'request.uri'}.'
STAMPOFPASSEDRESOURCEEND} \noindent '; + &clear_required_languages(); my $toc_line='\vskip 1 mm\noindent '.$startminipage. '\addcontentsline{toc}{subsection}{'.$name_of_resourse.'}'; @@ -956,6 +1423,8 @@ sub end_problem { my $duetime = &Apache::lonnet::EXT("resource.$id.duedate"); my $duedate = POSIX::strftime("%c",localtime($duetime)); + my $duedate_text = &mt('Due date: [_1]' + ,&Apache::lonlocal::locallocaltime($duetime)); my $temp_file; my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due"; @@ -987,18 +1456,22 @@ sub end_problem { if (not $env{'request.symb'} =~ m/\.page_/) { if(not $duedate=~m/1969/ and $Apache::lonhomework::type ne 'exam') { $frontmatter .= $begin_doc. - '\textit{Due date: '.$duedate.'} '.$toc_line; + '\textit{'.$duedate_text.'} '.$toc_line; } else { $frontmatter.= $begin_doc.$toc_line; - if ($Apache::lonhomework::type eq 'exam' and $allow_print_points==1) { $frontmatter .= '\fbox{\textit{'.$weight.' pt}}';} + if ($Apache::lonhomework::type eq 'exam' and $allow_print_points==1) { + $frontmatter .= '\fbox{\textit{'.&mt('[quant,_1,pt,pt]',$weight ).'}}'; + } } } else { - $frontmatter .= '\vskip 1mm\textit{Due date: '.$duedate.'} \\\\\\\\'.$startminipage; + $frontmatter .= '\vskip 1mm\textit{'.$duedate_text.'} \\\\\\\\'.$startminipage; } } else { if (not $env{'request.symb'} =~ m/\.page_/) { $frontmatter .= $begin_doc.$toc_line; - if (($Apache::lonhomework::type eq 'exam') and ($allow_print_points==1)) { $frontmatter .= '\fbox{\textit{'.$weight.' pt}}';} + if (($Apache::lonhomework::type eq 'exam') and ($allow_print_points==1)) { + $frontmatter .= '\fbox{\textit{'.&mt('[quant,_1,pt,pt]',$weight ).'}}'; + } } else { $frontmatter .= '\vskip 1mm \\\\\\\\'.$startminipage; } @@ -1021,7 +1494,8 @@ sub end_problem { } } elsif ( ($target eq 'web' || $target eq 'tex') && $Apache::inputtags::part eq '0' && - $status ne 'UNCHECKEDOUT' && $status ne 'NOT_YET_VIEWED') { + $status ne 'UNCHECKEDOUT' && $status ne 'NOT_YET_VIEWED' + && !$env{'form.grade_imsexport'}) { # if part is zero, no s existed, so we need show the current # grading status my $gradestatus = &Apache::inputtags::gradestatus($Apache::inputtags::part,$target); @@ -1031,13 +1505,19 @@ sub end_problem { (($target eq 'web') && ($env{'request.state'} ne 'construct')) || ($target eq 'answer') || ($target eq 'tex') ) { - if ($target ne 'tex' && - $env{'form.answer_output_mode'} ne 'tex') { + if (($target ne 'tex') && + ($env{'form.answer_output_mode'} ne 'tex') && + (!$env{'form.grade_imsexport'})) { $result.=""; - $result.= &Apache::lonhtmlcommon::htmlareaselectactive(&Apache::lonhtmlcommon::get_htmlareafields()); } if ($target eq 'web') { - $result.= &Apache::loncommon::end_page({'discussion' => 1}); + # + # Closing not added by end_page(). + # Added separately at end of this routine, after added + # so document will be valid xhtml. + # + $result.= &Apache::loncommon::end_page({'discussion' => 1, + 'notbody' => 1}); } elsif ($target eq 'tex') { my $endminipage = ''; if (not $env{'form.problem_split'}=~/yes/) { @@ -1055,6 +1535,9 @@ sub end_problem { } } } + if ($target eq 'web') { + $result.=&Apache::functionplotresponse::init_script(); + } if ($target eq 'grade') { &Apache::lonhomework::showhash(%Apache::lonhomework::results); &finalize_storage(); @@ -1085,6 +1568,19 @@ sub end_problem { &reset_problem_globals('problem'); + # + # This shouild be just above the return so that the + # time put in the javascript is as late as possible in the + # computation: + # + if ($target eq 'web') { + $result .= &Apache::lonhtmlcommon::set_compute_end_time(); + # + # Closing tags delayed so any tags + # not in head can appear inside body, for valid xhtml. + # + $result .= "\n"; + } return $result; } @@ -1112,10 +1608,15 @@ sub start_library { ($result,$form_tag_start)= &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval, $name); - my $rndseed=&setup_rndseed($safeeval); + my $rndseed=&setup_rndseed($safeeval,$target); $result.=" \n $form_tag_start". ''; $result.=&problem_web_to_edit_header($rndseed); + if ($Apache::lonhomework::type eq 'practice') { + $result.= ''. + &practice_problem_header().'
'; + } } return $result; } @@ -1206,54 +1707,101 @@ sub end_block { } return $result; } - +# +# +# ... +# +# +# This declares the intent to provide content that can be rendered in the +# set of languages in the include specificatino but not in the exclude +# specification. If a currently preferred language is in the include list +# the content in the ... is rendered +# If the currently preferred language is in the exclude list, +# the content in the ..>[2]->{'include'}; my $exclude = $token->[2]->{'exclude'}; - my @preferred_languages=&Apache::loncommon::preferred_languages(); -# This should not even happen, since we should at least have the server language - if (!$preferred_languages[0]) { $preferred_languages[0]='en'; } -# Now loop over all languages in order of preference + my @preferred_languages=&Apache::lonlocal::preferred_languages(); + + # This should not even happen, since we should at least have the server language + + if (!$preferred_languages[0]) { + $preferred_languages[0]='en'; + } + + # Now loop over all languages in order of preference + + my $render; foreach my $preferred_language (@preferred_languages) { -# If the languageblock has no arguments, show the contents - $result=1; + + # If neither include/nor exlude is present the block is going + # to get rendered. + my $found=0; -# Do we have an include argument? + $render=1; + + # If include is specified, don't render the block + # unless the preferred language is included in the set. + if ($include) { -# If include is specified, by default, don't render the block - $result=0; + $render=0; foreach my $included_language (split(/\,/,$include)) { -# ... but if my preferred language is included, render it if ($included_language eq $preferred_language) { - $result=1; + $render=1; $found=1; + last; # Only need to find the first. } } } -# Do we have an exclude argument? + # Do we have an exclude argument? + # If so, and one of the languages matches a preferred language + # inhibit rendering the block. Note that in the pathalogical case the + # author has specified a preferred language in both the include and exclude + # attribte exclude is preferred. + if ($exclude) { - $result=1; + $render=1; foreach my $excluded_language (split(/\,/,$exclude)) { if ($excluded_language eq $preferred_language) { - $result=0; + $render=0; $found=1; + last; # Only need to find the first. } } } - if ($found) { last; } + if ($found) { + last; # Done on any match of include or exclude. + } } - if ( ! $result ) { + # If $render not true skip the entire block until + # + + if ( ! $render ) { my $skip=&Apache::lonxml::get_all_text("/languageblock",$parser, $style); &Apache::lonxml::debug("skipping ahead :$skip: $$parser[-1]"); } - $result=''; + # If $render is true, we've not skipped the contents of the + # and the normal loncapa processing flow will render it as a matter of course. + } elsif ($target eq 'edit') { $result .=&Apache::edit::tag_start($target,$token); $result .=&Apache::edit::text_arg(&mt('Include Language:'),'include', @@ -1278,9 +1826,47 @@ sub end_languageblock { } return $result; } - +# languagblock specific tags: { - my %available_texts; + # For chunks of a resource that has translations, this hash contains + # the translations available indexed by language name. + # + + my %available_texts; + + # starts a block of a resource that has multiple translations. + # See the tag as well. + # When is encountered if there is a translation for the + # currently preferred language, that is rendered inthe web/tex/webgrade + # targets. Otherwise, the default text is rendered. + # + # Note that is only registered for the duration of the + # ... block + # + # Pathalogical case handling: + # - If there is no that specifies a 'default' and there is no + # translation that matches a preferred language, nothing is rendered. + # - Nested ... might be linguistically supported by + # XML due to the stack nature of tag registration(?) however the rendered + # output will be incorrect because there is only one %available_texts + # has and end_translated clears it. + # - Material outside of a ... block within the + # ... block won't render either e.g.: + # + # The following will be in your preferred langauge: + # + # This section in english + # + # + # Hier es ist auf Deutsch. + # + # + # En Francais + # + # + # + # The introductory text prior to the first tag is not rendered. + # sub start_translated { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; &Apache::lonxml::register('Apache::structuretags',('lang')); @@ -1299,14 +1885,55 @@ sub end_languageblock { my @possibilities = keys(%available_texts); my $which = &Apache::loncommon::languages(\@possibilities) || 'default'; - $result = $available_texts{$which}; + if ($target eq 'tex') { + $result = &select_hyphenation($which); + } + $result .= $available_texts{$which}; + if ($target eq 'tex') { + $result .= &select_metadata_hyphenation(); # Restore original language. + } } undef(%available_texts); &Apache::lonxml::deregister('Apache::structuretags',('lang')); return $result; } - + # + # Specifies that the block contained within it is a translation + # for a specific language specified by the 'which' attribute. The + # 'other' attribute can be used by itself or in conjunction with + # which to specify this tag _may_ be used as a translation for some + # list of languages. e.g.: + # specifying that the block provides a translation for US (primary) + # Canadian, Australian and UK Englush. + # + # Comment: this seems a bit silly why not just support a list of languages + # e.g. and ditch the other attribute? + # + # Effect: + # The material within the .. block is stored in the + # specified set of $available_texts hash entries, the appropriate one + # is selected at time. + # + # Pathalogical case handling: + # If a language occurs multiple times within a block, + # only the last one is rendered e.g.: + # + # + # + # Red green color blindness is quite common affecting about 7.8% of + # the male population, but onloy about .65% of the female population. + # + # Red green colour blindness is quite common affecting about 7.8% of + # the male population, but onloy about .65% of the female population. + # + # + # + # renders the correct spelling of color (colour) for people who have specified + # a preferred language that is one of the British Commonwealth languages + # even though those are also listed as valid selections for the US english + # block. + # sub start_lang { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' || @@ -1323,11 +1950,22 @@ sub end_languageblock { my $result = &Apache::lonxml::endredirection(); my $which = &Apache::lonxml::get_param('which',$parstack, $safeeval); - $available_texts{$which} = $result; + if ($which=~/\w/) { + $available_texts{$which} = $result; + } + my $otherlangs = &Apache::lonxml::get_param('other',$parstack, + $safeeval); + foreach my $language (split(/\s*\,\s*/,$otherlangs)) { + if ($language=~/\w/) { + $available_texts{$language} = $result; + } + } + } return ''; } -} +} # end langauge block specific tags. + sub start_instructorcomment { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; @@ -1336,7 +1974,7 @@ sub start_instructorcomment { if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' || $target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') { - $result=($env{'request.role'}=~/^(in|cc|au|ca|li)/); + $result=($env{'request.role'}=~/^(in|cc|co|au|ca|li)/); if ( (! $result) or ($env{'form.instructor_comments'} eq 'hide')) { my $skip=&Apache::lonxml::get_all_text("/instructorcomment", $parser,$style); @@ -1420,7 +2058,7 @@ sub end_while { $return = &Apache::run::run($code,$safeeval); } if ($error) { - &Apache::lonxml::error('
'.&mt('Code ran too long. It ran for more than').' '.$Apache::lonnet::perlvar{'lonScriptTimeout'}.' '.&mt('seconds occured while running <while> on line').' '.$line.'
'); + &Apache::lonxml::error('
'.&mt('Code ran too long. It ran for more than').' '.$Apache::lonnet::perlvar{'lonScriptTimeout'}.' '.&mt('seconds occurred while running <while> on line').' '.$line.'
'); } } elsif ($target eq "edit") { $result.= &Apache::edit::tag_end($target,$token,''); @@ -1474,6 +2112,20 @@ sub start_randomlist { my $showarg=&Apache::lonxml::get_param('show',$parstack,$safeeval); $showarg--; if ( ($showarg >= 0) && ($showarg < $show) ) { $show = $showarg; } + if (($target eq 'analyze') && ($env{'form.check_parts_withrandomlist'})) { + my @currlist; + my $part = $Apache::inputtags::part; + if ($part ne '') { + if (ref($Apache::lonhomework::analyze{'parts_withrandomlist'}) eq 'ARRAY') { + my @currlist = @{$Apache::lonhomework::analyze{'parts_withrandomlist'}}; + if (!(grep(/^\Q$part\E$/,@currlist))) { + push(@{$Apache::lonhomework::analyze{'parts_withrandomlist'}},$part); + } + } else { + push(@{$Apache::lonhomework::analyze{'parts_withrandomlist'}},$part); + } + } + } for(0 .. $show) { $bodytext .= "$randomlist[ $idx_arr[$_] ]"; } @@ -1527,6 +2179,49 @@ sub ordered_show_check { return $in_order_show; } + +sub start_startpartmarker { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my $result=''; + if ($target eq 'edit') { + $result=&Apache::edit::tag_start($target,$token); + $result.=&mt('Marker for the start of a part. Place end marker below to wrap in-between tags into a new part.').''; + $result.=&Apache::edit::end_table(); + + } + return $result; +} + +sub end_startpartmarker { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my @result; + if ($target eq 'edit') { $result[1]='no'; } + return @result; +} + +sub start_endpartmarker { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my $result=''; + if ($target eq 'edit') { + $result=&Apache::edit::tag_start($target,$token); + $result.=&mt('Marker for the end of a part. Place start marker above to wrap in-between tags into a new part.').''; + $result.=&Apache::edit::end_table(); + + } + return $result; +} + +sub end_endpartmarker { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my @result; + if ($target eq 'edit') { $result[1]='no'; } + return @result; +} + + + + + sub start_part { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; if (!$Apache::lonxml::metamode) { @@ -1611,9 +2306,31 @@ sub start_part { '.disableexampointprint'}) eq 'yes') { $allow_print_points=0; } - if (($Apache::lonhomework::type eq 'exam') && ($allow_print_points)) { $result .= '\fbox{\textit{'.$weight.' pt}}';} + if (($Apache::lonhomework::type eq 'exam') && ($allow_print_points)) { + $result .= '\vskip 10mm\fbox{\textit{'.&mt('[quant,_1,pt,pt]',$weight ).'}}'; + + } } elsif ($target eq 'web') { - $result.=''; + if ($status eq 'CAN_ANSWER') { + my $problemstatus = &get_problem_status($Apache::inputtags::part); + my $probrandomize = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[0].type"); + my $probrandtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[0].randomizeontries"); + my $num = scalar(@Apache::inputtags::partlist)-1; + if ($probrandomize eq 'randomizetry') { + if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") ne 'randomizetry') { + $result .= &randomizetry_part_header($problemstatus,'none',$num); + } else { + my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries"); + if ($probrandtries ne $reqtries) { + $result .= &randomizetry_part_header($problemstatus,$reqtries,$num); + } + } + } elsif (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") eq 'randomizetry') { + my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries"); + $result .= &randomizetry_part_header($problemstatus,$reqtries,$num); + } + } + $result.=''; } } } @@ -1659,7 +2376,8 @@ sub end_part { !$hidden && $in_order_show) { my $gradestatus=&Apache::inputtags::gradestatus($Apache::inputtags::part, $target); - if ($Apache::lonhomework::type eq 'exam' && $target eq 'tex') { + if (($Apache::lonhomework::type eq 'exam' && $target eq 'tex') || + ($env{'form.grade_imsexport'})) { $gradestatus=''; } $result.=$gradestatus; @@ -1780,7 +2498,12 @@ sub start_problemtype { $result .=&Apache::edit::checked_arg('When used as type(s):','for', [ ['exam','Exam/Quiz Problem'], ['survey','Survey'], - ['problem','Homework Problem'] ] + ['surveycred','Survey (with credit)'], + ['anonsurvey','Anonymous Survey'], + ['anonsurveycred','Anonymous Survey (with credit)'], + ['problem','Homework Problem'], + ['practice','Practice Problem'], + ['randomizetry','New Randomization Each Try'] ] ,$token); $result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row(); } elsif ($target eq 'modified') { @@ -1813,17 +2536,21 @@ sub end_startouttext { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; my $text=''; - if ($target eq 'edit') { + my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth; $text=&Apache::lonxml::get_all_text("endouttext",$parser,$style); - $result.=&Apache::edit::start_table($token)."".&mt('Text Block')." -".&mt('Delete:'). - &Apache::edit::deletelist($target,$token) - ." -". - &Apache::edit::insertlist($target,$token). - '' . - &Apache::loncommon::helpLatexCheatsheet(). + $result.=&Apache::edit::start_table($token)."".&mt('Text Block')."" + .''.&mt('Delete?').' ' + .&Apache::edit::deletelist($target,$token) + .'' + .'' + .&Apache::lonhtmlcommon::dragmath_button($areaid,1) + .'' + .'' + .&Apache::edit::insertlist($target,$token) + .'' + .'' . + &Apache::loncommon::helpLatexCheatsheet(). &Apache::edit::end_row(). &Apache::edit::start_spanning_row()."\n". &Apache::edit::editfield($token->[1],$text,"",80,8,1); @@ -1886,9 +2613,18 @@ sub start_simpleeditbutton { my $url=$env{'request.noversionuri'}; $url=~s/\?.*$//; my ($symb) = &Apache::lonnet::whichuser(); - $result='
'. - ''.&mt('Edit').' - '.&mt('Note: it can take up to 10 minutes for changes to take effect for all users.'). -&Apache::loncommon::help_open_topic('Caching').'

'; +# Warning makes more sense and is more important on edit screen +# $result='

' +# .&mt('Note: it can take up to 10 minutes for changes to take effect for all users.') +# .&Apache::loncommon::help_open_topic('Caching') +# .'

'; + $result.=&Apache::loncommon::head_subbox( + &Apache::lonhtmlcommon::start_funclist() + .&Apache::lonhtmlcommon::add_item_funclist( + '' + .&mt('Edit').'') + .&Apache::lonhtmlcommon::end_funclist()); + } return $result; } @@ -1897,5 +2633,74 @@ sub end_simpleeditbutton { return ''; } +sub practice_problem_header { + return '

'.&mt('Practice Problem').'

'. + ''.&mt('Submissions are not permanently recorded'). + ''; +} + +sub randomizetry_problem_header { + my ($problemstatus,$reqtries) = @_; + my ($header,$text); + if ($reqtries > 1) { + $header = &mt('New Problem Variation After Every [quant,_1,Try,Tries]',$reqtries); + if (($problemstatus eq 'no') || + ($problemstatus eq 'no_feedback_ever')) { + $text = &mt('A new variation will be generated after every [quant,_1,try,tries], until the tries limit is reached.',$reqtries); + } else { + $text = &mt('A new variation will be generated after every [quant,_1,try,tries], until correct or tries limit is reached.',$reqtries); + } + } else { + $header = &mt('New Problem Variation Each Try'); + if (($problemstatus eq 'no') || + ($problemstatus eq 'no_feedback_ever')) { + $text = &mt('A new variation will be generated after each try until the tries limit is reached.'); + + } else { + $text = &mt('A new variation will be generated after each try until correct or tries limit is reached.'); + } + } + return '

'.$header.'

'. + ''.$text.'
'; +} + +sub randomizetry_part_header { + my ($problemstatus,$reqtries,$num) = @_; + my ($header,$text); + if ($reqtries eq 'none') { + $header = &mt('No Question Variation'); + $text = &mt('For this question there will no new variation after a try.'); + } elsif ($reqtries > 1) { + $header = &mt('New Question Variation After Every [quant,_1,Try,Tries]',$reqtries); + if (($problemstatus eq 'no') || + ($problemstatus eq 'no_feedback_ever')) { + $text = &mt('For this question a new variation will be generated after every [quant,_1,try,tries], until the tries limit is reached.',$reqtries); + } else { + $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); + } + } else { + $header = &mt('New Question Variation For Each Try'); + if (($problemstatus eq 'no') || + ($problemstatus eq 'no_feedback_ever')) { + $text = &mt('For this question a new variation will be generated after each try until the tries limit is reached.'); + } else { + $text = &mt('For this question a new variation will be generated after each try until correct or tries limit is reached.'); + } + } + my $output; + if ($num > 1) { + $output .= '
'; + } + $output .= '

'.$header.'

'. + ''.$text.'

'; + return $output; +} + 1; __END__ + +=pod + +=back + +=cut