--- loncom/xml/lonxml.pm 2002/11/13 23:21:07 1.215 +++ loncom/xml/lonxml.pm 2003/03/30 21:58:17 1.243 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # XML Parser Module # -# $Id: lonxml.pm,v 1.215 2002/11/13 23:21:07 albertel Exp $ +# $Id: lonxml.pm,v 1.243 2003/03/30 21:58:17 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -41,7 +41,6 @@ # 6/1/1 Gerd Kortemeyer # 2/21,3/13 Guy # 3/29,5/4 Gerd Kortemeyer -# 5/10 Scott Harrison # 5/26 Gerd Kortemeyer # 5/27 H. K. Ng # 6/2,6/3,6/8,6/9 Gerd Kortemeyer @@ -101,6 +100,7 @@ use Apache::File(); use Apache::loncommon(); use Apache::lonfeedback(); use Apache::lonmsg(); +use Apache::loncacc(); #================================================== Main subroutine: xmlparse #debugging control, to turn on debugging modify the correct handler @@ -144,8 +144,8 @@ $Apache::lonxml::registered=0; # a pointer the the Apache request object $Apache::lonxml::request=''; -# a problem number counter, and check on hether it is used -$Apache::lonxml::counter=0; +# a problem number counter, and check on ether it is used +$Apache::lonxml::counter=1; $Apache::lonxml::counter_changed=0; #internal check on whether to look at style defs @@ -191,10 +191,18 @@ sub xmlend { my $idx; for ($idx=1;$idx<=$contrib{'version'};$idx++) { my $hidden=($contrib{'hidden'}=~/\.$idx\./); - unless (($hidden) && (!$seeid)) { + my $deleted=($contrib{'deleted'}=~/\.$idx\./); + unless ((($hidden) && (!$seeid)) || ($deleted)) { my $message=$contrib{$idx.':message'}; $message=~s/\n/\<br \/\>/g; $message=&Apache::lontexconvert::msgtexconverted($message); + if ($contrib{$idx.':attachmenturl'}) { + my ($fname,$ft) + =($contrib{$idx.':attachmenturl'}=~/\/(\w+)\.(\w+)$/); + $message.='<p>Attachment: <a href="'. + &Apache::lonnet::tokenwrapper($contrib{$idx.':attachmenturl'}). + '"><tt>'.$fname.'.'.$ft.'</tt></a>'; + } if ($message) { if ($hidden) { $message='<font color="#888888">'.$message.'</font>'; @@ -225,8 +233,10 @@ sub xmlend { } else { $sender.=' <a href="/adm/feedback?hide='. $symb.':::'.$idx.'">Hide</a>'; - } - } + } + $sender.=' <a href="/adm/feedback?deldisc='. + $symb.':::'.$idx.'">Delete</a>'; + } } else { if ($screenname) { $sender='<i>'.$screenname.'</i>'; @@ -245,7 +255,7 @@ sub xmlend { } if ($discussiononly) { $discussion.=(<<ENDDISCUSS); -<form action="/adm/feedback" method="post" name="mailform"> +<form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data"> <input type="submit" name="discuss" value="Post Discussion" /> <input type="submit" name="anondiscuss" value="Post Anonymous Discussion" /> <input type="hidden" name="symb" value="$symb" /> @@ -254,6 +264,9 @@ sub xmlend { <font size="1">Note: in anonymous discussion, your name is visible only to course faculty</font><br /> <textarea name=comment cols=60 rows=10 wrap=hard></textarea> +<p> +Attachment (128 KB max size): <input type="file" name="attachment" /> +</p> </form> ENDDISCUSS $discussion.=&Apache::lonfeedback::generate_preview_button(); @@ -267,7 +280,7 @@ sub tokeninputfield { my $defhost=$Apache::lonnet::perlvar{'lonHostID'}; $defhost=~tr/a-z/A-Z/; return (<<ENDINPUTFIELD) -<script> +<script type="text/javascript"> function updatetoken() { var comp=new Array; var barcode=unescape(document.tokeninput.barcode.value); @@ -351,7 +364,7 @@ sub printtokenheader { if ($target eq 'web') { my %idhash=&Apache::lonnet::idrget($tudom,($tuname)); return - '<img align="right" src="/cgi-bin/barcode.gif?encode='.$token.'" />'. + '<img align="right" src="/cgi-bin/barcode.png?encode='.$token.'" />'. 'Checked out for '.$plainname. '<br />User: '.$tuname.' at '.$tudom. '<br />ID: '.$idhash{$tuname}. @@ -373,153 +386,6 @@ sub fontsettings() { return $headerstring; } -sub registerurl { - my $forcereg=shift; - my $target = shift; - my $result = ''; - - if ($target eq 'edit') { - $result .="<script>\n". - "if (typeof menu != 'undefined') {menu.currentURL=null;}\n". - &Apache::loncommon::browser_and_searcher_javascript(). - "\n</script>\n"; - } - if ((($ENV{'request.publicaccess'}) || - (!&Apache::lonnet::is_on_map($ENV{'REQUEST_URI'}))) && - (!$forcereg)) { - return $result. - '<script>function LONCAPAreg(){} function LONCAPAstale(){}</script>'; - } - if ($Apache::lonxml::registered && !$forcereg) { return ''; } - $Apache::lonxml::registered=1; - my $nothing=''; - if ($ENV{'browser.type'} eq 'explorer') { $nothing='javascript:void(0);'; } - my $newmail=''; - if (&Apache::lonmsg::newmail()) { - $newmail='menu.setstatus("you have","messages");'; - } - my $timesync='menu.syncclock(1000*'.time.');'; - if (($ENV{'REQUEST_URI'}!~/^\/(res\/)*adm\//) || ($forcereg)) { - my $hwkadd=''; - if ($ENV{'request.filename'}=~/\.(problem|exam|quiz|assess|survey|form)$/) { - if (&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) { - $hwkadd.=(<<ENDSUBM); - menu.switchbutton(7,1,'subm.gif','view sub','missions','gocmd("/adm/grades","submission")', - 'View user submissions for this assessment resource'); -ENDSUBM - } - if (&Apache::lonnet::allowed('mgr',$ENV{'request.course.id'})) { - $hwkadd.=(<<ENDGRDS); - menu.switchbutton(7,2,'pgrd.gif','problem','grades','gocmd("/adm/grades","gradingmenu")', - 'Modify user grades for this assessment resource'); -ENDGRDS - } - if (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'})) { - $hwkadd.=(<<ENDPARM); - menu.switchbutton(7,3,'pparm.gif','problem','parms','gocmd("/adm/parmset","set")', - 'Modify deadlines, etc, for this assessment resource'); -ENDPARM - } - } - $result = (<<ENDREGTHIS); - -<script language="JavaScript"> -// BEGIN LON-CAPA Internal - - function LONCAPAreg() { - menu=window.open("$nothing","LONCAPAmenu","",false); - menu.clearTimeout(menu.menucltim); - $timesync - $newmail - menu.currentURL=window.location.pathname; - menu.reloadURL=window.location.pathname; - menu.currentSymb="$ENV{'request.symb'}"; - menu.reloadSymb="$ENV{'request.symb'}"; - menu.currentStale=0; - menu.clearbut(3,1); - menu.switchbutton - (6,3,'catalog.gif','catalog','info','catalog_info()'); - menu.switchbutton - (8,1,'eval.gif','evaluate','this','gopost("/adm/evaluate",currentURL)','Provide my evaluation of this resource'); - menu.switchbutton - (8,2,'fdbk.gif','feedback','discuss','gopost("/adm/feedback",currentURL)','Provide feedback messages or contribute to the course discussion about this resource'); - menu.switchbutton - (8,3,'prt.gif','prepare','printout','gopost("/adm/printout",currentURL)','Prepare a printable document'); - menu.switchbutton - (2,1,'back.gif','backward','','gopost("/adm/flip","back:"+currentURL)','Go to the previous resource in the course sequence'); - menu.switchbutton - (2,3,'forw.gif','forward','','gopost("/adm/flip","forward:"+currentURL)','Go to the next resource in the course sequence'); - menu.switchbutton - (9,1,'sbkm.gif','set','bookmark','set_bookmark()','Set a bookmark for this resource'); - menu.switchbutton - (9,2,'vbkm.gif','view','bookmark','edit_bookmarks()','Use or edit my bookmark collection'); - menu.switchbutton - (9,3,'anot.gif','anno-','tations','annotate()','Make notes and annotations about this resource'); - $hwkadd - } - - function LONCAPAstale() { - menu=window.open("$nothing","LONCAPAmenu","",false); - menu.currentStale=1; - if (menu.reloadURL!='' && menu.reloadURL!= null) { - menu.switchbutton - (3,1,'reload.gif','return','location','go(reloadURL)','Return to the last known location in the course sequence'); - } - menu.clearbut(7,1); - menu.clearbut(7,2); - menu.clearbut(7,3); - menu.menucltim=menu.setTimeout( - 'clearbut(2,1);clearbut(2,3);clearbut(8,1);clearbut(8,2);clearbut(8,3);'+ - 'clearbut(9,1);clearbut(9,2);clearbut(9,3);clearbut(6,3)', - 2000); - - } - -// END LON-CAPA Internal -</script> -ENDREGTHIS - - } else { - $result = (<<ENDDONOTREGTHIS); - -<script language="JavaScript"> -// BEGIN LON-CAPA Internal - - function LONCAPAreg() { - menu=window.open("$nothing","LONCAPAmenu","",false); - $timesync - menu.currentStale=1; - menu.clearbut(2,1); - menu.clearbut(2,3); - menu.clearbut(8,1); - menu.clearbut(8,2); - menu.clearbut(8,3); - if (menu.currentURL) { - menu.switchbutton - (3,1,'reload.gif','return','location','go(currentURL)'); - } else { - menu.clearbut(3,1); - } - } - - function LONCAPAstale() { - } - -// END LON-CAPA Internal -</script> -ENDDONOTREGTHIS - } - return $result; -} - -sub loadevents() { - return 'LONCAPAreg();'; -} - -sub unloadevents() { - return 'LONCAPAstale();'; -} - sub printalltags { my $temp; foreach $temp (sort keys %Apache::lonxml::alltags) { @@ -532,6 +398,9 @@ sub xmlparse { my ($request,$target,$content_file_string,$safeinit,%style_for_target) = @_; &setup_globals($request,$target); + &Apache::inputtags::initialize_inputtags(); + &Apache::outputtags::initialize_outputtags(); + &Apache::edit::initialize_edit(); # # do we have a course style file? # @@ -597,18 +466,22 @@ sub htmlclean { } sub latex_special_symbols { - my ($current_token,$stack,$parstack)=@_; - $current_token=~s/\\/\\char92 /g; - $current_token=~s/\^/\\char94 /g; - $current_token=~s/\~/\\char126 /g; - $current_token=~s/(&[^a-z\#])/\\$1/g; - $current_token=~s/([^&])\#/$1\\#/g; - $current_token=~s/(\$|_|{|})/\\$1/g; - $current_token=~s/\\char92 /\\texttt{\\char92}/g; - $current_token=~s/>/\$>\$/g; #more - $current_token=~s/</\$<\$/g; #less - if ($current_token=~m/\d%/) {$current_token =~ s/(\d)%/$1\\%/g;} #percent after digit - if ($current_token=~m/\s%/) {$current_token =~ s/(\s)%/$1\\%/g;} #persent after space + my ($current_token,$stack,$parstack,$where)=@_; + if ($where eq 'header') { + $current_token =~ s/(\\|_|\^)/ /g; + $current_token =~ s/(\$|%|\#|&|\{|\})/\\$1/g; + } else { + $current_token=~s/\\ /\\char92 /g; + $current_token=~s/\^/\\char94 /g; + $current_token=~s/\~/\\char126 /g; + $current_token=~s/(&[^a-z\#])/\\$1/g; + $current_token=~s/([^&])\#/$1\\#/g; + $current_token=~s/(\$|_|{|})/\\$1/g; + $current_token=~s/\\char92 /\\texttt{\\char92}/g; + $current_token=~s/(>|<)/\$$1\$/g; #more or less + if ($current_token=~m/\d%/) {$current_token =~ s/(\d)%/$1\\%/g;} #percent after digit + if ($current_token=~m/\s%/) {$current_token =~ s/(\s)%/$1\\%/g;} #persent after space + } return $current_token; } @@ -623,8 +496,8 @@ sub inner_xmlparse { if ($metamode<1) { my $text=$token->[1]; if ($token->[0] eq 'C' && $target eq 'tex') { - $text = '%'.$text; - $text =~ s/[\n\r]//g; + $text = ''; +# $text = '%'.$text."\n"; } $result.=$text; } @@ -702,7 +575,7 @@ sub inner_xmlparse { if ($token->[0] eq 'E') { &end_tag($stack,$parstack,$token); } - } + } if ($#$pars > -1) { pop @$pars; pop @Apache::lonxml::pwd; @@ -716,7 +589,7 @@ sub inner_xmlparse { if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) { $finaloutput=&afterburn($finaloutput); - } + } return $finaloutput; } @@ -728,6 +601,8 @@ sub callsub { my $sub1; no strict 'refs'; my $tag=$token->[1]; +# get utterly rid of extended html tags + if ($tag=~/^x\-/i) { return ''; } my $space=$Apache::lonxml::alltags{$tag}[-1]; if (!$space) { $tag=~tr/A-Z/a-z/; @@ -744,13 +619,13 @@ sub callsub { } if (!$deleted) { if ($space) { - &Apache::lonxml::debug("Calling sub $sub in $space $metamode"); + #&Apache::lonxml::debug("Calling sub $sub in $space $metamode"); $sub1="$space\:\:$sub"; ($currentstring,$nodefault) = &$sub1($target,$token,$tagstack, $parstack,$parser,$safeeval, $style); } else { - &Apache::lonxml::debug("NOT Calling sub $sub in $space $metamode"); + #&Apache::lonxml::debug("NOT Calling sub $sub in $space $metamode"); if ($metamode <1) { if (defined($token->[4]) && ($metamode < 1)) { $currentstring = $token->[4]; @@ -762,7 +637,7 @@ sub callsub { # &Apache::lonxml::debug("nodefalt:$nodefault:"); if ($currentstring eq '' && $nodefault eq '') { if ($target eq 'edit') { - &Apache::lonxml::debug("doing default edit for $token->[1]"); + #&Apache::lonxml::debug("doing default edit for $token->[1]"); if ($token->[0] eq 'S') { $currentstring = &Apache::edit::tag_start($target,$token); } elsif ($token->[0] eq 'E') { @@ -930,7 +805,7 @@ sub default_homework_load { my ($safeeval)=@_; &Apache::lonxml::debug('Loading default_homework'); my $default=&Apache::lonnet::getfile('/home/httpd/html/res/adm/includes/default_homework.lcpm'); - if ($default == -1) { + if ($default eq -1) { &Apache::lonxml::error("<b>Unable to find <i>default_homework.lcpm</i></b>"); } else { &Apache::run::run($default,$safeeval); @@ -1029,7 +904,7 @@ sub increment_counter { sub init_counter { if (defined($ENV{'form.counter'})) { $Apache::lonxml::counter=$ENV{'form.counter'}; - } elsif (not defined($Apache::lonxml::counter)) { + } else { $Apache::lonxml::counter=1; &store_counter(); } @@ -1044,7 +919,9 @@ sub store_counter { sub get_all_text { my($tag,$pars)= @_; &Apache::lonxml::debug("Got a ".ref($pars)); + my $gotfullstack=1; if (ref($pars) ne 'ARRAY') { + $gotfullstack=0; $pars=[$pars]; } my $depth=0; @@ -1053,7 +930,8 @@ sub get_all_text { if ( $tag =~ m:^/: ) { my $tag=substr($tag,1); #&Apache::lonxml::debug("have:$tag:"); - while (($depth >=0) && ($#$pars > -1)) { + my $top_empty=0; + while (($depth >=0) && ($#$pars > -1) && (!$top_empty)) { while (($depth >=0) && ($token = $$pars[-1]->get_token)) { #&Apache::lonxml::debug("e token:$token->[0]:$depth:$token->[1]:".$#$pars.":".$#Apache::lonxml::pwd); if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) { @@ -1071,11 +949,21 @@ sub get_all_text { } } } + if (($depth >=0) && ($#$pars == 0) ) { $top_empty=1; } if (($depth >=0) && ($#$pars > 0) ) { pop(@$pars); pop(@Apache::lonxml::pwd); } } + if ($top_empty && $depth >= 0) { + #never found the end tag ran out of text, throw error send back blank + &error('Never found end tag for <'.$tag.'>'); + if ($gotfullstack) { + my $newstring='</'.$tag.'>'.$result; + &Apache::lonxml::newparser($pars,\$newstring); + } + $result=''; + } } else { while ($#$pars > -1) { while ($token = $$pars[-1]->get_token) { @@ -1127,7 +1015,7 @@ sub parstring { foreach (@{$token->[3]}) { unless ($_=~/\W/) { my $val=$token->[2]->{$_}; - $val =~ s/([\%\@\\\"])/\\$1/g; + $val =~ s/([\%\@\\\"\'])/\\$1/g; #if ($val =~ m/^[\%\@]/) { $val="\\".$val; } $temp .= "my \$$_=\"$val\";" } @@ -1181,7 +1069,7 @@ sub afterburn { $matchthis=~s/\_+/\\s\+/g; $result=~s/($matchthis)/\<a name=\"$anchorname\"\>$1\<\/a\>/s; $result.=(<<"ENDSCRIPT"); -<script> +<script type="text/javascript"> document.location.hash='$anchorname'; </script> ENDSCRIPT @@ -1222,6 +1110,13 @@ sub inserteditinfo { my ($result,$filecontents)=@_; $filecontents = &HTML::Entities::encode($filecontents); # my $editheader='<a href="#editsection">Edit below</a><hr />'; + my $xml_help = '<table><tr><td>'. + &Apache::loncommon::help_open_topic("Greek_Symbols",'Greek Symbols', + undef,undef,600) + .'</td><td>'. + &Apache::loncommon::help_open_topic("Other_Symbols",'Other Symbols', + undef,undef,600) + .'</td></tr></table>'; my $buttons=(<<BUTTONS); <input type="submit" name="attemptclean" value="Save and then attempt to clean HTML" /> @@ -1232,6 +1127,7 @@ BUTTONS <hr /> <a name="editsection" /> <form method="post"> +$xml_help <input type="hidden" name="editmode" value="Edit" /> $buttons<br /> <textarea cols="80" rows="40" name="filecont">$filecontents</textarea> @@ -1301,7 +1197,7 @@ sub handler { my %mystyle; my $result = ''; my $filecontents=&Apache::lonnet::getfile($file); - if ($filecontents == -1) { + if ($filecontents eq -1) { $result=(<<ENDNOTFOUND); <html> <head> @@ -1417,14 +1313,22 @@ sub get_param_var { if ( ! $context ) { $context = -1; } my $args =''; if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; } + &Apache::lonxml::debug("Args are $args param is $param"); if ($case_insensitive) { if (! ($args=~s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei)) { return undef; } } elsif ( $args !~ /my \$\Q$param\E=\"/ ) { return undef; } my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #' - if ($value =~ /^[\$\@\%]/) { - return &Apache::run::run("return $value",$safeeval,1); + &Apache::lonxml::debug("first run is $value"); + if ($value =~ /^[\$\@\%]\w+$/) { + &Apache::lonxml::debug("doing second"); + my @result=&Apache::run::run("return $value",$safeeval,1); + if (!defined($result[0])) { + return $value + } else { + if (wantarray) { return @result; } else { return $result[0]; } + } } else { return $value; }