--- loncom/homework/lonhomework.pm 2015/04/15 04:11:20 1.350
+++ loncom/homework/lonhomework.pm 2015/10/05 02:35:40 1.358
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Homework handler
#
-# $Id: lonhomework.pm,v 1.350 2015/04/15 04:11:20 raeburn Exp $
+# $Id: lonhomework.pm,v 1.358 2015/10/05 02:35:40 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -49,8 +49,10 @@ use Apache::matchresponse();
use Apache::chemresponse();
use Apache::functionplotresponse();
use Apache::drawimage();
+use Apache::loncapamath();
use Apache::Constants qw(:common);
use Apache::loncommon();
+use Apache::lonparmset();
use Apache::lonlocal;
use Time::HiRes qw( gettimeofday tv_interval );
use HTML::Entities();
@@ -208,19 +210,50 @@ sub proctor_checked_in {
}
sub check_slot_access {
- my ($id,$type)=@_;
+ my ($id,$type,$symb)=@_;
# does it pass normal muster
- my ($status,$datemsg)=&check_access($id);
+ my ($status,$datemsg)=&check_access($id,$symb);
- my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
+ my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb);
if ($useslots ne 'resource' && $useslots ne 'map'
&& $useslots ne 'map_map') {
return ($status,$datemsg);
}
- if ($status eq 'SHOW_ANSWER' ||
- $status eq 'CLOSED' ||
+ my $checkin = 'resource.0.checkedin';
+ my $version;
+ if ($type eq 'Task') {
+ $version=$Apache::lonhomework::history{'resource.version'};
+ $checkin = "resource.$version.0.checkedin";
+ }
+ my $checkedin = $Apache::lonhomework::history{$checkin};
+ my ($returned_slot,$slot_name,$checkinslot,$ipused,$blockip,$now,$ip);
+ $now = time;
+ $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};
+
+ if ($checkedin) {
+ $checkinslot = $Apache::lonhomework::history{"$checkin.slot"};
+ my %slot=&Apache::lonnet::get_slot($checkinslot);
+ if ($slot{'iptied'}) {
+ $ipused = $Apache::lonhomework::history{"$checkin.ip"};
+ unless (($ip ne '') && ($ipused eq $ip)) {
+ $blockip = $slot{'iptied'};
+ $slot_name = $checkinslot;
+ $returned_slot = \%slot;
+ }
+ }
+ }
+
+ if ($status eq 'SHOW_ANSWER') {
+ if ($blockip eq 'answer') {
+ return ('NEED_DIFFERENT_IP','',$slot_name,$returned_slot,$ipused);
+ } else {
+ return ($status,$datemsg);
+ }
+ }
+
+ if ($status eq 'CLOSED' ||
$status eq 'INVALID_ACCESS' ||
$status eq 'UNAVAILABLE') {
return ($status,$datemsg);
@@ -230,24 +263,30 @@ sub check_slot_access {
}
if ($type eq 'Task') {
- my $version=$Apache::lonhomework::history{'resource.version'};
- if ($Apache::lonhomework::history{"resource.$version.0.checkedin"} &&
+ if ($checkedin &&
$Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass') {
- return ('SHOW_ANSWER');
- }
+ if ($blockip eq 'answer') {
+ return ('NEED_DIFFERENT_IP','',$slot_name,$returned_slot,$ipused);
+ } else {
+ return ('SHOW_ANSWER');
+ }
+ }
}
- my $availablestudent = &Apache::lonnet::EXT("resource.0.availablestudent");
- my $available = &Apache::lonnet::EXT("resource.0.available");
+ my $availablestudent = &Apache::lonnet::EXT("resource.0.availablestudent",$symb);
+ my $available = &Apache::lonnet::EXT("resource.0.available",$symb);
my @slots= (split(':',$availablestudent),split(':',$available));
# if (!@slots) {
# return ($status,$datemsg);
# }
+ undef($returned_slot);
+ undef($slot_name);
my $slotstatus='NOT_IN_A_SLOT';
- my ($returned_slot,$slot_name);
- my $now = time;
my $num_usable_slots = 0;
+ if (!$symb) {
+ ($symb) = &Apache::lonnet::whichuser();
+ }
foreach my $slot (@slots) {
$slot =~ s/(^\s*|\s*$)//g;
&Apache::lonxml::debug("getting $slot");
@@ -258,12 +297,41 @@ sub check_slot_access {
if ($slot{'starttime'} < $now &&
$slot{'endtime'} > $now &&
&Apache::loncommon::check_ip_acc($slot{'ip'})) {
- &Apache::lonxml::debug("$slot is good");
- $slotstatus='NEEDS_CHECKIN';
- $returned_slot=\%slot;
- $slot_name=$slot;
- last;
- }
+ if ($slot{'iptied'}) {
+ if ($env{'request.course.id'}) {
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ if ($slot eq $checkinslot) {
+ if ($ip eq $ipused) {
+ &Apache::lonxml::debug("$slot is good");
+ $slotstatus ='NEEDS_CHECKIN';
+ } else {
+ $slotstatus = 'NEED_DIFFERENT_IP';
+ $slot_name = $slot;
+ $returned_slot = \%slot;
+ last;
+ }
+ } elsif ($ip) {
+ my $uniqkey = "$slot\0$symb\0$ip";
+ my %used_ip = &Apache::lonnet::get('slot_uniqueips',[$uniqkey],$cdom,$cnum);
+ if ($used_ip{$uniqkey}) {
+ $slotstatus = 'NEED_DIFFERENT_IP';
+ } else {
+ &Apache::lonxml::debug("$slot is good");
+ $slotstatus ='NEEDS_CHECKIN';
+ }
+ }
+ }
+ } else {
+ &Apache::lonxml::debug("$slot is good");
+ $slotstatus='NEEDS_CHECKIN';
+ }
+ if ($slotstatus eq 'NEEDS_CHECKIN') {
+ $returned_slot=\%slot;
+ $slot_name=$slot;
+ last;
+ }
+ }
}
if ($slotstatus eq 'NEEDS_CHECKIN' &&
&proctor_checked_in($slot_name,$returned_slot,$type)) {
@@ -271,7 +339,7 @@ sub check_slot_access {
$slotstatus=$status;
}
- my ($is_correct,$got_grade,$checkedin);
+ my ($is_correct,$got_grade);
if ($type eq 'Task') {
my $version=$Apache::lonhomework::history{'resource.0.version'};
$got_grade =
@@ -280,11 +348,8 @@ sub check_slot_access {
$is_correct =
($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass'
|| $Apache::lonhomework::history{"resource.0.solved"} =~ /^correct_/ );
- $checkedin =
- $Apache::lonhomework::history{"resource.$version.0.checkedin"};
} elsif ($type eq 'problem') {
$got_grade = 1;
- $checkedin = $Apache::lonhomework::history{"resource.0.checkedin"};
$is_correct =
($Apache::lonhomework::history{"resource.0.solved"} =~/^correct_/);
}
@@ -303,14 +368,16 @@ sub check_slot_access {
# However, the problem is not closed, and potentially, another slot might be
# used to gain access to it to work on it, until the due date is reached, and the
# problem then becomes CLOSED. Therefore return the slotstatus -
- # (which will be one of: NOT_IN_A_SLOT, RESERVABLE, RESERVABLE_LATER, or NOTRESERVABLE.
+ # (which will be one of: NOT_IN_A_SLOT, RESERVABLE, RESERVABLE_LATER, or NOTRESERVABLE).
if (!defined($slot_name) && $type eq 'problem') {
if ($slotstatus eq 'NOT_IN_A_SLOT') {
if (!$num_usable_slots) {
if ($env{'request.course.id'}) {
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my ($symb)=&Apache::lonnet::whichuser();
+ unless ($symb) {
+ ($symb)=&Apache::lonnet::whichuser();
+ }
$slotstatus = 'NOTRESERVABLE';
my ($reservable_now_order,$reservable_now,$reservable_future_order,
$reservable_future) =
@@ -339,14 +406,18 @@ sub check_slot_access {
&& $checkedin ) {
if ($got_grade) {
- return ('SHOW_ANSWER');
+ if ($blockip eq 'answer') {
+ return ('NEED_DIFFERENT_IP','',$slot_name,$returned_slot,$ipused);
+ } else {
+ return ('SHOW_ANSWER');
+ }
} else {
return ('WAITING_FOR_GRADE');
}
}
- if ( $is_correct) {
+ if (($is_correct) && ($blockip ne 'answer')) {
if ($type eq 'problem') {
return ($status);
}
@@ -354,17 +425,17 @@ sub check_slot_access {
}
if ( $status eq 'CANNOT_ANSWER' &&
- ($slotstatus ne 'NEEDS_CHECKIN' && $slotstatus ne 'NOT_IN_A_SLOT')) {
+ ($slotstatus ne 'NEEDS_CHECKIN' && $slotstatus ne 'NOT_IN_A_SLOT' &&
+ $slotstatus ne 'NEED_DIFFERENT_IP') ) {
return ($status,$datemsg);
}
-
- return ($slotstatus,$datemsg,$slot_name,$returned_slot);
+ return ($slotstatus,$datemsg,$slot_name,$returned_slot,$ipused);
}
# JB, 9/24/2002: Any changes in this function may require a change
# in lonnavmaps::resource::getDateStatus.
sub check_access {
- my ($id) = @_;
+ my ($id,$symb) = @_;
my $date ='';
my $status;
my $datemsg = '';
@@ -394,11 +465,13 @@ sub check_access {
&Apache::lonxml::debug("checking for part :$id:");
&Apache::lonxml::debug("time:".time);
- my ($symb)=&Apache::lonnet::whichuser();
+ unless ($symb) {
+ ($symb)=&Apache::lonnet::whichuser();
+ }
&Apache::lonxml::debug("symb:".$symb);
#if ($env{'request.state'} ne "construct" && $symb ne '') {
if ($env{'request.state'} ne "construct") {
- my $idacc = &Apache::lonnet::EXT("resource.$id.acc");
+ my $idacc = &Apache::lonnet::EXT("resource.$id.acc",$symb);
my $allowed=&Apache::loncommon::check_ip_acc($idacc);
if (!$allowed && ($Apache::lonhomework::browse ne 'F')) {
$status='INVALID_ACCESS';
@@ -414,12 +487,12 @@ sub check_access {
foreach my $temp ("opendate","duedate","answerdate") {
$lastdate = $date;
if ($temp eq 'duedate') {
- $date = &due_date($id);
+ $date = &due_date($id,$symb);
} else {
- $date = &Apache::lonnet::EXT("resource.$id.$temp");
+ $date = &Apache::lonnet::EXT("resource.$id.$temp",$symb);
}
- my $thistype = &Apache::lonnet::EXT("resource.$id.$temp.type");
+ my $thistype = &Apache::lonnet::EXT("resource.$id.$temp.type",$symb);
if ($thistype =~ /^(con_lost|no_such_host)/ ||
$date =~ /^(con_lost|no_such_host)/) {
$status='UNAVAILABLE';
@@ -428,10 +501,10 @@ sub check_access {
}
if ($thistype eq 'date_interval') {
if ($temp eq 'opendate') {
- $date=&Apache::lonnet::EXT("resource.$id.duedate")-$date;
+ $date=&Apache::lonnet::EXT("resource.$id.duedate",$symb)-$date;
}
if ($temp eq 'answerdate') {
- $date=&Apache::lonnet::EXT("resource.$id.duedate")+$date;
+ $date=&Apache::lonnet::EXT("resource.$id.duedate",$symb)+$date;
}
}
&Apache::lonxml::debug("found :$date: for :$temp:");
@@ -465,7 +538,7 @@ sub check_access {
(($Apache::lonhomework::browse eq 'F') && ($status eq 'CLOSED'))) {
#check #tries, and if correct.
my $tries = $Apache::lonhomework::history{"resource.$id.tries"};
- my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries");
+ my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries",$symb);
if ( $tries eq '' ) { $tries = '0'; }
if ( $maxtries eq '' &&
$env{'request.state'} ne 'construct') { $maxtries = '2'; }
@@ -474,7 +547,7 @@ sub check_access {
if ( ($Apache::lonhomework::history{"resource.$id.solved"}=~/^correct/)
&& (&show_problem_status()) ) {
if (($Apache::lonhomework::history{"resource.$id.awarded"} >= 1) ||
- (&Apache::lonnet::EXT("resource.$id.retrypartial") !~/^1|on|yes$/i)) {
+ (&Apache::lonnet::EXT("resource.$id.retrypartial",$symb) !~/^1|on|yes$/i)) {
$status = 'CANNOT_ANSWER';
}
} elsif ($Apache::lonhomework::history{"resource.$id.solved"}=~/^excused/) {
@@ -486,14 +559,14 @@ sub check_access {
}
}
if ($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER') {
- my @interval=&Apache::lonnet::EXT("resource.$id.interval");
+ my @interval=&Apache::lonnet::EXT("resource.$id.interval",$symb);
&Apache::lonxml::debug("looking for interval @interval");
if ($interval[0]) {
- my $first_access=&Apache::lonnet::get_first_access($interval[1]);
+ my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);
&Apache::lonxml::debug("looking for accesstime $first_access");
if (!$first_access) {
$status='NOT_YET_VIEWED';
- my $due_date = &due_date($id);
+ my $due_date = &due_date($id,$symb);
my $seconds_left = $due_date - time;
if ($seconds_left > $interval[0] || $due_date eq '') {
$seconds_left = $interval[0];
@@ -1014,68 +1087,83 @@ sub editxmlmode {
&mt('Problem Editing').' '.&Apache::loncommon::help_open_topic('Problem_Editor_XML_Index').
'
';
- $result.='
'.
+ $result.='
'.
&Apache::structuretags::problem_edit_buttons('editxml');
- $result.='
';
+ $result.='
';
- unless ($env{'environment.nocodemirror'}) {
- # dropdown menues
- $result .= '';
- }
- $result .= '';
- $result.="
";
+ $result .= '
";
- $result.='
'.&Apache::lonxml::message_location().
- &Apache::loncommon::xmleditor_js().
- '
-
-
- ';
- my $resource = $env{'request.ambiguous'};
- unless($env{'environment.nocodemirror'}){
-
- $result .= '
-
- ",
- mode: CodeMirror.getMode(config, "perl"),
- delimStyle: "tag",
- }
- );
- });
- var cm = CodeMirror.fromTextArea(document.getElementById("LC_editxmltext"),
- {
- mode: "mixedmode",
- lineWrapping: true,
- lineNumbers: true,
- tabSize: 4,
- indentUnit: 4,
-
- autoCloseTags: true,
- autoCloseBrackets: true,
- height: "auto",
- styleActiveLine: true,
-
- extraKeys: {
- "Tab": "indentMore",
- "Shift-Tab": "indentLess",
- }
- });
- restoreScrollPosition("'.$resource.'");
- ';
- }
- $result .= &Apache::loncommon::end_page();
- &Apache::lonxml::add_messages(\$result);
- $request->print($result);
+ $result .= '' .
+ &Apache::lonxml::message_location() .
+ &Apache::loncommon::xmleditor_js() .
+ '
';
+
+ my $resource = $env{'request.ambiguous'};
+ unless($env{'environment.nocodemirror'}){
+ $result .= '
+
+ ",
+ mode: CodeMirror.getMode(config, "perl"),
+ delimStyle: "tag",
+ }
+ );
+ });
+ var cm = CodeMirror.fromTextArea(document.getElementById("LC_editxmltext"),
+ {
+ mode: "mixedmode",
+ lineWrapping: true,
+ lineNumbers: true,
+ tabSize: 4,
+ indentUnit: 4,
+
+ autoCloseTags: true,
+ autoCloseBrackets: true,
+ height: "auto",
+ styleActiveLine: true,
+
+ extraKeys: {
+ "Tab": "indentMore",
+ "Shift-Tab": "indentLess",
+ }
+ });
+ restoreScrollPosition("'.$resource.'");
+ ';
+ }
+
+ $result .= &Apache::loncommon::end_page();
+ &Apache::lonxml::add_messages(\$result);
+ $request->print($result);
}
return '';
}
@@ -1331,10 +1419,47 @@ sub update_construct_style {
}
}
+#
+# Sets interval for current user so time left will be zero, either for the entire folder
+# containing the current resource, or just the resource, depending on value of first item
+# in interval array retrieved from EXT("resource.0.interval");
+#
+sub zero_timer {
+ my ($symb) = @_;
+ my ($hastimeleft,$first_access,$now);
+ my @interval=&Apache::lonnet::EXT("resource.0.interval",$symb);
+ if (@interval > 1) {
+ if ($interval[1] eq 'course') {
+ return;
+ } else {
+ my $now = time;
+ my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);
+ if ($first_access > 0) {
+ my ($timelimit) = split(/_/,$interval[0]);
+ if ($first_access+$timelimit > $now) {
+ my $done_time = $now - $first_access;
+ my $snum = 1;
+ if ($interval[1] eq 'map') {
+ $snum = 2;
+ }
+ my $result =
+ &Apache::lonparmset::storeparm_by_symb_inner($symb,'0_interval',
+ $snum,$done_time,
+ 'date_interval',
+ $env{'user.name'},
+ $env{'user.domain'});
+ return $result;
+ }
+ }
+ }
+ }
+ return;
+}
sub handler {
#my $t0 = [&gettimeofday()];
my $request=$_[0];
+
$Apache::lonxml::request=$request;
$Apache::lonxml::debug=$env{'user.debug'};
$env{'request.uri'}=$request->uri;
@@ -1357,6 +1482,7 @@ sub handler {
&unset_permissions();
return OK;
}
+
&Apache::lonxml::debug("Permissions:$Apache::lonhomework::browse:$Apache::lonhomework::viewgrades:$Apache::lonhomework::modifygrades:$Apache::lonhomework::queuegrade");
&Apache::lonxml::debug("Problem Mode ".$env{'form.problemmode'});
my ($symb) = &Apache::lonnet::whichuser();
@@ -1387,6 +1513,12 @@ sub handler {
&newproblem($request);
}
} else {
+ # Set the event timer to zero if the "done button" was clicked. The button is
+ # part of the doneButton form created in lonmenu.pm
+ if ($symb && $env{'form.LC_interval_done'} eq 'true') {
+ &zero_timer($symb);
+ undef($env{'form.LC_interval_done'});
+ }
# just render the page normally outside of construction space
&Apache::lonxml::debug("not construct");
&renderpage($request,$file);
@@ -1400,5 +1532,175 @@ sub handler {
}
+sub template_dropdown_datastructure {
+ # gathering the all templates and their path, title, category and help topic
+ my @templates = get_template_list('problem');
+ # template category => title
+ my %tmplthash = ();
+ # template title => path
+ my %tmpltcontent = ();
+
+ foreach my $template (@templates){
+ # put in hash if the template is not empty
+ unless ($template->[1] eq ''){
+ push(@{$tmplthash{$template->[2]}}, $template->[1]);
+ push(@{$tmpltcontent{$template->[1]}},$template->[0]);
+ }
+ }
+
+ my $catList = [];
+ foreach my $cat (sort keys %tmplthash) {
+ my $catItems = [];
+ foreach my $title (sort @{$tmplthash{$cat}}) {
+ my $path = $tmpltcontent{$title}->[0];
+ my $code;
+ open(FH, "<$path");
+ while(){
+ $code.= $_ unless $_ =~ /()|(<\/problem>)/;
+ }
+ close(FH);
+
+ if ($code ne '') {
+ my $href = 'javascript:insertText(\'' . &convert_for_js(&HTML::Entities::encode($code,'<>&"')) . '\')';
+ my $currItem = [$href, $title, undef];
+ push @{$catItems}, $currItem;
+ }
+ }
+ push @{$catList}, [$catItems, $cat, undef];
+ }
+
+ return $catList;
+}
+
+sub responseblock_dropdown_datastructure {
+
+ my $mathCat = [
+ [
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_formularesponse())) . "\')", &mt("Formula Response"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_functionplotresponse())) . "\')", &mt("Function Plot Response"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_mathresponse())) . "\')", &mt("Math Response"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_numericalresponse())) . "\')", &mt("Numerical Response"), undef]
+ ],
+ &mt("Math"),
+ undef
+ ];
+
+ my $miscCat = [
+ [
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_imageresponse())) . "\')", &mt("Click on Image"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_customresponse())) . "\')", &mt("Custom Response"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_externalresponse())) . "\')", &mt("External Response"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_matchresponse())) . "\')", &mt("Match Two Lists"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_radiobuttonresponse())) . "\')", &mt("One out of N statements"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_optionresponse())) . "\')", &mt("Select from Options"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_rankresponse())) . "\')", &mt("Rank Values"), undef]
+ ],
+ &mt("Miscellaneous"),
+ undef
+ ];
+
+ my $chemCat = [
+ [
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_reactionresponse())) . "\')", &mt("Chemical Reaction"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicresponse())) . "\')", &mt("Organic Chemical Structure"), undef]
+ ],
+ &mt("Chemistry"),
+ undef
+ ];
+
+ my $textCat = [
+ [
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_stringresponse())) . "\')", &mt("String Response"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_essayresponse())) . "\')", &mt("Essay"), undef]
+ ],
+ &mt("Text"),
+ undef
+ ];
+
+ return [$mathCat, $miscCat, $chemCat, $textCat];
+}
+
+
+sub conditional_scripting_datastructure {
+# TODO: corresponding routines should be used for the javascript:insertText parts
+# instead of the placeholder routine default_xml_tag with the tags
+# e.g. &default_xml_tag("postanswerdate") should be replaced with a routine which
+# returns the corresponding content for this case
+
+#TODO translated is currently temporarily here, another solution should be found where the
+# needed string can be retrieved
+
+ my $translatedTag = '
+
+
+
+';
+ return [
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode($translatedTag)) . "\')", &mt("Translated Block"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("block"))) . "\')", &mt("Conditional Block"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("postanswerdate"))) . "\')", &mt("After Answer Date Block"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("preduedate"))) . "\')", &mt("Before Due Date Block"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("solved"))) . "\')", &mt("Block For After Solved"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("notsolved"))) . "\')", &mt("Block For When Not Solved"), undef]
+ ];
+}
+
+sub misc_datastructure {
+ return [
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_img())) . "\')", &mt("Image"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::lonplot::insert_gnuplot())) . "\')", &mt("GNU Plot"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicstructure())) . "\')", &mt("Organic Structure"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_script())) . "\')", &mt("Script Block"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("allow"))) . "\')", &mt("File Dependencies"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("import"))) . "\')", &mt("Import a File"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::londefdef::insert_meta())) . "\')", &mt("Custom Metadata"), undef],
+ ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("part"))) . "\')", &mt("Problem Part"), undef]
+ ];
+}
+
+# helper routine for the datastructure building subroutines
+sub default_xml_tag {
+ my ($tag) = @_;
+ return "\n<$tag>$tag>";
+}
+
+
+sub helpmenu_datastructure {
+
+ my $width = 500;
+ my $height = 600;
+
+ my $helpers = [
+ ['Problem_LON-CAPA_Functions', &mt('Script Functions')],
+ ['Greek_Symbols', &mt('Greek Symbols')],
+ ['Other_Symbols', &mt('Other Symbols')],
+ ['Authoring_Output_Tags', &mt('Output Tags')],
+ ['Authoring_Multilingual_Problems',
+ &mt('How to create problems in different languages')]
+ ];
+
+ my $help_structure = [];
+
+ foreach my $count (0..(scalar(@{$helpers})-1)) {
+ my $filename = $helpers->[$count]->[0];
+ my $title = $helpers->[$count]->[1];
+ my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename.hlp',$width,$height,'yes');");
+ push @{$help_structure}, [$href, $title, undef];
+ }
+
+ return $help_structure;
+}
+
+# we need substitution to not break javascript code
+sub convert_for_js {
+ my $return = shift;
+ $return =~ s|script|ESCAPEDSCRIPT|g;
+ $return =~ s|\\|\\\\|g;
+ $return =~ s|\n|\\r\\n|g;
+ $return =~ s|'|\\'|g;
+ $return =~ s|'|\\'|g;
+ return $return;
+}
+
1;
__END__