!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Rio is pre-alpha software. 
The documented interface and behaviour is subject to change without notice.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

=== Rio - Ruby I/O Comfort Class

Rio is a convenience class wrapping much of the functionality of 
IO, File, Dir, Pathname, FileUtils, Tempfile, StringIO, OpenURI, Zlib, and CSV.

To create the documentation for Rio run the command
  ruby RUNME.1st.rb
from the distribution directory.

Then point your browser at the 'doc/rdoc' directory.

Suggested Reading
* RIO::Doc::SYNOPSIS
* RIO::Doc::INTRO
* RIO::Doc::HOWTO
* RIO::Rio

== Version 0.3.7
* Maintenance release

== New for version 0.3.6
* Pipe operator and command pipes

  Pipe multiple commands
   rio('afile') | rio(?-,'acmd') | 'another_cmd' | ?-

  Run the same series of commands, with different input and/or output
   cmdpipe = rio(?-,'acmd') | rio(?-,'another_cmd')
   rio('infile1') | cmdpipe | rio('outfile1')
   rio('infile2') | cmdpipe | rio('outfile2')

   cmdpipe2 = rio(?|,'cmd1','cmd2',rio('outfile'))   # create a cmdpipe Rio
   rio('infile1') | cmdpipe2       # run with input coming from a file
   rio(?-) | cmdpipe2              # same commands with input from stdin


== New for version 0.3.5
* Partial support for MS Windows drive and UNC path specifications
  
  The separator must be '/'. Back-slashes are not supported.

  Drives and UNC paths may be specified as expected:
   rio("D:/adir/afile")
   rio('//ahost/adir/afile')

  This support has introduced a change in the behaviour
  of Rio#path. Rio#path now returns the path on the 
  file-system for Rios that are on the file-system; returns the path
  portion of the URL for FTP, HTTP and other Rios that
  have a path, and return nil for Rios that have no path
   rio('/a/b/c').path                     #==> "/a/b/c"
   rio('b/c').path                        #==> "b/c"
   rio('C:/b/c').path                     #==> "C:/b/c"
   rio('//ahost/a/b').path                #==> "//ahost/a/b"
   rio('file://ahost/a/b').path           #==> "//ahost/a/b"
   rio('file:///a/b').path                #==> "/a/b"
   rio('file://localhost/a/b').path       #==> "/a/b"
   rio('http://ahost/index.html').path    #==> "/index.html"
   rio('stdin:').path                     #==> nil


== New for version 0.3.4
* New Grande Selection parameter.

  A major weakness of Rio's selection methods (lines, files, etc.)
  has always been that it only implemented a logical OR.

   rio('afile').lines(0..10,/Rio/) {...}
  iterates through lines that are in the range 0..10 OR 
  contain 'Rio'.

   rio('adir').files(:executable?,'*.rb') {...}
  iterates through files that are executable OR match '*.rb'

  Selecting files that matched both required using a proc.
   rio('adir').files(proc{ |f| f.executable? and f.fnmatch?('*.rb')}) {...}

  Rio's grande selection methods will now accept an array of conditions
  which must all be matched, in order to be selected. A logical AND.

   rio('adir').files([:executable?,'*.rb']) {...}
  
  The array, of course, need not be the only paramter. 

   rio('adir').files('*.exe',[:executable?,'*.rb']) {...}

  selects .exe files and .rb files that are executable.

* Renamed some of grande rejection methods. 
  (based on a suggestion by Gavin Sinclair)
   nolines => skiplines
   nofiles => skipfiles
  etc.

* New skip() grande method
   rio('afile').skip.lines(/Rio/)       # same as skiplines(/Rio/)
   rio('afile').lines(/Rio/).skip(0..9) # lines with 'Rio', exclude 
                                        # the first ten lines

* Alternative syntaxes for creating Rios that have no path.

   rio(?-)          # create a Rio refering to stdio
   rio(:stdio)      # same thing.
   rio.stdio        # same thing
   RIO.stdio        # ditto
   RIO::Rio.stdio   # once again

* From Pathname added
  * root?
  * mountpoint?
  * realpath
  * cleanpath

* Removed Rio#slurp in favor of Rio#contents.


* Added aliases for the copy operators. (suggested by Dave Burt)
   * copy_to >
   * append_to >>
   * copy_from <
   * append_from <<


* Bug fixes and corrections    
  
Project:: http://rubyforge.org/projects/rio/
Documentation:: http://rio.rubyforge.org/
Bugs:: http://rubyforge.org/tracker/?group_id=821
Email:: rio4ruby@rubyforge.org

== New for version 0.3.3
* Expanded support and documentation for CSV files
  Examples:
  * Copy, changing the separator to a semicolon
     rio('comma.csv').csv > rio('semicolon.csv').csv(';')
  * Iterate through a file with each line parsed into an array
     rio('afile.csv').csv { |array_of_fields| ...}
  * Create an array of arrays of selected fields
     array_of_arrays = rio('afile.csv').csv.columns(1..3,7).to_a
  * Create a tab separated file of accounts in a UNIX passwd file,
    listing only the username, uid, and realname fields
     rio('/etc/passwd').csv(':').columns(0,2,4) > rio('report).csv("\t")

Project:: http://rubyforge.org/projects/rio/
Documentation:: http://rio.rubyforge.org/
Bugs:: http://rubyforge.org/tracker/?group_id=821

== New for version 0.3.2

* Based on a suggestion by Wybo Decker and code attributed to Nobu Nokada, 
  Rio now supports temporary directories in addition to temporary files.
* Bug fixes
* More tests and documentation.

== SYNOPSIS

For the following assume:
 astring = ""
 anarray = []

Copy a file into a string
 rio('afile') > astring 

Copy the chomped lines of a file into an array
 rio('afile').chomp > anarray
 
Copy a file into another file
 rio('afile') > rio('another_file')

Copy a file into a directory
 rio('afile') > rio('adir')

Copy an entire directory structure into another directory
 rio('adir') > rio('another_directory')

Copy a web page into a file
 rio('http://rubydoc.org/') > rio('afile')

Copy a file from a ftp server into a file
 rio('ftp://host/afile.gz') > rio('afile.gz')

Copy a gzipped file un-gzipping it
 rio('afile.gz').gzip > rio('afile')

Copy a file from a ftp server into a local file un-gzipping it
 rio('ftp://host/afile.gz').gzip > rio('afile')

Copy a plain file, gzipping it
 rio('afile.gz').gzip < rio('afile')

Iterate over the entries in a directory
 rio('adir').entries { |entrio| ... }

Iterate over only the files in a directory
 rio('adir').files { |entrio| ... }

Iterate over only the .rb files in a directory
 rio('adir').files('*.rb') { |entrio| ... }

Create an array of the .rb entries in a directory
 anarray = rio('adir')['*.rb']

Iterate over the .rb files in a directory and its subdirectories
 rio('adir').all.files('*.rb') { |entrio| ... }

Create an array of the .rb entries in a directory and its subdirectories
 anarray = rio('adir').all['*.rb']

Create an array of the .rb files in a directory and its subdirectories
 anarray = rio('adir').all.files['*.rb']

Copy an entire directory structure but only the .rb files from a directory and its subdirectories 
into another directory
 rio('adir').dirs.files('*.rb') > rio('another_directory')

Iterate over the chomped lines of a file
 rio('afile').chomp.lines { |line| ... }

Put the chomped lines of a file into an array
 anarray = rio('afile').chomp.lines[]

Iterate over the first 10 chomped lines of a file
 rio('afile').chomp.lines(0..9) { |line| ... }

Put the first 10 chomped lines of a file into an array
 anarray = rio('afile').chomp.lines[0..9]

Copy the first 10 lines of a file into another file
 rio('afile').lines(0..9) > rio('another_file')

Copy the first 10 lines of a file to stdout
 rio('afile').lines(0..9) > rio(?-)

Copy the first 10 lines of a gzipped file to stdout
 rio('afile.gz').gzip.lines(0..9) > rio(?-)

Copy the first 10 lines of a gzipped file on an ftp server to stdout
 rio('ftp://host/afile.gz').gzip.lines(0..9) > rio(?-)

Put the first 100 chomped lines of a gzipped file into an array
 anarray =  rio('afile.gz').gzip[0...100] 

Copy the output of th ps command into an array, skipping the header line and the ps command entry
 rio(?-,'ps -a').skiplines(0,/ps$/) > anarray 

Prompt for input and return what was typed
 ans = rio(?-).print("Type Something: ").chomp.gets 

Change the extension of all files with the extension '.htm' in a directory and its
subdirectories to have the extension '.html'
 rio('adir').rename.all.files('*.htm') do |htmfile|
   htmfile.extname = '.html'
 end

Create a symbolic link 'asymlink' in 'adir' which refers to 'adir/afile'
 rio('adir/afile').symlinke('adir/asymlink')