You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(53) |
Feb
(56) |
Mar
|
Apr
|
May
(30) |
Jun
(78) |
Jul
(121) |
Aug
(155) |
Sep
(77) |
Oct
(61) |
Nov
(45) |
Dec
(94) |
2006 |
Jan
(116) |
Feb
(33) |
Mar
(11) |
Apr
(23) |
May
(60) |
Jun
(89) |
Jul
(130) |
Aug
(109) |
Sep
(124) |
Oct
(63) |
Nov
(82) |
Dec
(45) |
2007 |
Jan
(31) |
Feb
(35) |
Mar
(123) |
Apr
(36) |
May
(18) |
Jun
(134) |
Jul
(133) |
Aug
(241) |
Sep
(126) |
Oct
(31) |
Nov
(15) |
Dec
(5) |
2008 |
Jan
(11) |
Feb
(6) |
Mar
(16) |
Apr
(29) |
May
(43) |
Jun
(149) |
Jul
(27) |
Aug
(29) |
Sep
(37) |
Oct
(20) |
Nov
(4) |
Dec
(6) |
2009 |
Jan
(34) |
Feb
(30) |
Mar
(16) |
Apr
(6) |
May
(1) |
Jun
(32) |
Jul
(22) |
Aug
(7) |
Sep
(18) |
Oct
(50) |
Nov
(22) |
Dec
(8) |
2010 |
Jan
(17) |
Feb
(15) |
Mar
(10) |
Apr
(9) |
May
(67) |
Jun
(30) |
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
|
From: Sam H. v. a. <we...@ma...> - 2005-12-01 20:37:21
|
Log Message: ----------- Modified Files: -------------- CVSROOT: config Revision Data ------------- |
From: Sam H. v. a. <we...@ma...> - 2005-12-01 20:24:24
|
Log Message: ----------- Modified Files: -------------- CVSROOT: config Revision Data ------------- Index: config =================================================================== RCS file: /webwork/cvs/system/CVSROOT/config,v retrieving revision 1.3 retrieving revision 1.4 diff -Lconfig -Lconfig -u -r1.3 -r1.4 --- config +++ config @@ -1,5 +1,5 @@ # Set this to "no" if pserver shouldn't check system users/passwords -SystemAuth=no +#SystemAuth=no # Put CVS lock files in this directory rather than directly in the repository. LockDir=/var/lock/cvs |
From: Sam H. v. a. <we...@ma...> - 2005-12-01 19:50:42
|
Log Message: ----------- SystemAuth=no Modified Files: -------------- CVSROOT: config Revision Data ------------- Index: config =================================================================== RCS file: /webwork/cvs/system/CVSROOT/config,v retrieving revision 1.2 retrieving revision 1.3 diff -Lconfig -Lconfig -u -r1.2 -r1.3 --- config +++ config @@ -1,5 +1,5 @@ # Set this to "no" if pserver shouldn't check system users/passwords -#SystemAuth=no +SystemAuth=no # Put CVS lock files in this directory rather than directly in the repository. LockDir=/var/lock/cvs |
From: dpvc v. a. <we...@ma...> - 2005-12-01 13:20:10
|
Log Message: ----------- Fixed a problem with not including parentheses when a negative number is the base of a power. (And in general, when a negative is used as an operand of a higher-precendence operation, but it really only affected powers.) Modified Files: -------------- pg/lib/Parser: Number.pm Revision Data ------------- Index: Number.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Parser/Number.pm,v retrieving revision 1.11 retrieving revision 1.12 diff -Llib/Parser/Number.pm -Llib/Parser/Number.pm -u -r1.11 -r1.12 --- lib/Parser/Number.pm +++ lib/Parser/Number.pm @@ -68,7 +68,12 @@ my $self = shift; Value::Real->make($self->{value})->TeX($self->{equation},@_); } -sub perl {shift->{value}} +sub perl { + my $self = shift; my $parens = shift; + my $n = $self->{value}; + $n = '('.$n.')' if $parens && $n < 0; + return $n; +} ########################################### |
From: Arnie P. v. a. <we...@ma...> - 2005-11-29 21:27:54
|
Log Message: ----------- Add underscores to the anonymous unique identifier for questionnaires in WW 2 by using ${setNumber}_${courseName}_$psvnNumber Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.47 retrieving revision 1.48 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.47 -r1.48 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -3149,7 +3149,7 @@ my $ans_eval = sub { my $text = shift; $text = '' unless defined($text); - my $new_text = "\n$setNumber$courseName$psvnNumber-Problem-$probNum-Question-$num:\n $text "; # modify entered text + my $new_text = "\n${setNumber}_${courseName}_$psvnNumber-Problem-$probNum-Question-$num:\n $text "; # modify entered text my $out = &$ans_eval_template($new_text); # standard evaluator #warn "$QUESTIONNAIRE_ANSWERS"; $out->{student_ans} = escapeHTML($text); # restore original entered text |
From: Sam H. v. a. <we...@ma...> - 2005-11-28 20:52:31
|
Log Message: ----------- reinstated "report bugs" item in links() Modified Files: -------------- webwork2/lib/WeBWorK: ContentGenerator.pm Revision Data ------------- Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.154 retrieving revision 1.155 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.154 -r1.155 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -487,10 +487,6 @@ =cut -# http://devel.webwork.rochester.edu:8000/webwork2/sam_2005-08-04_renamed1/fun_set -# /2/?user=sam&effectiveUser=sam&key=c0rr63Ki5r9HZh1J9pGG1loi.Hm4D!1caiFTjh*2& -# displayMode=images&showOldAnswers=1 - sub links { my ($self) = @_; my $r = $self->r; @@ -594,6 +590,13 @@ my %systemlink_args; $systemlink_args{params} = \%params if %params; + if (exists $ce->{webworkURLs}{bugReporter} and $ce->{webworkURLs}{bugReporter} ne "" + and $authz->hasPermissions($userID, "report_bugs")) { + print CGI::start_ul(); + print CGI::li(CGI::a({style=>"font-size:larger", href=>$ce->{webworkURLs}{bugReporter}}, "Report bugs")); + print CGI::end_ul(); + } + #print CGI::start_ul(); #print CGI::start_li(); # Courses #print &$makelink("${pfx}Home", text=>"Courses", systemlink_args=>{authen=>0}); |
From: Mike G. v. a. <we...@ma...> - 2005-11-22 01:47:01
|
Log Message: ----------- Modifications that set problems with path .../Library/setFoo/problemBar to reference the "Library" component in bugzilla. Also the problemSeed is added to the url sent to bugzilla e.g. /webwork/shared-courses/gage_course_single_sql/templates/rochesterLibrary/setMAAtutorial/simplemultiplechoiceexample.pg_with_problemSeed=4655 this means that you can't click on the link, but it automatically includes a seed which might be helpful. It is not guaranteed that this the seed that caused problems -- that depends on how the bug is submitted -- but it is often the case that this seed caused the problem. -- Mike Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: PGProblemEditor.pm Revision Data ------------- Index: PGProblemEditor.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm,v retrieving revision 1.62 retrieving revision 1.63 diff -Llib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm -Llib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm -u -r1.62 -r1.63 --- lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm +++ lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm @@ -423,11 +423,23 @@ # Construct url for reporting bugs: ######################################################################### - $editFilePath =~ m|([^/]*)Library|; #find the path to the file - my $libraryName = $1; # find the library, if any exists in the path name (first library is picked) - $libraryName ='rochester' unless defined($libraryName) and $libraryName =~/\S/; # default library - - my $BUGZILLA = "http://bugs.webwork.rochester.edu/enter_bug.cgi?product=Problem%20libraries&component=$libraryName&bug_file_loc=$editFilePath"; +# $editFilePath =~ m|([^/]*)Library|; #find the path to the file +# my $libraryName = $1; # find the library, if any exists in the path name (first library is picked) +# $libraryName ='rochester' unless defined($libraryName) and $libraryName =~/\S/; # default library + my $libraryName = ''; + if ($editFilePath =~ m|([^/]*)Library|) { #find the path to the file + # find the library, if any exists in the path name (first library is picked) + my $tempLibraryName = $1; + $libraryName = ( defined($tempLibraryName) and $tempLibraryName =~/\S/ ) ? + $tempLibraryName : "Library"; + # things that start /Library/setFoo/probBar are labeled as component "Library" + # which refers to the SQL based problem library. (is nationalLibrary a better name?) + } else { + $libraryName = 'rochester'; # make sure there is some default component defined. + } + + my $BUGZILLA = "http://bugs.webwork.rochester.edu/enter_bug.cgi?product=Problem%20libraries". + "&component=$libraryName&bug_file_loc=${editFilePath}_with_problemSeed=".$self->{problemSeed}; #FIXME # The construction of this URL is somewhat fragile. A separate module could be devoted to intelligent reporting of bugs. ######################################################################### |
From: Sam H. v. a. <we...@ma...> - 2005-11-22 01:44:27
|
Log Message: ----------- fixed a couple of bugs in the previous commit: * links() preserves displayMode/showOldAnswers properly (bug #896) * loginstatus() fixes formatting * ur.template fixes a typo Modified Files: -------------- webwork2/conf/templates: ur.template webwork2/lib/WeBWorK: ContentGenerator.pm Revision Data ------------- Index: ur.template =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/templates/ur.template,v retrieving revision 1.41 retrieving revision 1.42 diff -Lconf/templates/ur.template -Lconf/templates/ur.template -u -r1.41 -r1.42 --- conf/templates/ur.template +++ conf/templates/ur.template @@ -76,7 +76,7 @@ <!--#path style="text" image="/webwork2_files/images/right_arrow.png" text=" > "--> </span> <!--#endif--> - !--#if can="loginstatus"--> + <!--#if can="loginstatus"--> <span class="LoginStatus"> <!--#loginstatus--> </span> Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.153 retrieving revision 1.154 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.153 -r1.154 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -487,6 +487,10 @@ =cut +# http://devel.webwork.rochester.edu:8000/webwork2/sam_2005-08-04_renamed1/fun_set +# /2/?user=sam&effectiveUser=sam&key=c0rr63Ki5r9HZh1J9pGG1loi.Hm4D!1caiFTjh*2& +# displayMode=images&showOldAnswers=1 + sub links { my ($self) = @_; my $r = $self->r; @@ -575,8 +579,9 @@ # we'd like to preserve displayMode and showOldAnswers between pages, and we # don't have a general way of preserving non-authen params between requests, # so here is the hack: - $args{displayMode} = $r->param("displayMode") if defined $r->param("displayMode"); - $args{showOldAnswers} = $r->param("showOldAnswers") if defined $r->param("showOldAnswers"); + my %params; + $params{displayMode} = $r->param("displayMode") if defined $r->param("displayMode"); + $params{showOldAnswers} = $r->param("showOldAnswers") if defined $r->param("showOldAnswers"); # in the past, we were checking $self->{displayMode} and $self->{will}->{showOldAnswers} # to set these args, but I don't wanna do that anymore, since it relies on # fields specific to Problem.pm (pretty sure). The only differences in this @@ -586,6 +591,8 @@ # (b) showOldAnswers will get set to the value specified in the current # request, regardless of whether it is allowed, but this is OK since we # always this value before using it. + my %systemlink_args; + $systemlink_args{params} = \%params if %params; #print CGI::start_ul(); #print CGI::start_li(); # Courses @@ -598,17 +605,17 @@ print CGI::start_ul(); print CGI::start_li(); # Homework Sets - print &$makelink("${pfx}ProblemSets", text=>"Homework Sets", urlpath_args=>{%args}); + print &$makelink("${pfx}ProblemSets", text=>"Homework Sets", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); if (defined $setID) { print CGI::start_ul(); print CGI::start_li(); # $setID - print &$makelink("${pfx}ProblemSet", text=>"$setID", urlpath_args=>{%args,setID=>$setID}); + print &$makelink("${pfx}ProblemSet", text=>"$setID", urlpath_args=>{%args,setID=>$setID}, systemlink_args=>\%systemlink_args); # FIXME i think we only want this if the problem set is not a gateway quiz if (defined $problemID) { print CGI::start_ul(); print CGI::start_li(); # $problemID - print &$makelink("${pfx}Problem", text=>"Problem $problemID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}); + print &$makelink("${pfx}Problem", text=>"Problem $problemID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}, systemlink_args=>\%systemlink_args); print CGI::end_li(); # end $problemID print CGI::end_ul(); @@ -619,30 +626,30 @@ print CGI::end_li(); # end Homework Sets if ($authz->hasPermissions($userID, "change_password") or $authz->hasPermissions($userID, "change_email_address")) { - print CGI::li(&$makelink("${pfx}Options", urlpath_args=>{%args})); + print CGI::li(&$makelink("${pfx}Options", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); } - print CGI::li(&$makelink("${pfx}Grades", urlpath_args=>{%args})); + print CGI::li(&$makelink("${pfx}Grades", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); if ($authz->hasPermissions($userID, "access_instructor_tools")) { $pfx .= "Instructor::"; print CGI::start_li(); # Instructor Tools - print &$makelink("${pfx}Index", urlpath_args=>{%args}); + print &$makelink("${pfx}Index", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); print CGI::start_ul(); - print CGI::li(&$makelink("${pfx}UserList", urlpath_args=>{%args})); + print CGI::li(&$makelink("${pfx}UserList", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); print CGI::start_li(); # Homework Set Editor - print &$makelink("${pfx}ProblemSetList", urlpath_args=>{%args}); + print &$makelink("${pfx}ProblemSetList", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); if (defined $setID) { print CGI::start_ul(); print CGI::start_li(); # $setID - print &$makelink("${pfx}ProblemSetDetail", text=>"$setID", urlpath_args=>{%args,setID=>$setID}); + print &$makelink("${pfx}ProblemSetDetail", text=>"$setID", urlpath_args=>{%args,setID=>$setID}, systemlink_args=>\%systemlink_args); if (defined $problemID) { print CGI::start_ul(); - print CGI::li(&$makelink("${pfx}PGProblemEditor", text=>"$setID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID})); + print CGI::li(&$makelink("${pfx}PGProblemEditor", text=>"$setID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}, systemlink_args=>\%systemlink_args)); print CGI::end_ul(); } @@ -651,50 +658,50 @@ } print CGI::end_li(); # end Homework Set Editor - print CGI::li(&$makelink("${pfx}SetMaker", text=>"Library Browser", urlpath_args=>{%args})); + print CGI::li(&$makelink("${pfx}SetMaker", text=>"Library Browser", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); print CGI::start_li(); # Stats - print &$makelink("${pfx}Stats", urlpath_args=>{%args}); + print &$makelink("${pfx}Stats", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); if ($userID ne $eUserID or defined $setID) { print CGI::start_ul(); if ($userID ne $eUserID) { - print CGI::li(&$makelink("${pfx}Stats", text=>"$eUserID", urlpath_args=>{%args,statType=>"student",userID=>$eUserID})); + print CGI::li(&$makelink("${pfx}Stats", text=>"$eUserID", urlpath_args=>{%args,statType=>"student",userID=>$eUserID}, systemlink_args=>\%systemlink_args)); } if (defined $setID) { - print CGI::li(&$makelink("${pfx}Stats", text=>"$setID", urlpath_args=>{%args,statType=>"set",setID=>$setID})); + print CGI::li(&$makelink("${pfx}Stats", text=>"$setID", urlpath_args=>{%args,statType=>"set",setID=>$setID}, systemlink_args=>\%systemlink_args)); } print CGI::end_ul(); } print CGI::end_li(); # end Stats print CGI::start_li(); # Student Progress - print &$makelink("${pfx}StudentProgress", urlpath_args=>{%args}); + print &$makelink("${pfx}StudentProgress", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); if ($userID ne $eUserID or defined $setID) { print CGI::start_ul(); if ($userID ne $eUserID) { - print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$eUserID", urlpath_args=>{%args,statType=>"student",userID=>$eUserID})); + print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$eUserID", urlpath_args=>{%args,statType=>"student",userID=>$eUserID}, systemlink_args=>\%systemlink_args)); } if (defined $setID) { - print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$setID", urlpath_args=>{%args,statType=>"set",setID=>$setID})); + print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$setID", urlpath_args=>{%args,statType=>"set",setID=>$setID}, systemlink_args=>\%systemlink_args)); } print CGI::end_ul(); } print CGI::end_li(); # end Student Progress if ($authz->hasPermissions($userID, "score_sets")) { - print CGI::li(&$makelink("${pfx}Scoring", urlpath_args=>{%args})); + print CGI::li(&$makelink("${pfx}Scoring", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); } if ($authz->hasPermissions($userID, "send_mail")) { - print CGI::li(&$makelink("${pfx}SendMail", urlpath_args=>{%args})); + print CGI::li(&$makelink("${pfx}SendMail", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); } if ($authz->hasPermissions($userID, "manage_course_files")) { - print CGI::li(&$makelink("${pfx}FileManager", urlpath_args=>{%args})); + print CGI::li(&$makelink("${pfx}FileManager", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); } if ($authz->hasPermissions($userID, "manage_course_files")) { - print CGI::li(&$makelink("${pfx}Config", urlpath_args=>{%args})); + print CGI::li(&$makelink("${pfx}Config", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); } print CGI::end_ul(); @@ -737,17 +744,14 @@ params => { effectiveUser => $userID }, ); my $logoutURL = $self->systemLink($urlpath->newFromModule(__PACKAGE__ . "::Logout", courseID => $courseID)); - - my $text = "Logged in as $userID. " . CGI::br() . CGI::a({href=>$logoutURL}, "Log Out"); - if ($eUserID ne $userID) { - $text .= print " | Acting as $eUserID. " . CGI::a({href=>$stopActingURL}, "Stop Acting"); + if ($eUserID eq $userID) { + print "Logged in as $userID. " . CGI::br() . CGI::a({href=>$logoutURL}, "Log Out"); + } else { + print "Logged in as $userID. " . CGI::a({href=>$logoutURL}, "Log Out") . CGI::br(); + print "Acting as $eUserID. " . CGI::a({href=>$stopActingURL}, "Stop Acting"); } - - #print CGI::div({class=>"LoginStatus"}, $text); # soon, my friend, soon... - print $text; } else { - #print CGI::div({class=>"LoginStatus"}, "Not logged in."); # likewise... print "Not logged in."; } |
From: Sam H. v. a. <we...@ma...> - 2005-11-21 21:49:20
|
Log Message: ----------- reorganization and small changes for recent modifications to links(). split into two parts: * ur.template classes: These classes appear in ur.template and are NOT emitted by WeBWorK code. They need only appear in this template. * WeBWorK classes: These classes are emitted by WeBWorK code and should appear in ANY WeBWorK template. moved "minimal list style" to "div.Links ul" and "div.Links ul ul". div.Links is a ur.template class, and the proper place for styling the link menu lists is in ur.template. Consequently, any UL in a Links div gets styled this way, not just ULs of class LinksMenu. (In fact, class LinksMenu no longer exists.) Modified Files: -------------- webwork2/htdocs/css: ur.css Revision Data ------------- Index: ur.css =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/css/ur.css,v retrieving revision 1.13 retrieving revision 1.14 diff -Lhtdocs/css/ur.css -Lhtdocs/css/ur.css -u -r1.13 -r1.14 --- htdocs/css/ur.css +++ htdocs/css/ur.css @@ -1,10 +1,6 @@ -/* hack to get around MSIE peekaboo bug */ -/* this hack causes other problems and may no longer be needed for the peekaboo bug so we will comment it out */ -/* * {zoom: 1;} */ - -/********************/ -/* template classes */ -/********************/ +/******************************************************************************/ +/* ur.template classes: These classes appear in ur.template and are NOT + * emitted by WeBWorK code. They need only appear in this template. */ body { margin: 0px; } @@ -15,10 +11,15 @@ div.Logo { } div.Links { font-size: small; } +div.Links ul { list-style: none; margin-left: 0; padding-left: 0; } +div.Links ul ul { list-style: none; margin-left: 0.5em; padding-left: 0; } + /* we used to say "height: 10em; overflow: auto" here, but it caused * problems for mozilla. so we're back to having a looong siblings list * for the time being. :-( */ div.Siblings { font-size: small; } +div.Siblings ul { list-style: none; margin-left: 0; padding-left: 0; } +div.Siblings ul ul { list-style: none; margin-left: 0.5em; padding-left: 0; } div.Options { font-size: small; } /* top table cell, contains login message and path */ @@ -26,11 +27,12 @@ td.TopPanel a:link, td.TopPanel a:visited { color: #FF9933; } +.Path { } -*.LoginStatus { text-align: right; font-size: small; position:absolute; top: 0; right: 0; } +.LoginStatus { text-align: right; font-size: small; position:absolute; top: 0; right: 0; } td.Timestamp { text-align: left; font-size: small; font-style: italic; } -*.Path { } +/* (should have ContentPanelError here) */ /* main content panel, contains body */ td.ContentPanel { background-color: white; color: black; } @@ -38,54 +40,26 @@ td.ContentPanel a:visited { color: blue; } td.ContentPanel a:active { color: red; } -/* contains info */ -td.InfoPanel { background-color: #DDDDDD; color: black; width: 30% } -td.InfoPanel a:link, -td.InfoPanel a:visited { color: blue; } -td.InfoPanel a:active { color: red; } - -div.Info { } div.Nav { } div.Title { font-size: 16pt; } -div.SubmitError { color: red; font-style: italic; } div.Message { font-style: italic; } +div.SubmitError { color: red; font-style: italic; } div.Body { } div.Warnings { } -div.viewOptions { border: thin groove; padding: 1ex; margin: 2ex; align: left; } -/* background colors for success and failure messages */ -div.ResultsWithoutError { background-color: #66ff99 } /* light green */ -div.ResultsWithError { background-color: #ffcccc } /* light red */ -div.ResultsAlert { background-color: yellow } /* yellow */ - -div.NoFontMessage {padding: 10; border-style: solid; border-width:3; - border-color: #DD0000; background-color: #FFF8F8; - width: 75%; text-align: left; margin: 10px auto 10px 12%;} - -/* text colors for published and unpublished sets */ -font.Published { font-style: normal; font-weight: normal; color: #000000; } /* black */ -font.Unpublished { font-style: italic; font-weight: normal; color: #aaaaaa; } /* light grey */ - -/* styles used when editing a temporary file */ -div.temporaryFile { background-color: #ff9900 ; font-style: italic; } -p.temporaryFile { background-color: #ff9900 ; font-style: italic; } +/* (shuld have Message here) */ +/* contains info */ +td.InfoPanel { background-color: #DDDDDD; color: black; width: 30% } +td.InfoPanel a:link, +td.InfoPanel a:visited { color: blue; } +td.InfoPanel a:active { color: red; } +div.Info { } -/* text colors for Auditing, Current, and Dropped students */ -div.Audit { font-style: normal; color: purple; } -div.Enrolled { font-weight: normal; color: black; } -div.Drop { font-style: italic; color: grey; } - -/*******************/ -/* general classes */ -/*******************/ - -p.emphasis { font-style:italic; } - -/************************/ -/* new standard classes */ -/************************/ +/******************************************************************************/ +/* WeBWorK classes: These classes are emitted by WeBWorK code and should + * appear in ANY WeBWorK template. */ /* tables used for laying out form fields shouldn't have a border */ table.FormLayout { border: 0; } @@ -99,21 +73,27 @@ div.AuthorComment { background-color: #00E0E0; color: black; } /* minimal style for lists of links (generated by the links escape) */ -ul.LinksMenu { list-style: none; margin-left: 0; padding-left: 0; } -ul.LinksMenu ul { list-style: none; margin-left: 0.5em; padding-left: 0; } +/*ul.LinksMenu { list-style: none; margin-left: 0; padding-left: 0; }*/ +/*ul.LinksMenu ul { list-style: none; margin-left: 0.5em; padding-left: 0; }*/ -/*************************/ -/* WeBWorK::HTML widgets */ -/*************************/ +/* background styles for success and failure messages */ +div.ResultsWithoutError { background-color: #66ff99 } /* light green */ +div.ResultsWithError { background-color: #ffcccc } /* light red */ +div.ResultsAlert { background-color: yellow } /* yellow */ -/* WeBWorK::HTML::ScrollingRecordList */ +/* styles used by WeBWorK::HTML::ScrollingRecordList */ div.ScrollingRecordList { padding: 1em; white-space: nowrap; border: thin solid gray; } div.ScrollingRecordList select.ScrollingRecordList { width: 99%; } -/*************************************************************************/ -/* classes used in Problem.pm (replace these with new standard classes?) */ -/*************************************************************************/ +/* wraps the View Options form (generated by &optionsMacro) */ +/* FIXME: can't this style information just go in div.Options above? */ +div.viewOptions { border: thin groove; padding: 1ex; margin: 2ex; align: left; } +/* messages, attempt results, answer previews, etc. go in this DIV */ +/* this used to be "float:left", but that was suspected of causing MSIE peekaboo bug */ +div.problemHeader {} + +/* styles for the attemptResults table */ table.attemptResults { border-style: outset; border-width: 1px; @@ -129,9 +109,7 @@ padding: 2px 5px 2px 5px; background-color: #DDDDDD; } -/* - * override above settings in tables used to display ans_array results - */ +/* override above settings in tables used to display ans_array results */ table.attemptResults td td, table.attemptResults td th, table.ArrayLayout td { @@ -144,7 +122,32 @@ padding: 2px 5px 2px 5px; width: auto; } -# div.problemHeader { float: left; } # suspected of causing MSIE peekaboo bug -div.problemHeader {} -div.problem { clear: both; background-color: #E0E0E0; color: black; } +.attemptResultsSummary { font-style:italic; } .parsehilight { background-color:yellow; } + +/* the problem TEXT itself does in this box */ +div.problem { clear: both; background-color: #E0E0E0; color: black; } + +/* jsMath emits this class when appropriate math fonts aren't available */ +div.NoFontMessage { + padding: 10; + border-style: solid; + border-width:3; + border-color: #DD0000; + background-color: #FFF8F8; + width: 75%; + text-align: left; + margin: 10px auto 10px 12%; +} + +/* text colors for published and unpublished sets */ +font.Published { font-style: normal; font-weight: normal; color: #000000; } /* black */ +font.Unpublished { font-style: italic; font-weight: normal; color: #aaaaaa; } /* light grey */ + +/* styles used when editing a temporary file */ +.temporaryFile { background-color: #ff9900 ; font-style: italic; } + +/* text colors for Auditing, Current, and Dropped students */ +.Audit { font-style: normal; color: purple; } +.Enrolled { font-weight: normal; color: black; } +.Drop { font-style: italic; color: grey; } |
From: Sam H. v. a. <we...@ma...> - 2005-11-21 21:43:22
|
Log Message: ----------- changes to links subroutine: * sublists are now within list items, as required by html spec * use &makeLinks helper to generate links (makes the code easier to read) * hilite the "active" link item with a strong tag and the "active" class * change the way displayMode and showOldAnswers are preserved, and preserve them in all the links. (see comments in code) changes to help subroutine: * add alt-text for help icon (" ? ") to conform to html spec As of now, all the code generated by template functions in this file is XHTML 1.0 Transitional compliant. The same cannot be said for the code generated by other content generators or PG. Modified Files: -------------- webwork2/lib/WeBWorK: ContentGenerator.pm Revision Data ------------- Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.152 retrieving revision 1.153 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.152 -r1.153 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -490,217 +490,225 @@ sub links { my ($self) = @_; my $r = $self->r; + my $ce = $r->ce; my $db = $r->db; my $authen = $r->authen; my $authz = $r->authz; - my $ce = $r->ce; my $urlpath = $r->urlpath; - my $user = $r->param('user'); # we don't currently have any links to display if the user's not logged in. this may change, though. - return unless $authen and $authen->was_verified; + return "" unless $authen and $authen->was_verified; - # we're linking to other places in the same course, so grab the courseID from the current path + # grab some interesting data from the request my $courseID = $urlpath->arg("courseID"); - - # grab the effective user, set and problem - my $userID = $r->param("effectiveUser"); + my $userID = $r->param('user'); + my $eUserID = $r->param("effectiveUser"); my $setID = $urlpath->arg("setID"); - $setID = "" if (defined $setID && !(grep /$setID/, $db->listUserSets($userID))); my $problemID = $urlpath->arg("problemID"); - $problemID = "" if (defined $problemID && !(grep /$problemID/, $db->listUserProblems($userID, $setID))); - - # to make things more concise - my %args = ( courseID => $courseID); - my $pfx = "WeBWorK::ContentGenerator::"; - my $sets = $urlpath->newFromModule("${pfx}ProblemSets", %args); - my $options = $urlpath->newFromModule("${pfx}Options", %args); - my $grades = $urlpath->newFromModule("${pfx}Grades", %args); - my $logout = $urlpath->newFromModule("${pfx}Logout", %args); - - # experimental subroutine for generating links, to clean up the rest of the - # code. ignore for now. (this is a closure over $self and $urlpath.) - #my $makelink = sub { - # my ($module, $args, $name) = @_; - # - # defined $args or $args = {}; - # my $new_urlpath = $urlpath->newFromModule($module, %$args); - # - # defined $name or $name = $new_urlpath->name; - # $name = sp2nbsp($name); # i don't like it, but that's what we do... - # - # return CGI::a({href => $self->systemLink($new_urlpath)}, $name); - #}; - # - #my $home_link = &$makelink("${pfx}Home"); - - print "\n<!-- BEGIN " . __PACKAGE__ . "::links -->\n"; - - # only users with appropriate permissions can report bugs - if ($authz->hasPermissions($user, "report_bugs")) { - print CGI::p(CGI::a({style=>"font-size:larger", href=>$ce->{webworkURLs}{bugReporter}}, "Report bugs")),CGI::hr(); - } - - my %displayOptions = (displayMode => $self->{displayMode}, - showOldAnswers => $self->{will}->{showOldAnswers} - ); - print CGI::start_ul({class=>"LinksMenu"}); - print CGI::start_li(), - CGI::span({style=>"font-size:larger"}, - CGI::a({href=>$self->systemLink($sets, - params=>{ %displayOptions,} - )}, sp2nbsp("Homework Sets")) - ); - if (defined $setID and $setID ne "") { - my $setPath = $urlpath->newFromModule("${pfx}ProblemSet", courseID =>$courseID, setID =>$setID); - print CGI::start_ul(); - print CGI::li(CGI::a({href=>$self->systemLink($setPath, - params=>{ %displayOptions,} - )}, $setID) - ); -# Displaying a link back to the problem may not be necessary or useful. -# if (defined $problemID and $problemID ne "") { -# my $problemPath = $urlpath->newFromModule("${pfx}Problem", -# courseID =>$courseID, setID =>$setID, problemID =>$problemID); -# print CGI::start_ul(); -# CGI::li(CGI::a({href=>$self->systemLink($problemPath, -# params=>{ %displayOptions,} -# )}, $problemID) -# ); -# print CGI::end_ul(); -# } - - print CGI::end_ul(); - } - print CGI::end_li(); - - - - if ($authz->hasPermissions($user, "change_password") or $authz->hasPermissions($user, "change_email_address")) { - print CGI::li(CGI::a({href=>$self->systemLink($options, - params=>{ %displayOptions,} - ) - }, sp2nbsp($options->name)) - ); + # it's possible that the setID and the problemID are invalid, since they're just taken from the URL path info + if (defined $setID and $db->getUserSet($eUserID, $setID)) { + if (defined $problemID and $db->getUserProblem($eUserID, $setID, $problemID)) { + # both set and poblem exist -- do nothing + } else { + $problemID = undef; + } + } else { + $setID = undef; + $problemID = undef; } - print CGI::li(CGI::a({href=>$self->systemLink($grades, - params=>{ %displayOptions,} - )}, sp2nbsp($grades->name))); - print CGI::li(CGI::a({href=>$self->systemLink($logout)}, sp2nbsp($logout->name))); + # old method -- get rid of this after a while + #$setID = "" if (defined $setID && !(grep /$setID/, $db->listUserSets($eUserID))); + #$problemID = "" if (defined $problemID && !(grep /$problemID/, $db->listUserProblems($eUserID, $setID))); - if ($authz->hasPermissions($user, "access_instructor_tools")) { - my $ipfx = "${pfx}Instructor::"; - - - # instructor tools link - - my $instr = $urlpath->newFromModule("${ipfx}Index", %args); - # Class list editor - my $userList = $urlpath->newFromModule("${ipfx}UserList", %args); + # experimental subroutine for generating links, to clean up the rest of the + # code. ignore for now. (this is a closure over $self.) + my $makelink = sub { + my ($module, %options) = @_; - # Homework sets editor and set editing list links - my $setList = $urlpath->newFromModule("${ipfx}ProblemSetList", %args); - my $setDetail = $urlpath->newFromModule("${ipfx}ProblemSetDetail", %args, setID => $setID); - my $problemEditor = $urlpath->newFromModule("${ipfx}PGProblemEditor", %args, setID => $setID, problemID => $problemID); + my $urlpath_args = $options{urlpath_args} || {}; + my $systemlink_args = $options{systemlink_args} || {}; + my $text = $options{text}; + my $active = $options{active}; - # Library browser - my $maker = $urlpath->newFromModule("${ipfx}SetMaker", %args); + my $new_urlpath = $self->r->urlpath->newFromModule($module, %$urlpath_args); + my $new_systemlink = $self->systemLink($new_urlpath, %$systemlink_args); - my $assigner = $urlpath->newFromModule("${ipfx}Assigner", %args); - my $mail = $urlpath->newFromModule("${ipfx}SendMail", %args); - my $scoring = $urlpath->newFromModule("${ipfx}Scoring", %args); + defined $text or $text = $new_urlpath->name; + $text = sp2nbsp($text); # ugly hack to prevent text from wrapping - # statistics links - my $stats = $urlpath->newFromModule("${ipfx}Stats", %args); - my $userStats = $urlpath->newFromModule("${ipfx}Stats", %args, statType => "student", userID => $userID); - my $setStats = $urlpath->newFromModule("${ipfx}Stats", %args, statType => "set", setID => $setID); - - # progress links - my $progress = $urlpath->newFromModule("${ipfx}StudentProgress", %args); - my $userProgress = $urlpath->newFromModule("${ipfx}StudentProgress", %args, statType => "student", userID => $userID); - my $setProgress = $urlpath->newFromModule("${ipfx}StudentProgress", %args, statType => "set", setID => $setID); + # try to set $active automatically by comparing + if (not defined $active) { + if ($urlpath->module eq $new_urlpath->module) { + my @args = sort keys %{{$urlpath->args}}; + my @new_args = sort keys %{{$new_urlpath->args}}; + if (@args == @new_args) { + foreach my $i (0 .. $#args) { + $active = 0; + last if $args[$i] ne $new_args[$i]; + $active = 1; + } + } else { + $active = 0; + } + } else { + $active = 0; + } + } + my $new_anchor; + if ($active) { + # add <strong> for old browsers + $new_anchor = CGI::strong(CGI::a({href=>$new_systemlink, class=>"active"}, $text)); + } else { + $new_anchor = CGI::a({href=>$new_systemlink}, $text); + } - my $fileMgr = $urlpath->newFromModule("${ipfx}FileManager", %args); - my $courseConfig = $urlpath->newFromModule("${ipfx}Config", %args); + return $new_anchor; + }; + + # to make things more concise + my $pfx = "WeBWorK::ContentGenerator::"; + my %args = ( courseID => $courseID ); + + # we'd like to preserve displayMode and showOldAnswers between pages, and we + # don't have a general way of preserving non-authen params between requests, + # so here is the hack: + $args{displayMode} = $r->param("displayMode") if defined $r->param("displayMode"); + $args{showOldAnswers} = $r->param("showOldAnswers") if defined $r->param("showOldAnswers"); + # in the past, we were checking $self->{displayMode} and $self->{will}->{showOldAnswers} + # to set these args, but I don't wanna do that anymore, since it relies on + # fields specific to Problem.pm (pretty sure). The only differences in this + # approach are: + # (a) displayMode will not be set if it wasn't set in the current request, + # but this is ok since the resulting page will just use the default value + # (b) showOldAnswers will get set to the value specified in the current + # request, regardless of whether it is allowed, but this is OK since we + # always this value before using it. + + #print CGI::start_ul(); + #print CGI::start_li(); # Courses + #print &$makelink("${pfx}Home", text=>"Courses", systemlink_args=>{authen=>0}); + + if (defined $courseID) { + #print CGI::start_ul(); + #print CGI::start_li(); # $courseID + #print CGI::strong(CGI::span({class=>"active"}, $courseID)); - print CGI::hr(); - print CGI::start_li(); - ## Instructor tools - print CGI::span({style=>"font-size:larger"}, - CGI::a({href=>$self->systemLink($instr,params=>{ %displayOptions,})}, sp2nbsp($instr->name)) - ); - ## Class list editor print CGI::start_ul(); - print CGI::li(CGI::a({href=>$self->systemLink($userList,params=>{ %displayOptions,})}, sp2nbsp($userList->name))); - print CGI::start_li(); - ## Homework sets editor and sub links - print CGI::a({href=>$self->systemLink($setList,params=>{ %displayOptions,})}, sp2nbsp($setList->name)); - if (defined $setID and $setID ne "") { + print CGI::start_li(); # Homework Sets + print &$makelink("${pfx}ProblemSets", text=>"Homework Sets", urlpath_args=>{%args}); + + if (defined $setID) { print CGI::start_ul(); - print CGI::li( CGI::a({href=>$self->systemLink($setDetail,params=>{ %displayOptions,})}, $setID) ); - if (defined $problemID and $problemID ne "") { - print CGI::ul( - CGI::li(CGI::a({href=>$self->systemLink($problemEditor,params=>{ %displayOptions,})}, $problemID)) - ); + print CGI::start_li(); # $setID + print &$makelink("${pfx}ProblemSet", text=>"$setID", urlpath_args=>{%args,setID=>$setID}); + # FIXME i think we only want this if the problem set is not a gateway quiz + if (defined $problemID) { + print CGI::start_ul(); + print CGI::start_li(); # $problemID + print &$makelink("${pfx}Problem", text=>"Problem $problemID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}); + + print CGI::end_li(); # end $problemID + print CGI::end_ul(); } + print CGI::end_li(); # end $setID print CGI::end_ul(); } - print CGI::end_li(); - - ## Library browser - print CGI::li(CGI::a({href=>$self->systemLink($maker,params=>{ %displayOptions,})}, sp2nbsp($maker->name))) - if $authz->hasPermissions($user, "modify_problem_sets"); - print CGI::li(CGI::a({href=>$self->systemLink($assigner,params=>{ %displayOptions,})}, sp2nbsp($assigner->name))) - if $authz->hasPermissions($user, "assign_problem_sets"); - ## Stats - print CGI::li(CGI::a({href=>$self->systemLink($stats,params=>{ %displayOptions,})}, sp2nbsp($stats->name))); - print CGI::start_li(); - print CGI::start_ul(); - if (defined $userID and $userID ne "") { - print CGI::li(CGI::a({href=>$self->systemLink($userStats,params=>{ %displayOptions,})}, $userID)), + print CGI::end_li(); # end Homework Sets + + if ($authz->hasPermissions($userID, "change_password") or $authz->hasPermissions($userID, "change_email_address")) { + print CGI::li(&$makelink("${pfx}Options", urlpath_args=>{%args})); + } + + print CGI::li(&$makelink("${pfx}Grades", urlpath_args=>{%args})); + + if ($authz->hasPermissions($userID, "access_instructor_tools")) { + $pfx .= "Instructor::"; + + print CGI::start_li(); # Instructor Tools + print &$makelink("${pfx}Index", urlpath_args=>{%args}); + print CGI::start_ul(); + + print CGI::li(&$makelink("${pfx}UserList", urlpath_args=>{%args})); + + print CGI::start_li(); # Homework Set Editor + print &$makelink("${pfx}ProblemSetList", urlpath_args=>{%args}); + if (defined $setID) { + print CGI::start_ul(); + print CGI::start_li(); # $setID + print &$makelink("${pfx}ProblemSetDetail", text=>"$setID", urlpath_args=>{%args,setID=>$setID}); + + if (defined $problemID) { + print CGI::start_ul(); + print CGI::li(&$makelink("${pfx}PGProblemEditor", text=>"$setID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID})); + print CGI::end_ul(); + } + + print CGI::end_li(); # end $setID + print CGI::end_ul(); } - if (defined $setID and $setID ne "") { - print CGI::li(CGI::a({href=>$self->systemLink($setStats,params=>{ %displayOptions,})}, sp2nbsp($setID))), + print CGI::end_li(); # end Homework Set Editor + + print CGI::li(&$makelink("${pfx}SetMaker", text=>"Library Browser", urlpath_args=>{%args})); + + print CGI::start_li(); # Stats + print &$makelink("${pfx}Stats", urlpath_args=>{%args}); + if ($userID ne $eUserID or defined $setID) { + print CGI::start_ul(); + if ($userID ne $eUserID) { + print CGI::li(&$makelink("${pfx}Stats", text=>"$eUserID", urlpath_args=>{%args,statType=>"student",userID=>$eUserID})); + } + if (defined $setID) { + print CGI::li(&$makelink("${pfx}Stats", text=>"$setID", urlpath_args=>{%args,statType=>"set",setID=>$setID})); + } + print CGI::end_ul(); } - print CGI::end_ul(); - print CGI::end_li(); - ## Student Progress - print CGI::li(CGI::a({href=>$self->systemLink($progress,params=>{ %displayOptions,})}, sp2nbsp($progress->name))); - - print CGI::start_li(); - print CGI::start_ul(); - if (defined $userID and $userID ne "") { - print CGI::li(CGI::a({href=>$self->systemLink($userProgress,params=>{ %displayOptions,})}, $userID)); - + print CGI::end_li(); # end Stats + + print CGI::start_li(); # Student Progress + print &$makelink("${pfx}StudentProgress", urlpath_args=>{%args}); + if ($userID ne $eUserID or defined $setID) { + print CGI::start_ul(); + if ($userID ne $eUserID) { + print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$eUserID", urlpath_args=>{%args,statType=>"student",userID=>$eUserID})); + } + if (defined $setID) { + print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$setID", urlpath_args=>{%args,statType=>"set",setID=>$setID})); + } + print CGI::end_ul(); } - if (defined $setID and $setID ne "") { - - print CGI::li(CGI::a({href=>$self->systemLink($setProgress,params=>{ %displayOptions,})}, sp2nbsp($setID))); - + print CGI::end_li(); # end Student Progress + + if ($authz->hasPermissions($userID, "score_sets")) { + print CGI::li(&$makelink("${pfx}Scoring", urlpath_args=>{%args})); } + + if ($authz->hasPermissions($userID, "send_mail")) { + print CGI::li(&$makelink("${pfx}SendMail", urlpath_args=>{%args})); + } + + if ($authz->hasPermissions($userID, "manage_course_files")) { + print CGI::li(&$makelink("${pfx}FileManager", urlpath_args=>{%args})); + } + + if ($authz->hasPermissions($userID, "manage_course_files")) { + print CGI::li(&$makelink("${pfx}Config", urlpath_args=>{%args})); + } + print CGI::end_ul(); - print CGI::end_li(); - ## Scoring tools - print CGI::li(CGI::a({href=>$self->systemLink($scoring,params=>{ %displayOptions,})}, sp2nbsp($scoring->name))) - if $authz->hasPermissions($user, "score_sets"); - ## Email - print CGI::li(CGI::a({href=>$self->systemLink($mail,params=>{ %displayOptions,})}, sp2nbsp($mail->name))) - if $authz->hasPermissions($user, "send_mail"); - print CGI::li(CGI::a({href=>$self->systemLink($fileMgr,params=>{ %displayOptions,})}, sp2nbsp($fileMgr->name))) - if $authz->hasPermissions($user, "manage_course_files"); - print CGI::li(CGI::a({href=>$self->systemLink($courseConfig,params=>{ %displayOptions,})}, sp2nbsp($courseConfig->name))) - if $authz->hasPermissions($user, "manage_course_files"); - #print CGI::li(CGI::a({href=>$self->systemLink($fileXfer)}, sp2nbsp($fileXfer->name))); - print CGI::li( $self->helpMacro('instructor_links')); + print CGI::end_li(); # end Instructor Tools + } + print CGI::end_ul(); - + + #print CGI::end_li(); # end $courseID + #print CGI::end_ul(); } - print CGI::end_ul(); - print "<!-- end " . __PACKAGE__ . "::links -->\n"; + #print CGI::end_li(); # end Courses + #print CGI::end_ul(); return ""; } @@ -1323,7 +1331,7 @@ return CGI::a({href => $url, target => 'ww_help', onclick => "window.open(this.href,this.target,'width=550,height=350,scrollbars=yes,resizable=on')"}, - CGI::img({src=>$imageURL})); + CGI::img({src=>$imageURL, alt=>" ? "})); } =item optionsMacro(options_to_show => \@options_to_show, extra_params => \@extra_params) |
From: Sam H. v. a. <we...@ma...> - 2005-11-21 21:26:29
|
Log Message: ----------- change "die" to "croak" in a couple of places to make error messages more useful. Modified Files: -------------- webwork2/lib/WeBWorK: URLPath.pm Revision Data ------------- Index: URLPath.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/URLPath.pm,v retrieving revision 1.27 retrieving revision 1.28 diff -Llib/WeBWorK/URLPath.pm -Llib/WeBWorK/URLPath.pm -u -r1.27 -r1.28 --- lib/WeBWorK/URLPath.pm +++ lib/WeBWorK/URLPath.pm @@ -24,6 +24,7 @@ use strict; use warnings; +use Carp; use WeBWorK::Debug; { @@ -586,7 +587,7 @@ my ($invocant, $path) = @_; my ($type, %args) = getPathType($path); - die "no type matches path $path" unless $type; + croak "no type matches path $path" unless $type; return $invocant->new( type => $type, @@ -605,7 +606,7 @@ my ($invocant, $module, %args) = @_; my $type = getModuleType($module, keys %args); - die "no type matches module $module with args", map { " $_=>$args{$_}" } keys %args unless $type; + croak "no type matches module $module with args", map { " $_=>$args{$_}" } keys %args unless $type; return $invocant->new( type => $type, |
From: Sam H. v. a. <we...@ma...> - 2005-11-21 21:25:20
|
Log Message: ----------- don't check "if loggedin" before calling loginstatus. loginstatus now says "not logged in" when the user is not logged in. Modified Files: -------------- webwork2/conf/templates: ur.template Revision Data ------------- Index: ur.template =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/templates/ur.template,v retrieving revision 1.40 retrieving revision 1.41 diff -Lconf/templates/ur.template -Lconf/templates/ur.template -u -r1.40 -r1.41 --- conf/templates/ur.template +++ conf/templates/ur.template @@ -76,15 +76,10 @@ <!--#path style="text" image="/webwork2_files/images/right_arrow.png" text=" > "--> </span> <!--#endif--> - - <!--#if loggedin="1"--> - <!--#if can="loginstatus"--> - - <span class="LoginStatus"> - - <!--#loginstatus--> - </span> - <!--#endif--> + !--#if can="loginstatus"--> + <span class="LoginStatus"> + <!--#loginstatus--> + </span> <!--#endif--> </div> </td> |
From: Sam H. v. a. <we...@ma...> - 2005-11-21 21:22:24
|
Log Message: ----------- fix doctype, remove duplicate "message" escape. Modified Files: -------------- webwork2/conf/templates: test.template Revision Data ------------- Index: test.template =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/templates/test.template,v retrieving revision 1.4 retrieving revision 1.5 diff -Lconf/templates/test.template -Lconf/templates/test.template -u -r1.4 -r1.5 --- conf/templates/test.template +++ conf/templates/test.template @@ -1,6 +1,5 @@ -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- ################################################################################ @@ -92,11 +91,6 @@ <!--#warnings--> </div> -<h1>message</h1> -<div class="test_box"> -<!--#message--> -</div> - <h1>info</h1> <div class="test_box"> <!--#info--> |
From: Sam H. v. a. <we...@ma...> - 2005-11-21 21:08:57
|
Log Message: ----------- don't need this any more -- wwsh now uses the perl debugger instead. Removed Files: ------------- webwork2/lib: PSH.pm Revision Data ------------- --- lib/PSH.pm +++ /dev/null @@ -1,329 +0,0 @@ -package PSH; - -use vars '$it'; - -$PSH::VERSION = '0.7'; - -#use strict; ##use only for testing !!!!!!!! - -sub welcome { - print STDOUT "Welcome to psh $PSH::VERSION by Jenda\@Krynicky.cz\nRunning under Perl $]\n\n"; -} - -$PSH::allowsystem = 1; -%PSH::specials = (); - -eval {require 'PSH.config'}; - print STDERR "Error in psh.config : $@\n" if ($@ and $@ !~ /^Can't locate PSH.config in \@INC/i); -$@=''; - -sub Exec { - my $line = shift; - if ($PSH::allowsystem) { - if ($line =~ s/>\s*$//) { - ${$PSH::package.'::it'}= `$line`; - } else { - $line =~ /^(.*?)(?:\s(.*))?$/; - my $cmd; - if (defined ($cmd = $PSH::alias{lc $1})) { - ${$PSH::package.'::it'}=system( $cmd.' '.$2 ); - } else { - ${$PSH::package.'::it'}=system( $line ); - } - } - } else { - print STDOUT "Disallowed by the script!\n"; - } -} - -sub specials { - return if @_ % 2; # I need even number of parameters - my ($char,$fun); - while (defined($char = shift)) { - $fun = shift; - if ($fun) { - $PSH::specials{$char} = $fun; - } else { - delete $PSH::specials{$char}; - } - } - $PSH::specials = join('|', map {"\Q$_\E"} keys %PSH::specials); -} - -$PSH::specials{'!'} = \&PSH::Exec; - -sub prompt { - my $prompt = shift || 'perl'; - my $eval = shift; - $PSH::specials = join('|', map {"\Q$_\E"} keys %PSH::specials); # just for sure - local $it=''; - my $command=''; - local ($PSH::package, $PSH::filename, $PSH::ln) = caller; - ${$PSH::package.'::it'}=''; -# print "called from $PSH::package\n"; - print STDOUT "$prompt\$ "; - - my $line; - while (defined ($line = <STDIN>)) { - if (!$command and $line =~ /^$/) { - print STDOUT "$prompt\$ "; - } elsif (!$command and $PSH::specials and $line =~ /^\s*($PSH::specials)\s*/ and $PSH::specials{$1}) { - $line =~ s/^\s*($PSH::specials)\s*(.*)$/$2/o; - ${$PSH::package.'::it'}= &{$PSH::specials{$1}}($line); - print STDOUT "\n$prompt\$ "; - } elsif ($line =~ /^\?$/) { - PSH::help(); - print STDOUT "\n$prompt\$ "; - - } elsif (!$command and $line =~ /^<<(.*)$/) { - my $eoc = $1; - print STDOUT "$prompt($eoc)\$ "; - while (defined ($line = <STDIN>)) { - last if $line =~ /^\Q$eoc\E\s*$/; - $command .=$line; - print STDOUT "$prompt($eoc)\$ "; - } - if ($eval) { - ${$PSH::package.'::it'} = &$eval($command); - } else { - ${$PSH::package.'::it'} = eval "package $PSH::package;\n".$command; - } - $command = ''; - print STDOUT "\nERROR: $@\n" if $@; - print STDOUT "\n$prompt\$ "; - } elsif ($line =~ s/;$//) { - if ($eval) { - ${$PSH::package.'::it'} = &$eval($command.$line); - } else { - ${$PSH::package.'::it'} = eval "package $PSH::package;\n".$command.$line; - } - $command = ''; - print STDOUT "\nERROR: $@\n" if $@; - print STDOUT "\n$prompt\$ "; - } else { - $command .= $line; - print STDOUT "$prompt> "; - } - } - return ${$PSH::package.'::it'}; -} - -sub PSH::help { - print STDOUT <<"*END*"; -Commands starting by ! are passed to the command prompt. -If the line ends by >, the output of the command is redirected to -variable \$it. If you want to catch both STDOUT and STDERR use this: - - perl\$ ! command 2>&1 > - -All other commands are suposed to be a perl code. - -The code to be evaluated may be entered in two ways -or use something like heredoc - -If the first line in a new command starts with <<, the rest of the line -is considered as the heredoc delimiter. As long as you do not enter a -line containing only those characters, the lines are only appended into -a variable. As soon as you close the heredoc, the code is evaluated. - -Otherwise the code you enter is evaluated as soon as you enter a line -finished by a semicolon. - -The value of the last command may be found in \$it. - -You may exit this "shell" by either "exit;" or CTRL+Z. -Please keep in mind that "exit;" will close the whole script, while -CTRL+Z will only close the prompt and the script will continue runing! - -Therefore you should use "exit;" with caution. - -psh $PSH::VERSION by Jenda\@Krynicky.cz -*END* -} - -"I am an excellent programmer"; # A required file must return a true value ;-) - -__END__ - -=head1 NAME - -PSH - perl shell - -Version 0.7 - -=head1 SYNOPSIS - - use PSH; - ... - PSH::prompt; - -=head1 DESCRIPTION - -This module provides a "perl command prompt" facility for your program. -You may do some processing and then simply call PSH::prompt to allow -the user to finish the task if something went wrong by calling the functions -of your program. - -I use it for example at the end of the Golem (peoplemeter data processing software) -import script. Sometimes I get not only the new data, but also some -repairs of old ones and sometimes some stage of import fails. -This perl prompt at the end of the script allows me to fix such problems "by hand". - -=head2 Usage - -This module provides two functions, PSH::prompt and PSH::welcome. -The first prints the "perl$" prompt, waits for user interaction and executes the entered -commands. The user then closes the prompt by pressing CTRL-D (Unix/Mac) or CTRL-Z (Windoze). - -All commands are processed in the same package from which PSH::prompt was -called. You may access all global or local() variables, but of course not -my() variables. - -The call to PSH::prompt returns the value of the last executed statement. - - -Since version 0.4 you may pass two parameters to PSH::prompt : - - PSH::prompt [$prompttext, [ \&evalsub ] ] - -The first sets the prompt used by the module, the second sets the function used -to evaluate the code you entered. Default is - - PSH::prompt 'perl', \&eval; - -The second function prints out the version info. - -=head2 Prompt - -Commands starting by ! are passed to the command prompt, -If the line ends by >, the output of the command is redirected to -variable $it. If you want to catch both STDOUT and STDERR use this: - - perl$ ! command 2>&1 > - -All other commands are supposed to be a perl code. - -The code to be evaluated may be entered in two ways -or use something like heredoc - -If the first line in a new command starts with <<, the rest of the line -is considered as the heredoc delimiter. As long as you do not enter a -line containing only those characters, the lines are only appended into -a variable. As soon as you close the heredoc, the code is evaluated. - -Otherwise the code you enter is evaluated as soon as you enter a line -finished by a semicolon. - -The value of the last command may be found in $it. - -You may exit this "shell" by either "exit;" or CTRL+Z. -Please keep in mind that "exit;" will close the whole script, while -CTRL+Z will only close the prompt and the script will continue running! - -Therefore you should use "exit;" with caution. - -=head2 PSH.config - -In the same directory as PSH.pm may be also file PSH.config. -This file will be "required" whenever you use PSH. You may add some -function definitions and variables there. - -Please keep in mind that this file is required in PSH package so -the variables and functions you define therein are in this package by default! - -Also keep in mind that this file is require()d! -The last statement in this file MUST return a true value!!! -And there must be some command in the file! At least - - 1; - -You should not do any changes to PSH.pm cause it would -be quite hard to upgrade then. If possible, do the necessary personalization -through PSH.config. If you find something that would be useful for other people, -or something you cannot do from within PSH.config, contact me. -I'm always open to suggestions and additions :-) - -=head2 Options and settings - - $PSH::allowsystem = should the prompt allow executing system - commands through "! command" ? Default = yes. - - %PSH::alias = a hash of aliases for commands. - Every time you enter a line starting with an exclamation mark, - the first word is looked up in this hash and if a match is found, - this word is replaced by the value from the hash. - All keys in this hash should be lowercase, the match is case-insensitive. - - You will probably want to populate this hash according to macros in - your preferred shell or OS. On my pages you may find examples for - reading doskey macros and applications registered to Windoze. - - %PSH::specials = a hash of specials - This hash allows you to install additional special characters - similar to "!". If PSH sees a special character (a key from - this hash), it calls the specified function for that character - (the value). Actually it doesn't have to be a character :-) - - Default : $PSH::specials{'!'} = \&PSH::Exec; - - You should not modify this hash directly, you'd better use function - PSH::specials : - - PSH::specials '^' => \&foo; - PSH::specials '!' => undef; - - Otherwise the change may be ignored ! - -=head2 Example - - use PSH; - END {PSH::prompt unless $OK} - $do->some('processing) or die "Error : $do->{error}!\n"; - some(more->commands) or die "Error : some went wrong!\n"; - $OK=1; - __END__ - -This will allow the user to do some by-hand cleansing if an error occures. - - use PSH; - PSH::prompt 'hello', sub {print $_[0]}; - -=head2 Ussage example - - perl$ print 45+6; - 51 - perl$ print 12 - perl> + 15; - 27 - perl$ sub Foo { - perl> print "Foo called\n"; - - ERROR: Missing right bracket at (eval 3) line 5, at end of line - syntax error at (eval 3) line 5, at EOF - - perl$ sub Foo { - perl> print "Foo called\n"; # - perl> }; - - perl$ Foo; - Foo called - - perl$ <<END - perl(END)$ sub Bar { - perl(END)$ my $arg = shift; - perl(END)$ print "Bar called with ($arg)\n"; - perl(END)$ } - perl(END)$ END - - perl$ Bar(45); - Bar called with (45) - - perl$ ^Z - - c:\> - -=head2 AUTHOR - -J...@Kr... - -=cut |
From: Sam H. v. a. <we...@ma...> - 2005-11-21 21:07:45
|
Log Message: ----------- use the perl debugger for a shell instead of PSH. this gets us a readline (or readline-like?) editing environment, which is much nicer to work with. Modified Files: -------------- webwork2/bin: wwsh Revision Data ------------- Index: wwsh =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /webwork/cvs/system/webwork2/bin/wwsh,v retrieving revision 1.6 retrieving revision 1.7 diff -Lbin/wwsh -Lbin/wwsh -u -r1.6 -r1.7 --- bin/wwsh +++ bin/wwsh @@ -1,4 +1,4 @@ -#!/usr/bin/env perl +#!/usr/bin/env perl -d ########################################################################= ######## # WeBWorK Online Homework Delivery System # Copyright =A9 2000-2003 The WeBWorK Project, http://openwebwork.sf.net= / @@ -21,41 +21,38 @@ =20 =3Dcut =20 -use strict; -use warnings; +use Data::Dumper; =20 BEGIN { - die "WEBWORK_ROOT not found in environment.\n" - unless exists $ENV{WEBWORK_ROOT}; + DB::parse_options("NonStop=3D1"); + unless ($ENV{WEBWORK_ROOT}) { + die "WEBWORK_ROOT not found in environment.\n"; + } } =20 use lib "$ENV{WEBWORK_ROOT}/lib"; -use PSH; use WeBWorK::CourseEnvironment; use WeBWorK::DB; =20 -my ($course, $cmd) =3D @ARGV; +our $ce; +our $db; =20 -unless ($course) { - die "usage: $0 course\n"; +my $courseID =3D shift @ARGV; +unless ($courseID) { + die "usage: $0 courseID\n"; } =20 -our $ce =3D WeBWorK::CourseEnvironment->new($ENV{WEBWORK_ROOT}, "", "", = $course); -our $db =3D WeBWorK::DB->new($ce->{dbLayout}); -(undef) =3D $db; # placate warnings - -if ($cmd) { - no warnings; - no strict; - eval $cmd; - die $@ if $@; - use strict; - use warnings; -} else { - print <<'EOF'; +$ce =3D WeBWorK::CourseEnvironment->new({ + webwork_dir =3D> $ENV{WEBWORK_ROOT}, + courseName =3D> $courseID, +}); +$db =3D WeBWorK::DB->new($ce->{dbLayout}); + +print <<'EOF'; wwsh - The WeBWorK Shell Available objects: $ce (WeBWorK::CourseEnvironment) $db (WeBWorK::DB) +Available modules: Data::Dumper EOF - PSH::prompt(); -} + +DB::parse_options("NonStop=3D0"); |
From: Sam H. v. a. <we...@ma...> - 2005-11-21 17:35:23
|
Log Message: ----------- utility script to create tarballs of problem libraries. Added Files: ----------- webwork2/bin: export_problem_libraries_from_cvs.pl Revision Data ------------- --- /dev/null +++ bin/export_problem_libraries_from_cvs.pl @@ -0,0 +1,46 @@ +#!/usr/bin/perl -w + +use strict; + +## run this script in a directory that does not contain +## any files whose names end in ".tar.gz" since this +## produces one such file for each module below and then +## at the end + +## list the repository name and then the module name +my @repository_module = qw( +rochester rochester_problib +rochester rochester_grade8problems +rochester rochester_physics_problib +asu asu_problib +asu database_problems +dartmouth dartmouth_problib +dcds dcds_problib +indiana indiana_problib +nau nau_problib +ohio-state osu_problib +sunysb sunysb_problib +tcnj tcnj_problib +unh unh_highschool_problib +unh unh_problib +union union_problib +); + +my ($repository, $module, @command_args); +my @tar_file_list = (); + +while (@repository_module ) { + $repository = shift @repository_module; + $module = shift @repository_module; + mkdir $module; + @command_args = qq(cvs -q -d :ext:apizer\@devel.webwork.rochester.edu:/webwork/cvs/$repository export -D now -d $module $module); + system (@command_args); + push @tar_file_list, "${module}.tar.gz"; + @command_args = qq(tar -czf ${module}.tar.gz $module); + system (@command_args); + @command_args = qq(rm -r $module); + system (@command_args); +} + +@command_args = qq(tar -czf all_problem_libraries.tar.gz @tar_file_list); +system (@command_args); \ No newline at end of file |
From: dpvc v. a. <we...@ma...> - 2005-11-21 13:15:47
|
Log Message: ----------- Fixed a problem with formatStudentAnswer not being defined in the special context created for this answer checker. Modified Files: -------------- pg/macros: answerVariableList.pl Revision Data ------------- Index: answerVariableList.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerVariableList.pl,v retrieving revision 1.1 retrieving revision 1.2 diff -Lmacros/answerVariableList.pl -Lmacros/answerVariableList.pl -u -r1.1 -r1.2 --- macros/answerVariableList.pl +++ macros/answerVariableList.pl @@ -44,6 +44,7 @@ flags => { NumberCheck => sub {shift->Error("Entries in your list must be variable names")}, + formatStudentAnswer => 'evaluated', # or 'parsed' or 'reduced' }, ); Context("VariableList"); |
From: Sam H. v. a. <we...@ma...> - 2005-11-18 18:32:17
|
Log Message: ----------- give the style used for the attempt results summary a structural name (attemptResultsSummary) rather than a sort-of-stylistic name (emphasis). Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Problem.pm GatewayQuiz.pm Revision Data ------------- Index: GatewayQuiz.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm,v retrieving revision 1.14 retrieving revision 1.15 diff -Llib/WeBWorK/ContentGenerator/GatewayQuiz.pm -Llib/WeBWorK/ContentGenerator/GatewayQuiz.pm -u -r1.14 -r1.15 --- lib/WeBWorK/ContentGenerator/GatewayQuiz.pm +++ lib/WeBWorK/ContentGenerator/GatewayQuiz.pm @@ -330,7 +330,7 @@ CGI::table({-class=>"gwAttemptResults"}, $resultsRows{'Entered'}, $resultsRows{'Preview'}, $resultsRows{'Correct'}, $resultsRows{'Results'}, $resultsRows{'Messages'}) . - ($showSummary ? CGI::p({class=>'emphasis'},$summary) : ""); + ($showSummary ? CGI::p({class=>'attemptResultsSummary'},$summary) : ""); # CGI::table({-class=>"attemptResults"}, CGI::Tr(\@tableRows)) # . ($showSummary ? CGI::p({class=>'emphasis'},$summary) : ""); } Index: Problem.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Problem.pm,v retrieving revision 1.186 retrieving revision 1.187 diff -Llib/WeBWorK/ContentGenerator/Problem.pm -Llib/WeBWorK/ContentGenerator/Problem.pm -u -r1.186 -r1.187 --- lib/WeBWorK/ContentGenerator/Problem.pm +++ lib/WeBWorK/ContentGenerator/Problem.pm @@ -303,7 +303,7 @@ } return CGI::table({-class=>"attemptResults"}, CGI::Tr(\@tableRows)) - . ($showSummary ? CGI::p({class=>'emphasis'},$summary) : ""); + . ($showSummary ? CGI::p({class=>'attemptResultsSummary'},$summary) : ""); } |
From: Sam H. v. a. <we...@ma...> - 2005-11-18 18:15:37
|
Log Message: ----------- Use optionsMacro for options like we do in Problem.pm. This reduces the amount of (but doesn't eliminate) duplicated code between Problem and GatewayQuiz. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: GatewayQuiz.pm Revision Data ------------- Index: GatewayQuiz.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm,v retrieving revision 1.13 retrieving revision 1.14 diff -Llib/WeBWorK/ContentGenerator/GatewayQuiz.pm -Llib/WeBWorK/ContentGenerator/GatewayQuiz.pm -u -r1.13 -r1.14 --- lib/WeBWorK/ContentGenerator/GatewayQuiz.pm +++ lib/WeBWorK/ContentGenerator/GatewayQuiz.pm @@ -338,57 +338,6 @@ # *BeginPPM* ################################################################### # this code taken from Problem.pm; excerpted section ends at *EndPPM* # modifications are flagged with comments *GW* - -sub viewOptions { - my ($self) = @_; - my $ce = $self->r->ce; - - # don't show options if we don't have anything to show -# return if $self->{invalidSet} or $self->{invalidProblem}; -# return unless $self->{isOpen}; - return if $self->{invalidSet}; - - my $displayMode = $self->{displayMode}; - my %must = %{ $self->{must} }; - my %can = %{ $self->{can} }; - my %will = %{ $self->{will} }; - - my $optionLine; - $can{showOldAnswers} and $optionLine .= join "", - "Show: ".CGI::br(), - CGI::checkbox( - -name => "showOldAnswers", - -checked => $will{showOldAnswers}, - -label => "Saved answers", - ), " ".CGI::br(); - - $optionLine and $optionLine .= join "", CGI::br(); - - my %display_modes = %{WeBWorK::PG::DISPLAY_MODES()}; - my @active_modes = grep { exists $display_modes{$_} } - @{$ce->{pg}->{displayModes}}; - my $modeLine = (scalar(@active_modes) > 1) ? - "View equations as: ".CGI::br(). - CGI::radio_group( - -name => "displayMode", - -values => \@active_modes, - -default => $displayMode, - -linebreak=>'true', - -labels => { - plainText => "plain", - formattedText => "formatted", - images => "images", - jsMath => "jsMath", - asciimath => "asciimath", - }, - ). CGI::br().CGI::hr() : ''; - - return CGI::div({-style=>"border: thin groove; padding: 1ex; margin: 2ex align: left"}, - $modeLine, - $optionLine, - CGI::submit(-name=>"redisplay", -label=>"Apply Options"), - ); -} sub previewAnswer { my ($self, $answerResult, $imgGen) = @_; @@ -917,23 +866,23 @@ sub options { my ($self) = @_; + #warn "doing options in GatewayQuiz"; - return "" if $self->{invalidProblem}; - my $sourceFilePathfield = ''; - if($self->r->param("sourceFilePath")) { - $sourceFilePathfield = CGI::hidden(-name => "sourceFilePath", - -value => $self->r->param("sourceFilePath")); - } + # don't show options if we don't have anything to show + return if $self->{invalidSet} or $self->{invalidProblem}; + return unless $self->{isOpen}; + + my $displayMode = $self->{displayMode}; + my %can = %{ $self->{can} }; - return join("", - CGI::start_form("POST", $self->{r}->uri), - $self->hidden_authen_fields, - $sourceFilePathfield, - CGI::hr(), - CGI::start_div({class=>"viewOptions"}), - $self->viewOptions(), - CGI::end_div(), - CGI::end_form() + my @options_to_show = "displayMode"; + push @options_to_show, "showOldAnswers" if $can{showOldAnswers}; + push @options_to_show, "showHints" if $can{showHints}; + push @options_to_show, "showSolutions" if $can{showSolutions}; + + return $self->optionsMacro( + options_to_show => \@options_to_show, + extra_params => ["editMode", "sourceFilePath"], ); } |
From: Arnie P. v. a. <we...@ma...> - 2005-11-18 15:51:36
|
Log Message: ----------- Make notification message more explicit. Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: SendMail.pm Revision Data ------------- Index: SendMail.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SendMail.pm,v retrieving revision 1.43 retrieving revision 1.44 diff -Llib/WeBWorK/ContentGenerator/Instructor/SendMail.pm -Llib/WeBWorK/ContentGenerator/Instructor/SendMail.pm -u -r1.43 -r1.44 --- lib/WeBWorK/ContentGenerator/Instructor/SendMail.pm +++ lib/WeBWorK/ContentGenerator/Instructor/SendMail.pm @@ -458,7 +458,7 @@ $self->print_preview($setID); } elsif (($response eq 'send_email')){ my $message = CGI::i("Email is being sent to ". scalar(@{$self->{ra_send_to}})." recipients. You will be notified" - ." when the task is completed. This may take several minutes if the class is large." + ." by email when the task is completed. This may take several minutes if the class is large." ); $self->addgoodmessage($message); $self->{message} .= $message; |
From: dpvc v. a. <we...@ma...> - 2005-11-17 22:59:40
|
Log Message: ----------- Handle the new global.conf setting for jsMath's processDoubleClicks option. Modified Files: -------------- pg/macros: PG.pl Revision Data ------------- Index: PG.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PG.pl,v retrieving revision 1.26 retrieving revision 1.27 diff -Lmacros/PG.pl -Lmacros/PG.pl -u -r1.26 -r1.27 --- macros/PG.pl +++ macros/PG.pl @@ -181,10 +181,11 @@ if ($main::envir{displayMode} eq 'HTML_jsMath') { my $prefix = ""; if (!$main::envir{jsMath}{reportMissingFonts}) { - $prefix .= '<SCRIPT>noFontMessage = 1</SCRIPT>'; + $prefix .= '<SCRIPT>noFontMessage = 1</SCRIPT>'."\n"; } elsif ($main::envir{jsMath}{missingFontMessage}) { - $prefix .= '<SCRIPT>missingFontMessage = "'.$main::envir{jsMath}{missingFontMessage}.'"</SCRIPT>'; + $prefix .= '<SCRIPT>missingFontMessage = "'.$main::envir{jsMath}{missingFontMessage}.'"</SCRIPT>'."\n"; } + $prefix .= '<SCRIPT>processDoubleClicks = '.($main::envir{jsMath}{processDoubleClicks}?'1':'0')."</SCRIPT>\n"; $STRINGforOUTPUT = $prefix . '<SCRIPT SRC="'.$main::envir{jsMathURL}.'"></SCRIPT>' . "\n" . |
From: dpvc v. a. <we...@ma...> - 2005-11-17 22:58:26
|
Log Message: ----------- Updated jsMath to version 2.4a. This fixes a number of alignment problems. Most of these are for math in tables, and baseline alignment issues in MSIE. A new feature is the ability to double-click on a mathematical expression on get a small window witht eh TeX source code for the expression. This can be disabled by setting $pg{displayModeOptions}{jsMath}{processDoubleClicks} = 0; in gloabl.conf. [jsMath v2.4a also includes a number of new features for the tex2math plugin, but this is not used by WeBWorK, so they will not be listed here. See the jsMath home page for more details.] Modified Files: -------------- webwork-modperl/conf: global.conf.dist webwork-modperl/htdocs/jsMath: jsMath-controls.html jsMath-ww.js jsMath.js webwork-modperl/htdocs/jsMath/plugins: mimeTeX.js tex2math.js Revision Data ------------- Index: global.conf.dist =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/conf/global.conf.dist,v retrieving revision 1.152 retrieving revision 1.153 diff -Lconf/global.conf.dist -Lconf/global.conf.dist -u -r1.152 -r1.153 --- conf/global.conf.dist +++ conf/global.conf.dist @@ -708,6 +708,7 @@ reportMissingFonts => 0, # set to 1 to allow the missing font message missingFontMessage => undef, # set to an HTML string to replace the missing font message noImageFonts => 0, # set to 1 if you didn't install the jsMath image fonts + processDoubleClicks => 1, # set to 0 to disable double-click on math to get TeX source }; ##### Directories used by PG Index: jsMath-controls.html =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/jsMath/jsMath-controls.html,v retrieving revision 1.3 retrieving revision 1.4 diff -Lhtdocs/jsMath/jsMath-controls.html -Lhtdocs/jsMath/jsMath-controls.html -u -r1.3 -r1.4 --- htdocs/jsMath/jsMath-controls.html +++ htdocs/jsMath/jsMath-controls.html @@ -64,7 +64,7 @@ this.panel.style.display = "none"; jsMath.Element("jsMath").style.display = (this.cookie.button ? "block" : "none"); if (this.document.location.protocol == 'file:') return; - for (var id in {scale:1, scaleImg:1, font:1, print:1, autofont:1, alpha:1}) { + for (var id in {scale:1, scaleImg:1, font:1, print:1, autofont:1, alpha:1, tex2math:1}) { if (this.cookie[id] != this.oldCookie[id]) { this.loaded = 0; this.document.location.reload(); @@ -112,7 +112,7 @@ this.panel.innerHTML = document.getElementById("jsMath.options").innerHTML; jsMath.Element("scale").value = this.cookie.scale; jsMath.Element("keep").value = this.cookie.keep; - for (var id in {autofont:1, scaleImg:1, alpha:1, warn:1, button:1}) { + for (var id in {autofont:1, scaleImg:1, alpha:1, warn:1, button:1, tex2math:1}) { if (this.cookie[id]) {jsMath.Element(id).checked = true} } var font = this.document.getElementsByName("jsMath.font"); @@ -133,6 +133,9 @@ jsMath.Element("alphaText").style.color = "#888888"; jsMath.Element("alpha").disabled = true; } + if (!jsMath.tex2math) { + jsMath.Element("tex2mathRow").style.display = 'none'; + } /* * Seems to be a bug in Safari that messes up the button names @@ -151,7 +154,7 @@ var font = this.document.getElementsByName("jsMath.font"); for (var i = 0; i < font.length; i++) {if (font[i].checked) {this.cookie.font = font[i].value}} - for (var id in {autofont:1, scaleImg:1, alpha:1, warn:1, button:1}) { + for (var id in {autofont:1, scaleImg:1, alpha:1, warn:1, button:1, tex2math:1}) { this.cookie[id] = jsMath.Element(id).checked ? 1: 0; } this.cookie.keep = jsMath.Element("keep").value; @@ -181,7 +184,7 @@ <p> <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" STYLE="margin:0pt 1em"> <TR><TD ALIGN="CENTER"><TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0"> -<TR><TD ALIGN="CENTER" COLSPAN="2"> +<TR><TD ALIGN="CENTER" COLSPAN="3"> <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0"> <TR><TD> <UL STYLE="text-align:left; margin:0pt 0pt; padding-left:1em; padding-bottom:1em"> @@ -195,20 +198,21 @@ </TD></TR> </TABLE> </TD></TR> -<TR><TD ALIGN="CENTER" COLSPAN="2"> +<TR><TD ALIGN="CENTER" COLSPAN="3"> <INPUT TYPE="BUTTON" ID="jsMath.resolution" VALUE="Hi-Res Fonts for Printing" STYLE="width:17em" onClick="jsMath.Controls.PrintResolution()"> </TD></TR> <TR><TD HEIGHT="5"></TD></TR> <TR><TD ALIGN="LEFT"> <INPUT TYPE="BUTTON" VALUE="Options" ID="jsMath.opts" STYLE="width:8em" onClick="jsMath.Controls.Options()"> +</TD><TD> </TD><TD ALIGN="RIGHT"> <INPUT TYPE="BUTTON" VALUE="Done" ID="jsMath.done" STYLE="width:8em" onClick="jsMath.Controls.Close()"> </TD></TR> </TABLE></TD></TR> <TR><TD HEIGHT="10"></TD></TR> -<TR><TD ALIGN="CENTER" COLSPAN="2" STYLE="width:20em; font-size:x-small"> +<TR><TD ALIGN="CENTER" COLSPAN="3" STYLE="width:20em; font-size:x-small"> <I>Click on the jsMath floating button or <NOBR>ALT-click</NOBR> on a mathematical expression to get this dialog at any time.</I> </TD></TR> @@ -248,6 +252,7 @@ <TR><TD><INPUT TYPE="CHECKBOX" ID="jsMath.alpha" VALUE="1"> <SPAN ID="jsMath.alphaText">Use image alpha channels</SPAN></TD></TR> <TR><TD><INPUT TYPE="CHECKBOX" ID="jsMath.warn" VALUE="1"> Show font warnings</TD></TR> <TR><TD><INPUT TYPE="CHECKBOX" ID="jsMath.button" VALUE="1"> Show jsMath button</TD></TR> +<TR ID="jsMath.tex2mathRow"><TD><INPUT TYPE="CHECKBOX" ID="jsMath.tex2math" VALUE="1"> Enable <CODE>tex2math</CODE> plug-in</TD></TR> <TR><TD HEIGHT="8"></TD></TR> Index: jsMath.js =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/jsMath/jsMath.js,v retrieving revision 1.18 retrieving revision 1.19 diff -Lhtdocs/jsMath/jsMath.js -Lhtdocs/jsMath/jsMath.js -u -r1.18 -r1.19 --- htdocs/jsMath/jsMath.js +++ htdocs/jsMath/jsMath.js @@ -66,7 +66,7 @@ var jsMath = { - version: "2.3b", // change this if you edit the file + version: "2.4a", // change this if you edit the file // // Name of image files @@ -99,10 +99,11 @@ '.cmmi10': 'font-family: cmmi10', '.cmsy10': 'font-family: cmsy10', '.cmex10': 'font-family: cmex10', - - '.normal': 'font-family: serif; font-style: normal; font-weight: normal', + '.math': 'font-family: serif; font-style: normal; font-weight: normal', '.typeset': 'font-family: serif; font-style: normal; font-weight: normal', + '.normal': 'font-family: serif; font-style: normal; font-weight: normal; ' + + 'padding:0px; border:0px; margin:0px;', 'span.typeset': '', 'div.typeset': 'text-align: center; margin: 1em 0px;', '.mathlink': 'text-decoration: none', @@ -114,10 +115,17 @@ '.jsM_panel': 'position:fixed; bottom:1.5em; right:1.5em; padding: 10px 20px; ' + 'background-color:#DDDDDD; border: outset 2px; ' - + 'z-index:102; width:auto;', + + 'z-index:103; width:auto;', '.jsM_button': 'position:fixed; bottom:1px; right:2px; background-color:white; ' + 'border: solid 1px #959595; margin:0px; padding: 0px 3px 1px 3px; ' - + 'z-index:101; color:black; text-decoration:none; font-size:x-small; width:auto;', + + 'z-index:102; color:black; text-decoration:none; font-size:x-small; width:auto;', + '.jsM_float': 'position:absolute; top:0px; left:0px; max-width:80%; ' + + 'z-index:101; width:auto; height:auto;', + '.jsM_drag': 'background-color:#DDDDDD; border: outset 1px; height:12px; font-size: 1px;', + '.jsM_close': 'background-color:#E6E6E6; border: inset 1px; width:8px; height:8px; margin: 1px 2px;', + '.jsM_source': 'background-color:#E2E2E2; border: outset 1px; ' + + 'width:auto; height:auto; padding: 8px 15px; ' + + 'font-family: courier, fixed; font-size: 90%', '.jsM_noFont': 'text-align: center; padding: 10px 20px; border: 3px solid #DD0000; ' + ' background-color: #FFF8F8; color: #AA0000; font-size:small; width:auto;', '.jsM_fontLink': 'padding: 0px 5px 2px 5px; text-decoration:none; color:black;' @@ -131,9 +139,9 @@ * Get the width and height (in pixels) of an HTML string */ BBoxFor: function (s) { - this.hidden.innerHTML = '<SPAN CLASS="jsM_scale">'+s+'</SPAN>'; + this.hidden.innerHTML = '<NOBR><SPAN CLASS="jsM_scale">'+s+'</SPAN></NOBR>'; var bbox = {w: this.hidden.offsetWidth, h: this.hidden.offsetHeight}; - this.hidden.innerHTML = ''; // avoid MSIE bug on the Mac + this.hidden.innerHTML = ''; return bbox; }, @@ -161,7 +169,7 @@ * Initialize jsMath. This determines the em size, and a variety * of other parameters used throughout jsMath. */ - Init: function (em) { + Init: function () { if (jsMath.Setup.inited != 1) { if (jsMath.Setup.inited) { alert("It looks like jsMath failed to set up properly."); @@ -171,8 +179,7 @@ } jsMath.Setup.Init(); // may fail to load fallback files properly } - if (em) {this.em = em} - else {this.em = this.BBoxFor('<DIV STYLE="width: 10em; height: 1em"></DIV>').w/10} + this.em = this.BBoxFor('<IMG SRC="'+jsMath.blank+'" STYLE="width:10em; height:1em">').w/10; if (jsMath.Browser.italicString) jsMath.Browser.italicCorrection = jsMath.BBoxFor(jsMath.Browser.italicString).w; if (jsMath.Browser.hiddenSpace != '') { @@ -183,35 +190,36 @@ jsMath.Browser.hiddenSpace + jsMath.Browser.hiddenSpace).w/5; } - var h = this.BBoxFor('x').h; // Line height and depth to baseline + var bb = this.BBoxFor('x'); var h = bb.h; var d = this.BBoxFor('x<IMG SRC="'+jsMath.blank+'" HEIGHT="'+(h*jsMath.Browser.imgScale)+'" WIDTH="1">').h - h; this.h = (h-d)/this.em; this.d = d/this.em; this.hd = this.h + this.d; - this.ph = h-d; this.pd = d; + this.xWidth = bb.w; // used to tell if scale has changed this.Setup.TeXfonts(); var x_height = this.EmBoxFor('<SPAN CLASS="cmr10">M</SPAN>').w/2; this.TeX.M_height = x_height*(26/14); this.TeX.h = this.h; this.TeX.d = this.d; this.TeX.hd = this.hd; - // factor for \big and its brethren - this.p_height = (this.TeX.cmex10[0].h+this.TeX.cmex10[0].d) / .85; - + this.Img.Scale(); if (!this.initialized) { this.Setup.Sizes(); this.Img.UpdateFonts(); } - + + // factor for \big and its brethren + this.p_height = (this.TeX.cmex10[0].h + this.TeX.cmex10[0].d) / .85; + this.initialized = 1; }, /* - * Get the em size and if it has changed, reinitialize the sizes + * Get the xWidth size and if it has changed, reinitialize the sizes */ ReInit: function () { - var em = this.BBoxFor('<SPAN STYLE="width: 10em; height: 1em"></SPAN>').w/10; - if (em != this.em) {this.Init(em)} + var w = this.BBoxFor('x').w; + if (w != this.xWidth) {this.Init()} }, /* @@ -299,6 +307,7 @@ jsMath.hidden = this.TopHTML("Hidden",{'class':"normal"},{ position:"absolute", top:0, left:0, border:0, padding:0, margin:0 }); + jsMath.hiddenTop = jsMath.hidden; return; }, @@ -372,10 +381,10 @@ var WH = jsMath.EmBoxFor('<SPAN CLASS="'+name+'">'+font[65].c+'</SPAN>'); font.hd = WH.h; font.d = jsMath.EmBoxFor('<SPAN CLASS="'+name+'">'+ font[65].c + - '<IMG SRC="'+jsMath.blank+'" STYLE="height:'+(font.hd*jsMath.Browser.imgScale)+'em; width:1"></SPAN>').h + '<IMG SRC="'+jsMath.blank+'" STYLE="height:'+(font.hd*jsMath.Browser.imgScale)+'em; width:1px;"></SPAN>').h - font.hd; font.h = font.hd - font.d; - font.dh = .05; + font.dh = .05; if (jsMath.browser == 'Safari') {font.hd *= 2}; if (name == 'cmmi10') {font.skewchar = 0177} else if (name == 'cmsy10') {font.skewchar = 060} }, @@ -432,6 +441,7 @@ jsMath.Setup.Source(); jsMath.Browser.Init(); jsMath.Controls.Init(); + jsMath.Click.Init(); jsMath.Setup.Styles(); jsMath.Setup.User(); // do user-specific initialization @@ -514,6 +524,8 @@ hiddenSpace: "", // ditto valignBug: 0, // Konqueror doesn't nest vertical-align + operaHiddenFix: '', // for Opera to fix bug with math in tables + /* * Determine if the "top" of a <SPAN> is always at the same height * or varies with the height of the rest of the line (MSIE). @@ -540,7 +552,7 @@ }, /* - * Test for browser characteristics, and adjust the font table + * Test for browser characteristics, and adjust things * to overcome specific browser bugs */ Init: function () { @@ -582,21 +594,23 @@ jsMath.Update.TeXfonts({ cmr10: {'10': {c: 'Ω', tclass: 'normal'}}, cmmi10: { - '10': {c: '<I>Ω</I>', tclass: 'normal'}, - '126': {c: '~<SPAN STYLE="margin-left:.1em"></SPAN>'} - }, + '10': {c: '<I>Ω</I>', tclass: 'normal'}, + '126': {c: '~<SPAN STYLE="margin-left:.1em"></SPAN>'} + }, cmsy10: { - '10': {c: '⊗', tclass: 'arial'}, - '55': {c: '<SPAN STYLE="margin-right:-.54em">7</SPAN>'} - }, + '10': {c: '⊗', tclass: 'arial'}, + '55': {c: '<SPAN STYLE="margin-right:-.54em">7</SPAN>'} + }, cmex10: {'10': {c: '<SPAN STYLE="font-size: 67%">D</SPAN>'}}, cmti10: {'10': {c: '<I>Ω</I>', tclass: 'normal'}}, cmbx10: {'10': {c: '<B>Ω</B>', tclass: 'normal'}} }); this.allowAbsoluteDelim = 1; - this.separateSkips = 1; + this.separateSkips = 1; + this.buttonCheck = 1; + this.msieDivWidthBug = 1; this.msieFontBug = 1; this.msieIntegralBug = 1; - this.msieAlphaBug = 1; this.alphaPrintBug = 1; + this.msieAlphaBug = 1; this.alphaPrintBug = 1; this.msieCenterBugFix = 'position:relative; '; this.msieSpaceFix = '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD">'; this.msieInlineBlockFix = ' display: inline-block;'; @@ -614,10 +628,12 @@ this.imgScale *= screen.logicalXDPI/screen.deviceXDPI; jsMath.Controls.cookie.alpha = 0; } + // Handle bug with getting width of italic text this.italicString = '<I>x</I>'; jsMath.EmBoxFor = jsMath.EmBoxForItalics; } else if (navigator.platform == 'MacPPC') { this.msieAbsoluteBug = 1; this.msieButtonBug = 1; + this.msieDivWidthBug = 1; jsMath.Setup.Script('jsMath-msie-mac.js'); jsMath.Parser.prototype.macros.angle = ['Replace','ord','<FONT FACE="Symbol">‹</FONT>','normal']; jsMath.styles['.jsM_panel'] = 'width:25em; ' + jsMath.styles['.jsM_panel'].replace(/width:auto/,""); @@ -644,7 +660,7 @@ }); } else { jsMath.Setup.Script('jsMath-mozilla.js'); - this.alphaPrintBug = 1; + this.alphaPrintBug = 1; } for (var i = 0; i < jsMath.TeX.fam.length; i++) { if (jsMath.TeX.fam[i]) @@ -664,6 +680,7 @@ jsMath.browser = 'OmniWeb'; this.allowAbsolute = !navigator.userAgent.match("OmniWeb/v4"); this.allowAbsoluteDelim = this.allowAbsolute; + this.buttonCheck = 1; } }, @@ -701,6 +718,7 @@ }); this.allowAbsolute = 0; this.delay = 10; + this.operaHiddenFix = '[Processing Math]'; } }, @@ -713,11 +731,12 @@ var version = navigator.userAgent.match("Safari/([0-9]+)"); version = (version)? version[1] : 200; // FIXME: hack until I get Tiger for (var i = 0; i < jsMath.TeX.fam.length; i++) - {if (jsMath.TeX.fam[i] != '') {jsMath.TeX[jsMath.TeX.fam[i]].dh = .1}} + {if (jsMath.TeX.fam[i]) {jsMath.TeX[jsMath.TeX.fam[i]].dh = .1}} jsMath.TeX.axis_height += .05; this.allowAbsoluteDelim = version >= 125; this.safariIFRAMEbug = version >= 312; // FIXME: find out if they fixed it this.safariImgBug = 1; + this.buttonCheck = 1; } }, @@ -959,14 +978,6 @@ }, /* - * Handle clicking on math to get control panel - */ - CheckClick: function (event) { - if (!event) {event = window.event} - if (event.altKey) jsMath.Controls.Panel(); - }, - - /* * Create the control panel button */ Button: function () { @@ -1077,6 +1088,207 @@ /***************************************************************************/ /* + * Implements the actions for clicking and double-clicking + * on math formulas + */ +jsMath.Click = { + + dragging: 0, + + /* + * Create the hidden DIV used for the tex source window + */ + Init: function () { + this.source = jsMath.Setup.TopHTML("Source",{'class':'jsM_float'},{display:'none'}); + this.source.innerHTML = + '<DIV CLASS="jsM_drag"><DIV CLASS="jsM_close"></DIV></DIV>' + + '<DIV CLASS="jsM_source"><SPAN></SPAN></DIV>'; + this.drag = this.source.firstChild; + this.tex = this.drag.nextSibling.firstChild; + this.drag.firstChild.onclick = jsMath.Click.CloseSource; + this.drag.onmousedown = jsMath.Click.StartDragging; + this.drag.ondragstart = jsMath.Click.False; + this.drag.onselectstart = jsMath.Click.False; + this.source.onclick = jsMath.Click.CheckClose; + }, + False: function () {return false}, + + /* + * Handle clicking on math to get control panel + */ + CheckClick: function (event) { + if (!event) {event = window.event} + if (event.altKey) jsMath.Controls.Panel(); + }, + + /* + * Handle double-click for seeing TeX code + */ + CheckDblClick: function (event) { + if (!event) {event = window.event} + var event = jsMath.Click.Event(event); + + var source = jsMath.Click.source + var tex = jsMath.Click.tex; + + source.style.visibility = 'hidden'; + source.style.display = ''; source.style.width = ''; + source.style.left = ''; source.style.top = ''; + tex.innerHTML = ''; + + var TeX = this.alt; + TeX = TeX.replace(/^\s+|\s+$/g,''); + TeX = TeX.replace(/&/g,'&'); + TeX = TeX.replace(/</g,'<'); + TeX = TeX.replace(/>/g,'>'); + TeX = TeX.replace(/\n/g,'<BR>'); + tex.innerHTML = TeX; + + var h = source.offsetHeight; var w; + if (jsMath.Browser.msieDivWidthBug) { + tex.className = 'jsM_source'; // Work around MSIE bug where + w = tex.offsetWidth + 5; // DIV's don't collapse to + tex.className = ''; // their natural widths + } else { + w = source.offsetWidth; + } + w = Math.max(50,Math.min(w,.8*event.W,event.W-40)); + var x = Math.floor(event.x-w/2); var y = Math.floor(event.y-h/2); + x = event.X + Math.max(Math.min(x,event.W-w-20),20); + y = event.Y + Math.max(Math.min(y,event.H-h-5),5); + + source.style.left = x+'px'; source.style.top = y+'px'; + source.style.width = w+'px'; + source.style.visibility = ''; + jsMath.Click.left = x + event.X; jsMath.Click.top = y + event.Y; + jsMath.Click.w = w; jsMath.Click.h = source.offsetHeight; + + jsMath.Click.DeselectText(x,y); + return false; + }, + + /* + * Get window width, height, and offsets plus + * position of pointer relative to the window + */ + Event: function (event) { + var W = window.innerWidth || document.body.clientWidth; + var H = window.innerHeight || document.body.clientHeight; + var X = window.pageXOffset; var Y = window.pageYOffset; + if (X == null) {X = document.body.clientLeft; Y = document.body.clientTop} + var x = event.pageX; var y = event.pageY; + if (x == null) { + x = event.clientX; y = event.clientY; + if (jsMath.browser == 'MSIE' && document.compatMode == 'CSS1Compat') { + X = document.documentElement.scrollLeft; + Y = document.documentElement.scrollTop; + W = document.documentElement.clientWidth; + H = document.documentElement.clientHeight; + } else { + X = document.body.scrollLeft; + Y = document.body.scrollTop; + } + } else {x -= X; y -= Y} + + return {x: x, y: y, W: W, H: H, X: X, Y: Y}; + }, + + /* + * Unselect whatever text is selected (since double-clicking + * usually selects something) + */ + DeselectText: function (x,y) { + if (window.getSelection && window.getSelection().removeAllRanges) + {window.getSelection().removeAllRanges()} + else if (document.getSelection && document.getSelection().removeAllRanges) + {document.getSelection().removeAllRanges()} + else if (document.selection && document.selection.empty) + {document.selection.empty()} + else { + /* Hack to deselect the text in Opera and Safari */ + if (jsMath.browser == 'MSIE') return; // don't try it if MISE on Mac + jsMath.hiddenTop.innerHTML = + '<textarea style="visibility:hidden" ROWS="1" COLS="1">a</textarea>'; + jsMath.hiddenTop.firstChild.style.position = 'absolute'; + jsMath.hiddenTop.firstChild.style.left = x+'px'; + jsMath.hiddenTop.firstChild.style.top = y+'px'; + setTimeout(jsMath.Click.SelectHidden,1); + } + }, + SelectHidden: function () { + jsMath.hiddenTop.firstChild.focus(); + jsMath.hiddenTop.firstChild.select(); + jsMath.hiddenTop.innerHTML = ''; + }, + + /* + * Close the TeX source window + */ + CloseSource: function () { + jsMath.Click.tex.innerHTML = ''; + jsMath.Click.source.style.display = 'none'; + jsMath.Click.source.style.visibility = 'hidden'; + jsMath.Click.StopDragging(); + return false; + }, + CheckClose: function (event) { + if (!event) {event = window.event} + if (event.altKey) {jsMath.Click.CloseSource(); return false} + }, + + /* + * Set up for dragging the source panel + */ + StartDragging: function (event) { + if (!event) {event = window.event} + if (jsMath.Click.dragging) {jsMath.Click.StopDragging(event)} + var event = jsMath.Click.Event(event); + jsMath.Click.dragging = 1; + jsMath.Click.x = event.x + 2*event.X - jsMath.Click.left; + jsMath.Click.y = event.y + 2*event.Y - jsMath.Click.top; + jsMath.Click.oldonmousemove = document.body.onmousemove; + jsMath.Click.oldonmouseup = document.body.onmouseup; + document.body.onmousemove = jsMath.Click.DragSource; + document.body.onmouseup = jsMath.Click.StopDragging; + return false; + }, + + /* + * Stop dragging the source window + */ + StopDragging: function (event) { + if (jsMath.Click.dragging) { + document.body.onmousemove = jsMath.Click.oldonmousemove; + document.body.onmouseup = jsMath.Click.oldonmouseup; + jsMath.Click.oldonmousemove = null; + jsMath.Click.oldonmouseup = null; + jsMath.Click.dragging = 0; + } + return false; + }, + + /* + * Move the source window (but stay within the browser window) + */ + DragSource: function (event) { + if (!event) {event = window.event} + if (jsMath.Browser.buttonCheck && !event.button) {return jsMath.Click.StopDragging(event)} + event = jsMath.Click.Event(event); + var x = event.x + event.X - jsMath.Click.x; + var y = event.y + event.Y - jsMath.Click.y; + x = Math.max(event.X,Math.min(event.W+event.X-jsMath.Click.w,x)); + y = Math.max(event.Y,Math.min(event.H+event.Y-jsMath.Click.h,y)); + jsMath.Click.source.style.left = x + 'px'; + jsMath.Click.source.style.top = y + 'px'; + jsMath.Click.left = x + event.X; jsMath.Click.top = y + event.Y; + return false; + } + +}; + +/***************************************************************************/ + +/* * The TeX font information */ jsMath.TeX = { @@ -2352,9 +2564,9 @@ if (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha) { c.c = '<IMG SRC="'+jsMath.blank+'" ' + 'STYLE="'+jsMath.Browser.msieCenterBugFix - + resize + vadjust + wadjust - + ' filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + "'" - + URL + "', sizingMethod='scale'" + ');">'; + + resize + vadjust + wadjust + + ' filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + "'" + + URL + "', sizingMethod='scale'" + ');">'; } else { c.c = '<IMG SRC="'+URL+'" STYLE="'+jsMath.Browser.msieCenterBugFix + resize + vadjust + wadjust + '">'; @@ -5374,9 +5586,8 @@ if (isSmall) {// hide the extra size if (jsMath.Browser.allowAbsolute) { var y = 0; - if (jsMath.Browser.spanHeightVaries || box.bh > jsMath.h+.001) {y = (jsMath.h - box.bh)} + if (box.bh > jsMath.h+.001) {y = jsMath.h - box.bh} html = jsMath.HTML.Absolute(html,box.w,jsMath.h,0,y,jsMath.h); - isBig = 1; } else if (!jsMath.Browser.valignBug) { // remove line height and try to hide the depth var dy = jsMath.HTML.Em(Math.max(0,box.bd-jsMath.hd)/3); @@ -5384,14 +5595,15 @@ + ' position:relative; top:'+dy+'; vertical-align:'+dy + '">' + html + '</SPAN>'; } + isBig = 1; } if (isBig) {// add height and depth to the line (force a little // extra to separate lines if needed) html += '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD" STYLE="' - + 'height:'+jsMath.HTML.Em((box.h+box.d+.2)*jsMath.Browser.imgScale)+'; ' - + 'vertical-align:'+jsMath.HTML.Em(-box.d-.1)+';">' + + 'height:'+jsMath.HTML.Em((box.h+box.d+.1)*jsMath.Browser.imgScale)+'; ' + + 'vertical-align:'+jsMath.HTML.Em(-box.d-.05)+';">' } - return '<NOBR><SPAN CLASS="jsM_scale">'+html+'</SPAN><NOBR>'; + return '<NOBR><SPAN CLASS="jsM_scale">'+html+'</SPAN></NOBR>'; } }); @@ -5507,11 +5719,14 @@ * processed and reinitialize sizes for that location. */ ResetHidden: function (element) { - element.innerHTML = '<SPAN CLASS="normal" STYLE="position:absolute; top:0;left:0;"></SPAN>'; + element.innerHTML = + '<SPAN CLASS="normal" STYLE="position:absolute; top:0px;left:0px;"></SPAN>' + + jsMath.Browser.operaHiddenFix; // needed by Opera in tables element.className=''; jsMath.hidden = element.firstChild; jsMath.ReInit(); }, + /* * Typeset the contents of an element in \textstyle @@ -5521,6 +5736,7 @@ this.ResetHidden(element); element.innerHTML = this.TextMode(text); element.className = 'typeset'; + element.alt = text; }, /* @@ -5531,6 +5747,7 @@ this.ResetHidden(element); element.innerHTML = this.DisplayMode(text); element.className = 'typeset'; + element.alt = text; }, /* @@ -5543,16 +5760,17 @@ } else if (element.tagName == 'SPAN') { this.ConvertText(element); // - // Overcome a bug in MSIE where were tex2math can't insert DIV's inside + // Overcome a bug in MSIE where were tex2math can't insert DIV's inside // some elements, so fake it with SPANs, but can't fake the centering, - // so do that here. - // - if (element.parentNode.className == 'jsMath.recenter') { - element.parentNode.style.marginLeft = - Math.floor((element.parentNode.offsetWidth - element.offsetWidth)/2)+"px"; - } + // so do that here. + // + if (element.parentNode.className == 'jsMath.recenter') { + element.parentNode.style.marginLeft = + Math.floor((element.parentNode.offsetWidth - element.offsetWidth)/2)+"px"; + } } - element.onclick = jsMath.Controls.CheckClick; + element.onclick = jsMath.Click.CheckClick; + element.ondblclick = jsMath.Click.CheckDblClick; } catch (err) {} }, @@ -5645,11 +5863,12 @@ element[i].removeAttribute('NAME'); } } + jsMath.hidden = jsMath.hiddenTop; jsMath.element = []; window.status = 'Done'; if (jsMath.Browser.safariImgBug && (jsMath.Controls.cookie.font == 'symbol' || - jsMath.Controls.cookie.font == 'image')) { + jsMath.Controls.cookie.font == 'image')) { // // For Safari, the images don't always finish // updating, so nudge the window to cause a Index: jsMath-ww.js =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/jsMath/jsMath-ww.js,v retrieving revision 1.2 retrieving revision 1.3 diff -Lhtdocs/jsMath/jsMath-ww.js -Lhtdocs/jsMath/jsMath-ww.js -u -r1.2 -r1.3 --- htdocs/jsMath/jsMath-ww.js +++ htdocs/jsMath/jsMath-ww.js @@ -42,6 +42,7 @@ if (window.noFontMessage) {jsMath.styles['.jsM_Warning'] = "display: none"} if (window.missingFontMessage) {jsMath.Font.message = missingFontMessage} + if (!window.processDoubleClicks) {jsMath.Click = {CheckDblClick: function () {}}} // Load actual jsMath code jsMath.wwSource(); Index: mimeTeX.js =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/jsMath/plugins/mimeTeX.js,v retrieving revision 1.1 retrieving revision 1.2 diff -Lhtdocs/jsMath/plugins/mimeTeX.js -Lhtdocs/jsMath/plugins/mimeTeX.js -u -r1.1 -r1.2 --- htdocs/jsMath/plugins/mimeTeX.js +++ htdocs/jsMath/plugins/mimeTeX.js @@ -1 +1,195 @@ -/* * Treat ~ as space */ jsMath.Parser.prototype.nextIsSpace = function () { return this.string.charAt(this.i) == ' ' || this.string.charAt(this.i) == '~'; } jsMath.Parser.prototype.special['~'] = 'Space'; /* * Implement \[ ... \], \( ... \), etc. */ jsMath.Macro('[','\\left['); jsMath.Macro(']','\\right]'); jsMath.Macro('(','\\left('); jsMath.Macro(')','\\right)'); jsMath.Macro('<','\\left<'); jsMath.Macro('>','\\right>'); // can't do \. in a reasonable way jsMath.Parser.prototype.macros['|'] = ['HandleLR','|','|']; jsMath.Parser.prototype.macros['='] = ['HandleLR','\\|','\\|']; /* * Make non-standard \left{ and \right} work */ jsMath.Parser.prototype.delimiter['}'] = [5,2,0x67,3,0x09]; jsMath.Parser.prototype.delimiter['{'] = [4,2,0x66,3,0x08]; /* * Immitate mimeTeX \big... and \Big... ops */ // make the normal ones in text mode jsMath.Macro('int','\\intop\\nolimits'); jsMath.Macro('oint','\\ointop\\nolimits'); jsMath.Macro('sum','\\sumop\\n! olimits'); jsMath.Macro('prod','\\prodop\\nolimits'); jsMath.Macro('coprod','\\coprodop\\nolimits'); jsMath.Macro('bigint','\\bigintop\\nolimits'); jsMath.Macro('bigoint','\\bigointop\\nolimits'); jsMath.Macro('bigsum','\\bigsumop\\nolimits'); jsMath.Macro('bigprod','\\bigprodop\\nolimits'); jsMath.Macro('bigcoprod','\\bigcoprodop\\nolimits'); jsMath.Macro('Bigint','\\bigintop\\limits'); jsMath.Macro('Bigoint','\\bigointop\\limits'); jsMath.Macro('Bigsum','\\bigsumop\\limits'); jsMath.Macro('Bigprod','\\bigprodop\\limits'); jsMath.Macro('Bigcoprod','\\bigcoprod\\limits'); /* * The characters needed for the macros above */ jsMath.Parser.prototype.mathchardef['coprodop'] = [1,3,0x60]; jsMath.Parser.prototype.mathchardef['prodop'] = [1,3,0x51]; jsMath.Parser.prototype.mathchardef['sumop'] = [1,3,0x50]; jsMath.Parser.prototype.mathchardef['bigintop'] = [1,3,0x5A]; jsMath.Parser.prototype.mathchardef['bigointop'] = [1,3,0x49]; jsMath.Parser.prototype.mathcharde! f['bigcoprodop'] = [1,3,0x61]; jsMath.Parser.prototype.mathcha! rdef['bi gprodop'] = [1,3,0x59]; jsMath.Parser.prototype.mathchardef['bigsumop'] = [1,3,0x58]; /* * Unlink the small versions so they don't enlarge in display mode */ jsMath.TeX['cmex10'][0x48].n = null; jsMath.TeX['cmex10'][0x50].n = null; jsMath.TeX['cmex10'][0x51].n = null; jsMath.TeX['cmex10'][0x52].n = null; jsMath.TeX['cmex10'][0x60].n = null; /* * Some other missing items */ jsMath.Macro('/','{}'); // insert an empty box \/ jsMath.Macro('raisebox','\\raise #1px ',1); // convert to \raise jsMath.Macro('hfill','\\quad ',1); // punt jsMath.Macro('fbox','\\oldfbox{$#1$}',1); // do fbox in math mode /* * These get new JavaScript routines */ jsMath.Parser.prototype.macros['unitlength'] = 'unitlength'; jsMath.Parser.prototype.macros['hspace'] = 'hspace'; jsMath.Parser.prototype.macros['fs'] = 'fs'; jsMath.Parser.prototype.macros['oldfbox'] = 'FBox'; /* * Add some JavaScript functions to the parser */ jsMath.Package(jsMath.Parser,{ /* * Imp! lement \left x ... \right x */ HandleLR: function (name,data) { var arg = this.GetUpto(name,name); if (this.error) return; this.string = '\\left'+data[0]+arg+'\\right'+data[1]; this.i = 0; }, /* * Hold the unit length in mlist.data */ unitlength: function (name) { var n = this.GetArgument(this.cmd+name); if (this.error) return; if (!n.match(/^-?(\d+(\.\d*)?|\.\d+)$/)) { this.Error("Argument for "+this.cmd+name+" must be a number"); return; } this.mlist.data['unitlength'] = n; }, /* * Get the length (converted to ems) and multiply by the unit length */ hspace: function (name) { var w = this.GetArgument(this.cmd+name); if (this.error) return; if (!w.match(/^-?(\d+(\.\d*)?|\.\d+)$/)) { this.Error("Argument for "+this.cmd+name+" must be a number"); return; } w /= jsMath.em if (this.mlist.data['unitlength']) {w *= this.mlist.data['unitlength']} this.mlist.Add(jsMath.mItem! .Space(w)); }, /* * Implement \fs{...} for font-siz! e changi ng */ fs: function (name) { var n = this.GetArgument(this.cmd+name); if (this.error) return; if (!n.match(/^[-+]?\d+$/)) { this.Error("Argument for "+this.cmd+name+" must be an integer"); return; } if (n.match(/[-+]/)) {n = n - 0; n += this.mlist.data.size} this.mlist.data.size = n = Math.max(0,Math.min(9,n)); this.mlist.Add(new jsMath.mItem('size',{size: n})); }, /* * Repalce the Array function by one that accepts an optional * parameter for the column types, and that handle's mimeTeX's * "preamble" format. */ Array: function (name,delim) { var columns = delim[2]; var cspacing = delim[3]; if (!columns && this.GetNext() == '{') { columns = this.GetArgument(this.cmd+'begin{'+name+'}'); if (this.error) return; } else { columns = ''; } columns = columns.replace(/[^clr]/g,''); columns = columns.split(''); var data = this.mlist.data; var arg = this.GetEnd(name); if (th! is.error) return; if (arg.match(/\$/)) {arg = arg.replace(/^([^$]*)\$/,''); columns = RegExp.$1} var parse = new jsMath.Parser(arg+'\\\\',null,data.size); parse.matrix = name; parse.row = []; parse.table = []; parse.Parse(); if (parse.error) {this.Error(parse); return} parse.HandleRow(name,1); // be sure the last row is recorded var box = jsMath.Box.Layout(data.size,parse.table,columns,cspacing); // Add parentheses, if needed if (delim[0] && delim[1]) { var left = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[0]],'T'); var right = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[1]],'T'); box = jsMath.Box.SetList([left,box,right],data.style,data.size); } this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box)); }, /* * Similarly for Matrix (used by \matrix and \array) */ Matrix: function (name,delim) { var data = this.mlist.data; var arg = this.GetArgument(this.cmd+name);! if (this.error) return; if (arg.match(/\$/)) {arg = arg.r! eplace(/ ^([^$]*)\$/,''); delim[2] = RegExp.$1} var parse = new jsMath.Parser(arg+'\\\\',null,data.size); parse.matrix = name; parse.row = []; parse.table = []; parse.Parse(); if (parse.error) {this.Error(parse); return} parse.HandleRow(name,1); // be sure the last row is recorded var box = jsMath.Box.Layout(data.size,parse.table,delim[2]); // Add parentheses, if needed if (delim[0] && delim[1]) { var left = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[0]],'T'); var right = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[1]],'T'); box = jsMath.Box.SetList([left,box,right],data.style,data.size); } this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box)); } }); \ No newline at end of file +/* + * Treat ~ as space + */ +jsMath.Parser.prototype.nextIsSpace = function () { + return this.string.charAt(this.i) == ' ' || + this.string.charAt(this.i) == '~'; +} +jsMath.Parser.prototype.special['~'] = 'Space'; + +/* + * Implement \[ ... \], \( ... \), etc. + */ +jsMath.Macro('[','\\left['); jsMath.Macro(']','\\right]'); +jsMath.Macro('(','\\left('); jsMath.Macro(')','\\right)'); +jsMath.Macro('<','\\left<'); jsMath.Macro('>','\\right>'); +// can't do \. in a reasonable way +jsMath.Parser.prototype.macros['|'] = ['HandleLR','|','|']; +jsMath.Parser.prototype.macros['='] = ['HandleLR','\\|','\\|']; + +/* + * Make non-standard \left{ and \right} work + */ +jsMath.Parser.prototype.delimiter['}'] = [5,2,0x67,3,0x09]; +jsMath.Parser.prototype.delimiter['{'] = [4,2,0x66,3,0x08]; + + +/* + * Immitate mimeTeX \big... and \Big... ops + */ + +// make the normal ones in text mode +jsMath.Macro('int','\\intop\\nolimits'); +jsMath.Macro('oint','\\ointop\\nolimits'); +jsMath.Macro('sum','\\sumop\\nolimits'); +jsMath.Macro('prod','\\prodop\\nolimits'); +jsMath.Macro('coprod','\\coprodop\\nolimits'); + +jsMath.Macro('bigint','\\bigintop\\nolimits'); +jsMath.Macro('bigoint','\\bigointop\\nolimits'); +jsMath.Macro('bigsum','\\bigsumop\\nolimits'); +jsMath.Macro('bigprod','\\bigprodop\\nolimits'); +jsMath.Macro('bigcoprod','\\bigcoprodop\\nolimits'); + +jsMath.Macro('Bigint','\\bigintop\\limits'); +jsMath.Macro('Bigoint','\\bigointop\\limits'); +jsMath.Macro('Bigsum','\\bigsumop\\limits'); +jsMath.Macro('Bigprod','\\bigprodop\\limits'); +jsMath.Macro('Bigcoprod','\\bigcoprod\\limits'); + +/* + * The characters needed for the macros above + */ +jsMath.Parser.prototype.mathchardef['coprodop'] = [1,3,0x60]; +jsMath.Parser.prototype.mathchardef['prodop'] = [1,3,0x51]; +jsMath.Parser.prototype.mathchardef['sumop'] = [1,3,0x50]; + +jsMath.Parser.prototype.mathchardef['bigintop'] = [1,3,0x5A]; +jsMath.Parser.prototype.mathchardef['bigointop'] = [1,3,0x49]; +jsMath.Parser.prototype.mathchardef['bigcoprodop'] = [1,3,0x61]; +jsMath.Parser.prototype.mathchardef['bigprodop'] = [1,3,0x59]; +jsMath.Parser.prototype.mathchardef['bigsumop'] = [1,3,0x58]; + +/* + * Unlink the small versions so they don't enlarge in display mode + */ +jsMath.TeX['cmex10'][0x48].n = null; +jsMath.TeX['cmex10'][0x50].n = null; +jsMath.TeX['cmex10'][0x51].n = null; +jsMath.TeX['cmex10'][0x52].n = null; +jsMath.TeX['cmex10'][0x60].n = null; + + +/* + * Some other missing items + */ +jsMath.Macro('/','{}'); // insert an empty box \/ +jsMath.Macro('raisebox','\\raise #1px ',1); // convert to \raise +jsMath.Macro('hfill','\\quad ',1); // punt +jsMath.Macro('fbox','\\oldfbox{$#1$}',1); // do fbox in math mode + +/* + * These get new JavaScript routines + */ +jsMath.Parser.prototype.macros['unitlength'] = 'unitlength'; +jsMath.Parser.prototype.macros['hspace'] = 'hspace'; +jsMath.Parser.prototype.macros['fs'] = 'fs'; +jsMath.Parser.prototype.macros['oldfbox'] = 'FBox'; + +/* + * Add some JavaScript functions to the parser + */ +jsMath.Package(jsMath.Parser,{ + + /* + * Implement \left x ... \right x + */ + HandleLR: function (name,data) { + var arg = this.GetUpto(name,name); if (this.error) return; + this.string = '\\left'+data[0]+arg+'\\right'+data[1]; + this.i = 0; + }, + + /* + * Hold the unit length in mlist.data + */ + unitlength: function (name) { + var n = this.GetArgument(this.cmd+name); if (this.error) return; + if (!n.match(/^-?(\d+(\.\d*)?|\.\d+)$/)) { + this.Error("Argument for "+this.cmd+name+" must be a number"); + return; + } + this.mlist.data['unitlength'] = n; + }, + + /* + * Get the length (converted to ems) and multiply by the unit length + */ + hspace: function (name) { + var w = this.GetArgument(this.cmd+name); if (this.error) return; + if (!w.match(/^-?(\d+(\.\d*)?|\.\d+)$/)) { + this.Error("Argument for "+this.cmd+name+" must be a number"); + return; + } + w /= jsMath.em + if (this.mlist.data['unitlength']) {w *= this.mlist.data['unitlength']} + this.mlist.Add(jsMath.mItem.Space(w)); + }, + + /* + * Implement \fs{...} for font-size changing + */ + fs: function (name) { + var n = this.GetArgument(this.cmd+name); if (this.error) return; + if (!n.match(/^[-+]?\d+$/)) { + this.Error("Argument for "+this.cmd+name+" must be an integer"); + return; + } + if (n.match(/[-+]/)) {n = n - 0; n += this.mlist.data.size} + this.mlist.data.size = n = Math.max(0,Math.min(9,n)); + this.mlist.Add(new jsMath.mItem('size',{size: n})); + }, + + /* + * Repalce the Array function by one that accepts an optional + * parameter for the column types, and that handle's mimeTeX's + * "preamble" format. + */ + Array: function (name,delim) { + var columns = delim[2]; var cspacing = delim[3]; + if (!columns && this.GetNext() == '{') { + columns = this.GetArgument(this.cmd+'begin{'+name+'}'); + if (this.error) return; + } else { + columns = ''; + } + columns = columns.replace(/[^clr]/g,''); + columns = columns.split(''); + var data = this.mlist.data; + var arg = this.GetEnd(name); if (this.error) return; + if (arg.match(/\$/)) {arg = arg.replace(/^([^$]*)\$/,''); columns = RegExp.$1} + var parse = new jsMath.Parser(arg+'\\\\',null,data.size); + parse.matrix = name; parse.row = []; parse.table = []; + parse.Parse(); if (parse.error) {this.Error(parse); return} + parse.HandleRow(name,1); // be sure the last row is recorded + var box = jsMath.Box.Layout(data.size,parse.table,columns,cspacing); + // Add parentheses, if needed + if (delim[0] && delim[1]) { + var left = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[0]],'T'); + var right = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[1]],'T'); + box = jsMath.Box.SetList([left,box,right],data.style,data.size); + } + this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box)); + }, + + /* + * Similarly for Matrix (used by \matrix and \array) + */ + Matrix: function (name,delim) { + var data = this.mlist.data; + var arg = this.GetArgument(this.cmd+name); if (this.error) return; + if (arg.match(/\$/)) {arg = arg.replace(/^([^$]*)\$/,''); delim[2] = RegExp.$1} + var parse = new jsMath.Parser(arg+'\\\\',null,data.size); + parse.matrix = name; parse.row = []; parse.table = []; + parse.Parse(); if (parse.error) {this.Error(parse); return} + parse.HandleRow(name,1); // be sure the last row is recorded + var box = jsMath.Box.Layout(data.size,parse.table,delim[2]); + // Add parentheses, if needed + if (delim[0] && delim[1]) { + var left = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[0]],'T'); + var right = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[1]],'T'); + box = jsMath.Box.SetList([left,box,right],data.style,data.size); + } + this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box)); + } +}); \ No newline at end of file Index: tex2math.js =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/jsMath/plugins/tex2math.js,v retrieving revision 1.2 retrieving revision 1.3 diff -Lhtdocs/jsMath/plugins/tex2math.js -Lhtdocs/jsMath/plugins/tex2math.js -u -r1.2 -r1.3 --- htdocs/jsMath/plugins/tex2math.js +++ htdocs/jsMath/plugins/tex2math.js @@ -25,41 +25,126 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -jsMath.Add(jsMath,{ +jsMath.Insert(jsMath,{ - ConvertTeX: function (element) {jsMath.tex2math.ConvertMath("tex",element)}, - ConvertTeX2: function (element) {jsMath.tex2math.ConvertMath("tex2",element)}, - ConvertLaTeX: function (element) {jsMath.tex2math.ConvertMath("latex",element)}, + ConvertTeX: function (element) {jsMath.tex2math.Convert("tex",element)}, + ConvertTeX2: function (element) {jsMath.tex2math.Convert("tex2",element)}, + ConvertLaTeX: function (element) {jsMath.tex2math.Convert("latex",element)}, tex2math: { + /* + * Set up for the correct type of search, and recursively + * convert the mathematics. Disable tex2math if the cookie + * isn't set, or of there is an element with ID of 'tex2math_off'. + */ + Convert: function (type,element) { + if (jsMath.Controls.cookie.tex2math && + (!jsMath.tex2math.allowDisableTag || !document.getElementById('tex2math_off'))) { + var pattern = jsMath.tex2math.pattern[type]; + if (type == 'custom') {jsMath.tex2math.isDisplay = jsMath.tex2math.customIsDisplay} + else {jsMath.tex2math.isDisplay = jsMath.tex2math.standardIsDisplay} + jsMath.tex2math.ConvertMath(pattern,element); + } + }, + + /* + * Patterns for the various types of conversions + */ pattern: { tex: /((^|[^\\])(\\[^\[\(])*)(\\\((([^\\]|\\[^\)])*)\\\)|\\\[(([^\\]|\\[^\]])*)\\\]|\$\$((\\.|\$[^$\\]|[^$\\])*)\$\$|\$(([^$\\]|\\.)*)\$)/, tex2: /((^|[^\\])(\\[^\[\(])*)(\\\((([^\\]|\\[^\)])*)\\\)|\\\[(([^\\]|\\[^\]])*)\\\]|\$\$((\\.|\$[^$\\]|[^$\\])*)\$\$)/, latex: /((^|[^\\])(\\[^\[\(])*)(\\\((([^\\]|\\[^\)])*)\\\)|\\\[(([^\\]|\\[^\]])*)\\\])/ }, - - ConvertMath: function (method,element,recurse) { - if (!element) { - if (recurse) return; - element = document.body; + + /* + * Test if we have a string that initiates display math mode + */ + standardIsDisplay: function (string) { + string = string.substr(0,2); + return (string == '\\[' || + (!jsMath.tex2math.doubleDollarsAreInLine && string == '$$')); + }, + + /* + * Create a pattern for custom math and display indicators. E.g. + * + * jsMath.tex2math.CustomSearch('[math]','[/math]','[display]','[/display]'); + * + * would make in-line math be delimted by [math]...[/math] and + * display math by [display]...[/display]. Make sure that the opening + * delimiter is not something that would appear within the + * mathematics, or tex2math might not be able to match the delimiters + * properly. + */ + CustomSearch: function (mathopen,mathclose,displayopen,displayclose) { + var pattern = this.patternCombine(mathopen,displayopen); + this.pattern.custom = new RegExp('(()())(' + + this.patternQuote(displayopen) + pattern + this.patternQuote(displayclose) + + '|' + + this.patternQuote(mathopen) + pattern + this.patternQuote(mathclose) + + ')'); + this.customIsDisplay = function (string) { + return (string.substr(0,displayopen.length) == displayopen); + }; + jsMath.ConvertCustom = function (element) {jsMath.tex2math.Convert('custom',element)}; + }, + + patternCombine: function (s1,s2) { + for (var i = 0; i < s1.length && i < s2.length && s1.charAt(i) == s2.charAt(i); i++) {}; + var pattern = this.patternAdd('',s1.substr(0,i),0); + if (i) {pattern += '|'} + pattern += this.patternQuote(s1.substr(0,i)) + + '[^' + this.patternQuote(s1.charAt(i)+s2.charAt(i)) + ']'; + pattern = this.patternAdd(pattern,s1,i+1); + pattern = this.patternAdd(pattern,s2,i+1); + return '((' + pattern + ')*)'; + return pattern; + }, + + patternAdd: function (pattern,string,i) { + while (i < string.length) { + if (pattern != "") {pattern += '|'} + pattern += this.patternQuote(string.substr(0,i)) + + '[^' + this.patternQuote(string.charAt(i)) + ']'; + i++; } + return pattern; + }, + + patternQuote: function (s) { + s = s.replace(/([\^(){}+*?\-|\[\]\:\\])/g,'\\$1'); + return s; + }, + + /* + * Recursively look through text nodes for mathematics + * that needs to be surrounded by SPAN or DIV tags. + * Don't process SCRIPT, NOSCRIPT, STYLE, TEXTAREA or PRE + * tags (unless they are of class "tex2math_process") and don't + * process any that are of class "tex2math_ignore"). + */ + ConvertMath: function (pattern,element,recurse,ignore) { + if (!element) {if (recurse) {return} else {element = document.body}} if (typeof(element) == 'string') {element = document.getElementById(element)} - - var pattern = jsMath.tex2math.pattern[method]; + while (element) { if (element.nodeName == '#text') { - if (!element.parentNode.tagName || - !element.parentNode.tagName.match(/^(SCRIPT|NOSCRIPT|STYLE|TEXTAREA)$/i)) { - element = jsMath.tex2math.TeX2math(pattern,element); - } - } else { - this.ConvertMath(method,element.firstChild,1); + if (!ignore) {element = jsMath.tex2math.TeX2math(pattern,element)} + } else if (element.firstChild) { + var off = ignore || element.className == 'tex2math_ignore' || + (element.tagName && element.tagName.match(/^(SCRIPT|NOSCRIPT|STYLE|TEXTAREA|PRE)$/i)); + off = off && element.className != 'tex2math_process'; + this.ConvertMath(pattern,element.firstChild,1,off); } element = element.nextSibling; } }, + /* + * Search a string for the math pattern and and replace it + * by the proper type of SPAN or DIV + */ TeX2math: function (pattern,element) { var result; var text; var tag; var math; var rest; while (result = pattern.exec(element.nodeValue.replace(/\n/g,' '))) { @@ -69,7 +154,7 @@ {element.nodeValue = element.nodeValue.replace(/\\\$/g,'')} math.parentNode.removeChild(math); if (text = (result[5] || result[7] || result[9] || result[11])) { - tag = jsMath.tex2math.createMathTag(result[4].substr(0,2),text); + tag = jsMath.tex2math.createMathTag(result[4],text); if (rest.parentNode) { rest.parentNode.insertBefore(tag,rest); } else if (element.nextSibling) { @@ -85,8 +170,11 @@ return element; }, + /* + * Create an element for the mathematics + */ createMathTag: function (type,text) { - type = (type == '\\[' || type == '$$')? "div" : "span"; + type = (jsMath.tex2math.isDisplay(type))? "div" : "span"; var tag = document.createElement(type); tag.className = "math"; var math = document.createTextNode(text); tag.appendChild(math); @@ -105,7 +193,7 @@ MSIEcreateMathTag: function (type,text) { var tag = document.createElement("span"); tag.className = "math"; - if (type == '\\[' || type == '$$') { + if (jsMath.tex2math.isDisplay(type)) { tag.className = (jsMath.tex2math.center)? "jsMath.recenter": ""; tag.style.width = "100%"; tag.style.margin = jsMath.tex2math.margin; tag.style.display = "inline-block"; @@ -118,6 +206,18 @@ } }); +/* + * Enable this plugin by default + */ +if (jsMath.Controls.cookie.tex2math == null) {jsMath.Controls.cookie.tex2math = 1} +if (jsMath.tex2math.allowDisableTag == null) {jsMath.tex2math.allowDisableTag = 1} + +/* + * MSIE can't handle the DIV's properly, so we need to do it by + * hand. Look up the style for typeset math to see if the user + * has changed it, and get whether it is centered or indented + * so we can mirror that using a SPAN + */ if (jsMath.browser == 'MSIE' && navigator.platform == 'Win32') { jsMath.tex2math.createMathTag = jsMath.tex2math.MSIEcreateMathTag; jsMath.Add(jsMath.tex2math,{margin: "", center: 0}); |
From: dpvc v. a. <we...@ma...> - 2005-11-17 13:23:46
|
Log Message: ----------- Give better error messages when the entries in Points, Vectors and Matrices are not of the right type. Modified Files: -------------- pg/lib/Parser/List: Matrix.pm Point.pm Vector.pm Revision Data ------------- Index: Vector.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Parser/List/Vector.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -Llib/Parser/List/Vector.pm -Llib/Parser/List/Vector.pm -u -r1.4 -r1.5 --- lib/Parser/List/Vector.pm +++ lib/Parser/List/Vector.pm @@ -16,8 +16,11 @@ sub _check { my $self = shift; foreach my $x (@{$self->{coords}}) { - $self->{equation}->Error("Coordinates of Vector must be Numbers") - unless $x->isNumber; + unless ($x->isNumber) { + my $type = $x->type; + $type = (($type =~ m/^[aeiou]/i)? "an ": "a ") . $type; + $self->{equation}->Error(["Coordinates of Vectors must be Numbers, not %s",$type]); + } } } Index: Matrix.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Parser/List/Matrix.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -Llib/Parser/List/Matrix.pm -Llib/Parser/List/Matrix.pm -u -r1.4 -r1.5 --- lib/Parser/List/Matrix.pm +++ lib/Parser/List/Matrix.pm @@ -19,6 +19,10 @@ foreach my $x (@{$self->{coords}}) {$x->makeMatrix($self->{type}{name},$self->{open},$self->{close})} } + foreach my $x (@{$self->{coords}}) { + $self->{equation}->Error("Entries in a Matrix must be Numbers or Lists") + unless ($x->class =~ m/Number|List/); + } } # Index: Point.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Parser/List/Point.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -Llib/Parser/List/Point.pm -Llib/Parser/List/Point.pm -u -r1.2 -r1.3 --- lib/Parser/List/Point.pm +++ lib/Parser/List/Point.pm @@ -7,10 +7,20 @@ @ISA = qw(Parser::List); # -# The basic List class does it all. We only need this class -# for its name. +# The basic List class does most of the checking. # +sub _check { + my $self = shift; + foreach my $x (@{$self->{coords}}) { + unless ($x->isNumber) { + my $type = $x->type; + $type = (($type =~ m/^[aeiou]/i)? "an ": "a ") . $type; + $self->{equation}->Error(["Coordinates of Points must be Numbers, not %s",$type]); + } + } +} + ######################################################################### 1; |
From: dpvc v. a. <we...@ma...> - 2005-11-17 13:23:01
|
Log Message: ----------- Adjusted the parentheses slightly so that matrices will only be formed in Matrix context, not Point or Vector context (this produced confusing messages for students in some circumstances where they didn't balence their parentheses correctly). Modified Files: -------------- pg/lib/Parser/Context: Default.pm Revision Data ------------- Index: Default.pm =================================================================== RCS file: /webwork/cvs/system/pg/lib/Parser/Context/Default.pm,v retrieving revision 1.33 retrieving revision 1.34 diff -Llib/Parser/Context/Default.pm -Llib/Parser/Context/Default.pm -u -r1.33 -r1.34 --- lib/Parser/Context/Default.pm +++ lib/Parser/Context/Default.pm @@ -77,7 +77,7 @@ '(' => {close => ')', type => 'Point', formMatrix => 1, formInterval => ']', formList => 1, removable => 1, emptyOK => 1, function => 1}, '[' => {close => ']', type => 'Point', formMatrix => 1, formInterval => ')', removable => 1}, - '<' => {close => '>', type => 'Vector', formMatrix => 1}, + '<' => {close => '>', type => 'Vector'}, '{' => {close => '}', type => 'Point', removable => 1}, '|' => {close => '|', type => 'AbsoluteValue'}, 'start' => {close => 'start', type => 'List', formList => 1, @@ -280,6 +280,7 @@ $vectorContext->functions->undefine('arg','mod','Re','Im','conj'); $vectorContext->constants->replace(i=>Value::Vector->new(1,0,0)); $vectorContext->constants->set(i=>{TeX=>'\boldsymbol{i}', perl=>'i'}); +$vectorContext->parens->set('(' => {formMatrix => 0}); # # Point context (for symmetry) @@ -290,7 +291,10 @@ # Matrix context (square brackets make matrices in preference to points or intervals) # $matrixContext = $vectorContext->copy; -$matrixContext->parens->set('[' => {type => 'Matrix', removable => 0}); +$matrixContext->parens->set( + '(' => {formMatrix => 1}, + '[' => {type => 'Matrix', removable => 0}, +); # # Interval context (make intervals rather than lists) |
From: Sam H. v. a. <we...@ma...> - 2005-11-16 22:06:48
|
Log Message: ----------- also get rid of fixed height for siblings list :-P Modified Files: -------------- webwork2/htdocs/css: ur.css Revision Data ------------- Index: ur.css =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/css/ur.css,v retrieving revision 1.12 retrieving revision 1.13 diff -Lhtdocs/css/ur.css -Lhtdocs/css/ur.css -u -r1.12 -r1.13 --- htdocs/css/ur.css +++ htdocs/css/ur.css @@ -15,10 +15,10 @@ div.Logo { } div.Links { font-size: small; } -/* we used to say "overflow: auto" here, but it caused problems for - * mozilla. so we're back to having a looong siblings list for the time - * being. :-( */ -div.Siblings { font-size: small; height: 10em; } +/* we used to say "height: 10em; overflow: auto" here, but it caused + * problems for mozilla. so we're back to having a looong siblings list + * for the time being. :-( */ +div.Siblings { font-size: small; } div.Options { font-size: small; } /* top table cell, contains login message and path */ |