require "xmp"
  xmp <<-EOS
  xmp = "can't handle comments"
  a = [1,2,3]
  # in block it tries to evaluate

  # anyway it's quite a hack,
  # there's no hope I'm going to fix it, 
  # I decided after 5 minutes of pure amaze :)
  EOS

produces:

./xmp.rb:182:in `eval': (eval):40: compile error (SyntaxError)
(eval):16: parse error
^/, ___sep___);
 ^
(eval):21: unmatched ): /, ___sep___);
             rescue
               ___res___ << "!! " + $!;
             end
             begin
	       ___res___ << "=> " + ().inspect.gsub(/
(eval):27: unmatched ): /, ___sep___);
             rescue
               ___res___ << "!! " + $!;
             end
             begin
	       ___res___ << "=> " + (# anyway it's quite a
hack,).inspect.gsub(/
(eval):33: unmatched ): /, ___sep___);
             rescue
               ___res___ << "!! " + $!;
             end
             begin
	       ___res___ << "=> " + (# there's no hope I'm going to fix it,
).inspect.gsub(/
(eval):39: unmatched ): /, ___sep___);
             rescue
               ___res___ << "!! " + $!;
             end
             begin
	       ___res___ << "=> " + (# I decided after 5 minutes of pure
amaze :)).inspect.gsub(/
(eval):40: unterminated regexp meets end of file
	from ./xmp.rb:182:in `xmp'
	from ../xmp_hacked/xmptest.rb:2

################################################

The I relooked it and decided to give a try. I managed to "fix" the
functionality (probably introducing an error since it prints out even things
evaluating to nil). Then I patched the documentation (my English is bad too
!) and finally added one small functionality so that one can say 'ruby
xmp.rb test.rb' and xmp prints the code in test.rb.

The patch is here, apply the parts you see worthwhile.

	- Aleksi

#################################################

--- ../xmp/xmp.rb	Mon Feb  7 07:54:02 2000
+++ xmp.rb	Mon Jul  3 02:32:30 2000
@@ -12,24 +12,30 @@
 
 == DESCRIPTION
 
-((*xmp*)) is an example printer, which is helpful to show example
-code.  The function (({xmp})) evaluates the first argument
-((|string|)) then prints the ((|string|)) result value.  If
+((*xmp*)) is an example printer. It makes it easier to write example
+code.  It executes given code line by line printing the code and
+evaluated result.  
+
+The function (({xmp})) evaluates the first argument ((|string|))
+(code) and then prints the code and evaluated value ((|string|))
+result value.
+
+The second argument ((|fmt|)) specifies the report format. The format
+string ((|fmt|)) can include special patterns "%l" and "%r".  "%l"s
+are replaced with the code line and "%r" with the result.  If
 (({false})) or (({nil})) is given as second argument ((|fmt|)),
 (({xmp})) doesn't print the result.  
 
-The second argument ((|fmt|)) specifies the report format. In format
-string ((|fmt|)), special patterns "%l" and "%r" are available.  "%l"s
-are replaced by the line and "%r" by the result.  
-
 The third argument ((|sep|)) specifies the report separator for the 
 multi-line output.  This string ((|sep|)) is put between the output 
 lines unless ((|fmt|)) is false. 
 
 Unless (({false})) is given as the second argument, (({xmp})) can't
-treat a statement which consist of more than one line.  
+treat a statement which consist of more than one line.  If (({false}))
+is given as the second argument (({xmp})) doesn't print the evaluated
+result. In other words it doesn't support multi-line statements.
 
-== CONSTANT
+== CONSTANTS
  
 :XMP_VERSION
   (({XMP_VERSION})) is version string which stand for the last modification
@@ -54,7 +60,7 @@
 
 === EXAMPLE 2
 
-To show each lines 
+To demonstate few built-in library functions
 
   xmp <<-EOS
     a = "The moon Fly"
@@ -114,13 +120,14 @@
 
 == TIPS
 
-(({xmp})) puts ``(({#=> }))'' to each values.  It is covenient when one 
-includes (({xmp}))'s output to an email message by directly cut & paste
-because such message can be cut & paste again to execute by a reader. 
-
-Combinating with (({if __FILE__ == $0})) technic, (({xmp})) is useful to
-show how to use user's library.  For example, one can put some code at
-the end of foo.rb to show usage as follows:
+By default (({xmp})) prepends ``(({#=> }))'' to each evaluated result.
+It is convenient when one includes (({xmp}))'s output to an email
+message by cutting & pasting because such messages can be cut & pasted
+immediately to ruby interpreter by recipient.
+
+In combination with (({if __FILE__ == $0})) idiom, one can give an
+example how to use the functionality in the source file. For example,
+one can put some code at the end of foo.rb to show usage as follows:
 
   if __FILE__ == $0
     require "xmp"
@@ -138,6 +145,10 @@
     EOS
   end
 
+Another example in the end of (({xmp.rb})). For code demonstrating
+purposes, however, usage of RubyUnit or Testsupp might be more
+appropriate.
+
 == SEE ALSO
 
 Irb - interactive ruby (written by Keiju Ishitsuka)
@@ -147,10 +158,13 @@
 (({Xmp}))'s report follows the outout of the first argument ((|string|)) to
 the standard output or the standard error. 
 
+Doesn't handle multi-line statements or comments (well at least :).
+
 == HISTORY
 
- 07 Feb 00: format customizing and excepcion reporting
(gotoken / notwork.org)
- 03 Jan 00: documentation (gotoken / notwork.org)
+2000-07-03: few changes in documentation and simple comment handling
(aleksi)
+2000-02-07: format customizing and excepcion reporting
(gotoken / notwork.org)
+2000-01-03: documentation (gotoken / notwork.org)
 
 == URL
 
@@ -164,8 +178,8 @@
 =end
 
 module Kernel
-  XMP_VERSION = "2000-02-07"
-  XMP_DEFAULT_OPTION = ["%l\n    #%r\n", "\n    #   "]
+  XMP_VERSION = "2000-07-03"
+  XMP_DEFAULT_OPTION = ["%l\n    #=> %r\n", "\n    #   "]
 
   def xmpsec(*a) puts *a; end
 
@@ -176,7 +190,7 @@
       eval(arg.gsub(/^(.*)\n?/){
 	     %Q|
              begin
-	       ___res___ << "=> " + (#{$1}).inspect.gsub(/\n^/, ___sep___);
+	       ___res___ << eval(%Q?#{$1}?).inspect.gsub(/^\n/, ___sep___);
              rescue
                ___res___ << "!! " + $!;
              end|}, TOPLEVEL_BINDING)
@@ -194,6 +208,10 @@
 end
 
 if __FILE__ == $0
+  if ARGV[0] then
+    xmp open(ARGV[0]).read
+    exit
+  end
 
   puts "## EXAMPLE 1"
   xmp "nil.to_i"