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-02-08 20:58:06
|
Log Message: ----------- HEAD backport: Removes starting and ending whitespace from most of the form field entries when adding users (jj) Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: AddUsers.pm Revision Data ------------- Index: AddUsers.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/AddUsers.pm,v retrieving revision 1.15.4.1 retrieving revision 1.15.4.2 diff -Llib/WeBWorK/ContentGenerator/Instructor/AddUsers.pm -Llib/WeBWorK/ContentGenerator/Instructor/AddUsers.pm -u -r1.15.4.1 -r1.15.4.2 --- lib/WeBWorK/ContentGenerator/Instructor/AddUsers.pm +++ lib/WeBWorK/ContentGenerator/Instructor/AddUsers.pm @@ -47,7 +47,7 @@ my $numberOfStudents = $r->param('number_of_students'); warn "Internal error -- the number of students to be added has not been included" unless defined $numberOfStudents; foreach my $i (1..$numberOfStudents) { - my $new_user_id = $r->param("new_user_id_$i"); + my $new_user_id = trim_spaces($r->param("new_user_id_$i")); my $new_password = cryptPassword($r->param("student_id_$i")); next unless defined($new_user_id) and $new_user_id; push @userIDs, $new_user_id; @@ -59,13 +59,13 @@ $newPermissionLevel->user_id($new_user_id); $newPassword->user_id($new_user_id); $newPassword->password($new_password); - $newUser->last_name($r->param("last_name_$i")); - $newUser->first_name($r->param("first_name_$i")); - $newUser->student_id($r->param("student_id_$i")); - $newUser->email_address($r->param("email_address_$i")); - $newUser->section($r->param("section_$i")); - $newUser->recitation($r->param("recitation_$i")); - $newUser->comment($r->param("comment_$i")); + $newUser->last_name(trim_spaces($r->param("last_name_$i"))); + $newUser->first_name(trim_spaces($r->param("first_name_$i"))); + $newUser->student_id(trim_spaces($r->param("student_id_$i"))); + $newUser->email_address(trim_spaces($r->param("email_address_$i"))); + $newUser->section(trim_spaces($r->param("section_$i"))); + $newUser->recitation(trim_spaces($r->param("recitation_$i"))); + $newUser->comment(trim_spaces($r->param("comment_$i"))); $newUser->status('C'); $newPermissionLevel->permission(0); #FIXME handle errors if user exists already @@ -204,6 +204,14 @@ #or check individual users and click "save" at the bottom. </div> #Soon ( real soon -- honest!!! :-) ) you will also be able to assign sets to the students as they are entered from this page. } ); +} + + +## Utility function to trim whitespace off the start and end of its input +sub trim_spaces { + my $in = shift; + $in =~ s/^\s*(.*?)\s*$/$1/; + return($in); } 1; |
From: Sam H. v. a. <we...@ma...> - 2005-02-08 20:56:42
|
Log Message: ----------- HEAD backport: CourseID is now part of the subject line when feedback is sent (gage) Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Feedback.pm Revision Data ------------- Index: Feedback.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Feedback.pm,v retrieving revision 1.24 retrieving revision 1.24.2.1 diff -Llib/WeBWorK/ContentGenerator/Feedback.pm -Llib/WeBWorK/ContentGenerator/Feedback.pm -u -r1.24 -r1.24.2.1 --- lib/WeBWorK/ContentGenerator/Feedback.pm +++ lib/WeBWorK/ContentGenerator/Feedback.pm @@ -76,6 +76,8 @@ my $showSolutions = $r->param("showSolutions"); my $from = $r->param("from"); my $feedback = $r->param("feedback"); + my $courseID = $r->urlpath->arg("courseID"); + my ($user, $set, $problem); $user = $db->getUser($userName) # checked @@ -198,7 +200,7 @@ # *** we might want to have a CE setting for # "additional recipients" smtp => $ce->{mail}->{smtpServer}, - subject => "WeBWorK feedback: ".$user->first_name." ".$user->last_name. + subject => "WeBWorK feedback from $courseID: ".$user->first_name." ".$user->last_name. ( ( defined($setName) && defined($problemNumber) ) ? " set$setName/prob$problemNumber" : "" ), |
From: Sam H. v. a. <we...@ma...> - 2005-02-08 20:50:30
|
Log Message: ----------- HEAD backport: Adds checks to make sure that the multiple user problem is really gone (gage) Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK: Authen.pm Revision Data ------------- Index: Authen.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/Authen.pm,v retrieving revision 1.35.2.2 retrieving revision 1.35.2.3 diff -Llib/WeBWorK/Authen.pm -Llib/WeBWorK/Authen.pm -u -r1.35.2.2 -r1.35.2.3 --- lib/WeBWorK/Authen.pm +++ lib/WeBWorK/Authen.pm @@ -196,7 +196,8 @@ my $force_passwd_authen = $r->param('force_passwd_authen'); my $login_practice_user = $r->param('login_practice_user'); my $send_cookie = $r->param("send_cookie"); - + my @temp_users = $r->param("user"); + warn "users start out as ", join(" ", @temp_users) if @temp_users >1; my $error; my $failWithoutError = 0; my $credentialSource = "params"; @@ -240,6 +241,7 @@ $user = $cookieUser; $key = $cookieKey; $r->param("user", $user); + #$r->args->{user} = $user; $r->param("key", $key); $credentialSource = "cookie"; } else { @@ -384,6 +386,18 @@ # neither a key or a password were supplied. $error = "You must enter a password." } + ############################################# + # Check for multiply defined users + ############################################ + my @test_users = $r->param("user"); + if (@test_users>1) { + warn "User has been multiply defined in Authen.pm ", join(" ", @test_users) ; + $r->param("user"=>$test_users[0]); + @test_users = $r->param("user"); + warn "New value of user is ", join(" ", @test_users); + } + ##### end check ###################### + if (defined $error) { # authentication failed, store the error message |
From: Sam H. v. a. <we...@ma...> - 2005-02-08 20:41:40
|
Log Message: ----------- HEAD backport: Added Text/Binary/Automatic buttons for conversion of line-breaks on file uploads (dpvc) Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: FileManager.pm Revision Data ------------- Index: FileManager.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/FileManager.pm,v retrieving revision 1.5.2.2 retrieving revision 1.5.2.3 diff -Llib/WeBWorK/ContentGenerator/Instructor/FileManager.pm -Llib/WeBWorK/ContentGenerator/Instructor/FileManager.pm -u -r1.5.2.2 -r1.5.2.3 --- lib/WeBWorK/ContentGenerator/Instructor/FileManager.pm +++ lib/WeBWorK/ContentGenerator/Instructor/FileManager.pm @@ -32,6 +32,18 @@ use warnings; use CGI; +# +# The list of file extensions and the directories they usually go in. +# +my %uploadDir = ( + csv => 'scoring', + lst => 'templates', + pg => 'templates/.*', + pl => 'templates/macros', + def => 'templates', + html => 'html/.*', +); + ################################################## # # Check that the user is authorized, and then @@ -257,9 +269,12 @@ print CGI::Tr([ CGI::td(), CGI::td({colspan=>3}, - CGI::input({type=>"submit",name=>"action",style=>"width:7em",value=>"Upload:",id=>"Upload"}), - CGI::input({type=>"file",name=>"file",id=>"file",size=>40,onChange=>"checkFile()"}), - ), + CGI::input({type=>"submit",name=>"action",style=>"width:7em",value=>"Upload:",id=>"Upload"}), + CGI::input({type=>"file",name=>"file",id=>"file",size=>40,onChange=>"checkFile()"}), + CGI::br(), + CGI::small(join(' ',"Format:", + CGI::radio_group('format',['Text','Binary','Automatic'],'Automatic'))), + ), ]); # @@ -385,7 +400,7 @@ if (open(OUTFILE,">$file")) { eval {print OUTFILE $data; close(OUTFILE)}; if ($@) {$self->addbadmessage("Failed to save: $@")} - else {$self->addgoodmessage("File saved")} + else {$self->addgoodmessage("File saved")} } else {$self->addbadmessage("Can't write to file: $!")} } else {$data = ""; $self->addbadmessage("Error: no file data was submitted!")} @@ -456,8 +471,8 @@ my $newfile = $self->r->param('name'); if ($newfile = $self->verifyPath($newfile,$original)) { if (copy($oldfile, $newfile)) { - $self->addgoodmessage("File successfully copied"); - $self->Refresh; return; + $self->addgoodmessage("File successfully copied"); + $self->Refresh; return; } else {$self->addbadmessage("Can't copy file: $!")} } } @@ -511,14 +526,14 @@ # foreach my $file (@files) { if (defined checkPWD("$pwd/$file",1)) { - if (-d "$dir/$file") { - my $removed = eval {rmtree("$dir/$file",0,1)}; - if ($removed) {$self->addgoodmessage("Directory '$file' removed (items deleted: $removed)")} - else {$self->addbadmessage("Directory '$file' not removed: $!")} - } else { - if (unlink("$dir/$file")) {$self->addgoodmessage("File '$file' successfully removed")} - else {$self->addbadmessage("File '$file' not removed: $!")} - } + if (-d "$dir/$file") { + my $removed = eval {rmtree("$dir/$file",0,1)}; + if ($removed) {$self->addgoodmessage("Directory '$file' removed (items deleted: $removed)")} + else {$self->addbadmessage("Directory '$file' not removed: $!")} + } else { + if (unlink("$dir/$file")) {$self->addgoodmessage("File '$file' successfully removed")} + else {$self->addbadmessage("File '$file' not removed: $!")} + } } else {$self->addbadmessage("Illegal file '$file' specified"); last} } $self->Refresh; @@ -531,18 +546,18 @@ print CGI::start_table({border=>1,cellspacing=>2,cellpadding=>20, style=>"margin: 1em 0 0 5em"}); print CGI::Tr( CGI::td( - CGI::b("Warning:")," You have requested that the following items be deleted\n", - CGI::ul(CGI::li(\@files)), - ((grep { -d "$dir/$_" } @files)? - CGI::p({style=>"width:500"},"Some of these files are directories. ", - "Only delete directories if you really know what you are doing. ", - "You can seriously damage your course if you delete the wrong thing."): ""), - CGI::p({style=>"color:red"},"There is no undo for deleting files or directories!"), - CGI::p("Really delete the items listed above?"), - CGI::div({style=>"float:left; padding-left:3ex"}, - CGI::input({type=>"submit",name=>"action",value=>"Cancel"})), - CGI::div({style=>"float:right; padding-right:3ex"}, - CGI::input({type=>"submit",name=>"action",value=>"Delete"})), + CGI::b("Warning:")," You have requested that the following items be deleted\n", + CGI::ul(CGI::li(\@files)), + ((grep { -d "$dir/$_" } @files)? + CGI::p({style=>"width:500"},"Some of these files are directories. ", + "Only delete directories if you really know what you are doing. ", + "You can seriously damage your course if you delete the wrong thing."): ""), + CGI::p({style=>"color:red"},"There is no undo for deleting files or directories!"), + CGI::p("Really delete the items listed above?"), + CGI::div({style=>"float:left; padding-left:3ex"}, + CGI::input({type=>"submit",name=>"action",value=>"Cancel"})), + CGI::div({style=>"float:right; padding-right:3ex"}, + CGI::input({type=>"submit",name=>"action",value=>"Delete"})), ), ); print CGI::end_table(); @@ -563,9 +578,9 @@ my $name = $self->r->param('name'); if (my $file = $self->verifyName($name,"file")) { if (open(NEWFILE,">$file")) { - close(NEWFILE); - $self->RefreshEdit("",$name); - return; + close(NEWFILE); + $self->RefreshEdit("",$name); + return; } else {$self->addbadmessage("Can't create file: $!")} } } @@ -584,8 +599,8 @@ my $name = $self->r->param('name'); if (my $dir = $self->verifyName($name,"directory")) { if (mkdir $dir, 0750) { - $self->{pwd} .= '/'.$name; - $self->Refresh; return; + $self->{pwd} .= '/'.$name; + $self->Refresh; return; } else {$self->addbadmessage("Can't create directory: $!")} } } @@ -634,9 +649,29 @@ $upload->dispose; return; } + $self->checkFileLocation($name,$self->{pwd}); + + my $type = $self->r->param('format') || 'automatic'; + my $data; + + # + # Check if we need to convert linebreaks + # + if ($type ne 'Binary') { + my $fh = $upload->fileHandle; + my @lines = <$fh>; $data = join('',@lines); + if ($type eq 'Automatic') {$type = isText($data) ? 'Text' : 'Binary'} + } + if ($type eq 'Text') { + $data =~ s/\r\n?/\n/g; + open(UPLOAD,">$dir/$name") || $self->addbadmessage("Can't create file '$name'"); + print UPLOAD $data; close(UPLOAD); + $upload->dispose(); + } else { + $upload->disposeTo("$dir/$name"); + } - $upload->disposeTo("$dir/$name"); - $self->addgoodmessage("File '$name' uploaded successfully"); + $self->addgoodmessage("$type file '$name' uploaded successfully"); $self->Refresh; } @@ -653,15 +688,15 @@ print CGI::start_table({border=>1,cellspacing=>2,cellpadding=>20, style=>"margin: 1em 0 0 3em"}); print CGI::Tr( CGI::td( - $message, - CGI::input({type=>"text",name=>"name",size=>50}), - CGI::p(), - CGI::div({style=>"float:right; padding-right:3ex"}, - CGI::input({type=>"submit",name=>"action",value=>$button})), # this will be the default - CGI::div({style=>"float:left; padding-left:3ex"}, - CGI::input({type=>"submit",name=>"action",value=>"Cancel"})), - ), - ); + $message, + CGI::input({type=>"text",name=>"name",size=>50}), + CGI::p(), + CGI::div({style=>"float:right; padding-right:3ex"}, + CGI::input({type=>"submit",name=>"action",value=>$button})), # this will be the default + CGI::div({style=>"float:left; padding-left:3ex"}, + CGI::input({type=>"submit",name=>"action",value=>"Cancel"})), + ), + ); print CGI::end_table(); print CGI::hidden({name=>"confirmed",value=>1}); print CGI::script("window.document.FileManager.name.focus()"); @@ -751,7 +786,7 @@ my $original = $pwd; $pwd =~ s!(^|/)\.!$1_!g; # don't enter hidden directories $pwd =~ s!^/!!; # remove leading / - $pwd =~ s![^-_./a-zA-Z0-9 ]!_!g; # no illegal characters + $pwd =~ s![^-_./A-Z0-9~ ]!_!gi; # no illegal characters return if $renameError && $original ne $pwd; $pwd = '.' if $pwd eq ''; @@ -773,6 +808,20 @@ ################################################## # +# Check that a file is uploaded to the correct directory +# +sub checkFileLocation { + my $self = shift; + my $extension = shift; $extension =~ s/.*\.//; + my $dir = shift; + return unless defined($uploadDir{$extension}); + return if $dir =~ m/^$uploadDir{$extension}$/; + $dir = $uploadDir{$extension}; $dir =~ s!/.*!!; + $self->addbadmessage("Files with extension '.$extension' usually belong in '$dir'"); +} + +################################################## +# # Get a unique name (in case it already exists) # sub uniqueName { @@ -795,11 +844,11 @@ if ($name) { unless ($name =~ m!/!) { unless ($name =~ m!^\.!) { - unless ($name =~ m![^-_.a-zA-Z0-9 ]!) { - my $file = "$self->{courseRoot}/$self->{pwd}/$name"; - return $file unless (-e $file); - $self->addbadmessage("A file with that name already exists"); - } else {$self->addbadmessage("Your $object name contains illegal characters")} + unless ($name =~ m![^-_.a-zA-Z0-9 ]!) { + my $file = "$self->{courseRoot}/$self->{pwd}/$name"; + return $file unless (-e $file); + $self->addbadmessage("A file with that name already exists"); + } else {$self->addbadmessage("Your $object name contains illegal characters")} } else {$self->addbadmessage("Your $object name may not begin with a dot")} } else {$self->addbadmessage("Your $object name may not contain a path component")} } else {$self->addbadmessage("You must specify a $object name")} @@ -816,13 +865,13 @@ if ($path) { unless ($path =~ m![^-_.a-zA-Z0-9 /]!) { unless ($path =~ m!^/!) { - $path = checkPWD($self->{pwd}.'/'.$path,1); - if ($path) { - $path = $self->{courseRoot}.'/'.$path; - $path .= '/'.$name if -d $path && $name; - return $path unless (-e $path); - $self->addbadmessage("A file with that name already exists"); - } else {$self->addbadmessage("You have specified an illegal path")} + $path = checkPWD($self->{pwd}.'/'.$path,1); + if ($path) { + $path = $self->{courseRoot}.'/'.$path; + $path .= '/'.$name if -d $path && $name; + return $path unless (-e $path); + $self->addbadmessage("A file with that name already exists"); + } else {$self->addbadmessage("You have specified an illegal path")} } else {$self->addbadmessage("You can not specify an absolute path")} } else {$self->addbadmessage("Your file name contains illegal characters")} } else {$self->addbadmessage("You must specify a file name")} @@ -834,12 +883,12 @@ # Make HTML symbols printable # sub showHTML { - my $string = shift; - return '' unless defined $string; - $string =~ s/&/\&/g; - $string =~ s/</\</g; - $string =~ s/>/\>/g; - $string; + my $string = shift; + return '' unless defined $string; + $string =~ s/&/\&/g; + $string =~ s/</\</g; + $string =~ s/>/\>/g; + $string; } ################################################## |
From: Sam H. v. a. <we...@ma...> - 2005-02-08 20:36:53
|
Log Message: ----------- HEAD backport: Bring jsMath up to version 1.7e. (dpvc) Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/htdocs/jsMath: jsMath-fallback-mac.js jsMath-fallback-pc.js jsMath.js Revision Data ------------- Index: jsMath.js =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/jsMath/jsMath.js,v retrieving revision 1.11.2.2 retrieving revision 1.11.2.3 diff -Lhtdocs/jsMath/jsMath.js -Lhtdocs/jsMath/jsMath.js -u -r1.11.2.2 -r1.11.2.3 --- htdocs/jsMath/jsMath.js +++ htdocs/jsMath/jsMath.js @@ -2,7 +2,7 @@ * * jsMath: Mathematics on the Web * - * Version: 1.6b-ww + * Version: 1.7e-ww * * This jsMath package makes it possible to display mathematics in HTML pages * that are viewable by a wide range of browsers on both the Mac and the IBM PC, @@ -12,7 +12,7 @@ * * for the latest version, and for documentation on how to use jsMath. * - * Copyright (c) 2004 by Davide P. Cervone. + * Copyright (c) 2004-2005 by Davide P. Cervone. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -167,8 +167,9 @@ renameOK: 1, // tells if brower will find a tag whose name // has been set via setAttributes separateNetgativeSkips: 0, // MSIE doesn't do negative left margins + separateSkips: 0, // Netscape doesn't combine skips well noEmptySpans: 0, // empty spans are/aren't allowed - lineH: 1, // for MSIE span height adjustments + msieSpaceFix: '', // for MSIE spacing bug fix delay: 1, // delay for asynchronous math processing @@ -209,6 +210,8 @@ '.normal': 'font-family: serif; font-style: normal; font-size: 133%', '.math': 'font-family: serif; font-style: normal; color: grey33; font-size: 75%', '.typeset': 'font-family: serif; font-style: normal; font-size: 133%', + 'span.typeset': 'font-family: serif; font-style: normal', + 'div.typeset': 'font-family: serif; font-style: normal; text-align: center; margin-top: 1em; margin-bottom: 1em', '.mathlink': 'text-decoration: none', '.mathHD': 'border-width: 0; width: 1px; margin-right: -1px', @@ -272,7 +275,6 @@ if (n == null) {n = 124}; if (factor == null) {factor = 2} var wh1 = this.BBoxFor('<SPAN STYLE="font-family: '+name+', serif">'+this.TeX[name][n].c+'</SPAN>'); var wh2 = this.BBoxFor('<SPAN STYLE="font-family: serif">'+this.TeX[name][n].c+'</SPAN>'); -//alert([wh1.w,wh1.h,wh2.w,wh2.h,factor,wh1.w>factor*wh2.w && wh1.h != 0]); return (wh1.w > factor*wh2.w && wh1.h != 0); }, @@ -280,7 +282,6 @@ if (n == null) {n = 124}; if (factor == null) {factor = 2} var wh1 = this.BBoxFor('<SPAN STYLE="font-family: '+name+', serif">'+this.TeX[name][n].c+'</SPAN>'); var wh2 = this.BBoxFor('<SPAN STYLE="font-family: serif">'+this.TeX[name][n].c+'</SPAN>'); -//alert([this.TeX[name][n].c,wh1.w,wh1.h,wh2.w,wh2.h,factor,wh2.w > factor*wh1.w && wh1.h != 0]); return (wh2.w > factor*wh1.w && wh1.h != 0); }, @@ -349,7 +350,6 @@ this.h = (h-d)/this.em; this.d = d/this.em; this.hd = this.h + this.d; this.ph = h-d; this.pd = d; - if (this.lineH == null) {this.lineH = this.h} this.InitTeXfonts(); @@ -446,16 +446,18 @@ cmbx10: {'10': {c: '<B>Ω</B>', tclass: 'normal'}} }); this.allowAbsoluteDelim = 1; - this.separateNegativeSkips = 1; - this.lineH = 1.03; + this.separateSkips = 1; this.msieFontBug = 1; this.msieIntegralBug = 1; - jsMath.Macro('joinrel','\\mathrel{\\kern-5mu}'), + this.msieSpaceFix = '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD">'; + jsMath.Macro('joinrel','\\mathrel{\\kern-5mu}'), + jsMath.Macro('mapsto','\\mapstochar\\kern-.54em\\rightarrow'); jsMath.Macro('longmapsto','\\mapstochar\\kern-.54em\\char{cmsy10}{0}\\joinrel\\rightarrow'); } else if (navigator.platform == 'MacPPC') { document.writeln('<SCRIPT SRC="'+this.root+'jsMath-msie-mac.js"></SCRIPT>'); + jsMath.Parser.prototype.macros.angle = ['Replace','ord','<FONT FACE="Symbol">‹</FONT>','normal']; + jsMath.msieAbsoluteBug = 1; } jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}'); - jsMath.Parser.prototype.macros.angle = ['Replace','ord','<FONT FACE="Symbol">‹</FONT>','normal']; } // @@ -539,7 +541,7 @@ {if (this.TeX.fam[i] != '') {this.TeX[this.TeX.fam[i]].dh = .1}} this.absoluteOffsetY = -.05; this.TeX.axis_height += .05; -// this.allowAbsoluteDelim = ! this.oldSafari; + this.allowAbsoluteDelim = ! this.oldSafari; } // @@ -547,8 +549,10 @@ // if (this.allowAbsoluteDelim) { jsMath.Box.DelimExtend = jsMath.Box.DelimExtendAbsolute; + jsMath.Box.Layout = jsMath.Box.LayoutAbsolute; } else { jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative; + jsMath.Box.Layout = jsMath.Box.LayoutRelative; } if (this.separateNegativeSkips) { @@ -1499,7 +1503,8 @@ */ Spacer: function (w) { if (w == 0) {return ''}; - return '<SPAN STYLE="margin-left: '+this.Em(w)+'"></SPAN>'; + return jsMath.msieSpaceFix + + '<SPAN STYLE="margin-left: '+this.Em(w)+'"></SPAN>'; }, /* @@ -1526,27 +1531,6 @@ + 'vertical-align: '+this.Em(y)+'; left: '+this.Em(x)+'; ' + 'width:'+this.Em(w)+'; height: '+this.Em(h)+'; ' + 'border-color: '+c+'; border-style: solid; border-width: 1px;">'; - -// if (!c) {c = 'black'}; -// if (pos) {pos = 'absolute;'} else -// {pos = 'relative; margin-right: '+this.Em(-w-.1)+'; '} -// return '<IMG SRC="blank.gif" STYLE="position:' + pos -// + 'vertical-align: '+this.Em(y)+'; left: '+this.Em(x)+'; ' -// + 'width:'+this.Em(w)+'; height: '+this.Em(h)+'; ' -// + 'border-color: '+c+'; border-style: solid; border-width: 1px;">'; - - /* - * h = Math.round(h*jsMath.em)-2; // use pixels to compensate for border size - * w = Math.round(w*jsMath.em)-2; - * y = Math.round(y*jsMath.em)-1; - * if (!c) {c = 'black'}; - * if (pos) {pos = 'absolute;'} else - * {pos = 'relative; margin-right: '+(-w-2)+'px; '} - * return '<IMG SRC="'+jsMath.blank+'" STYLE="position:' + pos - * + 'vertical-align: '+y+'px; left: '+this.Em(x)+'; ' - * + 'width:'+w+'px; height: '+h+'px; ' - * + 'border-color: '+c+'; border-style: solid; border-width: 1px;">'; - */ }, /* @@ -1626,7 +1610,10 @@ if (y) {span += ' top:'+this.Em(-y)+';'} html = span + '">' + html + '</SPAN>'; } - if (x < 0) {html = '<SPAN STYLE="margin-left:'+this.Em(x)+';"></SPAN>' + html} + if (x < 0) { + html = jsMath.msieSpaceFix + + '<SPAN STYLE="margin-left:'+this.Em(x)+';"></SPAN>' + html; + } return html; }, @@ -1638,7 +1625,44 @@ if (Math.abs(y) < .0001) {y = 0} if (y) {html = '<SPAN STYLE="position: relative; top:'+this.Em(-y)+';' + '">' + html + '</SPAN>'} - if (x) {html = '<SPAN STYLE="margin-left:'+this.Em(x)+';"></SPAN>' + html} + if (x) {html = jsMath.msieSpaceFix + + '<SPAN STYLE="margin-left:'+this.Em(x)+';"></SPAN>' + html} + return html; + }, + + /* + * Place a SPAN with absolute coordinates + */ + PlaceAbsolute: function (html,x,y) { + if (Math.abs(x) < .0001) {x = 0} + if (Math.abs(y) < .0001) {y = 0} + html = '<SPAN STYLE="position: absolute; left:'+this.Em(x)+'; ' + + 'top:'+this.Em(y)+';">' + html + ' </SPAN>'; + // space normalizes line height + return html; + }, + + Absolute: function(html,w,h,d,y,H) { + var align = ""; + if (d) {align = ' vertical-align: '+jsMath.HTML.Em(-d)+';'} + if (y != "none") { + if (Math.abs(y) < .0001) {y = 0} + html = '<SPAN STYLE="position: absolute; ' + + 'top:'+jsMath.HTML.Em(y)+'; left: 0em;">' + + html + ' ' // space normalizes line height in script styles + + '</SPAN>'; + } + html += '<IMG SRC="'+jsMath.blank+'" STYLE="width: '+jsMath.HTML.Em(w)+'; ' + + 'height: '+jsMath.HTML.Em(h)+';'+align+'">'; + if (jsMath.msieAbsoluteBug) {// for MSIE (Mac) + html = '<SPAN STYLE="position: relative;">' + html + '</SPAN>'; + } + html = '<SPAN STYLE="position: relative;' + + ' width: '+jsMath.HTML.Em(w)+';' // for MSIE + + ' height: '+jsMath.HTML.Em(H)+';' // for MSIE + + '">' + + html + + '</SPAN>'; return html; } @@ -1747,7 +1771,7 @@ var c = jsMath.TeX[font][code]; if (c.tclass == null) {c.tclass = font} if (!c.computedW) { - c.w = jsMath.EmBoxFor(jsMath.HTML.Class(c.tclass,c.c)).w; + c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w; if (c.h == null) {c.h = jsMath.defaultH}; if (c.d == null) {c.d = 0} c.computedW = 1; } @@ -1787,7 +1811,7 @@ var top = this.GetChar(C.delim.top? C.delim.top: C.delim.rep,font); var rep = this.GetChar(C.delim.rep,font); var bot = this.GetChar(C.delim.bot? C.delim.bot: C.delim.rep,font); - var ext = jsMath.HTML.Class(rep.tclass,rep.c); + var ext = jsMath.Typeset.AddClass(rep.tclass,rep.c); var w = rep.w; var h = rep.h+rep.d var y; var dx; if (C.delim.mid) {// braces @@ -1795,9 +1819,9 @@ var n = Math.ceil((H-(top.h+top.d)-(mid.h+mid.d)-(bot.h+bot.d))/(2*(rep.h+rep.d))); H = 2*n*(rep.h+rep.d) + (top.h+top.d) + (mid.h+mid.d) + (bot.h+bot.d); if (nocenter) {y = 0} else {y = H/2+a}; var Y = y; - var html = jsMath.HTML.Place(jsMath.HTML.Class(top.tclass,top.c),0,y-top.h) - + jsMath.HTML.Place(jsMath.HTML.Class(bot.tclass,bot.c),-(top.w+bot.w)/2,y-(H-bot.d)) - + jsMath.HTML.Place(jsMath.HTML.Class(mid.tclass,mid.c),-(bot.w+mid.w)/2,y-(H+mid.h-mid.d)/2); + var html = jsMath.HTML.Place(jsMath.Typeset.AddClass(top.tclass,top.c),0,y-top.h) + + jsMath.HTML.Place(jsMath.Typeset.AddClass(bot.tclass,bot.c),-(top.w+bot.w)/2,y-(H-bot.d)) + + jsMath.HTML.Place(jsMath.Typeset.AddClass(mid.tclass,mid.c),-(bot.w+mid.w)/2,y-(H+mid.h-mid.d)/2); dx = (w-mid.w)/2; if (Math.abs(dx) < .0001) {dx = 0} if (dx) {html += jsMath.HTML.Spacer(dx)} y -= top.h+top.d + rep.h; @@ -1810,12 +1834,12 @@ if (top.h+top.d < .9*(rep.h+rep.d)) {n = Math.max(1,n)} H = n*(rep.h+rep.d) + (top.h+top.d) + (bot.h+bot.d); if (nocenter) {y = 0} else {y = H/2+a}; var Y = y; - var html = jsMath.HTML.Place(jsMath.HTML.Class(top.tclass,top.c),0,y-top.h) + var html = jsMath.HTML.Place(jsMath.Typeset.AddClass(top.tclass,top.c),0,y-top.h) dx = (w-top.w)/2; if (Math.abs(dx) < .0001) {dx = 0} if (dx) {html += jsMath.HTML.Spacer(dx)} y -= top.h+top.d + rep.h; for (var i = 0; i < n; i++) {html += jsMath.HTML.Place(ext,-w,y-i*h)} - html += jsMath.HTML.Place(jsMath.HTML.Class(bot.tclass,bot.c),-(w+bot.w)/2,Y-(H-bot.d)); + html += jsMath.HTML.Place(jsMath.Typeset.AddClass(bot.tclass,bot.c),-(w+bot.w)/2,Y-(H-bot.d)); } if (nocenter) {h = top.h} else {h = H/2+a} var box = new jsMath.Box('html',html,rep.w,h,H-h); @@ -1835,51 +1859,35 @@ var top = this.GetChar(C.delim.top? C.delim.top: C.delim.rep,font); var rep = this.GetChar(C.delim.rep,font); var bot = this.GetChar(C.delim.bot? C.delim.bot: C.delim.rep,font); - rep.h = 0; // fix adjusted heights if (C.delim.mid) {// braces var mid = this.GetChar(C.delim.mid,font); - var n = Math.ceil((H-(top.h+top.d)-(mid.h+mid.d)-(bot.h+bot.d))/(2*(rep.h+rep.d))); - H = 2*n*(rep.h+rep.d) + (top.h+top.d) + (mid.h+mid.d) + (bot.h+bot.d); + var n = Math.ceil((H-(top.h+top.d)-(mid.h+mid.d-.05)-(bot.h+bot.d-.05))/(2*(rep.h+rep.d-.05))); + H = 2*n*(rep.h+rep.d-.05) + (top.h+top.d) + (mid.h+mid.d-.05) + (bot.h+bot.d-.05); - html = jsMath.HTML.Place(jsMath.HTML.Class(top.tclass,top.c),0,-top.h); - var h = rep.h+rep.d - Font.hd; var y = -(top.h+top.d + rep.h-.05) + Font.hd; - var ext = jsMath.HTML.Class(font,rep.c) - for (var i = 0; i < n; i++) {html += '<BR>'+jsMath.HTML.Place(ext,0,y-i*h)} - html += '<BR>' + jsMath.HTML.Place(jsMath.HTML.Class(mid.tclass,mid.c),0,y-i*h); - y -= i*h+mid.h+mid.d - Font.hd; - for (var i = 0; i < n; i++) {html += '<BR>'+jsMath.HTML.Place(ext,0,y-i*h)} - html += '<BR>' + jsMath.HTML.Place(jsMath.HTML.Class(bot.tclass,bot.c),0,y-i*h); + html = jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(top.tclass,top.c),0,0); + var h = rep.h+rep.d - .05; var y = top.d-.05 + rep.h; + var ext = jsMath.Typeset.AddClass(font,rep.c) + for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)} + html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(mid.tclass,mid.c),0,y+n*h-rep.h+mid.h); + y += n*h + mid.h+mid.d - .05; + for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)} + html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(bot.tclass,bot.c),0,y+n*h-rep.h+bot.h); } else {// all others - var n = Math.ceil((H - (top.h+top.d) - (bot.h+bot.d))/(rep.h+rep.d-.1)); - H = n*(rep.h+rep.d-.1) + (top.h+top.d) + (bot.h+bot.d); + var n = Math.ceil((H - (top.h+top.d) - (bot.h+bot.d-.05))/(rep.h+rep.d-.05)); + H = n*(rep.h+rep.d-.05) + (top.h+top.d) + (bot.h+bot.d-.05); - html = jsMath.HTML.Place(jsMath.HTML.Class(top.tclass,top.c),0,-top.h); - var h = rep.h+rep.d-.1 - Font.hd; var y = -(top.h+top.d + rep.h-.05) + Font.hd; - var ext = jsMath.HTML.Class(rep.tclass,rep.c) - for (var i = 0; i < n; i++) {html += '<BR>'+jsMath.HTML.Place(ext,0,y-i*h)} - html += '<BR>' + jsMath.HTML.Place(jsMath.HTML.Class(bot.tclass,bot.c),0,y-i*h); + html = jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(top.tclass,top.c),0,0); + var h = rep.h+rep.d-.05; var y = top.d-.05 + rep.h; + var ext = jsMath.Typeset.AddClass(rep.tclass,rep.c); + for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)} + html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(bot.tclass,bot.c),0,y+n*h-rep.h+bot.h); } - var w = top.w; h = Font.h; - if (nocenter) {y = top.h} else {y = (H/2 + a) - top.h} - if (jsMath.isSafari) {y -= .2} - html = '<SPAN STYLE="position: relative; ' - + 'width: '+jsMath.HTML.Em(w)+'; ' // for MSIE - + 'height: '+jsMath.HTML.Em(top.h)+'; ' //for MSIE - + '">' - + '<SPAN STYLE="position: absolute; ' - + 'top: '+jsMath.HTML.Em(-y)+'; ' - + 'left: 0;">' - + html - + '</SPAN>' - + '<IMG SRC="'+jsMath.blank+'" STYLE="width: '+jsMath.HTML.Em(w)+'; ' - + 'height: '+jsMath.HTML.Em(h)+';">' - + '</SPAN>'; - - if (nocenter) {h = top.h} else {h = H/2+a} + var w = top.w; + if (nocenter) {h = top.h; y = 0} else {h = H/2 + a; y = h - top.h} + html = jsMath.HTML.Absolute(html,w,Font.h,"none",-y,top.h); var box = new jsMath.Box('html',html,rep.w,h,H-h); - box.bh = top.h; box.bd = top.d; box.bh = jsMath.TeX[font].h; box.bd = jsMath.TeX[font].d; return box; }, @@ -1914,10 +1922,20 @@ var font = jsMath.TeX.fam[(code&0xF00)>>8]; var Font = jsMath.TeX[font]; var c = Font[code & 0xFF]; - if (c.w == null) {c.w = jsMath.EmBoxFor(jsMath.HTML.Class(c.tclass,c.c)).w} - if (c.tclass == null) {c.tclass = font} + if (c.w == null) {c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w} + if (c.font == null) {c.font = font} return c; }, + + /* + * Add the class to the html, and use the font if there isn't one + * specified already + */ + + AddClass: function (tclass,html,font) { + if (tclass == null) {tclass = font} + return jsMath.Typeset.AddClass(tclass,html); + }, /* * Create a horizontally stretchable "delimiter" (like over- and @@ -1933,15 +1951,12 @@ var lmid = this.GetCharCode(leader.lmid); var rmid = this.GetCharCode(leader.rmid); w = (W - left.w - right.w - lmid.w - rmid.w)/2 - .1; h = .4; d = .3; - if (w > 0) { - html = jsMath.HTML.Class(left.tclass,left.c) - + jsMath.HTML.Rule(w,left.h) - + jsMath.HTML.Class(lmid.tclass,lmid.c+rmid.c) - + jsMath.HTML.Rule(w,right.h) - + jsMath.HTML.Class(right.tclass,right.c); - } else { - html = jsMath.HTML.Class(left.tclass,left.c + lmid.c + rmid.c + right.c); - } + if (w < 0) {w = 0} + html = this.AddClass(left.tclass,left.c,left.font) + + jsMath.HTML.Rule(w,left.h) + + this.AddClass(lmid.tclass,lmid.c+rmid.c,lmid.font) + + jsMath.HTML.Rule(w,right.h) + + this.AddClass(right.tclass,right.c,right.font); } else { //arrows font = jsMath.TeX.fam[(leader.rep &0xF00) >> 8]; var left = this.GetCharCode(leader.left? leader.left: leader.rep); @@ -1951,14 +1966,14 @@ w = (W - left.w - right.w + .4 - n*(rep.w - .3)); if (leader.left) {h = left.h; d = left.d} else {h = right.h; d = right.d} if (d == null) {d = 0}; if (h == null) {h = 0} - var html = jsMath.HTML.Class(left.tclass,left.c); var m = Math.floor(n/2); + var html = this.AddClass(left.tclass,left.c,left.font); var m = Math.floor(n/2); var ext = jsMath.HTML.Place(rep.c,-.3,0); var ehtml = ''; for (var i = 0; i < m; i++) {ehtml += ext}; - html += jsMath.HTML.Class(rep.tclass,ehtml) + jsMath.HTML.Spacer(w); + html += this.AddClass(rep.tclass,ehtml,rep.font) + jsMath.HTML.Spacer(w); ehtml = ''; for (var i = m; i < n; i++) {ehtml += ext}; - html += jsMath.HTML.Class(rep.tclass,ehtml); + html += this.AddClass(rep.tclass,ehtml,rep.font); if (jsMath.msieFontBug) {html += '<SPAN STYLE="display: none">x</SPAN>'} - html += jsMath.HTML.Place(jsMath.HTML.Class(right.tclass,right.c),-.4,0); + html += jsMath.HTML.Place(this.AddClass(right.tclass,right.c,right.font),-.4,0); } w = jsMath.EmBoxFor(html).w; if (w != W) { @@ -1980,7 +1995,7 @@ * ### still need to allow users to specify row and column attributes, * and do things like \span and \multispan ### */ - Layout: function (size,table,align,cspacing) { + LayoutRelative: function (size,table,align,cspacing) { if (align == null) {align = []} if (cspacing == null) {cspacing = []} @@ -2004,7 +2019,7 @@ if (bh == unset) {bh = 0}; if (bd == unset) {bd = 0} // lay out the columns - var HD = (jsMath.hd-.1)*scale; + var HD = (jsMath.hd-.01)*scale; var html = ''; var pW = 0; var cW = 0; var w; var h; var y; var box; var mlist; var entry; @@ -2031,20 +2046,86 @@ } // get the full width and height - w = -cspacing[W.length-1]; + w = -cspacing[W.length-1]; y = (H.length-1)*scale/10; for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]} - h = jsMath.TeX.axis_height-y/2; + for (i = 0; i < H.length; i++) {y += Math.max(HD,H[i]+D[i])} + h = y/2 + jsMath.TeX.axis_height; var d = y-h; // adjust the final row width, and vcenter the table // (add 1/6em at each side for the \,) html += jsMath.HTML.Spacer(cW-cspacing[W.length-1] + scale/6); html = jsMath.HTML.Place(html,scale/6,h); - box = new jsMath.Box('html',html,w+scale/3,h,-y-h); + box = new jsMath.Box('html',html,w+scale/3,h,d); box.bh = bh; box.bd = bd; return box; }, /* + * Create the HTML for an alignment (e.g., array or matrix) + * Use absolute position for elements in the array. + * + * ### still need to allow users to specify row and column attributes, + * and do things like \span and \multispan ### + */ + LayoutAbsolute: function (size,table,align,cspacing) { + if (align == null) {align = []} + if (cspacing == null) {cspacing = []} + + // get row and column maximum dimensions + var scale = jsMath.sizes[size]/100; + var HD = (jsMath.hd-.01)*scale; + var W = []; var H = []; var D = []; + var w = 0; var h; var x; var y; + var i; var j; var row; + for (i = 0; i < table.length; i++) { + row = table[i]; + H[i] = jsMath.h*scale; D[i] = jsMath.d*scale; + for (j = 0; j < row.length; j++) { + row[j] = row[j].Remeasured(); + if (row[j].h > H[i]) {H[i] = row[j].h} + if (row[j].d > D[i]) {D[i] = row[j].d} + if (j >= W.length) {W[j] = row[j].w} + else if (row[j].w > W[j]) {W[j] = row[j].w} + } + } + + // get the height and depth of the centered table + y = (H.length-1)*scale/6; + for (i = 0; i < H.length; i++) {y += Math.max(HD,H[i]+D[i])} + h = y/2 + jsMath.TeX.axis_height; var d = y - h; + + // lay out the columns + var html = ''; var entry; w = scale/6; + for (j = 0; j < W.length; j++) { + y = H[0]-h; + for (i = 0; i < table.length; i++) { + entry = table[i][j]; + if (entry && entry.format != 'null') { + if (align[j] == 'l') {x = 0} else + if (align[j] == 'r') {x = W[j] - entry.w} else + {x = (W[j] - entry.w)/2} + html += jsMath.HTML.PlaceAbsolute(entry.html,w+x, + y-Math.max(0,entry.bh-jsMath.h*scale)); + } + if (i == table.length-1) {y += D[i]} + else {y += Math.max(HD,D[i]+H[i+1]) + scale/6} + } + if (cspacing[j] == null) cspacing[j] = scale; + w += W[j] + cspacing[j]; + } + + // get the full width + w = -cspacing[W.length-1]+scale/3; + for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]} + + html = jsMath.HTML.Spacer(scale/6)+html+jsMath.HTML.Spacer(scale/6); + if (jsMath.spanHeightVaries) {y = h-jsMath.h} else {y = 0} + html = jsMath.HTML.Absolute(html,w,h+d,d,y,H[0]); + var box = new jsMath.Box('html',html,w+scale/3,h,d); + return box; + }, + + /* * Look for math within \hbox and other non-math text */ InternalMath: function (text,size) { @@ -2956,8 +3037,7 @@ * Add the font class, if needed */ AddClass: function (tclass,html) { - if (tclass != '' && tclass != 'normal') - {html = '<SPAN CLASS="'+tclass+'">'+html+'</SPAN>'} + if (tclass != '' && tclass != 'normal') {html = jsMath.HTML.Class(tclass,html)} return html; } @@ -3158,8 +3238,9 @@ {item.html = '<SPAN STYLE="position: relative; top:'+jsMath.HTML.Em(-item.y)+';' + '">' + item.html + '</SPAN>'} if (item.x) - {item.html = '<SPAN STYLE="margin-left:'+jsMath.HTML.Em(item.x)+';' - + '"></SPAN>' + item.html} + {item.html = jsMath.msieSpaceFix + + '<SPAN STYLE="margin-left:'+jsMath.HTML.Em(item.x)+';">' + + '</SPAN>' + item.html} item.h += item.y; item.d -= item.y; item.x = 0; item.y = 0; } @@ -3695,7 +3776,7 @@ matrix: 'Matrix', array: 'Matrix', // ### still need to do alignment options ### - pmatrix: ['Matrix','(',')'], + pmatrix: ['Matrix','(',')','c'], cases: ['Matrix','\\{','.',['l','l']], cr: 'HandleRow', '\\': 'HandleRow', @@ -4398,9 +4479,11 @@ if (c == '\\') {text += c + data[0].charAt(i++)} else if (c == '#') { c = data[0].charAt(i++); - if (!c.match(/[0-9]/) || c > args.length) - {this.Error("Illegal macro argument reference"); return} - text += args[c-1]; + if (c == "#") {text += c} else { + if (!c.match(/[1-9]/) || c > args.length) + {this.Error("Illegal macro argument reference"); return} + text += args[c-1]; + } } else {text += c} } } @@ -4526,7 +4609,6 @@ if (this.macros[cmd]) { var macro = this.macros[cmd]; if (typeof(macro) == "string") {macro = [macro]} -// var args = macro.slice(1); if (args.length == 1) {args = args[0]} this[macro[0]](cmd,macro.slice(1)); return; } if (this.mathchardef[cmd]) { @@ -4662,34 +4744,22 @@ box.Styled().Remeasured(); var isSmall = 0; var isBig = 0; var w = box.w; var h = box.bh; var d = box.bd; - if (box.bh > box.h && box.bh > jsMath.h+.001) {isSmall = 1; h = box.h;} - if (box.bd > box.d && box.bd > jsMath.d+.001) {isSmall = 1; d = box.d;} - if (box.h > jsMath.h) {isBig = 1; h = Math.max(h,box.h);} - if (box.d > jsMath.d) {isBig = 1; d = Math.max(d,box.d);} + if (box.bh > box.h && box.bh > jsMath.h+.001) {isSmall = 1} + if (box.bd > box.d && box.bd > jsMath.d+.001) {isSmall = 1} + if (box.h > jsMath.h) {isBig = 1; h = box.h} + if (box.d > jsMath.d) {isBig = 1; d = box.d} if (jsMath.show.BBox) {rules += jsMath.HTML.Frame(0,-box.d,w,box.h+box.d,'green')} if (jsMath.show.Top) {rules += jsMath.HTML.Line(0,box.h,w,'red')} if (jsMath.show.Baseline) {rules += jsMath.HTML.Line(0,0,w,'blue')} - html = box.html; var y = jsMath.absoluteOffsetY; - if (jsMath.absoluteHeightVaries || box.bh > jsMath.h+.001) {y += (jsMath.h - box.bh)} - if (jsMath.spanHeightVaries) {y = 1-box.bh} // for MSIE + html = box.html; if (isSmall) {// hide the extra size if (jsMath.allowAbsolute) { - html = '<SPAN STYLE="position: relative;' - + ' width: '+jsMath.HTML.Em(w)+';' // for MSIE - + ' height: '+jsMath.HTML.Em(jsMath.lineH)+';' // for MSIE - + '">' - + '<SPAN STYLE="position: relative;">' // for MSIE (Mac) - + '<SPAN STYLE="position: absolute; ' - + 'top:'+jsMath.HTML.Em(y)+'; left:0;">' - + html + ' ' // space normalizes line height in script styles - + '</SPAN>' - + '<IMG SRC="'+jsMath.blank+'" STYLE="width: '+jsMath.HTML.Em(w)+'; ' - + 'height: '+jsMath.HTML.Em(jsMath.h)+';">' - + '</SPAN>' // for MSIE (Mac) - + '</SPAN>'; - isBig = 1; + var y = jsMath.absoluteOffsetY; + if (jsMath.absoluteHeightVaries || box.bh > jsMath.h+.001) {y += (jsMath.h - box.bh)} + html = jsMath.HTML.Absolute(html,w,jsMath.h,0,y,jsMath.h); + isBig = 1; h = box.h; d = box.d; } else {// remove line height and try to hide the depth var dy = jsMath.HTML.Em(Math.max(0,box.bd-jsMath.hd)/3); html = '<SPAN STYLE="line-height: 0;' @@ -4700,10 +4770,11 @@ } } html = '<NOBR>' + rules + html; - if (isBig) {// add height and depth to the line + 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(h+d)+'; ' - + 'vertical-align: '+jsMath.HTML.Em(-d)+';">' + + 'STYLE="height: '+jsMath.HTML.Em(h+d+.2)+'; ' + + 'vertical-align: '+jsMath.HTML.Em(-d-.1)+';">' } html += '<NOBR>' return html; @@ -4797,7 +4868,6 @@ var parse = jsMath.Parse(s,null,null,'D'); parse.Atomize(); var html = parse.Typeset(); - html = '<p align="CENTER">' + html + '</p>' return html; }, Index: jsMath-fallback-mac.js =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/jsMath/jsMath-fallback-mac.js,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -Lhtdocs/jsMath/jsMath-fallback-mac.js -Lhtdocs/jsMath/jsMath-fallback-mac.js -u -r1.2 -r1.2.4.1 --- htdocs/jsMath/jsMath-fallback-mac.js +++ htdocs/jsMath/jsMath-fallback-mac.js @@ -467,8 +467,8 @@ {c: '}', h: 0.04, d: 1.16, n: 111, tclass: 'delim1'}, {c: '〈', h: 0.04, d: 1.16, n: 68, tclass: 'delim1c'}, {c: '〉', h: 0.04, d: 1.16, n: 69, tclass: 'delim1c'}, - {c: '|', h:.7, d:.1, delim: {rep: 12}, tclass: 'vertical2'}, - {c: '||', h:.7, d:.1, delim: {rep: 13}, tclass: 'vertical2'}, + {c: '|', h:.7, d:.15, delim: {rep: 12}, tclass: 'vertical1'}, + {c: '||', h:.7, d:.15, delim: {rep: 13}, tclass: 'vertical1'}, {c: '∕', h: 0.04, d: 1.16, n: 46, tclass: 'delim1b'}, {c: '∖', h: 0.04, d: 1.16, n: 47, tclass: 'delim1b'}, // 10 - 1F @@ -506,27 +506,27 @@ {c: '∕', h: 0.04, d: 1.76, n: 30, tclass: 'delim2b'}, {c: '∖', h: 0.04, d: 1.76, n: 31, tclass: 'delim2b'}, // 30 - 3F - {c: '', h: .8, d: .15, delim: {top: 48, bot: 64, rep: 66}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 49, bot: 65, rep: 67}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 50, bot: 52, rep: 54}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 51, bot: 53, rep: 55}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {bot: 52, rep: 54}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {bot: 53, rep: 55}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 50, rep: 54}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 51, rep: 55}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 56, mid: 60, bot: 58, rep: 62}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 57, mid: 61, bot: 59, rep: 62}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 56, bot: 58, rep: 62}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 57, bot: 59, rep: 62}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {rep: 63}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {rep: 119}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {rep: 62}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 48, bot: 64, rep: 66}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 49, bot: 65, rep: 67}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 50, bot: 52, rep: 54}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 51, bot: 53, rep: 55}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {bot: 52, rep: 54}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {bot: 53, rep: 55}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 50, rep: 54}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 51, rep: 55}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 56, mid: 60, bot: 58, rep: 62}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 57, mid: 61, bot: 59, rep: 62}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 56, bot: 58, rep: 62}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 57, bot: 59, rep: 62}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {rep: 63}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {rep: 119}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {rep: 62}, tclass: 'normal'}, {c: '|', h: .7, d: .15, delim: {top: 120, bot: 121, rep: 63}, tclass: 'vertical2'}, // 40 - 4F - {c: '', h: .8, d: .15, delim: {top: 56, bot: 59, rep: 62}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {top: 57, bot: 58, rep: 62}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {rep: 66}, tclass: 'normal'}, - {c: '', h: .8, d: .15, delim: {rep: 67}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 56, bot: 59, rep: 62}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {top: 57, bot: 58, rep: 62}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {rep: 66}, tclass: 'normal'}, + {c: '', h: .85, d: .2, delim: {rep: 67}, tclass: 'normal'}, {c: '〈', h: 0.04, d: 1.76, n: 28, tclass: 'delim2c'}, {c: '〉', h: 0.04, d: 1.76, n: 29, tclass: 'delim2c'}, {c: '⊔', h: 0, d: 1, n: 71, tclass: 'bigop1'}, @@ -581,15 +581,15 @@ {c: '<SPAN STYLE="font-size: 400%; position:relative; top:.92em">√</SPAN>', h: 0.1, d: 3.75, n: 117, tclass: 'root'}, {c: '<SPAN STYLE="font-size: 500%; position:relative; top:.9em">√</SPAN>', h: .12, d: 4.5, n: 118, tclass: 'root'}, {c: '<SPAN STYLE="font-size: 625%; position:relative; top:.9em">√</SPAN>', h: .14, d: 5.7, tclass: 'root'}, - {c: '<SPAN STYLE="margin:.1em">||</SPAN>', h:.65, d:.15, delim: {top: 126, bot: 127, rep: 119}, tclass: 'vertical2'}, - {c: '▵', h:.45, delim: {top: 120, rep: 63}, tclass: 'arrow1b'}, - {c: '▿', h:.45, delim: {bot: 121, rep: 63}, tclass: 'arrow1b'}, + {c: '||', h:.65, d:.15, delim: {top: 126, bot: 127, rep: 119}, tclass: 'vertical2'}, + {c: '▵', h:.4, delim: {top: 120, rep: 63}, tclass: 'arrow1b'}, + {c: '▿', h:.38, delim: {bot: 121, rep: 63}, tclass: 'arrow1b'}, {c: '<SPAN STYLE="font-size: 67%; position:relative; top:.35em; margin-left:-.5em">╭</SPAN>', h:.1, tclass: 'symbol'}, {c: '<SPAN STYLE="font-size: 67%; position:relative; top:.35em; margin-right:-.5em">╮</SPAN>', h:.1, tclass: 'symbol'}, {c: '<SPAN STYLE="font-size: 67%; position:relative; top:.35em; margin-left:-.5em">╰</SPAN>', h:.1, tclass: 'symbol'}, {c: '<SPAN STYLE="font-size: 67%; position:relative; top:.35em; margin-right:-.5em">╯</SPAN>', h:.1, tclass: 'symbol'}, - {c: '▵', h:.5, d:-.1, delim: {top: 126, rep: 119}, tclass: 'arrow2b'}, - {c: '▿', h:.5, d:-.1, delim: {bot: 127, rep: 119}, tclass: 'arrow2b'} + {c: '▵', h:.5, delim: {top: 126, rep: 119}, tclass: 'arrow2b'}, + {c: '▿', h:.6, d:-.1, delim: {bot: 127, rep: 119}, tclass: 'arrow2b'} ], cmti10: [ @@ -938,7 +938,8 @@ '.delim4b': 'font-family: Hiragino Mincho Pro; font-size: 325%; position:relative; top:.8em; margin: -.1em', '.delim4c': 'font-family: Symbol; font-size: 300%; position:relative; top:.8em;', '.vertical': 'font-family: Copperplate', - '.vertical2': 'font-family: Copperplate; font-size: 85%', + '.vertical1': 'font-family: Copperplate; font-size: 85%; margin: .15em;', + '.vertical2': 'font-family: Copperplate; font-size: 85%; margin: .17em;', '.greek': 'font-family: Symbol', '.bigop1': 'font-family: Hiragino Mincho Pro; font-size: 133%; position: relative; top: .85em; margin:-.05em', '.bigop1a': 'font-family: Baskerville; font-size: 100%; position: relative; top: .775em;', @@ -1050,7 +1051,6 @@ jsMath.Macro('not','\\mathrel{\\rlap{\\kern 4mu/}}'); -jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative; jsMath.absoluteHeightVaries = 1; -jsMath.defaultH = 0.8; \ No newline at end of file +jsMath.defaultH = 0.8; Index: jsMath-fallback-pc.js =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/jsMath/jsMath-fallback-pc.js,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -Lhtdocs/jsMath/jsMath-fallback-pc.js -Lhtdocs/jsMath/jsMath-fallback-pc.js -u -r1.2 -r1.2.4.1 --- htdocs/jsMath/jsMath-fallback-pc.js +++ htdocs/jsMath/jsMath-fallback-pc.js @@ -559,9 +559,9 @@ // 60 - 6F {c: '∐', h: 0, d: 1, n: 97, tclass: 'bigop1a'}, {c: '∐', h: 0.1, d: 1.5, tclass: 'bigop2a'}, - {c: '⁀', h: 0.722, w: .58, n: 99, tclass: 'wide1'}, - {c: '⁀', h: 0.85, w: 1.0, n: 100, tclass: 'wide2'}, - {c: '⁀', h: 0.99, w: 1.7, tclass: 'wide3'}, + {c: '︿', h: 0.722, w: .65, n: 99, tclass: 'wide1'}, + {c: '︿', h: 0.85, w: 1.1, n: 100, tclass: 'wide2'}, + {c: '︿', h: 0.99, w: 1.65, tclass: 'wide3'}, {c: '~', h: 0.722, w: .5, n: 102, tclass: 'wide1a'}, {c: '~', h: 0.8, w: .8, n: 103, tclass: 'wide2a'}, {c: '~', h: 0.99, w: 1.3, tclass: 'wide3a'}, @@ -581,13 +581,13 @@ {c: '<SPAN STYLE="font-size: 490%; position:relative; top:.8em; margin-right:-.03em">√</SPAN>', h: 0.1, d: 3.75, n: 117, tclass: 'root'}, {c: '<SPAN STYLE="font-size: 580%; position:relative; top:.775em; margin-right:-.04em">√</SPAN>', h: .12, d: 4.5, n: 118, tclass: 'root'}, {c: '<SPAN STYLE="font-size: 750%; position:relative; top:.775em;margin-right:-.04em">√</SPAN>', h: .14, d: 5.7, tclass: 'root'}, - {c: '<SPAN STYLE="margin-right:.125em">||</SPAN>', h:.8, d:0, delim: {top: 126, bot: 127, rep: 119}, tclass: 'normal'}, + {c: '<SPAN STYLE="margin-left:.02em">|</SPAN><SPAN STYLE="margin-left:.08em; margin-right:.125em">|</SPAN>', h:.8, d:0, delim: {top: 126, bot: 127, rep: 119}, tclass: 'normal'}, {c: '↑', h:.7, d:0, delim: {top: 120, rep: 63}, tclass: 'arrow1a'}, {c: '↓', h:.65, d:0, delim: {bot: 121, rep: 63}, tclass: 'arrow1a'}, - {c: '<SPAN STYLE="margin-left:-.1em"></SPAN><SPAN STYLE="position:relative; top:.6em; margin-right:-.3em">◜</SPAN>', h: 0.05, tclass: 'symbol'}, - {c: '<SPAN STYLE="margin-left:-.3em"></SPAN><SPAN STYLE="position:relative; top:.6em; margin-right:-.1em">◝</SPAN>', h: 0.05, tclass: 'symbol'}, - {c: '<SPAN STYLE="margin-left:-.1em"></SPAN><SPAN STYLE="position:relative; top:.2em; margin-right:-.3em">◟</SPAN>', h: 0.05, tclass: 'symbol'}, - {c: '<SPAN STYLE="margin-left:-.3em"></SPAN><SPAN STYLE="position:relative; top:.2em; margin-right:-.1em">◞</SPAN>', h: 0.05, tclass: 'symbol'}, + {c: '<SPAN STYLE="margin-left:-.1em"></SPAN><SPAN STYLE="position:relative; top:.55em; margin-right:-.3em">◜</SPAN>', h: 0.05, tclass: 'symbol'}, + {c: '<SPAN STYLE="margin-left:-.3em"></SPAN><SPAN STYLE="position:relative; top:.55em; margin-right:-.1em">◝</SPAN>', h: 0.05, tclass: 'symbol'}, + {c: '<SPAN STYLE="margin-left:-.1em"></SPAN><SPAN STYLE="position:relative; top:.15em; margin-right:-.3em">◟</SPAN>', h: 0.05, tclass: 'symbol'}, + {c: '<SPAN STYLE="margin-left:-.3em"></SPAN><SPAN STYLE="position:relative; top:.15em; margin-right:-.1em">◞</SPAN>', h: 0.05, tclass: 'symbol'}, {c: '⇑', h: .7, d:0, delim: {top: 126, rep: 119}, tclass: 'arrow1a'}, {c: '⇓', h: .7, d:0, delim: {bot: 127, rep: 119}, tclass: 'arrow1a'} ], @@ -874,7 +874,7 @@ /* * We need to replace the jsMath.Box.TeX function in order to use the - * different font metrics in thie tables above, and to handle the + * different font metrics in the tables above, and to handle the * scaling better. */ @@ -943,14 +943,14 @@ '.bigop2a': 'font-family: Arial unicode MS; font-size: 185%; position: relative; top: .75em', '.bigop2b': 'font-family: Arial unicode MS; font-size: 275%; position: relative; top: .55em', '.bigop2c': 'font-family: Arial unicode MS; font-size: 185%; position: relative; top: 1em; margin-right:-.1em', - '.wide1': 'font-family: Arial unicode MS; font-size: 75%; position: relative; top:-.1em', - '.wide2': 'font-family: Arial unicode MS; font-size: 133%; position: relative; top:.25em', - '.wide3': 'font-family: Arial unicode MS; font-size: 200%; position: relative; top:.35em', + '.wide1': 'font-size: 67%; position: relative; top:-.5em;', + '.wide2': 'font-size: 110%; position: relative; top:-.2em;', + '.wide3': 'font-size: 175%;', '.wide1a': 'font-family: Times New Roman; font-size: 75%; position: relative; top:-.5em', '.wide2a': 'font-family: Times New Roman; font-size: 133%; position: relative; top:-.2em', '.wide3a': 'font-family: Times New Roman; font-size: 200%; position: relative; top:-.1em', '.root': 'font-family: Arial unicode MS; margin-right:-.075em', - '.accent': 'font-family: Arial unicode MS; position:relative; top:.05em; left:.22em' + '.accent': 'font-family: Arial unicode MS; position:relative; top:.05em; left:.15em' }); // @@ -959,29 +959,41 @@ if (jsMath.hidden.ATTRIBUTE_NODE) { jsMath.UpdateTeXfonts({ cmex10: { - '48': {c: '(', d:0}, - '49': {c: ')', d:0}, - '50': {c: '[', d:0}, - '51': {c: ']', d:0}, - '52': {c: '[', d:0}, - '53': {c: ']', d:0}, - '54': {c: '<SPAN STYLE="margin:.075em">|</SPAN>', d:0}, - '55': {c: '<SPAN STYLE="margin:.075em">|</SPAN>', d:0}, - '56': {c: '{', d:0}, - '57': {c: '}', d:0}, - '58': {c: '{', d:0}, - '59': {c: '}', d:0}, - '60': {c: '{', d:0}, - '61': {c: '}', d:0}, - '62': {c: '<SPAN STYLE="margin:.075em">|</SPAN>', d:0}, - '64': {c: '(', d:0}, - '65': {c: ')', d:0}, - '66': {c: '<SPAN STYLE="margin:.075em">|</SPAN>', d:0}, - '67': {c: '<SPAN STYLE="margin:.075em">|</SPAN>', d:0} + '48': {c: ''}, + '49': {c: ''}, + '50': {c: ''}, + '51': {c: ''}, + '52': {c: ''}, + '53': {c: ''}, + '54': {c: ''}, + '55': {c: ''}, + '56': {c: ''}, + '57': {c: ''}, + '58': {c: ''}, + '59': {c: ''}, + '60': {c: ''}, + '61': {c: ''}, + '62': {c: ''}, + '64': {c: ''}, + '65': {c: ''}, + '66': {c: ''}, + '67': {c: ''} } }); jsMath.UpdateStyles({ - '.delimx': 'font-family: serif' + '.accent': 'font-family: Arial unicode MS; position:relative; top:.05em; left:.05em' + }); +} + +// +// adjust for MSIE +// +if (jsMath.browser == "MSIE") { + jsMath.UpdateTeXfonts({ + cmex10: { + '63': {c: '<SPAN STYLE="position:relative; left:.125em; margin-right:.125em">|</SPAN>'}, + '119': {c: '<SPAN STYLE="position:relative; left:.02em; margin-right=.08em">|</SPAN><SPAN STYLE="margin-right:.125em">|</SPAN>'} + } }); } @@ -1000,7 +1012,6 @@ jsMath.Macro('not','\\mathrel{\\rlap{\\kern 3mu/}}'); jsMath.Macro('bowtie','\\mathrel\\triangleright\\kern-6mu\\mathrel\\triangleleft'); -jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative; jsMath.absoluteHeightVaries = 1; jsMath.defaultH = 0.8; |
From: Mike G. v. a. <we...@ma...> - 2005-02-07 13:34:20
|
Log Message: ----------- Backporting changes to Home.pm This means that the options menu won't appear on the home page. Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Home.pm Revision Data ------------- Index: Home.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Home.pm,v retrieving revision 1.6 retrieving revision 1.6.6.1 diff -Llib/WeBWorK/ContentGenerator/Home.pm -Llib/WeBWorK/ContentGenerator/Home.pm -u -r1.6 -r1.6.6.1 --- lib/WeBWorK/ContentGenerator/Home.pm +++ lib/WeBWorK/ContentGenerator/Home.pm @@ -31,6 +31,7 @@ sub loginstatus { "" } sub links { "" } +sub options { "" }; sub body { my ($self) = @_; |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 21:05:32
|
Log Message: ----------- Added links to the sidebar for student and current set Added links to problems on the stats page Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK: ContentGenerator.pm webwork2/lib/WeBWorK/ContentGenerator/Instructor: Stats.pm Revision Data ------------- Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.123.2.3 retrieving revision 1.123.2.4 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.123.2.3 -r1.123.2.4 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -519,17 +519,19 @@ $setID = "" if (defined $setID && !(grep /$setID/, $db->listUserSets($userID))); my $problemID = $urlpath->arg("problemID"); $problemID = "" if (defined $problemID && !(grep /$problemID/, $db->listUserProblems($userID, $setID))); - + # instructor tools link my $instr = $urlpath->newFromModule("${ipfx}Index", %args); - my $addUsers = $urlpath->newFromModule("${ipfx}AddUsers", %args); + # Class list editor my $userList = $urlpath->newFromModule("${ipfx}UserList", %args); - # set list links + # 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); + # Library browser my $maker = $urlpath->newFromModule("${ipfx}SetMaker", %args); + my $assigner = $urlpath->newFromModule("${ipfx}Assigner", %args); my $mail = $urlpath->newFromModule("${ipfx}SendMail", %args); my $scoring = $urlpath->newFromModule("${ipfx}Scoring", %args); @@ -546,51 +548,62 @@ my $fileMgr = $urlpath->newFromModule("${ipfx}FileManager", %args); - #my $fileXfer = $urlpath->newFromModule("${ipfx}FileXfer", %args); print CGI::hr(); print CGI::start_li(); + ## Instructor tools print CGI::span({style=>"font-size:larger"}, - CGI::a({href=>$self->systemLink($instr,params=>{ %displayOptions,})}, space2nbsp($instr->name)) + 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_ul(); - print CGI::start_li(); - print CGI::a({href=>$self->systemLink($setDetail,params=>{ %displayOptions,})}, $setID); + 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::end_li(); - 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))); - - ## Added Link for Student Progress + print CGI::start_li(); + if (defined $userID and $userID ne "") { + print ' ', + CGI::a({href=>$self->systemLink($userStats,params=>{ %displayOptions,})}, $userID), + CGI::br(); + } + if (defined $setID and $setID ne "") { + print ' ', + CGI::a({href=>$self->systemLink($setStats,params=>{ %displayOptions,})}, sp2nbsp($setID)), + CGI::br(); + } + print CGI::end_li(); + ## Student Progress print CGI::li(CGI::a({href=>$self->systemLink($progress,params=>{ %displayOptions,})}, sp2nbsp($progress->name))); print CGI::start_li(); if (defined $userID and $userID ne "") { - print CGI::ul( - CGI::li(CGI::a({href=>$self->systemLink($userProgress,params=>{ %displayOptions,})}, $userID)) - ); + print ' ', + CGI::a({href=>$self->systemLink($userProgress,params=>{ %displayOptions,})}, $userID), + CGI::br(); } if (defined $setID and $setID ne "") { - print CGI::ul( - CGI::li(CGI::a({href=>$self->systemLink($setProgress,params=>{ %displayOptions,})}, space2nbsp($setID))) - ); + print ' ', + CGI::a({href=>$self->systemLink($setProgress,params=>{ %displayOptions,})}, sp2nbsp($setID)), + CGI::br(); } 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))); #print CGI::li(CGI::a({href=>$self->systemLink($fileXfer)}, sp2nbsp($fileXfer->name))); @@ -1571,21 +1584,24 @@ sub sp2nbsp { my ($str) = @_; return unless defined $str; - $str =~ s/ / /g; + #$str =~ s/ / /g; + $str =~ s/\s/ /g; return $str; } -=item space2nbsp($string) - -Replace spaces in the string with html non-breaking spaces. - -=cut - -sub space2nbsp { - my $str = shift; - $str =~ s/\s/ /g; - return($str); -} +# FIXME -- I don't think we need both this and the one above. +# Remove this comment block after some time.(2/6/05) +# =item space2nbsp($string) +# +# Replace spaces in the string with html non-breaking spaces. +# +# =cut +# +# sub space2nbsp { +# my $str = shift; +# $str =~ s/\s/ /g; +# return($str); +# } =item errorOutput($error, $details) Index: Stats.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/Stats.pm,v retrieving revision 1.47.2.1 retrieving revision 1.47.2.2 diff -Llib/WeBWorK/ContentGenerator/Instructor/Stats.pm -Llib/WeBWorK/ContentGenerator/Instructor/Stats.pm -u -r1.47.2.1 -r1.47.2.2 --- lib/WeBWorK/ContentGenerator/Instructor/Stats.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Stats.pm @@ -431,10 +431,13 @@ my %index_percentiles = determine_percentiles(\@brackets1, @index_list); my %score_percentiles = determine_percentiles(\@brackets1, @score_list); my %attempts_percentiles_for_problem = (); + my %problemPage = (); # link to the problem page foreach my $probID (@problemIDs) { $attempts_percentiles_for_problem{$probID} = { determine_percentiles([@brackets2], @{$attempts_list_for_problem{$probID}}) }; + $problemPage{$probID} = $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", + courseID => $courseName, setID => $setName, problemID => $probID); } ##################################################################################### @@ -446,7 +449,9 @@ CGI::p('The percentage of active students with correct answers for each problem'), CGI::start_table({-border=>1}), CGI::Tr(CGI::td( - ['Problem #', @problemIDs] + ['Problem #', + map {CGI::a({ href=>$self->systemLink($problemPage{$_}) },$_)} @problemIDs + ] )), CGI::Tr(CGI::td( [ '% correct',map {($number_of_students_attempting_problem{$_}) @@ -519,11 +524,9 @@ foreach my $probID (@problemIDs) { - my $problemPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", - courseID => $courseName, setID => $setName, problemID => $probID); print CGI::Tr( CGI::td( [ - CGI::a({href=>$self->systemLink($problemPage)},"Prob $probID"), + CGI::a({ href=>$self->systemLink($problemPage{$probID}) },"Prob $probID"), ( prevent_repeats reverse map { sprintf("%0.0f",$attempts_percentiles_for_problem{$probID}->{$_}) } @brackets2), ] |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 21:03:51
|
Log Message: ----------- Added links to problems to the stats page. Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: Stats.pm Revision Data ------------- Index: Stats.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/Stats.pm,v retrieving revision 1.49 retrieving revision 1.50 diff -Llib/WeBWorK/ContentGenerator/Instructor/Stats.pm -Llib/WeBWorK/ContentGenerator/Instructor/Stats.pm -u -r1.49 -r1.50 --- lib/WeBWorK/ContentGenerator/Instructor/Stats.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Stats.pm @@ -431,12 +431,15 @@ my %index_percentiles = determine_percentiles(\@brackets1, @index_list); my %score_percentiles = determine_percentiles(\@brackets1, @score_list); my %attempts_percentiles_for_problem = (); + my %problemPage = (); # link to the problem page foreach my $probID (@problemIDs) { $attempts_percentiles_for_problem{$probID} = { determine_percentiles([@brackets2], @{$attempts_list_for_problem{$probID}}) - }; + }; + $problemPage{$probID} = $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", + courseID => $courseName, setID => $setName, problemID => $probID); } - + ##################################################################################### # Table showing the percentage of students with correct answers for each problems ##################################################################################### @@ -446,7 +449,9 @@ CGI::p('The percentage of active students with correct answers for each problem'), CGI::start_table({-border=>1}), CGI::Tr(CGI::td( - ['Problem #', @problemIDs] + ['Problem #', + map {CGI::a({ href=>$self->systemLink($problemPage{$_}) },$_)} @problemIDs + ] )), CGI::Tr(CGI::td( [ '% correct',map {($number_of_students_attempting_problem{$_}) @@ -519,11 +524,9 @@ foreach my $probID (@problemIDs) { - my $problemPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", - courseID => $courseName, setID => $setName, problemID => $probID); print CGI::Tr( CGI::td( [ - CGI::a({href=>$self->systemLink($problemPage)},"Prob $probID"), + CGI::a({ href=>$self->systemLink($problemPage{$probID}) },"Prob $probID"), ( prevent_repeats reverse map { sprintf("%0.0f",$attempts_percentiles_for_problem{$probID}->{$_}) } @brackets2), ] |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 21:02:11
|
Log Message: ----------- Fixed formatting on sidebar links. Added sub links for student and set to the Statistics link Modified Files: -------------- webwork-modperl/lib/WeBWorK: ContentGenerator.pm Revision Data ------------- Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.133 retrieving revision 1.134 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.133 -r1.134 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -519,17 +519,19 @@ $setID = "" if (defined $setID && !(grep /$setID/, $db->listUserSets($userID))); my $problemID = $urlpath->arg("problemID"); $problemID = "" if (defined $problemID && !(grep /$problemID/, $db->listUserProblems($userID, $setID))); - + # instructor tools link my $instr = $urlpath->newFromModule("${ipfx}Index", %args); - my $addUsers = $urlpath->newFromModule("${ipfx}AddUsers", %args); + # Class list editor my $userList = $urlpath->newFromModule("${ipfx}UserList", %args); - # set list links + # 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); + # Library browser my $maker = $urlpath->newFromModule("${ipfx}SetMaker", %args); + my $assigner = $urlpath->newFromModule("${ipfx}Assigner", %args); my $mail = $urlpath->newFromModule("${ipfx}SendMail", %args); my $scoring = $urlpath->newFromModule("${ipfx}Scoring", %args); @@ -546,51 +548,62 @@ my $fileMgr = $urlpath->newFromModule("${ipfx}FileManager", %args); - #my $fileXfer = $urlpath->newFromModule("${ipfx}FileXfer", %args); print CGI::hr(); print CGI::start_li(); + ## Instructor tools print CGI::span({style=>"font-size:larger"}, - CGI::a({href=>$self->systemLink($instr,params=>{ %displayOptions,})}, space2nbsp($instr->name)) + 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_ul(); - print CGI::start_li(); - print CGI::a({href=>$self->systemLink($setDetail,params=>{ %displayOptions,})}, $setID); + 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::end_li(); - 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))); - - ## Added Link for Student Progress + print CGI::start_li(); + if (defined $userID and $userID ne "") { + print ' ', + CGI::a({href=>$self->systemLink($userStats,params=>{ %displayOptions,})}, $userID), + CGI::br(); + } + if (defined $setID and $setID ne "") { + print ' ', + CGI::a({href=>$self->systemLink($setStats,params=>{ %displayOptions,})}, sp2nbsp($setID)), + CGI::br(); + } + print CGI::end_li(); + ## Student Progress print CGI::li(CGI::a({href=>$self->systemLink($progress,params=>{ %displayOptions,})}, sp2nbsp($progress->name))); print CGI::start_li(); if (defined $userID and $userID ne "") { - print CGI::ul( - CGI::li(CGI::a({href=>$self->systemLink($userProgress,params=>{ %displayOptions,})}, $userID)) - ); + print ' ', + CGI::a({href=>$self->systemLink($userProgress,params=>{ %displayOptions,})}, $userID), + CGI::br(); } if (defined $setID and $setID ne "") { - print CGI::ul( - CGI::li(CGI::a({href=>$self->systemLink($setProgress,params=>{ %displayOptions,})}, space2nbsp($setID))) - ); + print ' ', + CGI::a({href=>$self->systemLink($setProgress,params=>{ %displayOptions,})}, sp2nbsp($setID)), + CGI::br(); } 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))); #print CGI::li(CGI::a({href=>$self->systemLink($fileXfer)}, sp2nbsp($fileXfer->name))); @@ -675,7 +688,6 @@ =item options() -Not defined in this package. Print an auxiliary options form, related to the content displayed in the C<body>. @@ -1572,21 +1584,24 @@ sub sp2nbsp { my ($str) = @_; return unless defined $str; - $str =~ s/ / /g; + #$str =~ s/ / /g; + $str =~ s/\s/ /g; return $str; } -=item space2nbsp($string) - -Replace spaces in the string with html non-breaking spaces. - -=cut - -sub space2nbsp { - my $str = shift; - $str =~ s/\s/ /g; - return($str); -} +# FIXME -- I don't think we need both this and the one above. +# Remove this comment block after some time.(2/6/05) +# =item space2nbsp($string) +# +# Replace spaces in the string with html non-breaking spaces. +# +# =cut +# +# sub space2nbsp { +# my $str = shift; +# $str =~ s/\s/ /g; +# return($str); +# } =item errorOutput($error, $details) |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 16:30:41
|
Log Message: ----------- Backporting changes to Stats.pm and Scoring.pm Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: Scoring.pm Stats.pm Revision Data ------------- Index: Stats.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/Stats.pm,v retrieving revision 1.47 retrieving revision 1.47.2.1 diff -Llib/WeBWorK/ContentGenerator/Instructor/Stats.pm -Llib/WeBWorK/ContentGenerator/Instructor/Stats.pm -u -r1.47 -r1.47.2.1 --- lib/WeBWorK/ContentGenerator/Instructor/Stats.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Stats.pm @@ -334,7 +334,7 @@ foreach my $problemRecord (@problemRecords) { next unless ref($problemRecord); my $probID = $problemRecord->problem_id; - $num_of_attempts = 0; + my $valid_status = 0; unless (defined($problemRecord) ){ @@ -384,7 +384,7 @@ $number_of_attempts_for_problem{$probID} += $num_of_attempts; $correct_answers_for_problem{$probID} += $status; } - + } @@ -396,6 +396,7 @@ my $avg_num_attempts = ($num_of_problems) ? $num_of_attempts/$num_of_problems : 0; my $successIndicator = ($avg_num_attempts) ? ($totalRight/$total)**2/$avg_num_attempts : 0 ; + my $temp_hash = { user_id => $studentRecord->user_id, last_name => $studentRecord->last_name, first_name => $studentRecord->first_name, @@ -531,55 +532,6 @@ } print CGI::end_table(); -##################################################################################### - # construct header - my $problem_header = ''; - - foreach my $i (1..$max_num_problems) { - $problem_header .= CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>"p$i"})},threeSpaceFill($i) ); - } - print - CGI::p("Details:",CGI::i('The success indicator for each student is calculated as'),CGI::br(), - '(totalNumberOfCorrectProblems / totalNumberOfProblems)^2/ AvgNumberOfAttemptsPerProblem)',CGI::br(), - CGI::i('or 0 if there are no attempts.') - ), - "Click heading to sort table: ", - defined($sort_method_name) ?" sort method is $sort_method_name":"", - CGI::start_table({-border=>5,style=>'font-size:smaller'}), - CGI::Tr(CGI::td( {-align=>'left'}, - [CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>'name' })},'Name'), - CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>'score'})},'Score'), - 'Out'.CGI::br().'Of', - CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>'index'})},'Ind'), - 'Problems'.CGI::br().$problem_header, - CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>'section'})},'Section'), - 'Recitation', - 'login_name', - ]) - - ); - - foreach my $rec (@augmentedUserRecords) { - my $fullName = join("", $rec->{first_name}," ", $rec->{last_name}); - my $email = $rec->{email_address}; - my $twoString = $rec->{twoString}; - print CGI::Tr( - CGI::td(CGI::a({-href=>$rec->{act_as_student}},$fullName), CGI::br(), CGI::a({-href=>"mailto:$email"},$email)), - CGI::td( sprintf("%0.2f",$rec->{score}) ), # score - CGI::td($rec->{total}), # out of - CGI::td(sprintf("%0.0f",100*($rec->{index}) )), # indicator - CGI::td($rec->{problemString}), # problems - CGI::td($self->nbsp($rec->{section})), - CGI::td($self->nbsp($rec->{recitation})), - CGI::td($rec->{user_id}), - - ); - } - - print CGI::end_table(); - - - return ""; } Index: Scoring.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm,v retrieving revision 1.36.2.1 retrieving revision 1.36.2.2 diff -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -u -r1.36.2.1 -r1.36.2.2 --- lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm @@ -30,6 +30,10 @@ use WeBWorK::DB::Utils qw(initializeUserProblem); use WeBWorK::Timing; + +our @userInfoColumnHeadings = ("STUDENT ID", "login ID", "LAST NAME", "FIRST NAME", "SECTION", "RECITATION"); +our @userInfoFields = ("student_id", "user_id","last_name", "first_name", "section", "recitation"); + sub initialize { my ($self) = @_; my $r = $self->r; @@ -45,13 +49,13 @@ return unless $authz->hasPermissions($user, "access_instructor_tools"); return unless $authz->hasPermissions($user, "score_sets"); - if (defined $r->param('scoreSelected')) { - my @selected = $r->param('selectedSet'); + my @selected = $r->param('selectedSet'); + my $scoreSelected = $r->param('scoreSelected'); + if (defined $scoreSelected && @selected) { + my @totals = (); my $recordSingleSetScores = $r->param('recordSingleSetScores'); - $self->addmessage(CGI::div({class=>'ResultsWithError'},"You must select one or more sets for scoring")) unless @selected; - # pre-fetch users $WeBWorK::timer->continue("pre-fetching users") if defined($WeBWorK::timer); my @Users = $db->getUsers($db->listUsers); @@ -60,21 +64,21 @@ next unless $User; $Users{$User->user_id} = $User; } - my @sortedUserIDs = sort { $Users{$a}->student_id cmp $Users{$b}->student_id } + my @sortedUserIDs = sort { $Users{$a}->last_name cmp $Users{$b}->last_name } keys %Users; - my @userInfo = (\%Users, \@sortedUserIDs); + #my @userInfo = (\%Users, \@sortedUserIDs); $WeBWorK::timer->continue("done pre-fetching users") if defined($WeBWorK::timer); my $scoringType = ($recordSingleSetScores) ?'everything':'totals'; my (@everything, @normal,@full,@info,@totalsColumn); - @info = $self->scoreSet($selected[0], "info", undef, @userInfo) if defined($selected[0]); + @info = $self->scoreSet($selected[0], "info", undef, \%Users, \@sortedUserIDs) if defined($selected[0]); @totals = @info; my $showIndex = defined($r->param('includeIndex')) ? defined($r->param('includeIndex')) : 0; foreach my $setID (@selected) { next unless defined $setID; if ($scoringType eq 'everything') { - @everything = $self->scoreSet($setID, "everything", $showIndex, @userInfo); + @everything = $self->scoreSet($setID, "everything", $showIndex, \%Users, \@sortedUserIDs); @normal = $self->everything2normal(@everything); @full = $self->everything2full(@everything); @info = $self->everything2info(@everything); @@ -83,12 +87,17 @@ $self->writeCSV("$scoringDir/s${setID}scr.csv", @normal); $self->writeCSV("$scoringDir/s${setID}ful.csv", @full); } else { - @totalsColumn = $self->scoreSet($setID, "totals", $showIndex, @userInfo); + @totalsColumn = $self->scoreSet($setID, "totals", $showIndex, \%Users, \@sortedUserIDs); $self->appendColumns(\@totals, \@totalsColumn); } } + my @sum_scores = $self->sumScores(\@totals, $showIndex, \%Users, \@sortedUserIDs); + $self->appendColumns( \@totals,\@sum_scores); $self->writeCSV("$scoringDir/${courseName}_totals.csv", @totals); - } + + } elsif (defined $scoreSelected) { + $self->addbadmessage("You must select one or more sets for scoring"); + } # Obtaining list of sets: #$WeBWorK::timer->continue("Begin listing sets") if defined $WeBWorK::timer; @@ -134,26 +143,45 @@ CGI::start_form(-method=>"POST", -action=>$scoringURL),"\n", $self->hidden_authen_fields,"\n", CGI::hidden({-name=>'scoreSelected', -value=>1}), - $self->popup_set_form, - CGI::br(), - CGI::checkbox({ -name=>'includeIndex', - -value=>1, - -label=>'IncludeIndex', - -checked=>1, - }, - 'Include Index' - ), - CGI::br(), - CGI::checkbox({ -name=>'recordSingleSetScores', - -value=>1, - -label=>'Record Scores for Single Sets', - -checked=>0, - }, - 'Record Scores for Single Sets' - ), - CGI::br(), - CGI::input({type=>'submit',value=>'Score selected set(s)...',name=>'score-sets'}), + CGI::start_table({border=>1,}), + CGI::Tr( + CGI::td($self->popup_set_form), + CGI::td( + CGI::checkbox({ -name=>'includeIndex', + -value=>1, + -label=>'Include Index', + -checked=>0, + }, + ), + CGI::br(), + CGI::checkbox({ -name=>'includeTotals', + -value=>1, + -label=>'Include Total score column', + -checked=>1, + }, + ), + CGI::br(), + CGI::checkbox({ -name=>'includePercent', + -value=>1, + -label=>'Include Percent correct column', + -checked=>1, + }, + ), + CGI::br(), + CGI::checkbox({ -name=>'recordSingleSetScores', + -value=>1, + -label=>'Record Scores for Single Sets', + -checked=>0, + }, + 'Record Scores for Single Sets' + ), + ), + ), + CGI::Tr(CGI::td({colspan =>2,align=>'center'}, + CGI::input({type=>'submit',value=>'Score selected set(s)...',name=>'score-sets'}), + )), + CGI::end_table(), ); @@ -289,8 +317,6 @@ push @scoringData, []; } - my @userInfoColumnHeadings = ("STUDENT ID", "LAST NAME", "FIRST NAME", "SECTION", "RECITATION"); - my @userInfoFields = ("student_id", "last_name", "first_name", "section", "recitation"); #my @userKeys = sort keys %users; # list of "student IDs" NOT user IDs if ($scoringItems->{header}) { @@ -375,15 +401,6 @@ } $valueTotal += $globalProblem->value; - #my @userLoginIDs = $db->listUsers(); - #$WeBWorK::timer->continue("Begin getting user problems for set $setID, problem $problemIDs[$problem]") if defined($WeBWorK::timer); - ##my @userProblems = $db->getMergedProblems( map { [ $_, $setID, $problemIDs[$problem] ] } @userLoginIDs ); - #my @userProblems = $db->getUserProblems( map { [ $_, $setID, $problemIDs[$problem] ] } @userLoginIDs ); # checked - #my %userProblems; - #foreach my $item (@userProblems) { - # $userProblems{$item->user_id} = $item if ref $item; - #} - #$WeBWorK::timer->continue("End getting user problems for set $setID, problem $problemIDs[$problem]") if defined($WeBWorK::timer); for (my $user = 0; $user < @sortedUserIDs; $user++) { #my $userProblem = $userProblems{ $users{$userKeys[$user]}->user_id }; @@ -397,8 +414,8 @@ $userProblem->num_incorrect(0); } $userStatusTotals{$user} = 0 unless exists $userStatusTotals{$user}; - #$userStatusTotals{$user} += $userProblem->status * $userProblem->value; - $userStatusTotals{$user} += $userProblem->status * $globalProblem->value; + my $user_problem_status = ($userProblem->status =~/^[\d\.]+$/) ? $userProblem->status : 0; # ensure it's numeric + $userStatusTotals{$user} += $user_problem_status * $globalProblem->value; if ($scoringItems->{successIndex}) { $numberOfAttempts{$user} = 0 unless defined($numberOfAttempts{$user}); my $num_correct = $userProblem->num_correct; @@ -427,22 +444,72 @@ my $totalsColumn = $format eq "totals" ? 0 : 5 + @problemIDs * $columnsPerProblem; $scoringData[0][$totalsColumn] = ""; $scoringData[1][$totalsColumn] = $setRecord->set_id; - $scoringData[1][$totalsColumn+1] = $setRecord->set_id if $scoringItems->{successIndex}; $scoringData[2][$totalsColumn] = ""; $scoringData[3][$totalsColumn] = ""; $scoringData[4][$totalsColumn] = ""; $scoringData[5][$totalsColumn] = $valueTotal; $scoringData[6][$totalsColumn] = "total"; - $scoringData[6][$totalsColumn+1] = "index" if $scoringItems->{successIndex}; + if ($scoringItems->{successIndex}) { + $scoringData[0][$totalsColumn+1] = ""; + $scoringData[1][$totalsColumn+1] = $setRecord->set_id; + $scoringData[2][$totalsColumn+1] = ""; + $scoringData[3][$totalsColumn+1] = ""; + $scoringData[4][$totalsColumn+1] = ""; + $scoringData[5][$totalsColumn+1] = '100'; + $scoringData[6][$totalsColumn+1] = "index" ; + } for (my $user = 0; $user < @sortedUserIDs; $user++) { $scoringData[7+$user][$totalsColumn] = sprintf("%4.1f",$userStatusTotals{$user}); - $scoringData[7+$user][$totalsColumn+1] = sprintf("%4.1f",$userSuccessIndex{$user}) if $scoringItems->{successIndex}; + $scoringData[7+$user][$totalsColumn+1] = sprintf("%4.0f",100*$userSuccessIndex{$user}) if $scoringItems->{successIndex}; } } $WeBWorK::timer->continue("End set $setID") if defined($WeBWorK::timer); return @scoringData; } +sub sumScores { # Create a totals column for each student + my $self = shift; + my $r_totals = shift; + my $showIndex = shift; + my $r_users = shift; + my $r_sorted_user_ids =shift; + my $r = $self->r; + my $db = $r->db; + my @scoringData = (); + my $index_increment = ($showIndex) ? 2 : 1; + # This whole thing is a hack, but here goes. We're going to sum the appropriate columns of the totals file: + # I believe we have $r_totals->[rows]->[cols] -- the way it's printed out. + my $start_column = 6; #The problem column + my $last_column = $#{$r_totals->[1]}; # try to figure out the number of the last column in the array. + my $row_count = $#{$r_totals}; + + # Calculate total number of problems for the course. + my $totalPoints = 0; + my $problemValueRow = 5; + for( my $j = $start_column;$j<=$last_column;$j+= $index_increment) { + my $score = $r_totals->[$problemValueRow]->[$j]; + $totalPoints += ($score =~/^\s*[\d\.]+\s*$/)? $score : 0; + } + foreach my $i (0..$row_count) { + my $studentTotal = 0; + for( my $j = $start_column;$j<=$last_column;$j+= $index_increment) { + my $score = $r_totals->[$i]->[$j]; + $studentTotal += ($score =~/^\s*[\d\.]+\s*$/)? $score : 0; + + } + $scoringData[$i][0] =sprintf("%4.1f",$studentTotal); + $scoringData[$i][1] =($totalPoints) ?sprintf("%4.1f",100*$studentTotal/$totalPoints) : 0; + } + $scoringData[0] = ['','']; + $scoringData[1] = ['summary', '%score']; + $scoringData[2] = ['','']; + $scoringData[3] = ['','']; + $scoringData[4] = ['','']; + $scoringData[6] = ['','']; + + return @scoringData; + +} # Often it's more efficient to just get everything out of the database # and then pick out what you want later. Hence, these "everything2*" functions sub everything2info { @@ -618,7 +685,7 @@ my ($self, $string, $padTo) = @_; $string = '' unless defined $string; my $spaces = $padTo - length $string; - return $string . " "x$spaces; + return " "x$spaces.$string; } sub maxLength { |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 16:19:24
|
Log Message: ----------- Backporting: ability to create a blank problem in a set. Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: ProblemSetDetail.pm Revision Data ------------- Index: ProblemSetDetail.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm,v retrieving revision 1.13.2.2 retrieving revision 1.13.2.3 diff -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -u -r1.13.2.2 -r1.13.2.3 --- lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm +++ lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm @@ -758,10 +758,9 @@ # if the current naming scheme is changed/broken, this could reek havoc # on all kinds of things foreach my $param ($r->param) { - $r->param($param, "") if $param =~ /^(set|problem|header)\./; + $r->param($param, "") if $param =~ /^(set|problem|header)\./ && $param !~ /displaymode/; } } - } # helper method for debugging @@ -1132,7 +1131,8 @@ my $editProblemPage = $urlpath->new(type => 'instructor_problem_editor_withset_withproblem', args => { courseID => $courseID, setID => $setID, problemID => $problemID }); my $editProblemLink = $self->systemLink($editProblemPage, params => { make_local_copy => 0 }); - + + # FIXME: should we have an "act as" type link here when editing for multiple users? my $viewProblemPage = $urlpath->new(type => 'problem_detail', args => { courseID => $courseID, setID => $setID, problemID => $problemID }); my $viewProblemLink = $self->systemLink($viewProblemPage, params => { effectiveUser => ($forOneUser ? $editForUser[0] : $userID)}); @@ -1199,6 +1199,10 @@ ])); } + my $editNewProblemPage = $urlpath->new(type => 'instructor_problem_editor_withset_withproblem', args => { courseID => $courseID, setID => $setID, problemID =>'new_problem' }); + my $editNewProblemLink = $self->systemLink($editNewProblemPage, params => { make_local_copy => 1, file_type => 'blank_problem' }); + +# print final lines print CGI::end_table(); print CGI::checkbox({ label=> "Force problems to be numbered consecutively from one", @@ -1207,6 +1211,7 @@ CGI::br(); print CGI::input({type=>"submit", name=>"submit_changes", value=>"Save Changes"}); print CGI::input({type=>"submit", name=>"handle_numbers", value=>"Reorder problems only"}) . "(Any unsaved changes will be lost.)"; + print CGI::p( CGI::a({href=>$editNewProblemLink},'Create'). 'a new blank problem'); print CGI::p(<<HERE); Any time problem numbers are intentionally changed, the problems will always be renumbered consecutively, starting from one. When deleting |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 16:18:55
|
Log Message: ----------- Backporting minor corrections in code Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Grades.pm Revision Data ------------- Index: Grades.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Grades.pm,v retrieving revision 1.9.2.2 retrieving revision 1.9.2.3 diff -Llib/WeBWorK/ContentGenerator/Grades.pm -Llib/WeBWorK/ContentGenerator/Grades.pm -u -r1.9.2.2 -r1.9.2.3 --- lib/WeBWorK/ContentGenerator/Grades.pm +++ lib/WeBWorK/ContentGenerator/Grades.pm @@ -295,16 +295,15 @@ $longStatus = 'X '; } - my $incorrect = $problemRecord->num_incorrect; $string .= $longStatus; - $twoString .= threeSpaceFill($incorrect); + $twoString .= threeSpaceFill($num_correct); my $probValue = $problemRecord->value; $probValue = 1 unless defined($probValue) and $probValue ne ""; # FIXME?? set defaults here? $total += $probValue; $totalRight += round_score($status*$probValue) if $valid_status; } - + my $avg_num_attempts = ($num_of_problems) ? $num_of_attempts/$num_of_problems : 0; my $successIndicator = ($avg_num_attempts) ? ($totalRight/$total)**2/$avg_num_attempts : 0 ; |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 16:06:54
|
Log Message: ----------- Backporting fix for problem which caused multiple users to be passed in the params of forms. Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Login.pm Revision Data ------------- Index: Login.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Login.pm,v retrieving revision 1.23 retrieving revision 1.23.4.1 diff -Llib/WeBWorK/ContentGenerator/Login.pm -Llib/WeBWorK/ContentGenerator/Login.pm -u -r1.23 -r1.23.4.1 --- lib/WeBWorK/ContentGenerator/Login.pm +++ lib/WeBWorK/ContentGenerator/Login.pm @@ -106,12 +106,16 @@ print CGI::startform({-method=>"POST", -action=>$r->uri}); - # write out the form data posted to the requested URI - #print $self->print_form_data('<input type="hidden" name="','" value="',"\"/>\n",qr/^(user|passwd|key|force_passwd_authen)$/); # preserve the form data posted to the requested URI my @fields_to_print = grep { not m/^(user|passwd|key|force_passwd_authen)$/ } $r->param; - print $self->hidden_fields(@fields_to_print); + + #FIXME: This next line can be removed in time. MEG 1/27/2005 + warn "Error in filtering fields : |", join("|",@fields_to_print),"|" if grep {m/user/} @fields_to_print; + + # Important note. If hidden_fields is passed an empty array it prints ALL parameters as hidden fields. + # That is not what we want in this case, so we don't print at all if @fields_to_print is empty. + print $self->hidden_fields(@fields_to_print) if @fields_to_print > 0; print CGI::table({class=>"FormLayout"}, CGI::Tr([ |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 15:58:42
|
Log Message: ----------- Removed the reference to float in div.problemHeader to see if this removes the peekaboo problem. Also removed the zoom statement which seems to have been causing trouble with the OL statement. Tags: ---- rel-2-1-patches 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.1.2.1 retrieving revision 1.1.2.2 diff -Lhtdocs/css/ur.css -Lhtdocs/css/ur.css -u -r1.1.2.1 -r1.1.2.2 --- htdocs/css/ur.css +++ htdocs/css/ur.css @@ -1,5 +1,5 @@ /* hack to get around MSIE peekaboo bug */ -* {zoom: 1;} +/* * {zoom: 1;} */ /********************/ /* template classes */ @@ -127,6 +127,7 @@ padding: 2px 5px 2px 5px; width: auto; } -div.problemHeader { float: left; } +# div.problemHeader { float: left; } # suspected of causing MSIE peekaboo bug +div.problemHeader {} div.problem { clear: both; background-color: #E0E0E0; color: black; } .parsehilight { background-color:yellow; } |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 15:42:50
|
Log Message: ----------- Backporting CSS changes to rel-2-1-patches Tags: ---- rel-2-1-patches Added Files: ----------- webwork2/htdocs/css: ur.css Revision Data ------------- --- /dev/null +++ htdocs/css/ur.css @@ -0,0 +1,132 @@ +/* hack to get around MSIE peekaboo bug */ +* {zoom: 1;} + +/********************/ +/* template classes */ +/********************/ + +body { margin: 0px; } + +/* left table cell, contains logo and menus */ +td.LeftPanel { background-color: #003366; color: white; white-space: nowrap; width: 1em; } +td.LeftPanel a:link, +td.LeftPanel a:visited { color: #FF9933; } + +div.Logo { } +div.Links { font-size: small; } +div.Siblings { font-size: small; } +div.Options { font-size: small; } + +/* top table cell, contains login message and path */ +td.TopPanel { background-color: #003366; color: white; height: 1; } +td.TopPanel a:link, +td.TopPanel a:visited { color: #FF9933; } + + +*.LoginStatus { text-align: right; font-size: small; position:absolute; right: 0; } +td.Timestamp { text-align: left; font-size: small; font-style: italic; } + +*.Path { } + +/* main content panel, contains body */ +td.ContentPanel { background-color: white; color: black; } +td.ContentPanel a:link, +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.Body { } +div.Warnings { } + +/* background colors for success and failure messages */ +div.ResultsWithoutError { background-color: #66ff99 } /* light green */ +div.ResultsWithError { background-color: #ffcccc } /* light red */ + +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; } + + + +/* 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 */ +/************************/ + +/* tables used for laying out form fields shouldn't have a border */ +table.FormLayout { border: 0; } +table.FormLayout tr { vertical-align: top; } +table.FormLayout th.LeftHeader { text-align: right; white-space: nowrap; } +table.FormLayout tr.ButtonRow { text-align: left; } +table.FormLayout tr.ButtonRowCenter { text-align: center; } + +/* for problems which are rendered by themselves, e.g., by Set Maker */ +div.RenderSolo { background-color: #E0E0E0; 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; } + +/*************************/ +/* WeBWorK::HTML widgets */ +/*************************/ + +/* 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?) */ +/*************************************************************************/ + +table.attemptResults { + border-style: outset; + border-width: 1px; + margin: 0px 10pt; + border-spacing: 1px; +} +table.attemptResults td, +table.attemptResults th { + border-style: inset; + border-width: 1px; + text-align: center; +# width: 15ex; + padding: 2px 5px 2px 5px; + background-color: #DDDDDD; +} +table.attemptResults td.Message { + text-align: left; + padding: 2px 5px 2px 5px; + width: auto; +} +div.problemHeader { float: left; } +div.problem { clear: both; background-color: #E0E0E0; color: black; } +.parsehilight { background-color:yellow; } |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 15:40:26
|
Log Message: ----------- Backporting CSS changes to 2-1-patches Tags: ---- rel-2-1-patches 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.34.2.2 retrieving revision 1.34.2.3 diff -Lconf/templates/ur.template -Lconf/templates/ur.template -u -r1.34.2.2 -r1.34.2.3 --- conf/templates/ur.template +++ conf/templates/ur.template @@ -25,142 +25,15 @@ <head> <title><!--#path style="text" text=" : " textonly="1"--></title> <!--#head--> -<style type="text/css"> - -/* hack to get around MSIE peekaboo bug */ -* {zoom: 1;} - -/********************/ -/* template classes */ -/********************/ - -body { margin: 0px; } - -/* left table cell, contains logo and menus */ -td.LeftPanel { background-color: #003366; color: white; white-space: nowrap; width: 1em; } -td.LeftPanel a:link, -td.LeftPanel a:visited { color: #FF9933; } - -div.Logo { } -div.Links { font-size: small; } -div.Siblings { font-size: small; } -div.Options { font-size: small; } - -/* top table cell, contains login message and path */ -td.TopPanel { background-color: #003366; color: white; height: 1; } -td.TopPanel a:link, -td.TopPanel a:visited { color: #FF9933; } - - -*.LoginStatus { text-align: right; font-size: small; position:absolute; right: 0; } -td.Timestamp { text-align: left; font-size: small; font-style: italic; } - -*.Path { } - -/* main content panel, contains body */ -td.ContentPanel { background-color: white; color: black; } -td.ContentPanel a:link, -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.Body { } -div.Warnings { } - -/* background colors for success and failure messages */ -div.ResultsWithoutError { background-color: #66ff99 } /* light green */ -div.ResultsWithError { background-color: #ffcccc } /* light red */ - -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 */ - -/* 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 */ -/************************/ - -/* tables used for laying out form fields shouldn't have a border */ -table.FormLayout { border: 0; } -table.FormLayout tr { vertical-align: top; } -table.FormLayout th.LeftHeader { text-align: right; white-space: nowrap; } -table.FormLayout tr.ButtonRow { text-align: left; } -table.FormLayout tr.ButtonRowCenter { text-align: center; } - -/* for problems which are rendered by themselves, e.g., by Set Maker */ -div.RenderSolo { background-color: #E0E0E0; 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; } - -/*************************/ -/* WeBWorK::HTML widgets */ -/*************************/ - -/* 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?) */ -/*************************************************************************/ - -table.attemptResults { - border-style: outset; - border-width: 1px; - margin: 0px 10pt; - border-spacing: 1px; -} -table.attemptResults td, -table.attemptResults th { - border-style: inset; - border-width: 1px; - text-align: center; -# width: 15ex; - padding: 2px 5px 2px 5px; - background-color: #DDDDDD; -} -table.attemptResults td.Message { - text-align: left; - padding: 2px 5px 2px 5px; - width: auto; -} -div.problemHeader { float: left; } -div.problem { clear: both; background-color: #E0E0E0; color: black; } -.parsehilight { background-color:yellow; } - -</style> +<style type="text/css" media="all">@import "<!--#url type="webwork" name="stylesheet"-->";</style> </head> <body> <table width="100%" cellpadding="10" cellspacing="0" border="0"> <tr valign="top"> <td align="left" valign="top" rowspan="2" class="LeftPanel"> + <a href="http://webwork.math.rochester.edu"> <img src="/webwork2_files/images/webwork_square.gif" alt="WeBWorK" height="64" width="66" /> + </a> <span style="position:relative;top: -44px; right: -10px"> <!--#help--> </span> @@ -275,4 +148,5 @@ </tr> </table> </body> + </html> |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 15:37:23
|
Log Message: ----------- backporting this file Modified Files: -------------- webwork2/conf/snippets: blankProblem.pg Revision Data ------------- Index: blankProblem.pg =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/snippets/blankProblem.pg,v retrieving revision 1.1 retrieving revision 1.2 diff -Lconf/snippets/blankProblem.pg -Lconf/snippets/blankProblem.pg -u -r1.1 -r1.2 |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 15:34:29
|
Log Message: ----------- Backporting entries that support CSS and the new blank problem snippet. Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/conf: global.conf.dist Revision Data ------------- Index: global.conf.dist =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/global.conf.dist,v retrieving revision 1.111.2.4 retrieving revision 1.111.2.5 diff -Lconf/global.conf.dist -Lconf/global.conf.dist -u -r1.111.2.4 -r1.111.2.5 --- conf/global.conf.dist +++ conf/global.conf.dist @@ -28,7 +28,7 @@ ################################################################################ # Set these variables to correspond to your configuration and preferences. You -# will need to restart the webserver to reset the variables in this section +# will need to restart the webserver to reset the variables in this section. # URL of WeBWorK handler. $webwork_url = "/webwork2"; @@ -49,6 +49,7 @@ ################################################################################ $externalPrograms{mkdir} = "/bin/mkdir"; +$externalPrograms{mv} = "/bin/mv"; $externalPrograms{mysql} = "/usr/local/bin/mysql"; $externalPrograms{latex} = "/usr/local/bin/latex"; @@ -162,6 +163,9 @@ # URL of WeBWorK Bugzilla database. $webworkURLs{bugReporter} = "http://bugs.webwork.rochester.edu/"; +# Location of CSS +$webworkURLs{stylesheet} = "$webworkURLs{htdocs}/css/ur.css"; + # Location of jsMath script, used for the jsMath display mode. $webworkURLs{jsMath} = "$webworkURLs{htdocs}/jsMath/jsMath.js"; @@ -252,6 +256,9 @@ # The set header is displayed on the problem set page. It is a PG file. $webworkFiles{screenSnippets}{setHeader} = "$webworkDirs{conf}/snippets/setHeader.pg"; # screenSetHeader.pg" +# A PG template for creation of new problems. +$webworkFiles{screenSnippets}{blankProblem} = "$webworkDirs{conf}/snippets/blankProblem.pg"; # screenSetHeader.pg" + ################################################################################ # Course-specific files ################################################################################ @@ -407,10 +414,11 @@ ################################################################################ # This lets you specify a minimum permission level needed to perform certain -# actions. In the current system, >=10 will allow a professor to perform the -# action, >=5 will allow a TA to, and >=0 will allow a student to perform an -# action (almost never what you want). +# actions. For each pair in the hash below, in order to perform the action +# described by the key, the user must have a permission level greater than or +# equal to the value. +my $guest = -1; my $student = 0; my $ta = 5; my $professor = 10; |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 15:31:02
|
Log Message: ----------- Backporting updates: Maintain displayOptions when following links. Allows one to view the default set headers in the PG editor. From there one can save the header locally and edit it. Tags: ---- rel-2-1-patches Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: ProblemSet.pm ProblemSets.pm Revision Data ------------- Index: ProblemSet.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/ProblemSet.pm,v retrieving revision 1.58 retrieving revision 1.58.2.1 diff -Llib/WeBWorK/ContentGenerator/ProblemSet.pm -Llib/WeBWorK/ContentGenerator/ProblemSet.pm -u -r1.58 -r1.58.2.1 --- lib/WeBWorK/ContentGenerator/ProblemSet.pm +++ lib/WeBWorK/ContentGenerator/ProblemSet.pm @@ -29,6 +29,7 @@ use CGI qw(*ul *li); use WeBWorK::PG; use WeBWorK::Timing; +use URI::Escape; use WeBWorK::Utils qw(sortByName); sub initialize { @@ -50,7 +51,11 @@ die "effective user $effectiveUserName not found. One 'acts as' the effective user." unless $effectiveUser; # FIXME: some day it would be nice to take out this code and consolidate the two checks - + + # get result and send to message + my $status_message = $r->param("status_message"); + $self->addmessage(CGI::p("$status_message")) if $status_message; + # because of the database fix, we have to split our invalidSet check into two parts # First, if $set is undefined then $setName was never valid $self->{invalidSet} = not defined $set; @@ -94,9 +99,11 @@ my $problemSetsPage = $urlpath->parent; my @links = ("Problem Sets" , $r->location . $problemSetsPage->path, "navUp"); - return $self->navMacro($args, "", @links); + my $tail = "&displayMode=".$self->{displayMode}."&showOldAnswers=".$self->{will}->{showOldAnswers}; + return $self->navMacro($args, $tail, @links); } + sub siblings { my ($self) = @_; my $r = $self->r; @@ -124,7 +131,11 @@ foreach my $setID (@setIDs) { my $setPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet", courseID => $courseID, setID => $setID); - print CGI::li(CGI::a({href=>$self->systemLink($setPage)}, $setID)) ; + print CGI::li(CGI::a({href=>$self->systemLink($setPage), + params=>{ displayMode => $self->{displayMode}, + showOldAnswers => $self->{will}->{showOldAnswers} + }}, $setID) + ) ; } $WeBWorK::timer->continue("End printing sets from listUserSets()") if defined $WeBWorK::timer; @@ -205,11 +216,11 @@ }, ); - if (defined($set) and $set->set_header and $authz->hasPermissions($userID, "modify_problem_sets")) { + if (defined($set) and $authz->hasPermissions($userID, "modify_problem_sets")) { #FIXME ? can't edit the default set header this way my $editorPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", courseID => $courseID, setID => $set->set_id, problemID => 0); - my $editorURL = $self->systemLink($editorPage); + my $editorURL = $self->systemLink($editorPage, params => { file_type => 'set_header'}); print CGI::p(CGI::b("Set Info"), " ", CGI::a({href=>$editorURL}, "[edit]")); @@ -336,7 +347,11 @@ my $interactiveURL = $self->systemLink( $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", - courseID => $courseID, setID => $setID, problemID => $problemID) + courseID => $courseID, setID => $setID, problemID => $problemID + ), + params=>{ displayMode => $self->{displayMode}, + showOldAnswers => $self->{will}->{showOldAnswers} + } ); my $interactive = CGI::a({-href=>$interactiveURL}, "Problem $problemID"); Index: ProblemSets.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/ProblemSets.pm,v retrieving revision 1.56 retrieving revision 1.56.2.1 diff -Llib/WeBWorK/ContentGenerator/ProblemSets.pm -Llib/WeBWorK/ContentGenerator/ProblemSets.pm -u -r1.56 -r1.56.2.1 --- lib/WeBWorK/ContentGenerator/ProblemSets.pm +++ lib/WeBWorK/ContentGenerator/ProblemSets.pm @@ -61,8 +61,12 @@ } else { print CGI::p(CGI::b("Course Info")); } - - if (-f $course_info_path) { + unless (-e $course_info_path) { # FIXME + `echo "" >$course_info_path`; # we seem to need to have this file + # around to prevent + # spurious errors when editing it. + } + if (-f $course_info_path) { #check that it's a plain file my $text = eval { readFile($course_info_path) }; if ($@) { print CGI::div({class=>"ResultsWithError"}, @@ -84,6 +88,26 @@ $name =~ s/\s/_/g; $self->helpMacro($name); } +sub initialize { + + + +# get result and send to message + my ($self) = @_; + my $r = $self->r; + my $authz = $r->authz; + my $urlpath = $r->urlpath; + + my $user = $r->param("user"); + my $effectiveUser = $r->param("effectiveUser"); + if ($authz->hasPermissions($user, "access_instructor_tools")) { + # get result and send to message + my $status_message = $r->param("status_message"); + $self->addmessage(CGI::p("$status_message")) if $status_message; + + + } +} sub body { my ($self) = @_; my $r = $self->r; @@ -202,7 +226,11 @@ my $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet", courseID => $courseName, setID => $name); - my $interactiveURL = $self->systemLink($problemSetPage); + my $interactiveURL = $self->systemLink($problemSetPage, + params=>{ displayMode => $self->{displayMode}, + showOldAnswers => $self->{will}->{showOldAnswers} + } + ); my $openDate = $self->formatDateTime($set->open_date); my $dueDate = $self->formatDateTime($set->due_date); |
From: Mike G. v. a. <we...@ma...> - 2005-02-06 01:40:57
|
Log Message: ----------- Back porting changes made to ContentGenerator.pm. These include: preserving display options through links. Moving definition of options menu up to ContentGenerator. Allowing warnings to contain HTML in order to display tables used when debugging fun_cmp calls. Tags: ---- rel-2-1-patches 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.123.2.2 retrieving revision 1.123.2.3 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.123.2.2 -r1.123.2.3 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -49,6 +49,7 @@ use Date::Format; use URI::Escape; use WeBWorK::Template qw(template); +use WeBWorK::PG; ############################################################################### @@ -294,7 +295,7 @@ =cut -# FIXME: we should probably + sub addmessage { my ($self, $message) = @_; @@ -487,16 +488,27 @@ 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::li(CGI::span({style=>"font-size:larger"}, - CGI::a({href=>$self->systemLink($sets)}, sp2nbsp("Homework Sets")))); + CGI::a({href=>$self->systemLink($sets, + params=>{ %displayOptions,} + )}, sp2nbsp("Homework Sets"))) + ); if ($authz->hasPermissions($user, "change_password") or $authz->hasPermissions($user, "change_email_address")) { - print CGI::li(CGI::a({href=>$self->systemLink($options)}, sp2nbsp($options->name))); + print CGI::li(CGI::a({href=>$self->systemLink($options, + params=>{ %displayOptions,} + ) + }, sp2nbsp($options->name)) + ); } - print CGI::li(CGI::a({href=>$self->systemLink($grades)}, sp2nbsp($grades->name))); + 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))); if ($authz->hasPermissions($user, "access_instructor_tools")) { @@ -534,55 +546,54 @@ my $fileMgr = $urlpath->newFromModule("${ipfx}FileManager", %args); - my $fileXfer = $urlpath->newFromModule("${ipfx}FileXfer", %args); + #my $fileXfer = $urlpath->newFromModule("${ipfx}FileXfer", %args); print CGI::hr(); print CGI::start_li(); print CGI::span({style=>"font-size:larger"}, - CGI::a({href=>$self->systemLink($instr)}, space2nbsp($instr->name)) + CGI::a({href=>$self->systemLink($instr,params=>{ %displayOptions,})}, space2nbsp($instr->name)) ); print CGI::start_ul(); - #print CGI::li(CGI::a({href=>$self->systemLink($addUsers)}, sp2nbsp($addUsers->name))) if $authz->hasPermissions($user, "modify_student_data"); - print CGI::li(CGI::a({href=>$self->systemLink($userList)}, sp2nbsp($userList->name))); + print CGI::li(CGI::a({href=>$self->systemLink($userList,params=>{ %displayOptions,})}, sp2nbsp($userList->name))); print CGI::start_li(); - print CGI::a({href=>$self->systemLink($setList)}, sp2nbsp($setList->name)); + print CGI::a({href=>$self->systemLink($setList,params=>{ %displayOptions,})}, sp2nbsp($setList->name)); if (defined $setID and $setID ne "") { print CGI::start_ul(); print CGI::start_li(); - print CGI::a({href=>$self->systemLink($setDetail)}, $setID); + print 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)}, $problemID)) + CGI::li(CGI::a({href=>$self->systemLink($problemEditor,params=>{ %displayOptions,})}, $problemID)) ); } print CGI::end_li(); print CGI::end_ul(); } print CGI::end_li(); - print CGI::li(CGI::a({href=>$self->systemLink($maker)}, sp2nbsp($maker->name))) if $authz->hasPermissions($user, "modify_problem_sets"); - print CGI::li(CGI::a({href=>$self->systemLink($assigner)}, sp2nbsp($assigner->name))) if $authz->hasPermissions($user, "assign_problem_sets"); + 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"); - print CGI::li(CGI::a({href=>$self->systemLink($stats)}, sp2nbsp($stats->name))); + print CGI::li(CGI::a({href=>$self->systemLink($stats,params=>{ %displayOptions,})}, sp2nbsp($stats->name))); ## Added Link for Student Progress - print CGI::li(CGI::a({href=>$self->systemLink($progress)}, sp2nbsp($progress->name))); + print CGI::li(CGI::a({href=>$self->systemLink($progress,params=>{ %displayOptions,})}, sp2nbsp($progress->name))); print CGI::start_li(); if (defined $userID and $userID ne "") { print CGI::ul( - CGI::li(CGI::a({href=>$self->systemLink($userProgress)}, $userID)) + CGI::li(CGI::a({href=>$self->systemLink($userProgress,params=>{ %displayOptions,})}, $userID)) ); } if (defined $setID and $setID ne "") { print CGI::ul( - CGI::li(CGI::a({href=>$self->systemLink($setProgress)}, space2nbsp($setID))) + CGI::li(CGI::a({href=>$self->systemLink($setProgress,params=>{ %displayOptions,})}, space2nbsp($setID))) ); } print CGI::end_li(); - print CGI::li(CGI::a({href=>$self->systemLink($scoring)}, sp2nbsp($scoring->name))) if $authz->hasPermissions($user, "score_sets"); - print CGI::li(CGI::a({href=>$self->systemLink($mail)}, sp2nbsp($mail->name))) if $authz->hasPermissions($user, "send_mail"); - print CGI::li(CGI::a({href=>$self->systemLink($fileMgr)}, sp2nbsp($fileMgr->name))); - print CGI::li(CGI::a({href=>$self->systemLink($fileXfer)}, sp2nbsp($fileXfer->name))); + print CGI::li(CGI::a({href=>$self->systemLink($scoring,params=>{ %displayOptions,})}, sp2nbsp($scoring->name))) if $authz->hasPermissions($user, "score_sets"); + 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))); + #print CGI::li(CGI::a({href=>$self->systemLink($fileXfer)}, sp2nbsp($fileXfer->name))); print CGI::li( $self->helpMacro('instructor_links')); print CGI::end_ul(); @@ -664,11 +675,105 @@ =item options() -Not defined in this package. Print an auxiliary options form, related to the content displayed in the C<body>. +=cut + +sub options { + my ($self) = @_; + + return "" if $self->{invalidProblem}; + my $sourceFilePathfield = ''; + if($self->r->param("sourceFilePath")) { + $sourceFilePathfield = CGI::hidden(-name => "sourceFilePath", + -value => $self->r->param("sourceFilePath")); + } + + my $r = $self->{r}; + my $ce = $self->{ce}; + # insure that certain defaults are defined + $self->{must} = {} unless defined $self->{must}; + $self->{can} = {} unless defined $self->{can}; + $self->{will} = {} unless defined $self->{will}; + + # displayMode + my $displayMode = $r->param("displayMode") || $ce->{pg}->{options}->{displayMode}; + $self->{displayMode} = $displayMode unless defined $self->{displayMode}; + + # showOldAnswers + my $want_to_showOldAnswers = defined($r->param("showOldAnswers")) ? + $r->param("showOldAnswers") : $ce->{pg}->{options}->{showOldAnswers}; + $self->{can}->{showOldAnswers} = 1; + $self->{will}->{showOldAnswers} = $self->{can}->{showOldAnswers} && $want_to_showOldAnswers; + + 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() + ); +} + +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}; + + my $displayMode = $self->{displayMode}; + my %must = %{ $self->{must} }; + my %can = %{ $self->{can} }; + my %will = %{ $self->{will} }; + + my $optionLine; + $can{showOldAnswers} and $optionLine .= join "", + "Show saved answers?".CGI::br(), + CGI::radio_group( + -name => "showOldAnswers", + -values => [1,0], + -default => $will{showOldAnswers}, + -labels => { + 0 => 'No', + 1 => 'Yes', + }, + ), .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"), + ); +} + =item path($args) Defined in this package. @@ -778,6 +883,7 @@ print "\n<!-- BEGIN " . __PACKAGE__ . "::message -->\n"; print $self->{status_message} if exists $self->{status_message}; + print "<!-- END " . __PACKAGE__ . "::message -->\n"; return ""; @@ -839,18 +945,45 @@ my $self = shift; my $args = shift; my $name = $args->{name}; - + # old naming scheme #$name = lc($self->r->urlpath->name) unless defined($name); #$name =~ s/\s/_/g; - + $name = $self->r->urlpath->module unless defined($name); $name =~ s/WeBWorK::ContentGenerator:://; $name =~ s/://g; - + $self->helpMacro($name); } +=item url($args) + +Defined in this package. + +Returns the specified URL from either %webworkURLs or %courseURLs in the course +environment. $args is a reference to a hash containing the following fields: + + type => type of URL: webwork|course + name => name of URL (key in URL hash) + +=cut + +sub url { + my ($self, $args) = @_; + my $ce = $self->r->ce; + my $type = $args->{type}; + my $name = $args->{name}; + + if ($type eq "webwork") { + return $ce->{webworkURLs}->{$name}; + } elsif ($type eq "course") { + return $ce->{courseURLs}->{$name}; + } else { + warn __PACKAGE__."::url: unrecognized type '$type'.\n"; + } +} + =back =cut @@ -1264,6 +1397,19 @@ return $self->url_args("user", "effectiveUser", "key"); } +=item url_display_args() + +Use url_args to return a URL query string for request fields used in +authentication. + +=cut + +sub url_display_args { + my ($self) = @_; + + return $self->url_args("displayMode", "showOldAnswer"); +} + =item print_form_data($begin, $middle, $end, $omit) Return a string containing every request field not matched by the quoted reguar @@ -1379,7 +1525,16 @@ @values = $r->param($name); } #FIXME -- evntually we'd like to catch where this happens - croak "internal error -- user has been multiply defined!" if $name eq 'user' and @values >1; + if ($name eq 'user' and @values >1 ) { + warn "internal error -- user has been multiply defined! You may need to logout and log back in to correct this."; + my $user = $r->param("user"); + $r->param(user => $user); + @values = ($user); + warn "requesting page is ", $r->headers_in->{'Referer'}; + warn "Parameters are ", join("|",$r->param()); + + } + if (@values) { if ($first) { $url .= "?"; @@ -1487,7 +1642,7 @@ my @warnings = split m/\n+/, $warnings; foreach my $warning (@warnings) { - $warning = escapeHTML($warning); + #$warning = escapeHTML($warning); # this would prevent using tables in output from answer evaluators $warning = CGI::li(CGI::code($warning)); } $warnings = join("", @warnings); |
From: jj v. a. <we...@ma...> - 2005-02-05 14:24:25
|
Log Message: ----------- Work around IE bug for ordered lists. Maybe someday this can be undone. Modified Files: -------------- pg/macros: PGchoicemacros.pl PGbasicmacros.pl Revision Data ------------- Index: PGbasicmacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGbasicmacros.pl,v retrieving revision 1.35 retrieving revision 1.36 diff -Lmacros/PGbasicmacros.pl -Lmacros/PGbasicmacros.pl -u -r1.35 -r1.36 --- macros/PGbasicmacros.pl +++ macros/PGbasicmacros.pl @@ -1660,25 +1660,33 @@ sub OL { my(@array) = @_; my $i = 0; + my @alpha = ("A".."Z"); + my $letter; my $out= &M3( "\\begin{enumerate}\n", " \\begin{rawhtml} <OL TYPE=\"A\" VALUE=\"1\"> \\end{rawhtml} ", - "<OL TYPE=\"A\" VALUE=\"1\">\n" + # kludge to fix IE/CSS problem + #"<OL TYPE=\"A\" VALUE=\"1\">\n" + "<BLOCKQUOTE>\n" ) ; my $elem; foreach $elem (@array) { + $letter = shift @alpha; $out .= MODES( TeX=> "\\item[$ALPHABET[$i].] $elem\n", Latex2HTML=> " \\begin{rawhtml} <LI> \\end{rawhtml} $elem ", - HTML=> "<LI> $elem\n", - HTML_dpng=> "<LI> $elem <br /> <br /> \n" + #HTML=> "<LI> $elem\n", + HTML=> "<br /> <b>$letter.</b> $elem\n", + #HTML_dpng=> "<LI> $elem <br /> <br /> \n" + HTML_dpng=> "<br /> <b>$letter.</b> $elem \n" ); $i++; } $out .= &M3( "\\end{enumerate}\n", " \\begin{rawhtml} </OL>\n \\end{rawhtml} ", - "</OL>\n" + #"</OL>\n" + "</BLOCKQUOTE>\n" ) ; } Index: PGchoicemacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGchoicemacros.pl,v retrieving revision 1.5 retrieving revision 1.6 diff -Lmacros/PGchoicemacros.pl -Lmacros/PGchoicemacros.pl -u -r1.5 -r1.6 --- macros/PGchoicemacros.pl +++ macros/PGchoicemacros.pl @@ -528,24 +528,31 @@ my $self = shift; my(@array) = @_; my $i = 0; + my @alpha = ("A".."Z"); + my $letter; my $out= &main::M3( "\\begin{enumerate}\n", " \\begin{rawhtml} <OL TYPE=\"A\" VALUE=\"1\"> \\end{rawhtml} ", - "<OL COMPACT TYPE=\"A\" START=\"1\">\n" + # kludge to fix IE/CSS problem + #"<OL COMPACT TYPE=\"A\" START=\"1\">\n" + "<BLOCKQUOTE>\n" ) ; my $elem; foreach $elem (@array) { + $letter = shift @alpha; $out .= &main::M3( "\\item[$main::ALPHABET[$i].] $elem\n", " \\begin{rawhtml} <LI> \\end{rawhtml} $elem ", - "<LI> $elem\n" + #"<LI> $elem</LI>\n" + "<br /> <b>$letter.</b> $elem\n" ) ; $i++; } $out .= &main::M3( "\\end{enumerate}\n", " \\begin{rawhtml} </OL>\n \\end{rawhtml} ", - "</OL>\n" + #"</OL>\n" + "</BLOCKQUOTE>\n" ) ; $out; |
From: Mike G. v. a. <we...@ma...> - 2005-02-05 02:04:17
|
Log Message: ----------- Changed formatting when reporting success index. Success index is now reported in % Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: Scoring.pm Revision Data ------------- Index: Scoring.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm,v retrieving revision 1.39 retrieving revision 1.40 diff -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -u -r1.39 -r1.40 --- lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm @@ -460,7 +460,7 @@ } for (my $user = 0; $user < @sortedUserIDs; $user++) { $scoringData[7+$user][$totalsColumn] = sprintf("%4.1f",$userStatusTotals{$user}); - $scoringData[7+$user][$totalsColumn+1] = sprintf("%4.1f",$userSuccessIndex{$user}) if $scoringItems->{successIndex}; + $scoringData[7+$user][$totalsColumn+1] = sprintf("%4.0f",100*$userSuccessIndex{$user}) if $scoringItems->{successIndex}; } } $WeBWorK::timer->continue("End set $setID") if defined($WeBWorK::timer); |
From: Mike G. v. a. <we...@ma...> - 2005-02-05 01:51:15
|
Log Message: ----------- Removed commented out code. Fixed a problem with calculating the success index. (the number of attempts was inappropriately zeroed out with each problem. Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: Stats.pm Revision Data ------------- Index: Stats.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/Stats.pm,v retrieving revision 1.48 retrieving revision 1.49 diff -Llib/WeBWorK/ContentGenerator/Instructor/Stats.pm -Llib/WeBWorK/ContentGenerator/Instructor/Stats.pm -u -r1.48 -r1.49 --- lib/WeBWorK/ContentGenerator/Instructor/Stats.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Stats.pm @@ -334,7 +334,7 @@ foreach my $problemRecord (@problemRecords) { next unless ref($problemRecord); my $probID = $problemRecord->problem_id; - $num_of_attempts = 0; + my $valid_status = 0; unless (defined($problemRecord) ){ @@ -384,7 +384,7 @@ $number_of_attempts_for_problem{$probID} += $num_of_attempts; $correct_answers_for_problem{$probID} += $status; } - + } @@ -396,6 +396,7 @@ my $avg_num_attempts = ($num_of_problems) ? $num_of_attempts/$num_of_problems : 0; my $successIndicator = ($avg_num_attempts) ? ($totalRight/$total)**2/$avg_num_attempts : 0 ; + my $temp_hash = { user_id => $studentRecord->user_id, last_name => $studentRecord->last_name, first_name => $studentRecord->first_name, @@ -531,55 +532,6 @@ } print CGI::end_table(); -##################################################################################### - # construct header -# my $problem_header = ''; -# -# foreach my $i (1..$max_num_problems) { -# $problem_header .= CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>"p$i"})},threeSpaceFill($i) ); -# } -# print -# CGI::p("Details:",CGI::i('The success indicator for each student is calculated as'),CGI::br(), -# '(totalNumberOfCorrectProblems / totalNumberOfProblems)^2/ AvgNumberOfAttemptsPerProblem)',CGI::br(), -# CGI::i('or 0 if there are no attempts.') -# ), -# "Click heading to sort table: ", -# defined($sort_method_name) ?" sort method is $sort_method_name":"", -# CGI::start_table({-border=>5,style=>'font-size:smaller'}), -# CGI::Tr(CGI::td( {-align=>'left'}, -# [CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>'name' })},'Name'), -# CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>'score'})},'Score'), -# 'Out'.CGI::br().'Of', -# CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>'index'})},'Ind'), -# 'Problems'.CGI::br().$problem_header, -# CGI::a({"href"=>$self->systemLink($setStatsPage,params=>{sort=>'section'})},'Section'), -# 'Recitation', -# 'login_name', -# ]) -# -# ); -# -# foreach my $rec (@augmentedUserRecords) { -# my $fullName = join("", $rec->{first_name}," ", $rec->{last_name}); -# my $email = $rec->{email_address}; -# my $twoString = $rec->{twoString}; -# print CGI::Tr( -# CGI::td(CGI::a({-href=>$rec->{act_as_student}},$fullName), CGI::br(), CGI::a({-href=>"mailto:$email"},$email)), -# CGI::td( sprintf("%0.2f",$rec->{score}) ), # score -# CGI::td($rec->{total}), # out of -# CGI::td(sprintf("%0.0f",100*($rec->{index}) )), # indicator -# CGI::td($rec->{problemString}), # problems -# CGI::td($self->nbsp($rec->{section})), -# CGI::td($self->nbsp($rec->{recitation})), -# CGI::td($rec->{user_id}), -# -# ); -# } -# -# print CGI::end_table(); -# - - return ""; } |
From: Mike G. v. a. <we...@ma...> - 2005-02-05 01:49:25
|
Log Message: ----------- minor cleanup -- removed a variable that had been defined twice. Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator: Grades.pm Revision Data ------------- Index: Grades.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Grades.pm,v retrieving revision 1.11 retrieving revision 1.12 diff -Llib/WeBWorK/ContentGenerator/Grades.pm -Llib/WeBWorK/ContentGenerator/Grades.pm -u -r1.11 -r1.12 --- lib/WeBWorK/ContentGenerator/Grades.pm +++ lib/WeBWorK/ContentGenerator/Grades.pm @@ -295,16 +295,15 @@ $longStatus = 'X '; } - my $incorrect = $problemRecord->num_incorrect; $string .= $longStatus; - $twoString .= threeSpaceFill($incorrect); + $twoString .= threeSpaceFill($num_correct); my $probValue = $problemRecord->value; $probValue = 1 unless defined($probValue) and $probValue ne ""; # FIXME?? set defaults here? $total += $probValue; $totalRight += round_score($status*$probValue) if $valid_status; } - + my $avg_num_attempts = ($num_of_problems) ? $num_of_attempts/$num_of_problems : 0; my $successIndicator = ($avg_num_attempts) ? ($totalRight/$total)**2/$avg_num_attempts : 0 ; |
From: Robert V. D. v. a. <we...@ma...> - 2005-02-04 20:20:28
|
Log Message: ----------- Added friendly message when no set is selected. Fixes #750 Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: Scoring.pm Revision Data ------------- Index: Scoring.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm,v retrieving revision 1.38 retrieving revision 1.39 diff -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -u -r1.38 -r1.39 --- lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm @@ -49,13 +49,13 @@ return unless $authz->hasPermissions($user, "access_instructor_tools"); return unless $authz->hasPermissions($user, "score_sets"); - if (defined $r->param('scoreSelected')) { - my @selected = $r->param('selectedSet'); + my @selected = $r->param('selectedSet'); + my $scoreSelected = $r->param('scoreSelected'); + if (defined $scoreSelected && @selected) { + my @totals = (); my $recordSingleSetScores = $r->param('recordSingleSetScores'); - $self->addmessage(CGI::div({class=>'ResultsWithError'},"You must select one or more sets for scoring")) unless @selected; - # pre-fetch users $WeBWorK::timer->continue("pre-fetching users") if defined($WeBWorK::timer); my @Users = $db->getUsers($db->listUsers); @@ -94,7 +94,10 @@ my @sum_scores = $self->sumScores(\@totals, $showIndex, \%Users, \@sortedUserIDs); $self->appendColumns( \@totals,\@sum_scores); $self->writeCSV("$scoringDir/${courseName}_totals.csv", @totals); - } + + } elsif (defined $scoreSelected) { + $self->addbadmessage("You must select one or more sets for scoring"); + } # Obtaining list of sets: #$WeBWorK::timer->continue("Begin listing sets") if defined $WeBWorK::timer; |