--- loncom/homework/structuretags.pm 2006/04/15 01:06:59 1.346
+++ loncom/homework/structuretags.pm 2013/07/15 14:32:55 1.514
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# definition of tags that give a structure to a document
#
-# $Id: structuretags.pm,v 1.346 2006/04/15 01:06:59 albertel Exp $
+# $Id: structuretags.pm,v 1.514 2013/07/15 14:32:55 bisitz 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,17 +59,131 @@ 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','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)=@_;
- my $bodytext=&Apache::lonxml::get_all_text("/web",$parser,$style);
- if ($target eq 'web' || $target eq 'webgrade') {
- return $bodytext;
+ if ($target ne 'edit' && $target ne 'modified') {
+ my $bodytext=&Apache::lonxml::get_all_text("/web",$parser,$style);
+ if ($target eq 'web' || $target eq 'webgrade') {
+ return $bodytext;
+ }
+ } elsif ($target eq "edit" ) {
+ my $bodytext =
+ &Apache::lonxml::get_all_text_unbalanced("/web",$parser);
+ my $result = &Apache::edit::tag_start($target,$token);
+ $result .= &Apache::edit::editfield($token->[1],$bodytext,'',80,1);
+ return $result;
+ } elsif ( $target eq "modified" ) {
+ return $token->[4].&Apache::edit::modifiedfield("/web",$parser);
}
return '';
}
@@ -58,9 +195,26 @@ sub end_web {
sub start_tex {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
my $result='';
- my $bodytext=&Apache::lonxml::get_all_text("/tex",$parser,$style);
- if ($target eq 'tex') {
- return $bodytext.' ';
+ if ($target ne 'edit' && $target ne 'modified') {
+ my $bodytext=&Apache::lonxml::get_all_text("/tex",$parser,$style);
+ if ($target eq 'tex') {
+
+ # 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 =
+ &Apache::lonxml::get_all_text_unbalanced("/tex",$parser);
+ my $result = &Apache::edit::tag_start($target,$token);
+ $result .= &Apache::edit::editfield($token->[1],$bodytext,'',80,1);
+ return $result;
+ } elsif ( $target eq "modified" ) {
+ return $token->[4].&Apache::edit::modifiedfield("/tex",$parser);
}
return $result;;
}
@@ -69,6 +223,55 @@ sub end_tex {
return '';
}
+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)=@_;
@@ -79,13 +282,79 @@ sub page_start {
}
}
-
if ($target eq 'tex') {
return
&Apache::londefdef::start_html($target,$token,$tagstack,
$parstack,$parser,$safeeval);
}
+ $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'})) {
$body_args{'skip_phases'}{'head'}=1;
@@ -93,13 +362,9 @@ sub page_start {
$extra_head .= &Apache::lonhtmlcommon::spellheader();
- my $css_href = &Apache::lonnet::EXT('resource.0.cssfile');
- if ($css_href =~ /\S/) {
- &Apache::lonxml::extlink($css_href);
- $extra_head .=
- '';
- }
- if ($target eq 'edit') {
+ $extra_head .= &Apache::londefdef::generate_css_links();
+
+ if ($env{'request.state'} eq 'construct') {
$extra_head.=&Apache::edit::js_change_detection().
" 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/) {
@@ -872,17 +1525,19 @@ sub end_problem {
}
if ($env{'form.print_discussions'} eq 'yes') {
$result.=&Apache::lonxml::xmlend($target,$parser);
- $result=~s/<\/html>//;
} else {
$result .= '\keephidden{ENDOFPROBLEM}\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}';
if (not $env{'request.symb'} =~ m/\.page_/) {
$result .= $endminipage.'\end{document} ';
} else {
- $result .= '';
+ $result .= $endminipage;
}
}
}
}
+ if ($target eq 'web') {
+ $result.=&Apache::functionplotresponse::init_script();
+ }
if ($target eq 'grade') {
&Apache::lonhomework::showhash(%Apache::lonhomework::results);
&finalize_storage();
@@ -905,7 +1560,6 @@ sub end_problem {
$result .= &problem_edit_footer();
} elsif ($target eq 'modified') {
$result .= $token->[2];
- $result.=&Apache::edit::handle_insertafter($token->[1]);
}
if ($env{'request.state'} eq 'construct' && $target eq 'web') {
@@ -914,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 .= "