version 1.80, 2002/02/04 10:30:58
|
version 1.93, 2002/07/04 17:51:32
|
Line 508 sub HASH {
|
Line 508 sub HASH {
|
return $Values[-1]; |
return $Values[-1]; |
} |
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=item NUM(range) |
|
|
|
returns the number of items in the range. |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub NUM { |
sub NUM { |
my $mask=mask(@_); |
my $mask=mask(@_); |
my $num= $#{@{grep(/$mask/,keys(%v))}}+1; |
my $num= $#{@{grep(/$mask/,keys(%v))}}+1; |
Line 527 sub BIN {
|
Line 536 sub BIN {
|
} |
} |
|
|
|
|
|
#------------------------------------------------------- |
|
|
|
=item SUM(range) |
|
|
|
returns the sum of items in the range. |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub SUM { |
sub SUM { |
my $mask=mask(@_); |
my $mask=mask(@_); |
my $sum=0; |
my $sum=0; |
Line 536 sub SUM {
|
Line 554 sub SUM {
|
return $sum; |
return $sum; |
} |
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=item MEAN(range) |
|
|
|
compute the average of the items in the range. |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub MEAN { |
sub MEAN { |
my $mask=mask(@_); |
my $mask=mask(@_); |
my $sum=0; my $num=0; |
my $sum=0; my $num=0; |
Line 550 sub MEAN {
|
Line 577 sub MEAN {
|
} |
} |
} |
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=item STDDEV(range) |
|
|
|
compute the standard deviation of the items in the range. |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub STDDEV { |
sub STDDEV { |
my $mask=mask(@_); |
my $mask=mask(@_); |
my $sum=0; my $num=0; |
my $sum=0; my $num=0; |
Line 566 sub STDDEV {
|
Line 602 sub STDDEV {
|
return sqrt($sum/($num-1)); |
return sqrt($sum/($num-1)); |
} |
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=item PROD(range) |
|
|
|
compute the product of the items in the range. |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub PROD { |
sub PROD { |
my $mask=mask(@_); |
my $mask=mask(@_); |
my $prod=1; |
my $prod=1; |
Line 575 sub PROD {
|
Line 620 sub PROD {
|
return $prod; |
return $prod; |
} |
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=item MAX(range) |
|
|
|
compute the maximum of the items in the range. |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub MAX { |
sub MAX { |
my $mask=mask(@_); |
my $mask=mask(@_); |
my $max='-'; |
my $max='-'; |
Line 585 sub MAX {
|
Line 639 sub MAX {
|
return $max; |
return $max; |
} |
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=item MIN(range) |
|
|
|
compute the minimum of the items in the range. |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub MIN { |
sub MIN { |
my $mask=mask(@_); |
my $mask=mask(@_); |
my $min='-'; |
my $min='-'; |
Line 595 sub MIN {
|
Line 658 sub MIN {
|
return $min; |
return $min; |
} |
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=item SUMMAX(num,lower,upper) |
|
|
|
compute the sum of the largest 'num' items in the range from |
|
'lower' to 'upper' |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub SUMMAX { |
sub SUMMAX { |
my ($num,$lower,$upper)=@_; |
my ($num,$lower,$upper)=@_; |
my $mask=mask($lower,$upper); |
my $mask=mask($lower,$upper); |
my @inside=(); |
my @inside=(); |
foreach (grep /$mask/,keys(%v)) { |
foreach (grep /$mask/,keys(%v)) { |
$inside[$#inside+1]=$v{$_}; |
push (@inside,$v{$_}); |
} |
} |
@inside=sort(@inside); |
@inside=sort(@inside); |
my $sum=0; my $i; |
my $sum=0; my $i; |
Line 610 sub SUMMAX {
|
Line 683 sub SUMMAX {
|
return $sum; |
return $sum; |
} |
} |
|
|
|
#------------------------------------------------------- |
|
|
|
=item SUMMIN(num,lower,upper) |
|
|
|
compute the sum of the smallest 'num' items in the range from |
|
'lower' to 'upper' |
|
|
|
=cut |
|
|
|
#------------------------------------------------------- |
sub SUMMIN { |
sub SUMMIN { |
my ($num,$lower,$upper)=@_; |
my ($num,$lower,$upper)=@_; |
my $mask=mask($lower,$upper); |
my $mask=mask($lower,$upper); |
Line 657 sub expandnamed {
|
Line 740 sub expandnamed {
|
return 0; |
return 0; |
} |
} |
} else { |
} else { |
return '$c{\''.$expression.'\'}'; |
# it is not a function, so it is a parameter name |
|
# We should do the following: |
|
# 1. Take the list of parameter names |
|
# 2. look through the list for ones that match the parameter we want |
|
# 3. If there are no collisions, return the one that matches |
|
# 4. If there is a collision, return 'bad parameter name error' |
|
my $returnvalue = ''; |
|
my @matches = (); |
|
$#matches = -1; |
|
study $expression; |
|
foreach $parameter (keys(%c)) { |
|
push @matches,$parameter if ($parameter =~ /$expression/); |
|
} |
|
if ($#matches == 0) { |
|
$returnvalue = '$c{\''.$matches[0].'\'}'; |
|
} else { |
|
$returnvalue = "'bad parameter name : $expression'"; |
|
} |
|
return $returnvalue; |
} |
} |
} |
} |
|
|
Line 677 sub sett {
|
Line 778 sub sett {
|
if ($_=~/A(\d+)/) { |
if ($_=~/A(\d+)/) { |
my $trow=$1; |
my $trow=$1; |
if ($trow) { |
if ($trow) { |
|
# Get the name of this cell |
my $lb=$col.$trow; |
my $lb=$col.$trow; |
|
# Grab the template declaration |
$t{$lb}=$f{'template_'.$col}; |
$t{$lb}=$f{'template_'.$col}; |
|
# Replace '#' with the row number |
$t{$lb}=~s/\#/$trow/g; |
$t{$lb}=~s/\#/$trow/g; |
|
# Replace '....' with ',' |
$t{$lb}=~s/\.\.+/\,/g; |
$t{$lb}=~s/\.\.+/\,/g; |
|
# Replace 'A0' with the value from 'A0' |
$t{$lb}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$v\{\'$2\'\}/g; |
$t{$lb}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$v\{\'$2\'\}/g; |
|
# Replace parameters |
$t{$lb}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.&expandnamed($2)/ge; |
$t{$lb}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.&expandnamed($2)/ge; |
} |
} |
} |
} |
Line 704 sub sett {
|
Line 811 sub sett {
|
} |
} |
} |
} |
} |
} |
|
# For some reason 'A0' gets special treatment... This seems superfluous |
|
# but I imagine it is here for a reason. |
$t{'A0'}=$f{'A0'}; |
$t{'A0'}=$f{'A0'}; |
$t{'A0'}=~s/\.\.+/\,/g; |
$t{'A0'}=~s/\.\.+/\,/g; |
$t{'A0'}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$v\{\'$2\'\}/g; |
$t{'A0'}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$v\{\'$2\'\}/g; |
Line 754 sub outrowassess {
|
Line 863 sub outrowassess {
|
my @cols=(); |
my @cols=(); |
if ($n) { |
if ($n) { |
my ($usy,$ufn)=split(/\_\_\&\&\&\_\_/,$f{'A'.$n}); |
my ($usy,$ufn)=split(/\_\_\&\&\&\_\_/,$f{'A'.$n}); |
|
if ($rl{$usy}) { |
$cols[0]=$rl{$usy}.'<br>'. |
$cols[0]=$rl{$usy}.'<br>'. |
'<select name="sel_'.$n.'" onChange="changesheet('.$n. |
'<select name="sel_'.$n.'" onChange="changesheet('.$n. |
')"><option name="default">Default</option>'; |
')"><option name="default">Default</option>'; |
|
} else { $cols[0]=''; } |
foreach (@os) { |
foreach (@os) { |
$cols[0].='<option name="'.$_.'"'; |
$cols[0].='<option name="'.$_.'"'; |
if ($ufn eq $_) { |
if ($ufn eq $_) { |
Line 774 sub outrowassess {
|
Line 885 sub outrowassess {
|
'n','o','p','q','r','s','t','u','v','w','x','y','z') { |
'n','o','p','q','r','s','t','u','v','w','x','y','z') { |
my $fm=$f{$_.$n}; |
my $fm=$f{$_.$n}; |
$fm=~s/[\'\"]/\&\#34;/g; |
$fm=~s/[\'\"]/\&\#34;/g; |
$cols[$#cols+1]="'$_$n','$fm'".'___eq___'.$v{$_.$n}; |
push(@cols,"'$_$n','$fm'".'___eq___'.$v{$_.$n}); |
} |
} |
return @cols; |
return @cols; |
} |
} |
Line 1133 sub outsheet {
|
Line 1244 sub outsheet {
|
# |
# |
# ----------------------------------------------- Read list of available sheets |
# ----------------------------------------------- Read list of available sheets |
# |
# |
|
|
sub othersheets { |
sub othersheets { |
my ($safeeval,$stype)=@_; |
my ($safeeval,$stype)=@_; |
|
# |
my $cnum=&getcnum($safeeval); |
my $cnum=&getcnum($safeeval); |
my $cdom=&getcdom($safeeval); |
my $cdom=&getcdom($safeeval); |
my $chome=&getchome($safeeval); |
my $chome=&getchome($safeeval); |
|
# |
my @alternatives=(); |
my @alternatives=(); |
my $result=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.':'. |
my %results=&Apache::lonnet::dump($stype.'_spreadsheets',$cdom,$cnum); |
$stype.'_spreadsheets',$chome); |
my ($tmp) = keys(%results); |
if ($result!~/^error\:/) { |
unless ($tmp =~ /^(con_lost|error|no_such_host)/i) { |
foreach (split(/\&/,$result)) { |
@alternatives = sort (keys(%results)); |
$alternatives[$#alternatives+1]= |
} |
&Apache::lonnet::unescape((split(/\=/,$_))[0]); |
|
} |
|
} |
|
return @alternatives; |
return @alternatives; |
} |
} |
|
|
|
|
|
# |
|
# -------------------------------------- Parse a spreadsheet |
|
# |
|
sub parse_sheet { |
|
# $sheetxml is a scalar reference or a scalar |
|
my ($sheetxml) = @_; |
|
if (! ref($sheetxml)) { |
|
my $tmp = $sheetxml; |
|
$sheetxml = \$tmp; |
|
} |
|
my %f; |
|
my $parser=HTML::TokeParser->new($sheetxml); |
|
my $token; |
|
while ($token=$parser->get_token) { |
|
if ($token->[0] eq 'S') { |
|
if ($token->[1] eq 'field') { |
|
$f{$token->[2]->{'col'}.$token->[2]->{'row'}}= |
|
$parser->get_text('/field'); |
|
} |
|
if ($token->[1] eq 'template') { |
|
$f{'template_'.$token->[2]->{'col'}}= |
|
$parser->get_text('/template'); |
|
} |
|
} |
|
} |
|
return \%f; |
|
} |
|
|
# |
# |
# -------------------------------------- Read spreadsheet formulas for a course |
# -------------------------------------- Read spreadsheet formulas for a course |
# |
# |
Line 1164 sub readsheet {
|
Line 1300 sub readsheet {
|
my $cdom=&getcdom($safeeval); |
my $cdom=&getcdom($safeeval); |
my $chome=&getchome($safeeval); |
my $chome=&getchome($safeeval); |
|
|
# --------- There is no filename. Look for defaults in course and global, cache |
if (! defined($fn)) { |
|
# There is no filename. Look for defaults in course and global, cache |
unless($fn) { |
|
unless ($fn=$defaultsheets{$cnum.'_'.$cdom.'_'.$stype}) { |
unless ($fn=$defaultsheets{$cnum.'_'.$cdom.'_'.$stype}) { |
$fn=&Apache::lonnet::reply('get:'.$cdom.':'.$cnum. |
my %tmphash = &Apache::lonnet::get('environment', |
':environment:spreadsheet_default_'.$stype, |
['spreadsheet_default_'.$stype], |
$chome); |
$cdom,$cnum); |
unless (($fn) && ($fn!~/^error\:/)) { |
my ($tmp) = keys(%tmphash); |
$fn='default_'.$stype; |
if ($tmp =~ /^(con_lost|error|no_such_host)/i) { |
} |
$fn = 'default_'.$stype; |
$defaultsheets{$cnum.'_'.$cdom.'_'.$stype}=$fn; |
} else { |
|
$fn = $tmphash{'spreadsheet_default_'.$stype}; |
|
} |
|
unless (($fn) && ($fn!~/^error\:/)) { |
|
$fn='default_'.$stype; |
|
} |
|
$defaultsheets{$cnum.'_'.$cdom.'_'.$stype}=$fn; |
} |
} |
} |
} |
|
|
Line 1193 sub readsheet {
|
Line 1334 sub readsheet {
|
my %f=(); |
my %f=(); |
|
|
if ($fn=~/^default\_/) { |
if ($fn=~/^default\_/) { |
my $sheetxml=''; |
my $sheetxml=''; |
{ |
|
my $fh; |
my $fh; |
my $dfn=$fn; |
my $dfn=$fn; |
$dfn=~s/\_/\./g; |
$dfn=~s/\_/\./g; |
if ($fh=Apache::File->new($includedir.'/'.$dfn)) { |
if ($fh=Apache::File->new($includedir.'/'.$dfn)) { |
$sheetxml=join('',<$fh>); |
$sheetxml=join('',<$fh>); |
} else { |
} else { |
$sheetxml='<field row="0" col="A">"Error"</field>'; |
$sheetxml='<field row="0" col="A">"Error"</field>'; |
} |
} |
} |
%f=%{&parse_sheet(\$sheetxml)}; |
my $parser=HTML::TokeParser->new(\$sheetxml); |
} elsif($fn=~/\/*\.spreadsheet$/) { |
my $token; |
my $sheetxml=&Apache::lonnet::getfile |
while ($token=$parser->get_token) { |
(&Apache::lonnet::filelocation('',$fn)); |
if ($token->[0] eq 'S') { |
if ($sheetxml == -1) { |
if ($token->[1] eq 'field') { |
$sheetxml='<field row="0" col="A">"Error loading spreadsheet ' |
$f{$token->[2]->{'col'}.$token->[2]->{'row'}}= |
.$fn.'"</field>'; |
$parser->get_text('/field'); |
} |
} |
%f=%{&parse_sheet(\$sheetxml)}; |
if ($token->[1] eq 'template') { |
} else { |
$f{'template_'.$token->[2]->{'col'}}= |
my $sheet=''; |
$parser->get_text('/template'); |
my %tmphash = &Apache::lonnet::dump($fn,$cdom,$cnum); |
|
my ($tmp) = keys(%tmphash); |
|
unless ($tmp =~ /^(con_lost|error|no_such_host)/i) { |
|
foreach (keys(%tmphash)) { |
|
$f{$_}=$tmphash{$_}; |
} |
} |
} |
} |
} |
} |
} else { |
|
my $sheet=''; |
|
my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.':'.$fn, |
|
$chome); |
|
unless ($reply=~/^error\:/) { |
|
$sheet=$reply; |
|
} |
|
foreach (split(/\&/,$sheet)) { |
|
my ($name,$value)=split(/\=/,$_); |
|
$f{&Apache::lonnet::unescape($name)}= |
|
&Apache::lonnet::unescape($value); |
|
} |
|
} |
|
# --------------------------------------------------------------- Cache and set |
# --------------------------------------------------------------- Cache and set |
$spreadsheets{$cnum.'_'.$cdom.'_'.$stype.'_'.$fn}=join('___;___',%f); |
$spreadsheets{$cnum.'_'.$cdom.'_'.$stype.'_'.$fn}=join('___;___',%f); |
&setformulas($safeeval,%f); |
&setformulas($safeeval,%f); |
Line 1337 sub tmpread {
|
Line 1468 sub tmpread {
|
$fn=$tmpdir.$fn.'.tmp'; |
$fn=$tmpdir.$fn.'.tmp'; |
my $fh; |
my $fh; |
my %fo=(); |
my %fo=(); |
|
my $countrows=0; |
if ($fh=Apache::File->new($fn)) { |
if ($fh=Apache::File->new($fn)) { |
my $name; |
my $name; |
while ($name=<$fh>) { |
while ($name=<$fh>) { |
Line 1344 sub tmpread {
|
Line 1476 sub tmpread {
|
my $value=<$fh>; |
my $value=<$fh>; |
chomp($value); |
chomp($value); |
$fo{$name}=$value; |
$fo{$name}=$value; |
|
if ($name=~/^A(\d+)$/) { |
|
if ($1>$countrows) { |
|
$countrows=$1; |
|
} |
|
} |
} |
} |
} |
} |
if ($nform eq 'changesheet') { |
if ($nform eq 'changesheet') { |
Line 1351 sub tmpread {
|
Line 1488 sub tmpread {
|
unless ($ENV{'form.sel_'.$nfield} eq 'Default') { |
unless ($ENV{'form.sel_'.$nfield} eq 'Default') { |
$fo{'A'.$nfield}.='__&&&__'.$ENV{'form.sel_'.$nfield}; |
$fo{'A'.$nfield}.='__&&&__'.$ENV{'form.sel_'.$nfield}; |
} |
} |
|
} elsif ($nfield eq 'insertrow') { |
|
$countrows++; |
|
if ($nform eq 'top') { |
|
$fo{'A'.$countrows}='AAAAA_'.$countrows; |
|
} else { |
|
$fo{'A'.$countrows}='zzzzz_'.$countrows; |
|
} |
} else { |
} else { |
if ($nfield) { $fo{$nfield}=$nform; } |
if ($nfield) { $fo{$nfield}=$nform; } |
} |
} |
Line 2271 $tmpdir=$r->dir_config('lonDaemons').'/t
|
Line 2415 $tmpdir=$r->dir_config('lonDaemons').'/t
|
|
|
# --------------------------- Get query string for limited number of parameters |
# --------------------------- Get query string for limited number of parameters |
|
|
foreach (split(/&/,$ENV{'QUERY_STRING'})) { |
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, |
my ($name, $value) = split(/=/,$_); |
['uname','udom','usymb','ufn']); |
$value =~ tr/+/ /; |
|
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; |
|
if (($name eq 'uname') || ($name eq 'udom') || |
|
($name eq 'usymb') || ($name eq 'ufn')) { |
|
unless ($ENV{'form.'.$name}) { |
|
$ENV{'form.'.$name}=$value; |
|
} |
|
} |
|
} |
|
|
|
if (($ENV{'form.usymb'}=~/^\_(\w+)/) && (!$ENV{'form.ufn'})) { |
if (($ENV{'form.usymb'}=~/^\_(\w+)/) && (!$ENV{'form.ufn'})) { |
$ENV{'form.ufn'}='default_'.$1; |
$ENV{'form.ufn'}='default_'.$1; |
Line 2319 $tmpdir=$r->dir_config('lonDaemons').'/t
|
Line 2454 $tmpdir=$r->dir_config('lonDaemons').'/t
|
|
|
function celledit(cn,cf) { |
function celledit(cn,cf) { |
var cnf=prompt(cn,cf); |
var cnf=prompt(cn,cf); |
if (cnf!=null) { |
if (cnf!=null) { |
document.sheet.unewfield.value=cn; |
document.sheet.unewfield.value=cn; |
document.sheet.unewformula.value=cnf; |
document.sheet.unewformula.value=cnf; |
document.sheet.submit(); |
document.sheet.submit(); |
} |
} |
Line 2332 $tmpdir=$r->dir_config('lonDaemons').'/t
|
Line 2467 $tmpdir=$r->dir_config('lonDaemons').'/t
|
document.sheet.submit(); |
document.sheet.submit(); |
} |
} |
|
|
|
function insertrow(cn) { |
|
document.sheet.unewfield.value='insertrow'; |
|
document.sheet.unewformula.value=cn; |
|
document.sheet.submit(); |
|
} |
|
|
</script> |
</script> |
ENDSCRIPT |
ENDSCRIPT |
$r->print('</head><body bgcolor="#FFFFFF">'. |
$r->print('</head><body bgcolor="#FFFFFF">'. |
Line 2548 ENDSCRIPT
|
Line 2689 ENDSCRIPT
|
} |
} |
} |
} |
$r->print('>'); |
$r->print('>'); |
|
|
if (&gettype($asheet) eq 'classcalc') { |
if (&gettype($asheet) eq 'classcalc') { |
$r->print( |
$r->print( |
' Output CSV format: <input type=checkbox name=showcsv onClick="submit()"'); |
' Output CSV format: <input type=checkbox name=showcsv onClick="submit()"'); |
if ($ENV{'form.showcsv'}) { $r->print(' checked'); } |
if ($ENV{'form.showcsv'}) { $r->print(' checked'); } |
$r->print('>'); |
$r->print('>'); |
} |
} |
|
|
|
# ------------------------------------------------------------------ Insertrows |
|
|
|
$r->print(<<ENDINSERTBUTTONS); |
|
<br> |
|
<input type='button' onClick='insertrow("top");' |
|
value='Insert Row Top'> |
|
<input type='button' onClick='insertrow("bottom");' |
|
value='Insert Row Bottom'><br> |
|
ENDINSERTBUTTONS |
|
|
# ------------------------------------------------------------- Print out sheet |
# ------------------------------------------------------------- Print out sheet |
|
|
&outsheet($r,$asheet); |
&outsheet($r,$asheet); |