(1) The path to the DocBook XSLT stylesheet. For example, /usr/share/xml/docbook/xsl-stylesheets/html/docbook.xsl
+(2) The path to the colorer XSLT stylesheet.
+(3) Or colorer-fo.xsl for FO output.
+
+
Test data
+
+
The package contains test files test.xml, testdoc.xsl and testdoc.html. Use them as the starting point:
+
+
+
diff --git a/manual/docbook/programlisting/mkdist.sh b/manual/docbook/programlisting/mkdist.sh
new file mode 100644
index 000000000..5851cf3f8
--- /dev/null
+++ b/manual/docbook/programlisting/mkdist.sh
@@ -0,0 +1,6 @@
+rm -rf xsieve-programlisting.zip xsieve-programlisting
+mkdir xsieve-programlisting
+rsync -av --exclude CVS vimcolor xsieve-programlisting/
+cp colorer.xsl colorer-html.xsl testdoc.xsl index.html sxml-utils.scm colorer.scm run-colorer.scm test.xml testdoc.html xsieve-programlisting/
+zip xsieve-programlisting.zip -r xsieve-programlisting
+
diff --git a/manual/docbook/programlisting/run-colorer.scm b/manual/docbook/programlisting/run-colorer.scm
new file mode 100644
index 000000000..b4b40afde
--- /dev/null
+++ b/manual/docbook/programlisting/run-colorer.scm
@@ -0,0 +1,51 @@
+; Run colorer and return the result as SXML
+; $Id: run-colorer.scm,v 1.6 2006/04/29 05:47:24 olpa Exp $
+
+(define colorer-bin #f)
+(define colorer-params #f)
+(define colorer-param-type #f)
+(define colorer-param-outfile #f)
+
+; Initialize colorer variables (only once)
+(define (init-colorer-variables)
+ (if (not colorer-bin) (begin
+ (set! colorer-bin (x:eval "string($colorer.bin)"))
+ (set! colorer-params (x:eval "string($colorer.params)"))
+ (set! colorer-param-type (x:eval "string($colorer.param.type)"))
+ (set! colorer-param-outfile (x:eval "string($colorer.param.outfile)")))))
+
+(define-macro (no-errors . body)
+ `(catch #t (lambda () ,@body) (lambda (dummy . args) #f)))
+
+(define (run-colorer program-text program-type)
+ ; Some sanity check
+ (init-colorer-variables)
+ (if (not (and program-text (> (string-length program-text) 0)))
+ #f
+ (let* (
+ ; Construct command line to run the colorer
+ (infile (tmpnam)) ; for the program text
+ (outfile (tmpnam)) ; for the colored tokens
+ (cmdline (string-append
+ colorer-bin " " colorer-params " "
+ (if (and program-type (> (string-length program-type) 0))
+ (string-append colorer-param-type program-type " ")
+ "")
+ colorer-param-outfile outfile " " infile)))
+ ;(display "Command line: ")(display cmdline)(newline)
+ ; Ignore errors
+ (no-errors
+ ; Write the program text to the file and execute the colorer
+ (with-output-to-file infile
+ (lambda () (display program-text)))
+ ;(system (string-append "cp " infile " lastin")) ; DEBUG
+ (system cmdline)
+ ;(system (string-append "cp " outfile " last")) ; DEBUG
+ ; Load the XML result, cleanup and return the result
+ (let* (
+ (eval-str (string-append "document('file://" outfile "')"))
+ (tree (x:eval eval-str)))
+ (no-errors (delete-file outfile))
+ (no-errors (delete-file infile))
+ ; drop "*TOP*" and drop namespace declaration from "syn:syntax"
+ (cons 'syn:syntax (cdr (cdadar tree))))))))
diff --git a/manual/docbook/programlisting/run.sh b/manual/docbook/programlisting/run.sh
new file mode 100644
index 000000000..277dd5f20
--- /dev/null
+++ b/manual/docbook/programlisting/run.sh
@@ -0,0 +1 @@
+~/p/xsieve/opt/bin/xsieve --xinclude -o testdoc.html testdoc.xsl testdoc.xml
diff --git a/manual/docbook/programlisting/run2.sh b/manual/docbook/programlisting/run2.sh
new file mode 100644
index 000000000..7150b7268
--- /dev/null
+++ b/manual/docbook/programlisting/run2.sh
@@ -0,0 +1,2 @@
+#~/p/xsieve/opt/bin/xsieve --xinclude -o testdoc.html testdoc.xsl /home/olpa/p/xsieve/doc/book/xsieve.xml
+~/p/xsieve/opt/bin/xsieve -o testdoc.html testdoc.xsl xsieve.xml
diff --git a/manual/docbook/programlisting/run3.sh b/manual/docbook/programlisting/run3.sh
new file mode 100644
index 000000000..72bc7787f
--- /dev/null
+++ b/manual/docbook/programlisting/run3.sh
@@ -0,0 +1 @@
+~/p/xsieve/opt/bin/xsieve --xinclude -o testdoc.html colorer-one.xsl /home/olpa/p/xsieve/example/hello/doc/listing2.xml
diff --git a/manual/docbook/programlisting/run4.sh b/manual/docbook/programlisting/run4.sh
new file mode 100644
index 000000000..5c8215d0f
--- /dev/null
+++ b/manual/docbook/programlisting/run4.sh
@@ -0,0 +1,2 @@
+#~/p/xsieve/opt/bin/xsieve --xinclude -o testdoc.html testdoc.xsl /home/olpa/p/xsieve/doc/book/xsieve.xml
+~/p/xsieve/opt/bin/xsieve -o testdoc.html --param callout.graphics 0 testdoc.xsl /home/olpa/p/xsieve/doc/project/xtech2006/programlisting/test.xml
diff --git a/manual/docbook/programlisting/sxml-utils.scm b/manual/docbook/programlisting/sxml-utils.scm
new file mode 100644
index 000000000..1b42fd514
--- /dev/null
+++ b/manual/docbook/programlisting/sxml-utils.scm
@@ -0,0 +1,35 @@
+; $Id: sxml-utils.scm,v 1.1 2006/03/02 04:32:58 olpa Exp $
+; A copy-paste of a part of the SXML library
+
+; from CVS: SSAX/lib/SXML-tree-trans.scm
+(define (pre-post-order tree bindings)
+ (let* ((default-binding (assq '*default* bindings))
+ (text-binding (or (assq '*text* bindings) default-binding))
+ (text-handler ; Cache default and text bindings
+ (and text-binding
+ (if (procedure? (cdr text-binding))
+ (cdr text-binding) (cddr text-binding)))))
+ (let loop ((tree tree))
+ (cond
+ ((null? tree) '())
+ ((not (pair? tree))
+ (let ((trigger '*text*))
+ (if text-handler (text-handler trigger tree)
+ (error "Unknown binding for " trigger " and no default"))))
+ ((not (symbol? (car tree))) (map loop tree)) ; tree is a nodelist
+ (else ; tree is an SXML node
+ (let* ((trigger (car tree))
+ (binding (or (assq trigger bindings) default-binding)))
+ (cond
+ ((not binding)
+ (error "Unknown binding for " trigger " and no default"))
+ ((not (pair? (cdr binding))) ; must be a procedure: handler
+ (apply (cdr binding) trigger (map loop (cdr tree))))
+ ((eq? '*preorder* (cadr binding))
+ (apply (cddr binding) tree))
+ ((eq? '*macro* (cadr binding))
+ (loop (apply (cddr binding) tree)))
+ (else ; (cadr binding) is a local binding
+ (apply (cddr binding) trigger
+ (pre-post-order (cdr tree) (append (cadr binding) bindings)))
+ ))))))))
diff --git a/manual/docbook/programlisting/test-one.scm b/manual/docbook/programlisting/test-one.scm
new file mode 100644
index 000000000..d63d38e06
--- /dev/null
+++ b/manual/docbook/programlisting/test-one.scm
@@ -0,0 +1,13 @@
+(load "sxml-utils.scm")
+(load "colorer.scm")
+
+(define main-tree '(programlisting (*PI* a "b") (@ (format "linespecific")) "
+ Hello
+ Hello !
+"))
+
+(define h-tree "")
+
+(define result (colorer:join-markup main-tree h-tree '(h)))
+
+(write result)
diff --git a/manual/docbook/programlisting/test.scm b/manual/docbook/programlisting/test.scm
new file mode 100644
index 000000000..aa7db8615
--- /dev/null
+++ b/manual/docbook/programlisting/test.scm
@@ -0,0 +1,16 @@
+; $Id: test.scm,v 1.2 2006/03/02 06:01:06 olpa Exp $
+
+(define (test-case main-tree h-tree expected-result)
+ (display "------- Running a test case...")
+ (let ((result (caddr (colorer:join-markup main-tree h-tree '(h)))))
+ (if (equal? result expected-result)
+ (begin
+ (display "Ok")(newline))
+ (begin
+ (display "Error")(newline)
+ (display "Expected: ")(write expected-result)(newline)
+ (display "Result: ")(write result)(newline)))))
+
+(load "sxml-utils.scm")
+(load "colorer.scm")
+(load "testdata.scm")
diff --git a/manual/docbook/programlisting/test.xml b/manual/docbook/programlisting/test.xml
new file mode 100644
index 000000000..e4e101224
--- /dev/null
+++ b/manual/docbook/programlisting/test.xml
@@ -0,0 +1,9 @@
+
+
+ Testing Syntax Highlighting
+ Testing syntax highlighting
+
+<para>Hello, &who;!</para>
+
+
diff --git a/manual/docbook/programlisting/testdata.scm b/manual/docbook/programlisting/testdata.scm
new file mode 100644
index 000000000..966d2efe1
--- /dev/null
+++ b/manual/docbook/programlisting/testdata.scm
@@ -0,0 +1,65 @@
+; test cases for joining parallel markup
+; $Id: testdata.scm,v 1.2 2006/03/02 05:58:55 olpa Exp $
+; (test-case in-xml also-xml joined-xml)
+
+; the simplest test, no highlighting at all
+(test-case
+ '(i "012")
+ '(h "012")
+ '(i "012"))
+
+; the simplest test, some highlighting
+(test-case
+ '(i "012")
+ '(h "0" (a "1") "2")
+ '(i (colorer:dummy "0" (a "1") "2")))
+
+; the size of text is different
+(test-case
+ '(i "0123456789")
+ '(h (a "01") "234" (b "56") "7")
+ '(i (colorer:dummy (a "01") "234" (b "56") "7" "89")))
+
+(test-case
+ '(i "01234567")
+ '(h "0" (a "12") "345" (b "5789"))
+ '(i (colorer:dummy "0" (a "12") "345" (b "67"))))
+
+; the text of the main tree is not corrupted
+(test-case
+ '(i "012345")
+ '(h "ab" (c "cd") "ef")
+ '(i (colorer:dummy "01" (c "23") "45")))
+
+; attributes are saved
+(test-case
+ '(i "012345")
+ '(h "01"
+ (a (@ (a1 "a1") (a2 "a2"))
+ (b (@ (b1 "b1") (b2 "b2"))
+ "23"))
+ "45")
+ '(i (colorer:dummy "01"
+ (a (@ (a1 "a1") (a2 "a2"))
+ (b (@ (b1 "b1") (b2 "b2"))
+ "23"))
+ "45")))
+
+; ordering and nesting of empty tags
+(test-case
+ '(i "012" (x (y)) (z) "34")
+ '(h "01" (a "23") "4")
+ '(i (colorer:dummy "01" (a "2")) (x (y)) (z) (colorer:dummy (a "3") "4")))
+
+; intersecting at left
+(test-case
+ '(i "01" (a "2345" (b "67")))
+ '(h "012" (x (y "3456")) "7")
+ '(i "01" (a (colorer:dummy "2" (x (y "345"))) (b (colorer:dummy (x (y "6")) "7")))))
+
+; intersecting at right
+(test-case
+ '(i "01" (a "23" (b "45") "6") "78")
+ '(h "01234" (x (y "56")) "78")
+ '(i "01" (a "23" (b (colorer:dummy "4" (x (y "5")))) (x (y "6"))) "78"))
+
diff --git a/manual/docbook/programlisting/testdoc.html b/manual/docbook/programlisting/testdoc.html
new file mode 100644
index 000000000..6e0b7839c
--- /dev/null
+++ b/manual/docbook/programlisting/testdoc.html
@@ -0,0 +1,5 @@
+
+
+Article with code
Article with code
A sample code:
Example 1.
Testing Syntax Highlighting
Testing syntax highlighting
+<para>Hello, &who;!</para>
+
diff --git a/manual/docbook/programlisting/testdoc.xml b/manual/docbook/programlisting/testdoc.xml
new file mode 100644
index 000000000..e042e5e64
--- /dev/null
+++ b/manual/docbook/programlisting/testdoc.xml
@@ -0,0 +1,7 @@
+
+ Article with code
+ A sample code:
+
+
+
+
diff --git a/manual/docbook/programlisting/testdoc.xsl b/manual/docbook/programlisting/testdoc.xsl
new file mode 100644
index 000000000..9e04280f9
--- /dev/null
+++ b/manual/docbook/programlisting/testdoc.xsl
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/manual/docbook/programlisting/vimcolor/CVS/Entries b/manual/docbook/programlisting/vimcolor/CVS/Entries
new file mode 100644
index 000000000..f27b0ee20
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/CVS/Entries
@@ -0,0 +1,6 @@
+/README/1.1/Fri Apr 28 07:09:09 2006//
+/README-Path-Class/1.1/Fri Apr 28 07:09:09 2006//
+/README-Text-VimColor/1.1/Fri Apr 28 07:09:09 2006//
+/text-vimcolor/1.1/Fri Apr 28 07:09:09 2006//
+/vimcolor-wrapper/1.1/Fri Apr 28 07:09:09 2006//
+D/lib////
diff --git a/manual/docbook/programlisting/vimcolor/CVS/Repository b/manual/docbook/programlisting/vimcolor/CVS/Repository
new file mode 100644
index 000000000..53ac94a43
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/CVS/Repository
@@ -0,0 +1 @@
+xsieve/experiments/programlisting/vimcolor
diff --git a/manual/docbook/programlisting/vimcolor/CVS/Root b/manual/docbook/programlisting/vimcolor/CVS/Root
new file mode 100644
index 000000000..d6bc77dba
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@xsieve.cvs.sourceforge.net:/cvsroot/xsieve
diff --git a/manual/docbook/programlisting/vimcolor/README b/manual/docbook/programlisting/vimcolor/README
new file mode 100644
index 000000000..de5a14f1b
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/README
@@ -0,0 +1,8 @@
+Command-line syntax highlighting based on vim
+
+It uses Perl modules Text::VimColor and Path::Class.
+Perl libraries of these modules are copied to "lib".
+
+The program "vimcolor-wrapper" sets the path to the
+local copy of the libraries and runs the original
+script "text-vimcolor".
diff --git a/manual/docbook/programlisting/vimcolor/README-Path-Class b/manual/docbook/programlisting/vimcolor/README-Path-Class
new file mode 100644
index 000000000..194b5f396
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/README-Path-Class
@@ -0,0 +1,127 @@
+NAME
+ Path::Class - Cross-platform path specification manipulation
+
+SYNOPSIS
+ use Path::Class;
+
+ my $dir = dir('foo', 'bar'); # Path::Class::Dir object
+ my $file = file('bob', 'file.txt'); # Path::Class::File object
+
+ # Stringifies to 'foo/bar' on Unix, 'foo\bar' on Windows, etc.
+ print "dir: $dir\n";
+
+ # Stringifies to 'bob/file.txt' on Unix, 'bob\file.txt' on Windows
+ print "file: $file\n";
+
+ my $subdir = $dir->subdir('baz'); # foo/bar/baz
+ my $parent = $subdir->parent; # foo/bar
+ my $parent2 = $parent->parent; # foo
+
+ my $dir2 = $file->dir; # bob
+
+ # Work with foreign paths
+ use Path::Class qw(foreign_file foreign_dir);
+ my $file = foreign_file('Mac', ':foo:file.txt');
+ print $file->dir; # :foo:
+ print $file->as_foreign('Win32'); # foo\file.txt
+
+ # Interact with the underlying filesystem:
+
+ # $dir_handle is an IO::Dir object
+ my $dir_handle = $dir->open or die "Can't read $dir: $!";
+
+ # $file_handle is an IO::File object
+ my $file_handle = $file->open($mode) or die "Can't read $file: $!";
+
+DESCRIPTION
+ `Path::Class' is a module for manipulation of file and directory
+ specifications (strings describing their locations, like
+ `'/home/ken/foo.txt'' or `'C:\Windows\Foo.txt'') in a cross-platform
+ manner. It supports pretty much every platform Perl runs on, including
+ Unix, Windows, Mac, VMS, Epoc, Cygwin, OS/2, and NetWare.
+
+ The well-known module `File::Spec' also provides this service, but it's
+ sort of awkward to use well, so people sometimes avoid it, or use it in
+ a way that won't actually work properly on platforms significantly
+ different than the ones they've tested their code on.
+
+ In fact, `Path::Class' uses `File::Spec' internally, wrapping all the
+ unsightly details so you can concentrate on your application code.
+ Whereas `File::Spec' provides functions for some common path
+ manipulations, `Path::Class' provides an object-oriented model of the
+ world of path specifications and their underlying semantics.
+ `File::Spec' doesn't create any objects, and its classes represent the
+ different ways in which paths must be manipulated on various platforms
+ (not a very intuitive concept). `Path::Class' creates objects
+ representing files and directories, and provides methods that relate
+ them to each other. For instance, the following `File::Spec' code:
+
+ my $absolute = File::Spec->file_name_is_absolute(
+ File::Spec->catfile( @dirs, $file )
+ );
+
+ can be written using `Path::Class' as
+
+ my $absolute = Path::Class::File->new( @dirs, $file )->is_absolute;
+
+ or even as
+
+ my $absolute = file( @dirs, $file )->is_absolute;
+
+ Similar readability improvements should happen all over the place when
+ using `Path::Class'.
+
+ Using `Path::Class' can help solve real problems in your code too - for
+ instance, how many people actually take the "volume" (like `C:' on
+ Windows) into account when writing `File::Spec'-using code? I thought
+ not. But if you use `Path::Class', your file and directory objects will
+ know what volumes they refer to and do the right thing.
+
+ The guts of the `Path::Class' code live in the `Path::Class::File' and
+ `Path::Class::Dir' modules, so please see those modules' documentation
+ for more details about how to use them.
+
+ EXPORT
+
+ The following functions are exported by default.
+
+ file
+ A synonym for `Path::Class::File->new'.
+
+ dir A synonym for `Path::Class::Dir->new'.
+
+ If you would like to prevent their export, you may explicitly pass an
+ empty list to perl's `use', i.e. `use Path::Class ()'.
+
+ The following are exported only on demand.
+
+ foreign_file
+ A synonym for `Path::Class::File->new_foreign'.
+
+ foreign_dir
+ A synonym for `Path::Class::Dir->new_foreign'.
+
+Notes on Cross-Platform Compatibility
+ Although it is much easier to write cross-platform-friendly code with
+ this module than with `File::Spec', there are still some issues to be
+ aware of.
+
+ * Some platforms, notably VMS and some older versions of DOS (I
+ think), all filenames must have an extension. Thus if you create a
+ file called foo/bar and then ask for a list of files in the
+ directory foo, you may find a file called bar. instead of the bar
+ you were expecting. Thus it might be a good idea to use an extension
+ in the first place.
+
+AUTHOR
+ Ken Williams, KWILLIAMS@cpan.org
+
+COPYRIGHT
+ Copyright (c) Ken Williams. All rights reserved.
+
+ This library is free software; you can redistribute it and/or modify it
+ under the same terms as Perl itself.
+
+SEE ALSO
+ Path::Class::Dir, Path::Class::File, File::Spec
+
diff --git a/manual/docbook/programlisting/vimcolor/README-Text-VimColor b/manual/docbook/programlisting/vimcolor/README-Text-VimColor
new file mode 100644
index 000000000..38b37e8d0
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/README-Text-VimColor
@@ -0,0 +1,25 @@
+Text::VimColor
+--------------
+
+This module tries to markup text files according to their syntax. It can
+be used to produce web pages with pretty-printed colourful source code
+samples. It can produce output in the following formats:
+
+The module comes with a command line program, text-vimcolor, which makes
+it easy to do 'ad-hoc' syntax coloring jobs.
+
+
+ Geoff Richards
+
+
+Release procedure
+-----------------
+
+ * Update the version number in lib/Text/VimColor.pm and META.yml
+ * Update the changelog with a new section for a matching version number
+ and the correct date and time
+ * Copy the ChangeLog into place (from 'debian' directory in my CVS)
+ * Realclean, make and test
+ * Make the dist, take it to another machine and build and test there
+ * Commit everything, and set tag like 'Release_0_07-1'
+ * Upload to CPAN
diff --git a/manual/docbook/programlisting/vimcolor/lib/CVS/Entries b/manual/docbook/programlisting/vimcolor/lib/CVS/Entries
new file mode 100644
index 000000000..cc0a28410
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/lib/CVS/Entries
@@ -0,0 +1,2 @@
+D/Path////
+D/Text////
diff --git a/manual/docbook/programlisting/vimcolor/lib/CVS/Repository b/manual/docbook/programlisting/vimcolor/lib/CVS/Repository
new file mode 100644
index 000000000..43c4fcd3b
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/lib/CVS/Repository
@@ -0,0 +1 @@
+xsieve/experiments/programlisting/vimcolor/lib
diff --git a/manual/docbook/programlisting/vimcolor/lib/CVS/Root b/manual/docbook/programlisting/vimcolor/lib/CVS/Root
new file mode 100644
index 000000000..d6bc77dba
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/lib/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@xsieve.cvs.sourceforge.net:/cvsroot/xsieve
diff --git a/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Entries b/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Entries
new file mode 100644
index 000000000..7166213fb
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Entries
@@ -0,0 +1,2 @@
+/Class.pm/1.1/Fri Apr 28 07:17:33 2006//
+D/Class////
diff --git a/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Repository b/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Repository
new file mode 100644
index 000000000..43ef3dddb
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Repository
@@ -0,0 +1 @@
+xsieve/experiments/programlisting/vimcolor/lib/Path
diff --git a/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Root b/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Root
new file mode 100644
index 000000000..d6bc77dba
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/lib/Path/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@xsieve.cvs.sourceforge.net:/cvsroot/xsieve
diff --git a/manual/docbook/programlisting/vimcolor/lib/Path/Class.pm b/manual/docbook/programlisting/vimcolor/lib/Path/Class.pm
new file mode 100644
index 000000000..3829279df
--- /dev/null
+++ b/manual/docbook/programlisting/vimcolor/lib/Path/Class.pm
@@ -0,0 +1,177 @@
+package Path::Class;
+
+$VERSION = '0.15';
+@ISA = qw(Exporter);
+@EXPORT = qw(file dir);
+@EXPORT_OK = qw(file dir foreign_file foreign_dir);
+
+use strict;
+use Exporter;
+use Path::Class::File;
+use Path::Class::Dir;
+
+sub file { Path::Class::File->new(@_) }
+sub dir { Path::Class::Dir ->new(@_) }
+sub foreign_file { Path::Class::File->new_foreign(@_) }
+sub foreign_dir { Path::Class::Dir ->new_foreign(@_) }
+
+
+1;
+__END__
+
+=head1 NAME
+
+Path::Class - Cross-platform path specification manipulation
+
+=head1 SYNOPSIS
+
+ use Path::Class;
+
+ my $dir = dir('foo', 'bar'); # Path::Class::Dir object
+ my $file = file('bob', 'file.txt'); # Path::Class::File object
+
+ # Stringifies to 'foo/bar' on Unix, 'foo\bar' on Windows, etc.
+ print "dir: $dir\n";
+
+ # Stringifies to 'bob/file.txt' on Unix, 'bob\file.txt' on Windows
+ print "file: $file\n";
+
+ my $subdir = $dir->subdir('baz'); # foo/bar/baz
+ my $parent = $subdir->parent; # foo/bar
+ my $parent2 = $parent->parent; # foo
+
+ my $dir2 = $file->dir; # bob
+
+ # Work with foreign paths
+ use Path::Class qw(foreign_file foreign_dir);
+ my $file = foreign_file('Mac', ':foo:file.txt');
+ print $file->dir; # :foo:
+ print $file->as_foreign('Win32'); # foo\file.txt
+
+ # Interact with the underlying filesystem:
+
+ # $dir_handle is an IO::Dir object
+ my $dir_handle = $dir->open or die "Can't read $dir: $!";
+
+ # $file_handle is an IO::File object
+ my $file_handle = $file->open($mode) or die "Can't read $file: $!";
+
+=head1 DESCRIPTION
+
+C is a module for manipulation of file and directory
+specifications (strings describing their locations, like
+C<'/home/ken/foo.txt'> or C<'C:\Windows\Foo.txt'>) in a cross-platform
+manner. It supports pretty much every platform Perl runs on,
+including Unix, Windows, Mac, VMS, Epoc, Cygwin, OS/2, and NetWare.
+
+The well-known module C also provides this service, but
+it's sort of awkward to use well, so people sometimes avoid it, or use
+it in a way that won't actually work properly on platforms
+significantly different than the ones they've tested their code on.
+
+In fact, C uses C internally, wrapping all
+the unsightly details so you can concentrate on your application code.
+Whereas C provides functions for some common path
+manipulations, C provides an object-oriented model of the
+world of path specifications and their underlying semantics.
+C doesn't create any objects, and its classes represent
+the different ways in which paths must be manipulated on various
+platforms (not a very intuitive concept). C creates
+objects representing files and directories, and provides methods that
+relate them to each other. For instance, the following C
+code:
+
+ my $absolute = File::Spec->file_name_is_absolute(
+ File::Spec->catfile( @dirs, $file )
+ );
+
+can be written using C as
+
+ my $absolute = Path::Class::File->new( @dirs, $file )->is_absolute;
+
+or even as
+
+ my $absolute = file( @dirs, $file )->is_absolute;
+
+Similar readability improvements should happen all over the place when
+using C.
+
+Using C can help solve real problems in your code too -
+for instance, how many people actually take the "volume" (like C
+on Windows) into account when writing C-using code? I
+thought not. But if you use C, your file and directory objects
+will know what volumes they refer to and do the right thing.
+
+The guts of the C code live in the C
+and C modules, so please see those
+modules' documentation for more details about how to use them.
+
+=head2 EXPORT
+
+The following functions are exported by default.
+
+=over 4
+
+=item file
+
+A synonym for C<< Path::Class::File->new >>.
+
+=item dir
+
+A synonym for C<< Path::Class::Dir->new >>.
+
+=back
+
+If you would like to prevent their export, you may explicitly pass an
+empty list to perl's C