--- loncom/xml/lonxml.pm 2005/06/17 17:51:15 1.377
+++ loncom/xml/lonxml.pm 2024/09/25 00:15:10 1.574
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
-# XML Parser Module
+# XML Parser Module
#
-# $Id: lonxml.pm,v 1.377 2005/06/17 17:51:15 albertel Exp $
+# $Id: lonxml.pm,v 1.574 2024/09/25 00:15:10 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -25,23 +25,43 @@
#
# http://www.lon-capa.org/
#
-# Copyright for TtHfunc and TtMfunc by Ian Hutchinson.
-# TtHfunc and TtMfunc (the "Code") may be compiled and linked into
-# binary executable programs or libraries distributed by the
-# Michigan State University (the "Licensee"), but any binaries so
+# Copyright for TtHfunc and TtMfunc by Ian Hutchinson.
+# TtHfunc and TtMfunc (the "Code") may be compiled and linked into
+# binary executable programs or libraries distributed by the
+# Michigan State University (the "Licensee"), but any binaries so
# distributed are hereby licensed only for use in the context
-# of a program or computational system for which the Licensee is the
-# primary author or distributor, and which performs substantial
+# of a program or computational system for which the Licensee is the
+# primary author or distributor, and which performs substantial
# additional tasks beyond the translation of (La)TeX into HTML.
# The C source of the Code may not be distributed by the Licensee
# to any other parties under any circumstances.
#
+=pod
-package Apache::lonxml;
+=head1 NAME
+
+Apache::lonxml
+
+=head1 SYNOPSIS
+
+XML Parsing Module
+
+This is part of the LearningOnline Network with CAPA project
+described at http://www.lon-capa.org.
+
+
+=head1 SUBROUTINES
+
+=cut
+
+
+
+package Apache::lonxml;
use vars
-qw(@pwd @outputstack $redirection $import @extlinks $metamode $evaluate %insertlist @namespace $errorcount $warningcount @htmlareafields);
+qw(@pwd @outputstack $redirection $import @extlinks $metamode $evaluate %insertlist @namespace $errorcount $warningcount);
use strict;
+use LONCAPA;
use HTML::LCParser();
use HTML::TreeBuilder();
use HTML::Entities();
@@ -49,9 +69,12 @@ use Safe();
use Safe::Hole();
use Math::Cephes();
use Math::Random();
+use Math::Calculus::Expression();
+use Number::FormatEng();
use Opcode();
use POSIX qw(strftime);
use Time::HiRes qw( gettimeofday tv_interval );
+use Symbol();
sub register {
my ($space,@taglist) = @_;
@@ -87,10 +110,17 @@ use Apache::loncommon();
use Apache::lonfeedback();
use Apache::lonmsg();
use Apache::loncacc();
+use Apache::lonmaxima();
+use Apache::lonr();
use Apache::lonlocal;
+use Apache::lonhtmlcommon();
+use Apache::functionplotresponse();
+use Apache::lonnavmaps();
+
+#==================================== Main subroutine: xmlparse
-#================================================== Main subroutine: xmlparse
#debugging control, to turn on debugging modify the correct handler
+
$Apache::lonxml::debug=0;
# keeps count of the number of warnings and errors generated in a parse
@@ -116,14 +146,14 @@ $metamode = 0;
# turns on and of run::evaluate actually derefencing var refs
$evaluate = 1;
-# data structure for eidt mode, determines what tags can go into what other tags
+# data structure for edit mode, determines what tags can go into what other tags
%insertlist=();
# stores the list of active tag namespaces
@namespace=();
-# has the dynamic menu been updated to know about this resource
-$Apache::lonxml::registered=0;
+# stores all Scrit Vars displays for later showing
+my @script_var_displays=();
# a pointer the the Apache request object
$Apache::lonxml::request='';
@@ -132,6 +162,16 @@ $Apache::lonxml::request='';
$Apache::lonxml::counter=1;
$Apache::lonxml::counter_changed=0;
+# Part counter hash. In analysis mode, the
+# problems can use this to record which parts increment the counter
+# by how much. The counter subs will maintain this hash via
+# their optional part parameters. Note that the assumption is that
+# analysis is done in one request and therefore it is not necessary to
+# save this information request-to-request.
+
+
+%Apache::lonxml::counters_per_part = ();
+
#internal check on whether to look at style defs
$Apache::lonxml::usestyle=1;
@@ -148,26 +188,17 @@ $Apache::lonxml::post_evaluate=1;
#a header message to emit in the case of any generated warning or errors
$Apache::lonxml::warnings_error_header='';
-sub xmlbegin {
- my ($style)=@_;
- my $output='';
- @htmlareafields=();
- if ($env{'browser.mathml'}) {
- $output=''
- #.''."\n"
-# .'] >'
- .''
- .'';
- } else {
- $output='';
- }
- if ($style eq 'encode') {
- $output=&HTML::Entities::encode($output,'<>&"');
- }
- return $output;
+# 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 xmlend {
@@ -177,143 +208,33 @@ sub xmlend {
if ($Apache::lonhomework::parsing_a_problem ||
$Apache::lonhomework::parsing_a_task ) {
$mode='problem';
- $status=$Apache::inputtags::status[-1];
+ $status=$Apache::inputtags::status[-1];
}
my $discussion;
- &Apache::loncommon::get_unprocessed_cgi
- ($env{'query_string'},['LONCAPA_INTERNAL_no_discussion']);
- if (! exists($env{'form.LONCAPA_INTERNAL_no_discussion'}) ||
- $env{'form.LONCAPA_INTERNAL_no_discussion'} ne 'true') {
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+ ['LONCAPA_INTERNAL_no_discussion']);
+ if (
+ ( (!exists($env{'form.LONCAPA_INTERNAL_no_discussion'}))
+ || ($env{'form.LONCAPA_INTERNAL_no_discussion'} ne 'true')
+ )
+ && ($env{'form.inhibitmenu'} ne 'yes')
+ ) {
$discussion=&Apache::lonfeedback::list_discussion($mode,$status);
}
if ($target eq 'tex') {
$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();
- }
-}
-
-sub tokeninputfield {
- my $defhost=$Apache::lonnet::perlvar{'lonHostID'};
- $defhost=~tr/a-z/A-Z/;
- return (<
- function updatetoken() {
- var comp=new Array;
- var barcode=unescape(document.tokeninput.barcode.value);
- comp=barcode.split('*');
- if (typeof(comp[0])!="undefined") {
- document.tokeninput.codeone.value=comp[0];
- }
- if (typeof(comp[1])!="undefined") {
- document.tokeninput.codetwo.value=comp[1];
- }
- if (typeof(comp[2])!="undefined") {
- comp[2]=comp[2].toUpperCase();
- document.tokeninput.codethree.value=comp[2];
- }
- document.tokeninput.barcode.value='';
- }
-
-
-ENDINPUTFIELD
-}
-
-sub maketoken {
- my ($symb,$tuname,$tudom,$tcrsid)=@_;
- unless ($symb) {
- $symb=&Apache::lonnet::symbread();
- }
- unless ($tuname) {
- $tuname=$env{'user.name'};
- $tudom=$env{'user.domain'};
- $tcrsid=$env{'request.course.id'};
- }
-
- return &Apache::lonnet::checkout($symb,$tuname,$tudom,$tcrsid);
-}
-
-sub printtokenheader {
- my ($target,$token,$tsymb,$tcrsid,$tudom,$tuname)=@_;
- unless ($token) { return ''; }
-
- my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();
- unless ($tsymb) {
- $tsymb=$symb;
- }
- unless ($tuname) {
- $tuname=$name;
- $tudom=$domain;
- $tcrsid=$courseid;
- }
-
- my %reply=&Apache::lonnet::get('environment',
- ['firstname','middlename','lastname','generation'],
- $tudom,$tuname);
- my $plainname=$reply{'firstname'}.' '.
- $reply{'middlename'}.' '.
- $reply{'lastname'}.' '.
- $reply{'generation'};
-
- if ($target eq 'web') {
- my %idhash=&Apache::lonnet::idrget($tudom,($tuname));
- return
- ''.
- &mt('Checked out for').' '.$plainname.
- ' '.&mt('User').': '.$tuname.' at '.$tudom.
- ' '.&mt('ID').': '.$idhash{$tuname}.
- ' '.&mt('CourseID').': '.$tcrsid.
- ' '.&mt('Course').': '.$env{'course.'.$tcrsid.'.description'}.
- ' '.&mt('DocID').': '.$token.
- ' '.&mt('Time').': '.&Apache::lonlocal::locallocaltime().'';
- } else {
- return $token;
}
-}
-sub fontsettings {
- my $headerstring='';
- if (($env{'browser.os'} eq 'mac') && (!$env{'browser.mathml'})) {
- $headerstring.=
- '';
- } elsif (!$env{'browser.mathml'} && $env{'browser.unicode'}) {
- $headerstring.=
- '';
- }
- return $headerstring;
+ return $discussion;
}
sub printalltags {
- my $temp;
- foreach $temp (sort keys %Apache::lonxml::alltags) {
- &Apache::lonxml::debug("$temp -- ".
- join(',',@{ $Apache::lonxml::alltags{$temp} }));
- }
+ foreach my $temp (sort(keys(%Apache::lonxml::alltags))) {
+ &Apache::lonxml::debug("$temp -- ".
+ join(',',@{ $Apache::lonxml::alltags{$temp} }));
+ }
}
sub xmlparse {
@@ -343,13 +264,14 @@ sub xmlparse {
}
}
}
- } elsif ($env{'construct.style'} && ($env{'request.state'} eq 'construct')) {
+ } elsif ($env{'construct.style'}
+ && ($env{'request.state'} eq 'construct')) {
my $location=&Apache::lonnet::filelocation('',$env{'construct.style'});
my $styletext=&Apache::lonnet::getfile($location);
- if ($styletext ne '-1') {
- %style_for_target = (%style_for_target,
- &Apache::style::styleparser($target,$styletext));
- }
+ if ($styletext ne '-1') {
+ %style_for_target = (%style_for_target,
+ &Apache::style::styleparser($target,$styletext));
+ }
}
#&printalltags();
my @pars = ();
@@ -369,14 +291,36 @@ sub xmlparse {
&initdepth();
&init_alarm();
my $finaloutput = &inner_xmlparse($target,\@stack,\@parstack,\@pars,
- $safeeval,\%style_for_target);
+ $safeeval,\%style_for_target,1);
+ if (@stack) {
+ &warning(&mt('At end of file some tags were still left unclosed:').
+ ' <'.join('>, <',reverse(@stack)).
+ '>');
+ }
if ($env{'request.uri'}) {
&writeallows($env{'request.uri'});
}
&do_registered_ssi();
if ($Apache::lonxml::counter_changed) { &store_counter() }
+
+ &clean_safespace($safeeval);
+
+ if (@script_var_displays) {
+ if ($finaloutput =~ m{\s*\s*$}s) {
+ my $scriptoutput = join('',@script_var_displays);
+ $finaloutput=~s{(