--- loncom/xml/lonxml.pm 2005/10/18 21:49:37 1.385
+++ loncom/xml/lonxml.pm 2006/04/18 20:43:47 1.407
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# XML Parser Module
#
-# $Id: lonxml.pm,v 1.385 2005/10/18 21:49:37 albertel Exp $
+# $Id: lonxml.pm,v 1.407 2006/04/18 20:43:47 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -52,6 +52,7 @@ use Math::Random();
use Opcode();
use POSIX qw(strftime);
use Time::HiRes qw( gettimeofday tv_interval );
+use Symbol();
sub register {
my ($space,@taglist) = @_;
@@ -148,6 +149,19 @@ $Apache::lonxml::post_evaluate=1;
#a header message to emit in the case of any generated warning or errors
$Apache::lonxml::warnings_error_header='';
+# Control whether or not LaTeX symbols should be substituted for their
+# \ style equivalents...this may be turned off e.g. in an verbatim
+# environment.
+
+$Apache::lonxml::substitute_LaTeX_symbols = 1; # Starts out on.
+
+sub enable_LaTeX_substitutions {
+ $Apache::lonxml::substitute_LaTeX_symbols = 1;
+}
+sub disable_LaTeX_substitutions {
+ $Apache::lonxml::substitute_LaTeX_symbols = 0;
+}
+
sub xmlbegin {
my ($style)=@_;
my $output='';
@@ -190,9 +204,9 @@ sub xmlend {
$discussion.='\keephidden{ENDOFPROBLEM}\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\end{document}';
&Apache::lonxml::newparser($parser,\$discussion,'');
return '';
- } else {
- return $discussion.&Apache::loncommon::endbodytag();
}
+
+ return $discussion;
}
sub tokeninputfield {
@@ -272,13 +286,7 @@ sub printtokenheader {
$tcrsid=$courseid;
}
- my %reply=&Apache::lonnet::get('environment',
- ['firstname','middlename','lastname','generation'],
- $tudom,$tuname);
- my $plainname=$reply{'firstname'}.' '.
- $reply{'middlename'}.' '.
- $reply{'lastname'}.' '.
- $reply{'generation'};
+ my $plainname=&Apache::loncommon::plainname($tuname,$tudom);
if ($target eq 'web') {
my %idhash=&Apache::lonnet::idrget($tudom,($tuname));
@@ -369,13 +377,16 @@ sub xmlparse {
&initdepth();
&init_alarm();
my $finaloutput = &inner_xmlparse($target,\@stack,\@parstack,\@pars,
- $safeeval,\%style_for_target);
+ $safeeval,\%style_for_target,1);
if ($env{'request.uri'}) {
&writeallows($env{'request.uri'});
}
&do_registered_ssi();
if ($Apache::lonxml::counter_changed) { &store_counter() }
+
+ &clean_safespace($safeeval);
+
if ($env{'form.return_only_error_and_warning_counts'}) {
return "$errorcount:$warningcount";
}
@@ -384,6 +395,13 @@ sub xmlparse {
sub latex_special_symbols {
my ($string,$where)=@_;
+ #
+ # If e.g. in verbatim mode, then don't substitute.
+ # but return original string.
+ #
+ if (!($Apache::lonxml::substitute_LaTeX_symbols)) {
+ return $string;
+ }
if ($where eq 'header') {
$string =~ s/(\\|_|\^)/ /g;
$string =~ s/(\$|%|\{|\})/\\$1/g;
@@ -413,11 +431,12 @@ sub latex_special_symbols {
}
sub inner_xmlparse {
- my ($target,$stack,$parstack,$pars,$safeeval,$style_for_target)=@_;
+ my ($target,$stack,$parstack,$pars,$safeeval,$style_for_target,$start)=@_;
my $finaloutput = '';
my $result;
my $token;
my $dontpop=0;
+ my $startredirection = $Apache::lonxml::redirection;
while ( $#$pars > -1 ) {
while ($token = $$pars['-1']->get_token) {
if (($token->[0] eq 'T') || ($token->[0] eq 'C') ) {
@@ -527,7 +546,12 @@ sub inner_xmlparse {
# $finaloutput.=&endredirection;
# }
-
+ if ( $start && $target eq 'grade') { &endredirection(); }
+ if ( $Apache::lonxml::redirection > $startredirection) {
+ while ($Apache::lonxml::redirection > $startredirection) {
+ $finaloutput .= &endredirection();
+ }
+ }
if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {
$finaloutput=&afterburn($finaloutput);
}
@@ -625,6 +649,7 @@ sub setup_globals {
@Apache::lonxml::ssi_info=();
$Apache::lonxml::post_evaluate=1;
$Apache::lonxml::warnings_error_header='';
+ $Apache::lonxml::substitute_LaTeX_symbols = 1;
if ($target eq 'meta') {
$Apache::lonxml::redirection = 0;
$Apache::lonxml::metamode = 1;
@@ -636,7 +661,7 @@ sub setup_globals {
$Apache::lonxml::evaluate = 1;
$Apache::lonxml::import = 1;
} elsif ($target eq 'grade') {
- &startredirection;
+ &startredirection(); #ended in inner_xmlparse on exit
$Apache::lonxml::metamode = 0;
$Apache::lonxml::evaluate = 1;
$Apache::lonxml::import = 1;
@@ -795,6 +820,34 @@ sub init_safespace {
&initialize_rndseed($safeeval);
}
+sub clean_safespace {
+ my ($safeeval) = @_;
+ delete_package_recurse($safeeval->{Root});
+}
+
+sub delete_package_recurse {
+ my ($package) = @_;
+ my @subp;
+ {
+ no strict 'refs';
+ while (my ($key,$val) = each(%{*{"$package\::"}})) {
+ if (!defined($val)) { next; }
+ local (*ENTRY) = $val;
+ if (defined *ENTRY{HASH} && $key =~ /::$/ &&
+ $key ne "main::" && $key ne "::")
+ {
+ my ($p) = $package ne "main" ? "$package\::" : "";
+ ($p .= $key) =~ s/::$//;
+ push(@subp,$p);
+ }
+ }
+ }
+ foreach my $p (@subp) {
+ delete_package_recurse($p);
+ }
+ Symbol::delete_package($package);
+}
+
sub initialize_rndseed {
my ($safeeval)=@_;
my $rndseed;
@@ -918,6 +971,16 @@ sub decreasedepth {
#print "
e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n";
}
+sub get_id {
+ my ($parstack,$safeeval)=@_;
+ my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval);
+ if ($env{'request.state'} eq 'construct' && $id =~ /(\.|_)/) {
+ &error(&mt("IDs are not allowed to contain "_" or ".""));
+ }
+ if ($id =~ /^\s*$/) { $id = $Apache::lonxml::curdepth; }
+ return $id;
+}
+
sub get_all_text_unbalanced {
#there is a copy of this in lonpublisher.pm
my($tag,$pars)= @_;
@@ -926,7 +989,7 @@ sub get_all_text_unbalanced {
$tag='<'.$tag.'>';
while ($token = $$pars[-1]->get_token) {
if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
- if ($token->[2]) {
+ if ($token->[0] eq 'T' && $token->[2]) {
$result.='[1].']]>';
} else {
$result.=$token->[1];
@@ -961,7 +1024,10 @@ sub increment_counter {
}
sub init_counter {
- if (defined($env{'form.counter'})) {
+ if ($env{'request.state'} eq 'construct') {
+ $Apache::lonxml::counter=1;
+ $Apache::lonxml::counter_changed=1;
+ } elsif (defined($env{'form.counter'})) {
$Apache::lonxml::counter=$env{'form.counter'};
$Apache::lonxml::counter_changed=0;
} else {
@@ -972,9 +1038,36 @@ sub init_counter {
sub store_counter {
&Apache::lonnet::appenv(('form.counter' => $Apache::lonxml::counter));
+ $Apache::lonxml::counter_changed=0;
return '';
}
+{
+ my $state;
+ sub clear_problem_counter {
+ undef($state);
+ &Apache::lonnet::delenv('form.counter');
+ &Apache::lonxml::init_counter();
+ &Apache::lonxml::store_counter();
+ }
+
+ sub remember_problem_counter {
+ &Apache::lonnet::transfer_profile_to_env();
+ $state = $env{'form.counter'};
+ }
+
+ sub restore_problem_counter {
+ if (defined($state)) {
+ &Apache::lonnet::appenv(('form.counter' => $state));
+ }
+ }
+ sub get_problem_counter {
+ if ($Apache::lonxml::counter_changed) { &store_counter() }
+ &Apache::lonnet::transfer_profile_to_env();
+ return $env{'form.counter'};
+ }
+}
+
sub get_all_text {
my($tag,$pars,$style)= @_;
my $gotfullstack=1;
@@ -1365,17 +1458,13 @@ sub handler {
my $result = '';
my $filecontents=&Apache::lonnet::getfile($file);
if ($filecontents eq -1) {
- my $bodytag=&Apache::loncommon::bodytag('File Error');
+ my $start_page=&Apache::loncommon::start_page('File Error');
+ my $end_page=&Apache::loncommon::end_page('File Error');
my $fnf=&mt('File not found');
$result=(<
-
-$fnf
-
-$bodytag
+$start_page
$fnf: $file
-