--- rat/lonratedt.pm 2006/09/12 22:13:12 1.83 +++ rat/lonratedt.pm 2009/01/20 16:38:49 1.92 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Edit Handler for RAT Maps # -# $Id: lonratedt.pm,v 1.83 2006/09/12 22:13:12 albertel Exp $ +# $Id: lonratedt.pm,v 1.92 2009/01/20 16:38:49 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -29,381 +29,16 @@ package Apache::lonratedt; -=pod - -=head1 NAME - -Apache::lonratedt: simple resource assembly tool - -=head1 SYNOPSIS - -lonratedt provides the routines and the handler for the Advanced - Resource Assembly Tool (RAT), and ties the various pieces together - with Javascript. - -=head1 OVERVIEW - -=head2 Map Representation - -=begin latex - -% -\begin{figure} -\begin{center}\includegraphics[% - width=0.55\paperwidth,bb = 0 0 200 100, draft, type=eps]{Map_Example}\end{center} - - -\caption{\label{Map_In_Advanced_Editor}Example of a Map in the Advanced Editor} -\end{figure} -% -\begin{figure} -\begin{lyxcode} - - -~~ - -~~~~ - -~~ - -~~~~ - -~~ - -~~~~ - -~~ - -~~~~ - -~~ - -~~~~ - -~~ - -~~~~ - -~~ - -~~ - -~~ - -~~ - -~~ -\end{lyxcode} - -\caption{\label{XML}XML for Map in Figure \ref{Map_In_Advanced_Editor}} -\end{figure} - -=end latex - -Fig. "XML for Map in Figure" shows the XML representation of the -resource map shown in Fig. "Example of a Map in the Advanced Editor", -which is the format in which maps are stored. In the figure, however, -additional graphical map layout information generated by the Advanced -Resource Assembly Tool is not displayed. This graphical information is -optional to re-generate the same graphical layout when the map is -brought up again in the Resource Assembly Tool, and is not needed for -any other system functionality. - -Maps can be generated by tools other than the Resource Assembly -Tool. In particular, an author might have some other representation of -a course sequence, which can be converted into a map using scripts. If -this map then were to be brought up in the Resource Assembly Tool, the -Tool would automatically generate a graphical layout for it. Each -entry of the map (resources, conditions and links) is stored in a -separate tag. - -Resources and conditionsX have to have unique ID -numbers. These numbers are automatically generated by the Resource -Assembly Tool when the entry is first created, or added to the entries -when a map generated outside the Resource Assembly Tool is first -retrieved. They can also be assigned by custom scripts or added in by -hand. - -In the XML example, entry 1 is the start resource of the map. When -this map is accessed, the source (src) URL of this tag will be the -first resource rendered. Entry 2 is the finish resource of this -map. This resource will be the last resource in the sequence of -resources. Entry 6 is a problem resource with the given URL and title, -as well as the priority "mandatory". Entry 19 is a condition, which is -used by the link between entries 6, the problem, and 9, a -sequence. I - -=cut - use strict; use Apache::Constants qw(:common); use Apache::lonnet; -use Apache::lonratsrv; -use Apache::lonsequence; -use Apache::loncommon; +use Apache::lonsequence(); +use Apache::loncommon(); use Apache::lonlocal; +use LONCAPA::map(); use File::Copy; -use lib '/home/httpd/lib/perl/'; use LONCAPA; - - -use vars qw(@order @resources @resparms @zombies); - - -# Mapread read maps into global arrays @links and @resources, determines status -# sets @order - pointer to resources in right order -# sets @resources - array with the resources with correct idx -# -sub mapread { - my $fn=shift; - - my @links; - undef @links; - undef @resources; - undef @order; - undef @resparms; - undef @zombies; - - @resources=(''); - @order=(); - @resparms=(); - @zombies=(); - - my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,''); - if ($errtext) { return ($errtext,2); } - -# -------------------------------------------------------------------- Read map - foreach (split(/\<\&\>/,$outtext)) { - my ($command,$number,$content)=split(/\<\:\>/,$_); - if ($command eq 'objcont') { - my ($title,$src,$ext,$type)=split(/\:/,$content); - if ($ext eq 'cond') { next; } - if ($type ne 'zombie') { - $resources[$number]=$content; - } else { - $zombies[$number]=$content; - } - } - if ($command eq 'objlinks') { - $links[$number]=$content; - } - if ($command eq 'objparms') { - if ($resparms[$number]) { - $resparms[$number].='&&&'.$content; - } else { - $resparms[$number]=$content; - } - } - } -# ------------------------------------------------------- Is this a linear map? - my @starters=(); - my @endings=(); - undef @starters; - undef @endings; - - foreach (@links) { - if (defined($_)) { - my ($start,$end,$cond)=split(/\:/,$_); - if ((defined($starters[$start])) || (defined($endings[$end]))) { - return - (&mt('Map has branchings. Use advanced editor.'),1); - } - $starters[$start]=1; - $endings[$end]=1; - if ($cond) { - return - (&mt('Map has conditions. Use advanced editor.'),1); - } - } - - } - for (my $i=1; $i<=$#resources; $i++) { - if (defined($resources[$i])) { - unless (($starters[$i]) || ($endings[$i])) { - return - (&mt('Map has unconnected resources. Use advanced editor.'),1); - } - } - } -# ---------------------------------------------- Did we just read an empty map? - if ($#resources<1) { - undef $resources[0]; - $resources[1]=':::start'; - $resources[2]=':::finish'; - } -# -------------------------------------------------- This is a linear map, sort - - my $startidx=0; - my $endidx=0; - for (my $i=0; $i<=$#resources; $i++) { - if (defined($resources[$i])) { - my ($title,$url,$ext,$type)=split(/\:/,$resources[$i]); - if ($type eq 'start') { $startidx=$i; } - if ($type eq 'finish') { $endidx=$i; } - } - } - my $k=0; - my $currentidx=$startidx; - $order[$k]=$currentidx; - for (my $i=0; $i<=$#resources; $i++) { - foreach (@links) { - my ($start,$end)=split(/\:/,$_); - if ($start==$currentidx) { - $currentidx=$end; - $k++; - $order[$k]=$currentidx; - last; - } - } - if ($currentidx==$endidx) { last; } - } - return $errtext; -} - -# ---------------------------------------------- Read a map as well as possible -# Also used by the sequence handler -# Call lonsequence::attemptread to read from resource space -# -sub attemptread { - my $fn=shift; - - my @links; - undef @links; - my @theseres; - undef @theseres; - - my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,''); - if ($errtext) { return @theseres } - -# -------------------------------------------------------------------- Read map - foreach (split(/\<\&\>/,$outtext)) { - my ($command,$number,$content)=split(/\<\:\>/,$_); - if ($command eq 'objcont') { - my ($title,$src,$ext,$type)=split(/\:/,$content); - unless ($type eq 'zombie') { - $theseres[$number]=$content; - } - } - if ($command eq 'objlinks') { - $links[$number]=$content; - } - } - -# --------------------------------------------------------------- Sort, sort of - - my @objsort=(); - undef @objsort; - - my @data1=(); - my @data2=(); - undef @data1; - undef @data2; - - my $k; - my $kj; - my $j; - my $ij; - - for ($k=1;$k<=$#theseres;$k++) { - if (defined($theseres[$k])) { - $objsort[$#objsort+1]=$k; - } - } - - for ($k=1;$k<=$#links;$k++) { - if (defined($links[$k])) { - @data1=split(/\:/,$links[$k]); - $kj=-1; - for (my $j=0;$j<=$#objsort;$j++) { - if ((split(/\:/,$objsort[$j]))[0]==$data1[0]) { - $kj=$j; - } - } - if ($kj!=-1) { $objsort[$kj].=':'.$data1[1]; } - } - } - for ($k=0;$k<=$#objsort;$k++) { - for ($j=0;$j<=$#objsort;$j++) { - if ($k!=$j) { - @data1=split(/\:/,$objsort[$k]); - @data2=split(/\:/,$objsort[$j]); - my $dol=$#data1+1; - my $dtl=$#data2+1; - if ($dol+$dtl<1000) { - for ($kj=1;$kj<$dol;$kj++) { - if ($data1[$kj]==$data2[0]) { - for ($ij=1;$ij<$dtl;$ij++) { - $data1[$#data1+1]=$data2[$ij]; - } - } - } - for ($kj=1;$kj<$dtl;$kj++) { - if ($data2[$kj]==$data1[0]) { - for ($ij=1;$ij<$dol;$ij++) { - $data2[$#data2+1]=$data1[$ij]; - } - } - } - $objsort[$k]=join(':',@data1); - $objsort[$j]=join(':',@data2); - } - } - } - } -# ---------------------------------------------------------------- Now sort out - - @objsort=sort { - my @data1=split(/\:/,$a); - my @data2=split(/\:/,$b); - my $rvalue=0; - my $k; - for ($k=1;$k<=$#data1;$k++) { - if ($data1[$k]==$data2[0]) { $rvalue--; } - } - for ($k=1;$k<=$#data2;$k++) { - if ($data2[$k]==$data1[0]) { $rvalue++; } - } - if ($rvalue==0) { $rvalue=$#data2-$#data1; } - $rvalue; - } @objsort; - - my @outres=(); - undef @outres; - - for ($k=0;$k<=$#objsort;$k++) { - $outres[$k]=$theseres[(split(/\:/,$objsort[$k]))[0]]; - } - return @outres; -} +use HTML::Entities(); # --------------------------------------------------------- Build up RAT screen sub ratedt { @@ -455,197 +90,6 @@ sub buttons { return $output.'
'; } -# ------------------------------------- Revive zombie idx or get unused number - -sub getresidx { - my $url=shift; - my $max=1+($#resources>$#zombies?$#resources:$#zombies); - unless ($url) { return $max; } - for (my $i=0; $i<=$#zombies; $i++) { - my ($title,$src,$ext,$type)=split(/\:/,$zombies[$i]); - if ($src eq $url) { - undef $zombies[$i]; - return $i; - } - } - return $max; -} - -# --------------------------------------------------------------- Make a zombie - -sub makezombie { - my $idx=shift; - my ($name,$url,$ext)=split(/\:/,$resources[$idx]); - my $now=time; - $zombies[$idx]=$name. - ' [('.$now.','.$env{'user.name'}.','.$env{'user.domain'}.')]:'. - $url.':'.$ext.':zombie'; -} - -# ----------------------------------------------------------- Paste into target -# modifies @order, @resources - -sub pastetarget { - my ($after,@which)=@_; - my @insertorder=(); - foreach (@which) { - if (defined($_)) { - my ($name,$url)=split(/\=/,$_); - $name=&unescape($name); - $url=&unescape($url); - if ($url) { - my $idx=&getresidx($url); - $insertorder[$#insertorder+1]=$idx; - my $ext='false'; - if ($url=~/^http\:\/\//) { $ext='true'; } - $url=~s/\:/\:/g; - $name=~s/\:/\:/g; - $resources[$idx]=$name.':'.$url.':'.$ext.':normal:res'; - } - } - } - my @oldorder=splice(@order,$after); - @order=(@order,@insertorder,@oldorder); -} - -# ------------------------------------------------ Get start and finish correct -# modifies @resources - -sub startfinish { -# Remove all start and finish - foreach (@order) { - my ($name,$url,$ext)=split(/\:/,$resources[$_]); - if ($url=~/http\&colon\:\/\//) { $ext='true'; } - $resources[$_]=$name.':'.$url.':'.$ext.':normal:res'; - } -# Garbage collection - my $stillchange=1; - while (($#order>1) && ($stillchange)) { - $stillchange=0; - for (my $i=0;$i<=$#order;$i++) { - my ($name,$url,$ext)=split(/\:/,$resources[$order[$i]]); - unless ($url) { -# Take out empty resource - for (my $j=$i+1;$j<=$#order;$j++) { - $order[$j-1]=$order[$j]; - } - $#order--; - $stillchange=1; - last; - } - } - } -# Put in a start resource - my ($name,$url,$ext)=split(/\:/,$resources[$order[0]]); - $resources[$order[0]]=$name.':'.$url.':'.$ext.':start:res'; -# Make sure this has at least start and finish - if ($#order==0) { - $resources[&getresidx()]='::false'; - $order[1]=$#resources; - } -# Make the last one a finish resource - ($name,$url,$ext)=split(/\:/,$resources[$order[$#order]]); - $resources[$order[$#order]]=$name.':'.$url.':'.$ext.':finish:res'; -} - -# ------------------------------------------------------------------- Store map - -sub storemap { - my $realfn=shift; - my $fn=$realfn; -# unless this is forced to work from the original file, use a temporary file -# instead - unless (shift) { - $fn=$realfn.'.tmp'; - unless (-e $fn) { - copy($realfn,$fn); - } - } -# store data either into tmp or real file - &startfinish(); - my $output='graphdef<:>no'; - my $k=1; - for (my $i=0; $i<=$#order; $i++) { - if (defined($resources[$order[$i]])) { - $output.='<&>objcont<:>'.$order[$i].'<:>'.$resources[$order[$i]]; - } - if (defined($resparms[$order[$i]])) { - foreach (split('&&&',$resparms[$order[$i]])) { - if ($_) { - $output.='<&>objparms<:>'.$order[$i].'<:>'.$_; - } - } - } - if (defined($order[$i+1])) { - if (defined($resources[$order[$i+1]])) { - $output.='<&>objlinks<:>'.$k.'<:>'. - $order[$i].':'.$order[$i+1].':0'; - $k++; - } - } - } - for (my $i=0; $i<=$#zombies; $i++) { - if (defined($zombies[$i])) { - $output.='<&>objcont<:>'.$i.'<:>'.$zombies[$i]; - } - } - $output=~s/http\&colon\;\/\///g; - $env{'form.output'}=$output; - return - &Apache::lonratsrv::loadmap($fn,&Apache::lonratsrv::savemap($fn,'')); -} - -# ------------------------------------------ Store and get parameters in global - -sub storeparameter { - my ($to,$name,$value,$ptype)=@_; - my $newentry=''; - my $nametype=''; - foreach (split('&&&',$resparms[$to])) { - my ($thistype,$thisname,$thisvalue)=split('___',$_); - if ($thisname) { - unless ($thisname eq $name) { - $newentry.=$_.'&&&'; - } else { - $nametype=$thistype; - } - } - } - unless ($ptype) { $ptype=$nametype; } - unless ($ptype) { $ptype='string'; } - $newentry.=$ptype.'___'.$name.'___'.$value; - $resparms[$to]=$newentry; -} - -sub delparameter { - my ($to,$name)=@_; - my $newentry=''; - my $nametype=''; - foreach (split('&&&',$resparms[$to])) { - my ($thistype,$thisname,$thisvalue)=split('___',$_); - if ($thisname) { - unless ($thisname eq $name) { - $newentry.=$_.'&&&'; - } - } - } - $resparms[$to]=$newentry; -} - -sub getparameter { - my ($to,$name)=@_; - my $value=undef; - my $ptype=undef; - foreach (split('&&&',$resparms[$to])) { - my ($thistype,$thisname,$thisvalue)=split('___',$_); - if ($thisname eq $name) { - $value=$thisvalue; - $ptype=$thistype; - } - } - return ($value,$ptype); -} - # ----------------------------------------------------------------- Edit script sub editscript { my $mode=shift; @@ -695,7 +139,7 @@ function idxopen(mode) { var options="scrollbars=1,resizable=1,menubar=0,location=1,toolbar=1"; idxmode=mode; idxflag=1; - idx=open('$resurl/?launch=1&mode=$mode&catalogmode='+mode,'idxout',options); + idx=open('$resurl/?inhibitmenu=yes&launch=1&mode=$mode&catalogmode='+mode,'idxout',options); idx.focus(); } @@ -703,7 +147,7 @@ function idxopen(mode) { function groupopen(url,recover,bookmarks) { var options="scrollbars=1,resizable=1,menubar=0"; idxflag=1; - idx=open("/adm/groupsort?mode=$mode&recover="+recover+"&readfile="+url+"&bookmarks="+bookmarks,"idxout",options); + idx=open("/adm/groupsort?inhibitmenu=yes&mode=$mode&recover="+recover+"&readfile="+url+"&bookmarks="+bookmarks,"idxout",options); idx.focus(); } @@ -712,7 +156,7 @@ function srchopen(mode) { var options="scrollbars=1,resizable=1,menubar=0"; srchmode=mode; srchflag=1; - srch=open("/adm/searchcat?launch=1&mode=$mode&catalogmode="+mode,"srchout",options); + srch=open("/adm/searchcat?inhibitmenu=yes&launch=1&mode=$mode&catalogmode="+mode,"srchout",options); srch.focus(); } // ----------------------------------------------------- launch indexer browser @@ -747,6 +191,7 @@ function idxcheck(mode) { if (editbrowser == null) { url += 'launch=1&'; } + url += 'inhibitmenu=yes&'; url += 'catalogmode=interactive&'; url += 'mode=edit&'; url += 'form=' + formname + '&'; @@ -776,23 +221,23 @@ sub smpedt { copy($tmpfn,&Apache::lonnet::filelocation('',$url)); unlink($tmpfn); my ($errtext,$fatal)= - &mapread(&Apache::lonnet::filelocation('',$url),''); + &LONCAPA::map::mapread(&Apache::lonnet::filelocation('',$url),''); unless ($fatal) { $targetmsg=''.&mt('Saved.').'
'; } else { - $targetmsg=''.&mt('An error occured while saving.').'
'; + $targetmsg=''.&mt('An error occurred while saving.').'
'; } } if ($env{'form.revert'}) { $targetmsg=''.&mt('Reverted.').'
'; unlink($tmpfn); my ($errtext,$fatal)= - &mapread(&Apache::lonnet::filelocation('',$url),''); + &LONCAPA::map::mapread(&Apache::lonnet::filelocation('',$url),''); } if (-e $tmpfn) { $targetmsg= ''.&mt('You are working with an unsaved version of your map.').'
'; - my ($errtext,$fatal)=&mapread($tmpfn,''); + my ($errtext,$fatal)=&LONCAPA::map::mapread($tmpfn,''); } # ---------------------------------------------------------- Process form input @@ -895,10 +340,10 @@ sub smpedt { if (defined($targetselect[-1])) { $lastsel=$targetselect[-1]; } else { - $lastsel=$#order+1; + $lastsel=$#LONCAPA::map::order+1; } - &pastetarget($lastsel,split(/\&/,$env{'form.importdetail'})); - &storemap(&Apache::lonnet::filelocation('',$url)); + &LONCAPA::map::pastetarget($lastsel,split(/\&/,$env{'form.importdetail'})); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); # ------------------------------------------------------------------------- Cut } elsif (($env{'form.cut'}) || ($env{'form.copy'})) { $importdetail=''; @@ -920,7 +365,7 @@ sub smpedt { } foreach (@targetselect) { - my ($name,$url)=split(/\:/,$resources[$order[$_-1]]); + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$LONCAPA::map::order[$_-1]]); if ($url) { $importdetail.='&'.&escape($name).'='. &escape($url); @@ -938,19 +383,19 @@ sub smpedt { if ($env{'form.cut'}) { my @neworder=(); - for (my $i=0;$i<=$#order;$i++) { + for (my $i=0;$i<=$#LONCAPA::map::order;$i++) { my $include=1; foreach (@targetselect) { if ($_-1==$i) { $include=0; } } if ($include) { - $neworder[$#neworder+1]=$order[$i]; + $neworder[$#neworder+1]=$LONCAPA::map::order[$i]; } else { - &makezombie($order[$i]); + &LONCAPA::map::makezombie($LONCAPA::map::order[$i]); } } - @order=@neworder; - &storemap(&Apache::lonnet::filelocation('',$url)); + @LONCAPA::map::order=@neworder; + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); } # ----------------------------------------------------------------------- Paste @@ -959,43 +404,43 @@ sub smpedt { if (defined($targetselect[-1])) { $lastsel=$targetselect[-1]; } else { - $lastsel=$#order+1; + $lastsel=$#LONCAPA::map::order+1; } my @newsequence; my @curimport=split(/\&/,$env{'form.curimpdetail'}); foreach (@importselect) { $newsequence[$#newsequence+1]=$curimport[$_]; } - &pastetarget($lastsel,@newsequence); - &storemap(&Apache::lonnet::filelocation('',$url)); + &LONCAPA::map::pastetarget($lastsel,@newsequence); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); # -------------------------------------------------------------------- Move up } elsif ($env{'form.moveup'}) { foreach (sort @targetselect) { if ($_-1>0) { - my $movethis=$order[$_-1]; - $order[$_-1]=$order[$_-2]; - $order[$_-2]=$movethis; + my $movethis=$LONCAPA::map::order[$_-1]; + $LONCAPA::map::order[$_-1]=$LONCAPA::map::order[$_-2]; + $LONCAPA::map::order[$_-2]=$movethis; } } - &storemap(&Apache::lonnet::filelocation('',$url)); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); # ------------------------------------------------------------------ Move down } elsif ($env{'form.movedown'}) { foreach (reverse sort @targetselect) { - if ($_-1<$#order) { - my $movethis=$order[$_-1]; - $order[$_-1]=$order[$_]; - $order[$_]=$movethis; + if ($_-1<$#LONCAPA::map::order) { + my $movethis=$LONCAPA::map::order[$_-1]; + $LONCAPA::map::order[$_-1]=$LONCAPA::map::order[$_]; + $LONCAPA::map::order[$_]=$movethis; } } - &storemap(&Apache::lonnet::filelocation('',$url)); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); # --------------------------------------------------------------------- Rename } elsif ($env{'form.renameres'}) { - my $residx=$Apache::lonratedt::order[$env{'form.renameidx'}-1]; - my ($name,@resrest)=split(/\:/,$Apache::lonratedt::resources[$residx]); + my $residx=$LONCAPA::map::order[$env{'form.renameidx'}-1]; + my ($name,@resrest)=split(/\:/,$LONCAPA::map::resources[$residx]); $name=$env{'form.renametitle'}; $name=~s/\:/\&colon\;/g; - $Apache::lonratedt::resources[$residx]=$name.':'.join(':',@resrest); - &storemap(&Apache::lonnet::filelocation('',$url)); + $LONCAPA::map::resources[$residx]=$name.':'.join(':',@resrest); + &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url)); } # ------------------------------------------------------------ Assemble windows @@ -1020,15 +465,17 @@ sub smpedt { my $targetwindow= ''. join("\n",map { - my ($name,$url)=split(/\:/,$resources[$_]); + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$_]); unless ($name) { $name=(split(/\//,$url))[-1]; } unless ($name) { $name='EMPTY'; } + $name = &LONCAPA::map::qtescape($name); + $url = &LONCAPA::map::qtescape($url); $targetdetail.='&'.&escape($name).'='. &escape($url); $idx++; - $name=~s/\:/\:/g; + $name = &HTML::Entities::encode($name,'\'"<>&'); ''; - } @order); + } @LONCAPA::map::order); # ----------------------------------------------------- Start simple RAT screen my $editscript=&editscript('simple'); @@ -1063,8 +510,6 @@ sub smpedt { function openview(entry) { var url=unescape((entry.split('='))[1]); var parts=new Array; - parts=url.split(':'); - url=parts.join(':'); if (url) { open(url,'cat'); } } @@ -1083,12 +528,6 @@ sub smpedt { var entry=(document.forms.simpleedit.targetdetail.value.split('&')) [selidx]; var oldname=unescape((entry.split('='))[0]); - var nameparts=oldname.split(':'); - oldname=unescape(nameparts.join(':')); - nameparts=oldname.split('"'); - oldname=unescape(nameparts.join('"')); - nameparts=oldname.split('''); - oldname=unescape(nameparts.join("'")); newtitle=prompt('$lt{'nt'}',oldname); if (newtitle) { document.forms.simpleedit.renameres.value=1; @@ -1154,7 +593,7 @@ $lt{'as'} - $importwindow @@ -1168,7 +607,7 @@ $lt{'ps'}
$lt{'pas'}
- $targetwindow @@ -1184,7 +623,7 @@ ENDSMPHEAD # ----------------------------------------------------------------- No such dir sub nodir { my ($r,$dir)=@_; - $dir=~s{^/home/\w+/public_html}{}; + $dir=~s{^/home/$LONCAPA::username_re/public_html}{}; $r->print(&Apache::loncommon::start_page(undef,undef, {'only_body' => 1, 'bgcolor' => '#FFFFFF',}). @@ -1201,31 +640,39 @@ sub viewmap { &Apache::loncommon::help_open_menu('','',6,'RAT'). &buttons($adv)); if ($errtext) { - $r->print($errtext.'
'); + $r->print('
' + .$errtext + .'
' + .'
' + ); } my $idx=0; $r->print('

'.$url.'

'); if ($adv) { - $r->print('

'.&mt('Map contents are not shown in order.').'


'); - } - $r->print( ''. - ''. - ''. - ''. - ''. - ''. - ''); - my @backgroundColors = ("#FFFFFF", "#F6F6F6"); - foreach (&attemptread(&Apache::lonnet::filelocation('',$url))) { + $r->print('

' + .&mt('Map contents are not shown in order.') + .'


' + ); + } + $r->print(&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row() + .'' + .'' + .'' + .'' + .'' + .&Apache::loncommon::end_data_table_header_row() + ); + foreach (&LONCAPA::map::attemptread(&Apache::lonnet::filelocation('',$url))) { if (defined($_)) { $idx++; my ($title,$url,$cond)=split(/\:/,$_); if ($cond eq 'cond') { next; } - $title=~s/\&colon\;/\:/g; - $url=~s/\&colon\;/\:/g; + $title= &LONCAPA::map::qtescape($title); + $url = &LONCAPA::map::qtescape($url); unless ($title) { $title=(split(/\//,$url))[-1] }; unless ($title) { $title=''.&mt('Empty').''; } - my $resurl = &Apache::lonratsrv::qtescape($url); + my $resurl = $url; my $resfilepath = $Apache::lonnet::perlvar{'lonDocRoot'}.$resurl; my $filename; if ($resurl =~ m#/([^/]+)$#) { @@ -1233,23 +680,34 @@ sub viewmap { } my $cstrurl = $resurl; $cstrurl =~ s#^/res/[^/]+/([^/]+)/#/priv/$1/#; - my $bgcol = $idx%2; - $r->print('' + .'' + .'' + .''."\n"); + $r->print('' + .&Apache::loncommon::end_data_table_row() + ); } } - $r->print('
'.&mt('Type').''.&mt('Title in map').''.&mt('Filename of resource').''.&mt('Link to published resource').''.&mt('Link to resource in Construction Space').'
'.&mt('Type').''.&mt('Title in map').''.&mt('Filename of resource').''.&mt('Link to published resource').''.&mt('Link to resource in Construction Space').'
'. - ''.&Apache::lonratsrv::qtescape($title). - ''.$filename.''); + $r->print(&Apache::loncommon::start_data_table_row() + .'' + .'' + .'' + .&HTML::Entities::encode(&LONCAPA::map::qtescape($title)) + .''.$filename.'' + ); if ($url) { $r->print(''.&mt('Resource space').''); + } else { + $r->print(' '); } $r->print(''); if ($url) { $r->print(''. &mt('Construction space').''); + } else { + $r->print(' '); } - $r->print('
'); + $r->print(&Apache::loncommon::end_data_table()); $r->print(&Apache::loncommon::end_page()); } @@ -1293,7 +751,7 @@ sub handler { my $fatal=0; # -------------------------------------------------------------------- Load map - ($errtext,$fatal)=&mapread($fn,$errtext); + ($errtext,$fatal)=&LONCAPA::map::mapread($fn,$errtext); if ($fatal==1) { $adv=1; } @@ -1314,7 +772,140 @@ __END__ +=pod + +=head1 NAME + +Apache::lonratedt: simple resource assembly tool + +=head1 SYNOPSIS + +lonratedt provides the routines and the handler for the Advanced + Resource Assembly Tool (RAT), and ties the various pieces together + with Javascript. + +=head1 OVERVIEW + +=head2 Map Representation + +=begin latex + +% +\begin{figure} +\begin{center}\includegraphics[% + width=0.55\paperwidth,bb = 0 0 200 100, draft, type=eps]{Map_Example}\end{center} + + +\caption{\label{Map_In_Advanced_Editor}Example of a Map in the Advanced Editor} +\end{figure} +% +\begin{figure} +\begin{lyxcode} + + +~~ + +~~~~ + +~~ + +~~~~ + +~~ + +~~~~ + +~~ + +~~~~ + +~~ + +~~~~ + +~~ + +~~~~ + +~~ + +~~ + +~~ + +~~ + +~~ +\end{lyxcode} + +\caption{\label{XML}XML for Map in Figure \ref{Map_In_Advanced_Editor}} +\end{figure} + +=end latex +Fig. "XML for Map in Figure" shows the XML representation of the +resource map shown in Fig. "Example of a Map in the Advanced Editor", +which is the format in which maps are stored. In the figure, however, +additional graphical map layout information generated by the Advanced +Resource Assembly Tool is not displayed. This graphical information is +optional to re-generate the same graphical layout when the map is +brought up again in the Resource Assembly Tool, and is not needed for +any other system functionality. + +Maps can be generated by tools other than the Resource Assembly +Tool. In particular, an author might have some other representation of +a course sequence, which can be converted into a map using scripts. If +this map then were to be brought up in the Resource Assembly Tool, the +Tool would automatically generate a graphical layout for it. Each +entry of the map (resources, conditions and links) is stored in a +separate tag. + +Resources and conditionsX have to have unique ID +numbers. These numbers are automatically generated by the Resource +Assembly Tool when the entry is first created, or added to the entries +when a map generated outside the Resource Assembly Tool is first +retrieved. They can also be assigned by custom scripts or added in by +hand. + +In the XML example, entry 1 is the start resource of the map. When +this map is accessed, the source (src) URL of this tag will be the +first resource rendered. Entry 2 is the finish resource of this +map. This resource will be the last resource in the sequence of +resources. Entry 6 is a problem resource with the given URL and title, +as well as the priority "mandatory". Entry 19 is a condition, which is +used by the link between entries 6, the problem, and 9, a +sequence. I + +=cut