--- loncom/interface/loncommon.pm 2013/05/10 23:18:42 1.1075.2.35
+++ loncom/interface/loncommon.pm 2013/03/01 04:48:59 1.1116
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.1075.2.35 2013/05/10 23:18:42 raeburn Exp $
+# $Id: loncommon.pm,v 1.1116 2013/03/01 04:48:59 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -72,6 +72,7 @@ use Apache::lonuserstate();
use LONCAPA qw(:DEFAULT :match);
use DateTime::TimeZone;
use DateTime::Locale::Catalog;
+use Text::Aspell;
use Authen::Captcha;
use Captcha::reCAPTCHA;
@@ -158,6 +159,7 @@ sub ssi_with_retries {
# ----------------------------------------------- Filetypes/Languages/Copyright
my %language;
my %supported_language;
+my %supported_codes;
my %latex_language; # For choosing hyphenation in
my %latex_language_bykey; # for choosing hyphenation from metadata
my %cprtag;
@@ -192,14 +194,15 @@ BEGIN {
while (my $line = <$fh>) {
next if ($line=~/^\#/);
chomp($line);
- my ($key,$two,$country,$three,$enc,$val,$sup,$latex)=(split(/\t/,$line));
+ my ($key,$code,$country,$three,$enc,$val,$sup,$latex)=(split(/\t/,$line));
$language{$key}=$val.' - '.$enc;
if ($sup) {
$supported_language{$key}=$sup;
+ $supported_codes{$key} = $code;
}
if ($latex) {
$latex_language_bykey{$key} = $latex;
- $latex_language{$two} = $latex;
+ $latex_language{$code} = $latex;
}
}
close($fh);
@@ -663,7 +666,7 @@ if (!Array.prototype.indexOf) {
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
- if (n !== n) { // shortcut for verifying if it's NaN
+ if (n !== n) { // shortcut for verifying if it is NaN
n = 0;
} else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
@@ -899,12 +902,12 @@ sub check_uncheck_jscript {
function checkAll(field) {
if (field.length > 0) {
for (i = 0; i < field.length; i++) {
- if (!field[i].disabled) {
+ if (!field[i].disabled) {
field[i].checked = true;
}
}
} else {
- if (!field.disabled) {
+ if (!field.disabled) {
field.checked = true;
}
}
@@ -1000,7 +1003,7 @@ sub select_language {
my ($name,$selected,$includeempty) = @_;
my %langchoices;
if ($includeempty) {
- %langchoices = ('' => 'No language preference');
+ %langchoices = ('' => &mt('No language preference'));
}
foreach my $id (&languageids()) {
my $code = &supportedlanguagecode($id);
@@ -1008,12 +1011,38 @@ sub select_language {
$langchoices{$code} = &plainlanguagedescription($id);
}
}
- %langchoices = &Apache::lonlocal::texthash(%langchoices);
return &select_form($selected,$name,\%langchoices);
}
=pod
+
+=item * &list_languages()
+
+Returns an array reference that is suitable for use in language prompters.
+Each array element is itself a two element array. The first element
+is the language code. The second element a descsriptiuon of the
+language itself. This is suitable for use in e.g.
+&Apache::edit::select_arg (once dereferenced that is).
+
+=cut
+
+sub list_languages {
+ my @lang_choices;
+
+ foreach my $id (&languageids()) {
+ my $code = &supportedlanguagecode($id);
+ if ($code) {
+ my $selector = $supported_codes{$id};
+ my $description = &plainlanguagedescription($id);
+ push (@lang_choices, [$selector, $description]);
+ }
+ }
+ return \@lang_choices;
+}
+
+=pod
+
=item * &linked_select_forms(...)
linked_select_forms returns a string containing a block
@@ -2521,7 +2550,7 @@ sub authform_nochange {
kerb_def_dom => 'MSU.EDU',
@_,
);
- my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});
+ my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});
my $result;
if (!$authnum) {
$result = &mt('Under your current role you are not permitted to change login settings for this user');
@@ -3017,6 +3046,45 @@ sub get_related_words {
untie %thesaurus_db;
return @Words;
}
+###############################################################
+#
+# Spell checking
+#
+
+=pod
+
+=head1 Spell checking
+
+=over 4
+
+=item * &check_spelling($wordlist $language)
+
+Takes a string containing words and feeds it to an external
+spellcheck program via a pipeline. Returns a string containing
+them mis-spelled words.
+
+Parameters:
+
+=over 4
+
+=item - $wordlist
+
+String that will be fed into the spellcheck program.
+
+=item - $language
+
+Language string that specifies the language for which the spell
+check will be performed.
+
+=back
+
+=back
+
+Note: This sub assumes that aspell is installed.
+
+
+=cut
+
=pod
@@ -3024,6 +3092,31 @@ sub get_related_words {
=cut
+sub check_spelling {
+ my ($wordlist, $language) = @_;
+ my @misspellings;
+
+ # Generate the speller and set the langauge.
+ # if explicitly selected:
+
+ my $speller = Text::Aspell->new;
+ if ($language) {
+ $speller->set_option('lang', $language);
+ }
+
+ # Turn the word list into an array of words by splittingon whitespace
+
+ my @words = split(/\s+/, $wordlist);
+
+ foreach my $word (@words) {
+ if(! $speller->check($word)) {
+ push(@misspellings, $word);
+ }
+ }
+ return join(' ', @misspellings);
+
+}
+
# -------------------------------------------------------------- Plaintext name
=pod
@@ -4985,9 +5078,6 @@ Inputs:
=item * $bgcolor, used to override the bgcolor on a webpage to a specific value
-=item * $no_inline_link, if true and in remote mode, don't show the
- 'Switch To Inline Menu' link
-
=item * $args, optional argument valid values are
no_auto_mt_title -> prevents &mt()ing the title arg
inherit_jsmath -> when creating popup window in a page,
@@ -5009,7 +5099,7 @@ other decorations will be returned.
sub bodytag {
my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,
- $no_nav_bar,$bgcolor,$no_inline_link,$args,$advtoolsref)=@_;
+ $no_nav_bar,$bgcolor,$args,$advtoolsref)=@_;
my $public;
if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))
@@ -5085,25 +5175,11 @@ sub bodytag {
$role = '('.$role.')' if $role;
&get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);
- if ($no_nav_bar || $env{'form.inhibitmenu'} eq 'yes') {
- return $bodytag;
- }
+ if ($no_nav_bar || $env{'form.inhibitmenu'} eq 'yes') {
+ return $bodytag;
+ }
- if ($env{'request.state'} eq 'construct') { $forcereg=1; }
-
- my $funclist;
- if (($env{'environment.remote'} eq 'on') && ($env{'request.state'} ne 'construct')) {
- $bodytag .= Apache::lonhtmlcommon::scripttag(Apache::lonmenu::utilityfunctions(), 'start')."\n".
- Apache::lonmenu::serverform();
- my $forbodytag;
- &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},
- $forcereg,$args->{'group'},
- $args->{'bread_crumbs'},
- $advtoolsref,'',\$forbodytag);
- unless (ref($args->{'bread_crumbs'}) eq 'ARRAY') {
- $funclist = $forbodytag;
- }
- } else {
+ if ($env{'request.state'} eq 'construct') { $forcereg=1; }
# if ($env{'request.state'} eq 'construct') {
# $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls
@@ -5112,11 +5188,11 @@ sub bodytag {
if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) {
- if ($dc_info) {
+ if ($dc_info) {
$dc_info = qq|$dc_info|;
- }
- $bodytag .= qq|
$name $role
- $realm $dc_info
|;
+ }
+ $bodytag .= qq|
$name $role
+ $realm $dc_info
|;
return $bodytag;
}
@@ -5142,18 +5218,15 @@ sub bodytag {
if ($env{'request.state'} eq 'construct') {
$bodytag .= &Apache::lonmenu::innerregister($forcereg,
$args->{'bread_crumbs'});
- } elsif ($forcereg) {
+ } elsif ($forcereg) {
$bodytag .= &Apache::lonmenu::innerregister($forcereg,undef,
$args->{'group'});
} else {
- my $forbodytag;
- &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},
- $forcereg,$args->{'group'},
- $args->{'bread_crumbs'},
- $advtoolsref,'',\$forbodytag);
- unless (ref($args->{'bread_crumbs'}) eq 'ARRAY') {
- $bodytag .= $forbodytag;
- }
+ $bodytag .=
+ &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},
+ $forcereg,$args->{'group'},
+ $args->{'bread_crumbs'},
+ $advtoolsref);
}
}else{
# this is to seperate menu from content when there's no secondary
@@ -5163,44 +5236,6 @@ sub bodytag {
}
return $bodytag;
- }
-
-#
-# Top frame rendering, Remote is up
-#
-
- my $imgsrc = $img;
- if ($img =~ /^\/adm/) {
- $imgsrc = &lonhttpdurl($img);
- }
- my $upperleft='';
-
- # Explicit link to get inline menu
- my $menu= ($no_inline_link?''
- :''.&mt('Switch to Inline Menu Mode').'');
-
- if ($dc_info) {
- $dc_info = qq|($dc_info)|;
- }
-
- unless ($env{'form.inhibitmenu'}) {
- $bodytag .= qq|
$name $role
-
-
$menu
-
$realm $dc_info
|;
- }
- if ($env{'request.state'} eq 'construct') {
- if (!$public){
- if ($env{'request.state'} eq 'construct') {
- $funclist = &Apache::lonhtmlcommon::scripttag(
- &Apache::lonmenu::utilityfunctions(), 'start').
- &Apache::lonhtmlcommon::scripttag('','end').
- &Apache::lonmenu::innerregister($forcereg,
- $args->{'bread_crumbs'});
- }
- }
- }
- return $bodytag."\n".$funclist;
}
sub dc_courseid_toggle {
@@ -5232,15 +5267,8 @@ sub make_attr_string {
delete($attr_ref->{$key});
}
}
- if ($env{'environment.remote'} eq 'on') {
- $attr_ref->{'onload'} =
- &Apache::lonmenu::loadevents(). $on_load;
- $attr_ref->{'onunload'}=
- &Apache::lonmenu::unloadevents().$on_unload;
- } else {
- $attr_ref->{'onload'} = $on_load;
- $attr_ref->{'onunload'}= $on_unload;
- }
+ $attr_ref->{'onload'} = $on_load;
+ $attr_ref->{'onunload'}= $on_unload;
}
my $attr_string;
@@ -6445,11 +6473,6 @@ div.LC_edit_problem_saves {
padding-bottom: 5px;
}
-.LC_edit_opt {
- padding-left: 1em;
- white-space: nowrap;
-}
-
img.stift {
border-width: 0;
vertical-align: middle;
@@ -6673,7 +6696,6 @@ ul#LC_secondary_menu li {
font-weight: bold;
line-height: 1.8em;
border-right: 1px solid black;
- vertical-align: middle;
float: left;
}
@@ -6706,7 +6728,7 @@ ul#LC_secondary_menu li ul li {
vertical-align: top;
border-left: 1px solid black;
border-right: 1px solid black;
- background-color: $data_table_light;
+ background-color: $data_table_light
list-style:none;
float: none;
}
@@ -7233,8 +7255,8 @@ sub headtag {
if (!$args->{'frameset'}) {
$result .= &Apache::lonhtmlcommon::htmlareaheaders();
}
- if ($args->{'force_register'}) {
- $result .= &Apache::lonmenu::registerurl(1);
+ if ($args->{'force_register'} && $env{'request.noversionuri'} !~ m{^/res/adm/pages/}) {
+ $result .= Apache::lonxml::display_title();
}
if (!$args->{'no_nav_bar'}
&& !$args->{'only_body'}
@@ -7443,16 +7465,14 @@ $args - additional optional args support
skip_phases -> hash ref of
head -> skip the generation
body -> skip all generation
- no_inline_link -> if true and in remote mode, don't show the
- 'Switch To Inline Menu' link
no_auto_mt_title -> prevent &mt()ing the title arg
inherit_jsmath -> when creating popup window in a page,
should it have jsmath forced on by the
current page
bread_crumbs -> Array containing breadcrumbs
bread_crumbs_component -> if exists show it as headline else show only the breadcrumbs
- group -> includes the current group, if page is for a
- specific group
+ group -> includes the current group, if page is for a
+ specific group
=back
@@ -7482,8 +7502,8 @@ sub start_page {
$args->{'function'}, $args->{'add_entries'},
$args->{'only_body'}, $args->{'domain'},
$args->{'force_register'}, $args->{'no_nav_bar'},
- $args->{'bgcolor'}, $args->{'no_inline_link'},
- $args, \@advtools);
+ $args->{'bgcolor'}, $args,
+ \@advtools);
}
}
@@ -7523,11 +7543,6 @@ sub start_page {
}else{
$result .= &Apache::lonhtmlcommon::breadcrumbs();
}
- } elsif (($env{'environment.remote'} eq 'on') &&
- ($env{'form.inhibitmenu'} ne 'yes') &&
- ($env{'request.noversionuri'} =~ m{^/res/}) &&
- ($env{'request.noversionuri'} !~ m{^/res/adm/pages/})) {
- $result .= '
';
}
return $result;
}
@@ -7791,9 +7806,11 @@ sub LCprogressbar {
$LCcurrentid=$$.'_'.$LCidcnt;
my $starting=&mt('Starting');
my $content=(<
$starting
+
ENDPROGBAR
&r_print($r,$content.&LCprogressbar_script($LCcurrentid));
}
@@ -8207,19 +8224,7 @@ sub get_sections {
my %sectioncount;
my $now = time;
- my $check_students = 1;
- my $only_students = 0;
- if (ref($possible_roles) eq 'ARRAY') {
- if (grep(/^st$/,@{$possible_roles})) {
- if (@{$possible_roles} == 1) {
- $only_students = 1;
- }
- } else {
- $check_students = 0;
- }
- }
-
- if ($check_students) {
+ if (!defined($possible_roles) || (grep(/^st$/,@$possible_roles))) {
my ($classlist) = &Apache::loncoursedata::get_classlist($cdom,$cnum);
my $sec_index = &Apache::loncoursedata::CL_SECTION();
my $status_index = &Apache::loncoursedata::CL_STATUS();
@@ -8246,9 +8251,6 @@ sub get_sections {
}
}
}
- if ($only_students) {
- return %sectioncount;
- }
my %courseroles = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
foreach my $user (sort(keys(%courseroles))) {
if ($user !~ /^(\w{2})/) { next; }
@@ -9532,23 +9534,18 @@ sub ask_for_embedded_content {
my $heading = &mt('Upload embedded files');
my $buttontext = &mt('Upload');
- my ($navmap,$cdom,$cnum);
+ my $navmap;
if ($env{'request.course.id'}) {
- if ($actionurl eq '/adm/dependencies') {
- $navmap = Apache::lonnavmaps::navmap->new();
- }
- $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ $navmap = Apache::lonnavmaps::navmap->new();
}
- if (($actionurl eq '/adm/portfolio') ||
- ($actionurl eq '/adm/coursegrp_portfolio')) {
+ if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
my $current_path='/';
if ($env{'form.currentpath'}) {
$current_path = $env{'form.currentpath'};
}
if ($actionurl eq '/adm/coursegrp_portfolio') {
- $udom = $cdom;
- $uname = $cnum;
+ $udom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ $uname = $env{'course.'.$env{'request.course.id'}.'.num'};
$url = '/userfiles/groups/'.$env{'form.group'}.'/portfolio';
} else {
$udom = $env{'user.domain'};
@@ -9572,51 +9569,32 @@ sub ask_for_embedded_content {
$toplevel = $url;
if ($args->{'context'} eq 'paste') {
($cdom,$cnum) = ($url =~ m{^\Q/uploaded/\E($match_domain)/($match_courseid)/});
- ($path) =
+ ($path) =
($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/});
$fileloc = &Apache::lonnet::filelocation('',$toplevel);
$fileloc =~ s{^/}{};
}
}
- } elsif ($actionurl eq '/adm/dependencies') {
+ } elsif ($actionurl eq '/adm/dependencies') {
if ($env{'request.course.id'} ne '') {
+ $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
if (ref($args) eq 'HASH') {
$url = $args->{'docs_url'};
$title = $args->{'docs_title'};
- $toplevel = $url;
- unless ($toplevel =~ m{^/}) {
- $toplevel = "/$url";
- }
+ $toplevel = "/$url";
($rem) = ($toplevel =~ m{^(.+/)[^/]+$});
- if ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/portfolio/syllabus\E)}) {
- $path = $1;
- } else {
- ($path) =
- ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/});
- }
+ ($path) =
+ ($toplevel =~ m{^(\Q/uploaded/$cdom/$cnum/\E(?:docs|supplemental)/(?:default|\d+)/\d+)/});
$fileloc = &Apache::lonnet::filelocation('',$toplevel);
$fileloc =~ s{^/}{};
($filename) = ($fileloc =~ m{.+/([^/]+)$});
$heading = &mt('Status of dependencies in [_1]',"$title ($filename)");
}
}
- } elsif ($actionurl eq "/public/$cdom/$cnum/syllabus") {
- $udom = $cdom;
- $uname = $cnum;
- $url = "/uploaded/$cdom/$cnum/portfolio/syllabus";
- $toplevel = $url;
- $path = $url;
- $fileloc = &Apache::lonnet::filelocation('',$toplevel).'/';
- $fileloc =~ s{^/}{};
}
- }
- foreach my $file (keys(%{$allfiles})) {
- my $embed_file;
- if (($path eq "/uploaded/$cdom/$cnum/portfolio/syllabus") && ($file =~ m{^\Q$path/\E(.+)$})) {
- $embed_file = $1;
- } else {
- $embed_file = $file;
- }
+ my $now = time();
+ foreach my $embed_file (keys(%{$allfiles})) {
my $absolutepath;
if ($embed_file =~ m{^\w+://}) {
$newfiles{$embed_file} = 1;
@@ -9654,8 +9632,7 @@ sub ask_for_embedded_content {
my $dirptr = 16384;
foreach my $path (keys(%subdependencies)) {
$currsubfile{$path} = {};
- if (($actionurl eq '/adm/portfolio') ||
- ($actionurl eq '/adm/coursegrp_portfolio')) {
+ if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
my ($sublistref,$listerror) =
&Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath);
if (ref($sublistref) eq 'ARRAY') {
@@ -9671,15 +9648,9 @@ sub ask_for_embedded_content {
}
} elsif (($actionurl eq '/adm/dependencies') ||
(($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') &&
- ($args->{'context'} eq 'paste')) ||
- ($actionurl eq "/public/$cdom/$cnum/syllabus")) {
+ ($args->{'context'} eq 'paste'))) {
if ($env{'request.course.id'} ne '') {
- my $dir;
- if ($actionurl eq "/public/$cdom/$cnum/syllabus") {
- $dir = $fileloc;
- } else {
- ($dir) = ($fileloc =~ m{^(.+/)[^/]+$});
- }
+ my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$});
if ($dir ne '') {
my ($sublistref,$listerror) =
&Apache::lonnet::dirlist($dir.$path,$cdom,$cnum,$getpropath,undef,'/');
@@ -9727,8 +9698,7 @@ sub ask_for_embedded_content {
}
}
my %currfile;
- if (($actionurl eq '/adm/portfolio') ||
- ($actionurl eq '/adm/coursegrp_portfolio')) {
+ if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
my ($dirlistref,$listerror) =
&Apache::lonnet::dirlist($url,$udom,$uname,$getpropath);
if (ref($dirlistref) eq 'ARRAY') {
@@ -9744,8 +9714,7 @@ sub ask_for_embedded_content {
}
} elsif (($actionurl eq '/adm/dependencies') ||
(($actionurl eq '/adm/coursedocs') && (ref($args) eq 'HASH') &&
- ($args->{'context'} eq 'paste')) ||
- ($actionurl eq "/public/$cdom/$cnum/syllabus")) {
+ ($args->{'context'} eq 'paste'))) {
if ($env{'request.course.id'} ne '') {
my ($dir) = ($fileloc =~ m{^(.+/)[^/]+$});
if ($dir ne '') {
@@ -9780,14 +9749,12 @@ sub ask_for_embedded_content {
($file eq $filename.'.bak') ||
($dependencies{$file})) {
if ($actionurl eq '/adm/dependencies') {
- unless ($toplevel =~ m{^\Q/uploaded/$cdom/$cnum/portfolio/syllabus\E}) {
- next if (($rem ne '') &&
- (($env{"httpref.$rem".$file} ne '') ||
- (ref($navmap) &&
- (($navmap->getResourceByUrl($rem.$file) ne '') ||
- (($file =~ /^(.*\.s?html?)\.bak$/i) &&
- ($navmap->getResourceByUrl($rem.$1)))))));
- }
+ next if (($rem ne '') &&
+ (($env{"httpref.$rem".$file} ne '') ||
+ (ref($navmap) &&
+ (($navmap->getResourceByUrl($rem.$file) ne '') ||
+ (($file =~ /^(.*\.s?html?)\.bak$/i) &&
+ ($navmap->getResourceByUrl($rem.$1)))))));
}
$unused{$file} = 1;
}
@@ -9796,38 +9763,28 @@ sub ask_for_embedded_content {
($args->{'context'} eq 'paste')) {
$counter = scalar(keys(%existing));
$numpathchg = scalar(keys(%pathchanges));
- return ($output,$counter,$numpathchg,\%existing);
- } elsif (($actionurl eq "/public/$cdom/$cnum/syllabus") &&
- (ref($args) eq 'HASH') && ($args->{'context'} eq 'rewrites')) {
- $counter = scalar(keys(%existing));
- $numpathchg = scalar(keys(%pathchanges));
- return ($output,$counter,$numpathchg,\%existing,\%mapping);
+ return ($output,$counter,$numpathchg,\%existing);
}
foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) {
if ($actionurl eq '/adm/dependencies') {
next if ($embed_file =~ m{^\w+://});
}
$upload_output .= &start_data_table_row().
- '
'.
&Apache::loncommon::end_data_table_row()."\n";
}
}
@@ -9953,7 +9909,7 @@ sub ask_for_embedded_content {
$output = ''.&mt('Referenced files').': ';
if ($applies > 1) {
$output .=
- &mt('No dependencies need to be uploaded, as one of the following applies to each reference:').'
';
+ &mt('No files need to be uploaded, as one of the following applies to each reference:').'
';
if ($numremref) {
$output .= '
'.&mt('reference is to a URL which points to another server').'