[前][次][番号順一覧][スレッド一覧]

ruby-changes:3544

From: ko1@a...
Date: Mon, 14 Jan 2008 12:34:34 +0900 (JST)
Subject: [ruby-changes:3544] drbrain - Ruby:r15033 (trunk): Renamespace lib/rdoc/markup from SM::SimpleMarkup to RDoc::Markup.

drbrain	2008-01-14 12:34:05 +0900 (Mon, 14 Jan 2008)

  New Revision: 15033

  Added files:
    trunk/lib/rdoc/markup/fragments.rb
    trunk/lib/rdoc/markup/inline.rb
    trunk/lib/rdoc/markup/lines.rb
    trunk/lib/rdoc/markup/preprocess.rb
    trunk/lib/rdoc/markup/to_flow.rb
    trunk/lib/rdoc/markup/to_html.rb
    trunk/lib/rdoc/markup/to_latex.rb
    trunk/lib/rdoc/markup.rb
    trunk/lib/rdoc/stats.rb
  Removed files:
    trunk/lib/rdoc/markup/.document
    trunk/lib/rdoc/markup/simple_markup/fragments.rb
    trunk/lib/rdoc/markup/simple_markup/inline.rb
    trunk/lib/rdoc/markup/simple_markup/lines.rb
    trunk/lib/rdoc/markup/simple_markup/preprocess.rb
    trunk/lib/rdoc/markup/simple_markup/to_flow.rb
    trunk/lib/rdoc/markup/simple_markup/to_html.rb
    trunk/lib/rdoc/markup/simple_markup/to_latex.rb
    trunk/lib/rdoc/markup/simple_markup.rb
  Modified files:
    trunk/ChangeLog
    trunk/bin/rdoc
    trunk/lib/.document
    trunk/lib/rdoc/README
    trunk/lib/rdoc/code_objects.rb
    trunk/lib/rdoc/generator/html.rb
    trunk/lib/rdoc/generator/ri.rb
    trunk/lib/rdoc/generator.rb
    trunk/lib/rdoc/parsers/parse_rb.rb
    trunk/lib/rdoc/parsers/parse_simple.rb
    trunk/lib/rdoc/rdoc.rb
    trunk/lib/rdoc/ri/descriptions.rb
    trunk/lib/rdoc/ri/display.rb
    trunk/lib/rdoc/ri/driver.rb
    trunk/lib/rdoc/ri/formatter.rb
    trunk/lib/rdoc/ri/reader.rb
    trunk/lib/rdoc.rb

  Log:
    Renamespace lib/rdoc/markup from SM::SimpleMarkup to RDoc::Markup.

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/to_latex.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/preprocess.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/inline.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/fragments.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/README?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/ri/formatter.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/generator/html.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/ri/driver.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/simple_markup/to_flow.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/simple_markup/fragments.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/parsers/parse_rb.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/to_html.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/generator.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/parsers/parse_simple.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/simple_markup.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/simple_markup/to_html.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/code_objects.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/stats.rb?revision=15033&view=markup
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/stats.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/ri/reader.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/lines.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/generator/ri.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/ri/descriptions.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/simple_markup/to_latex.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/simple_markup/inline.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/.document?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/ri/display.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/rdoc.rb?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/to_flow.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bin/rdoc?r1=15033&r2=15032&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/simple_markup/preprocess.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/simple_markup/lines.rb
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/markup/.document

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 15032)
+++ ChangeLog	(revision 15033)
@@ -1,3 +1,8 @@
+Mon Jan 14 12:33:07 2008  Eric Hodel  <drbrain@s...>
+
+	* lib/rdoc/markup*:  Renamespace from SM::SimpleMarkup to
+	RDoc::Markup.
+
 Mon Jan 14 10:45:45 2008  Martin Duerst  <duerst@i...>
 
 	* enc/ascii.c: Exchanged order of arguments for one ENC_ALIAS
Index: lib/rdoc.rb
===================================================================
--- lib/rdoc.rb	(revision 15032)
+++ lib/rdoc.rb	(revision 15033)
@@ -4,6 +4,13 @@
 module RDoc
 
   ##
+  # Exception thrown by any rdoc error.
+
+  class Error < RuntimeError; end
+
+  RDocError = Error # :nodoc:
+
+  ##
   # RDoc version you are using
 
   VERSION = "2.0.0"
@@ -14,5 +21,16 @@
 
   DOT_DOC_FILENAME = ".document"
 
+  GENERAL_MODIFIERS = %w[nodoc].freeze
+
+  CLASS_MODIFIERS = GENERAL_MODIFIERS
+
+  ATTR_MODIFIERS  = GENERAL_MODIFIERS
+
+  CONSTANT_MODIFIERS = GENERAL_MODIFIERS
+
+  METHOD_MODIFIERS = GENERAL_MODIFIERS +
+    %w[arg args yield yields notnew not-new not_new doc]
+
 end
 
Index: lib/.document
===================================================================
--- lib/.document	(revision 15032)
+++ lib/.document	(revision 15033)
@@ -64,6 +64,7 @@
 pstore.rb
 racc
 rational.rb
+rdoc.rb
 rdoc
 readbytes.rb
 resolv-replace.rb
Index: lib/rdoc/parsers/parse_rb.rb
===================================================================
--- lib/rdoc/parsers/parse_rb.rb	(revision 15032)
+++ lib/rdoc/parsers/parse_rb.rb	(revision 15033)
@@ -7,9 +7,9 @@
 
 # This file contains stuff stolen outright from:
 #
-#   rtags.rb - 
+#   rtags.rb -
 #   ruby-lex.rb - ruby lexcal analizer
-#   ruby-token.rb - ruby tokens 
+#   ruby-token.rb - ruby tokens
 #   	by Keiju ISHITSUKA (Nippon Rational Inc.)
 #
 
@@ -19,11 +19,11 @@
 require "rdoc/code_objects"
 require "rdoc/tokenstream"
 
-require "rdoc/markup/simple_markup/preprocess"
+require "rdoc/markup/preprocess"
 
 require "rdoc/parsers/parserfactory"
 
-$TOKEN_DEBUG = $DEBUG_RDOC
+#$TOKEN_DEBUG = $DEBUG_RDOC
 
 # Definitions of all tokens involved in the lexical analysis
 
@@ -35,7 +35,7 @@
   EXPR_FNAME = :EXPR_FNAME
   EXPR_DOT   = :EXPR_DOT
   EXPR_CLASS = :EXPR_CLASS
-  
+
   class Token
     NO_TEXT = "??".freeze
     attr_accessor :text
@@ -117,8 +117,8 @@
       if (tk = source[token]).nil?
         fail TkReading2TokenNoKey, token
       end
-      tk = Token(tk[0], value) 
-    else 
+      tk = Token(tk[0], value)
+    else
       tk = if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
              token.new(@prev_line_no, @prev_char_no)
            else
@@ -218,14 +218,14 @@
     [:TkASSOC,      TkOp,   "=>"],
     [:TkQUESTION,   TkOp,   "?"],	 #?
     [:TkCOLON,      TkOp,   ":"],        #:
-    
+
     [:TkfLPAREN],         # func( #
     [:TkfLBRACK],         # func[ #
     [:TkfLBRACE],         # func{ #
     [:TkSTAR],            # *arg
     [:TkAMPER],           # &arg #
     [:TkSYMBOL,     TkId],          # :SYMBOL
-    [:TkSYMBEG,     TkId], 
+    [:TkSYMBEG,     TkId],
     [:TkGT,	    TkOp,   ">"],
     [:TkLT,	    TkOp,   "<"],
     [:TkPLUS,	    TkOp,   "+"],
@@ -276,7 +276,7 @@
     token_c =  Class.new super_token
     RubyToken.const_set token_n, token_c
 #    token_c.inspect
- 
+
     if reading
       if TkReading2Token[reading]
         fail TkReading2TokenDuplicateError, token_n, reading
@@ -338,14 +338,14 @@
   # here document.  Once complete, it needs to read the rest of the
   # original line, but then skip the here document body.
   #
-  
+
   class BufferedReader
-    
+
     attr_reader :line_num
-    
+
     def initialize(content, options)
       @options = options
-      
+
       if /\t/ =~ content
         tab_width = @options.tab_width
         content = content.split(/\n/).map do |line|
@@ -363,34 +363,34 @@
       @last_newline = 0
       @newline_pending = false
     end
-    
+
     def column
       @offset - @last_newline
     end
-    
+
     def getc
       return nil if @offset >= @size
       ch = @content[@offset, 1]
-      
+
       @offset += 1
       @hwm = @offset if @hwm < @offset
-      
+
       if @newline_pending
         @line_num += 1
         @last_newline = @offset - 1
         @newline_pending = false
       end
-      
+
       if ch == "\n"
         @newline_pending = true
       end
       ch
     end
-    
+
     def getc_already_read
       getc
     end
-    
+
     def ungetc(ch)
       raise "unget past beginning of file" if @offset <= 0
       @offset -= 1
@@ -398,13 +398,13 @@
         @newline_pending = false
       end
     end
-    
+
     def get_read
       res = @content[@read_back_offset...@offset]
       @read_back_offset = @offset
       res
     end
-    
+
     def peek(at)
       pos = @offset + at
       if pos >= @size
@@ -413,11 +413,11 @@
         @content[pos, 1]
       end
     end
-    
+
     def peek_equal(str)
       @content[@offset, str.length] == str
     end
-    
+
     def divert_read_from(reserve)
       @content[@offset, 0] = reserve
       @size      = @content.size
@@ -430,10 +430,10 @@
   def_exception(:AlreadyDefinedToken, "Already defined token(%s)")
   def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')")
   def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')")
-  def_exception(:TkReading2TokenDuplicateError, 
+  def_exception(:TkReading2TokenDuplicateError,
 		"key duplicate(token_n='%s', key='%s')")
   def_exception(:SyntaxError, "%s")
-  
+
   include RubyToken
   include IRB
 
@@ -459,7 +459,7 @@
     @quoted = nil
     @lex_state = EXPR_BEG
     @space_seen = false
-    
+
     @continue = false
     @line = ""
 
@@ -546,10 +546,9 @@
       get_read
     end
 #   throw :eof unless tk
-    p tk if $DEBUG_RDOC
     tk
   end
-  
+
   ENINDENT_CLAUSE = [
     "case", "class", "def", "do", "for", "if",
     "module", "unless", "until", "while", "begin" #, "when"
@@ -564,7 +563,7 @@
     "r" => "/",
     "w" => "]"
   }
-  
+
   PERCENT_PAREN = {
     "{" => "}",
     "[" => "]",
@@ -647,10 +646,10 @@
       Token(TkNL).set_text("\n")
     end
 
-    @OP.def_rules("*", "**",	
+    @OP.def_rules("*", "**",
 		  "!", "!=", "!~",
-		  "=", "==", "===", 
-		  "=~", "<=>",	
+		  "=", "==", "===",
+		  "=~", "<=>",
 		  "<", "<=",
 		  ">", ">=", ">>") do
       |op, io|
@@ -717,8 +716,8 @@
       @lex_state = EXPR_BEG
       Token(op).set_text(op)
     end
-    
-    @OP.def_rules("+=", "-=", "*=", "**=", 
+
+    @OP.def_rules("+=", "-=", "*=", "**=",
 		  "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
       |op, io|
       @lex_state = EXPR_BEG
@@ -772,7 +771,7 @@
 
     lex_int2
   end
-  
+
   def lex_int2
     @OP.def_rules("]", "}", ")") do
       |op, io|
@@ -814,7 +813,7 @@
 	Token(TkOPASGN, :/).set_text("/=") #")
       elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
 	identify_string(op)
-      else 
+      else
 	@lex_state = EXPR_BEG
         Token("/").set_text(op)
       end
@@ -829,7 +828,7 @@
     # 	@lex_state = EXPR_BEG
     # 	Token(TkOPASGN, :^)
     #       end
-    
+
     @OP.def_rules(",", ";") do
       |op, io|
       @lex_state = EXPR_BEG
@@ -845,7 +844,7 @@
       @lex_state = EXPR_BEG
       Token("~").set_text("~@")
     end
-    
+
     @OP.def_rule("(") do
       @indent += 1
       if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
@@ -895,15 +894,15 @@
     end
 
     @OP.def_rule('\\') do   #'
-      if getc == "\n" 
+      if getc == "\n"
 	@space_seen = true
 	@continue = true
 	Token(TkSPACE).set_text("\\\n")
-      else 
+      else
 	ungetc
 	Token("\\").set_text("\\")  #"
-      end 
-    end 
+      end
+    end
 
     @OP.def_rule('%') do
       |op, io|
@@ -933,7 +932,7 @@
       end
     end
 
-    #       @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do 
+    #       @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do
     # 	|op, io|
     # 	@indent += 1
     # 	@lex_state = EXPR_FNAME
@@ -958,10 +957,10 @@
       printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug?
       t
     end
-    
+
     p @OP if RubyLex.debug?
   end
-  
+
   def identify_gvar
     @lex_state = EXPR_END
     str = "$"
@@ -970,15 +969,15 @@
          when /[~_*$?!@\/\\;,=:<>".]/   #"
            str << ch
            Token(TkGVAR, str)
-           
+
          when "-"
            str << "-" << getc
            Token(TkGVAR, str)
-           
+
          when "&", "`", "'", "+"
            str << ch
            Token(TkBACK_REF, str)
-           
+
          when /[1-9]/
            str << ch
            while (ch = getc) =~ /[0-9]/
@@ -990,13 +989,13 @@
            ungetc
            ungetc
            return identify_identifier
-         else 
+         else
            ungetc
-           Token("$")     
+           Token("$")
          end
     tk.set_text(str)
   end
-  
+
   def identify_identifier
     token = ""
     token.concat getc if peek(0) =~ /[$@]/
@@ -1007,7 +1006,7 @@
       token.concat ch
     end
     ungetc
-    
+
     if ch == "!" or ch == "?"
       token.concat getc
     end
@@ -1022,7 +1021,7 @@
       @lex_state = EXPR_END
       return Token(TkIVAR, token).set_text(token)
     end
-    
+
     if @lex_state != EXPR_DOT
       print token, "\n" if RubyLex.debug?
 
@@ -1120,7 +1119,7 @@
     @lex_state = EXPR_END
     Token(Ltype2Token[lt], str).set_text(str.dump)
   end
-  
+
   def identify_quotation(initial_char)
     ch = getc
     if lt = PERCENT_LTYPE[ch]
@@ -1201,7 +1200,7 @@
     end
     Token(type).set_text(str)
   end
-  
+
   def identify_string(ltype, quoted = ltype, opener=nil, initial_char = nil)
     @ltype = ltype
     @quoted = quoted
@@ -1213,9 +1212,9 @@
 
     nest = 0
     begin
-      while ch = getc 
+      while ch = getc
 	str << ch
-	if @quoted == ch 
+	if @quoted == ch
           if nest == 0
             break
           else
@@ -1276,7 +1275,7 @@
         if ch == "\n"
           ch = " "
         else
-          comment << "\\" 
+          comment << "\\"
         end
       else
         if ch == "\n"
@@ -1289,7 +1288,7 @@
     end
     return Token(TkCOMMENT).set_text(comment)
   end
-  
+
   def read_escape
     res = ""
     case ch = getc
@@ -1306,7 +1305,7 @@
 	end
         res << ch
       end
-      
+
     when "x"
       res << ch
       2.times do
@@ -1361,493 +1360,476 @@
 #
 # This file is based on rtags
 
-module RDoc
+class RDoc::RubyParser
 
-  GENERAL_MODIFIERS = [ 'nodoc' ].freeze
+  include RubyToken
+  include RDoc::TokenStream
 
-  CLASS_MODIFIERS = GENERAL_MODIFIERS
+  extend RDoc::ParserFactory
 
-  ATTR_MODIFIERS  = GENERAL_MODIFIERS
+  parse_files_matching(/\.rbw?$/)
 
-  CONSTANT_MODIFIERS = GENERAL_MODIFIERS
+  def initialize(top_level, file_name, content, options, stats)
+    @options = options
+    @stats   = stats
+    @size = 0
+    @token_listeners = nil
+    @input_file_name = file_name
+    @scanner = RubyLex.new content, @options
+    @scanner.exception_on_syntax_error = false
+    @top_level = top_level
+    @progress = $stderr unless options.quiet
+  end
 
-  METHOD_MODIFIERS = GENERAL_MODIFIERS + 
-    [ 'arg', 'args', 'yield', 'yields', 'notnew', 'not-new', 'not_new', 'doc' ]
+  def scan
+    @tokens = []
+    @unget_read = []
+    @read = []
+    catch(:eof) do
+      catch(:enddoc) do
+        begin
+          parse_toplevel_statements(@top_level)
+        rescue Exception => e
+          $stderr.puts "\n\n"
+          $stderr.puts "RDoc failure in #@input_file_name at or around " +
+                       "line #{@scanner.line_no} column #{@scanner.char_no}"
+          $stderr.puts
+          $stderr.puts "Before reporting this, could you check that the file"
+          $stderr.puts "you're documenting compiles cleanly--RDoc is not a"
+          $stderr.puts "full Ruby parser, and gets confused easily if fed"
+          $stderr.puts "invalid programs."
+          $stderr.puts
+          $stderr.puts "The internal error was:\n\n"
 
-
-  class RubyParser
-    include RubyToken
-    include TokenStream
-
-    extend ParserFactory
-
-    parse_files_matching(/\.rbw?$/)
-
-
-    def initialize(top_level, file_name, content, options, stats)
-      @options = options
-      @stats   = stats
-      @size = 0
-      @token_listeners = nil
-      @input_file_name = file_name
-      @scanner = RubyLex.new content, @options
-      @scanner.exception_on_syntax_error = false
-      @top_level = top_level
-      @progress = $stderr unless options.quiet
-    end
-
-    def scan
-      @tokens = []
-      @unget_read = []
-      @read = []
-      catch(:eof) do
-        catch(:enddoc) do
-          begin
-            parse_toplevel_statements(@top_level)
-          rescue Exception => e
-            $stderr.puts "\n\n"
-            $stderr.puts "RDoc failure in #@input_file_name at or around " +
-                         "line #{@scanner.line_no} column #{@scanner.char_no}"
-            $stderr.puts 
-            $stderr.puts "Before reporting this, could you check that the file"
-            $stderr.puts "you're documenting compiles cleanly--RDoc is not a"
-            $stderr.puts "full Ruby parser, and gets confused easily if fed"
-            $stderr.puts "invalid programs."
-            $stderr.puts
-            $stderr.puts "The internal error was:\n\n"
-            
-            e.set_backtrace(e.backtrace[0,4])
-            raise
-          end
+          e.set_backtrace(e.backtrace[0,4])
+          raise
         end
       end
-      @top_level
     end
+    @top_level
+  end
 
-    private 
+  private
 
-    def make_message(msg)
-      prefix = "\n" + @input_file_name + ":"
-      if @scanner
-        prefix << "#{@scanner.line_no}:#{@scanner.char_no}: "
-      end
-      return prefix + msg
+  def make_message(msg)
+    prefix = "\n" + @input_file_name + ":"
+    if @scanner
+      prefix << "#{@scanner.line_no}:#{@scanner.char_no}: "
     end
+    return prefix + msg
+  end
 
-    def warn(msg)
-      return if @options.quiet
-      msg = make_message msg
-      $stderr.puts msg
-    end
+  def warn(msg)
+    return if @options.quiet
+    msg = make_message msg
+    $stderr.puts msg
+  end
 
-    def error(msg)
-      msg = make_message msg
-      $stderr.puts msg
-      exit(1)
-    end
+  def error(msg)
+    msg = make_message msg
+    $stderr.puts msg
+    exit(1)
+  end
 
-    def progress(char)
-      unless @options.quiet
-        @progress.print(char)
-	@progress.flush
-      end
+  def progress(char)
+    unless @options.quiet
+      @progress.print(char)
+      @progress.flush
     end
+  end
 
-    def add_token_listener(obj)
-      @token_listeners ||= []
-      @token_listeners << obj
-    end
+  def add_token_listener(obj)
+    @token_listeners ||= []
+    @token_listeners << obj
+  end
 
-    def remove_token_listener(obj)
-      @token_listeners.delete(obj)
+  def remove_token_listener(obj)
+    @token_listeners.delete(obj)
+  end
+
+  def get_tk
+    tk = nil
+    if @tokens.empty?
+      tk = @scanner.token
+      @read.push @scanner.get_read
+      puts "get_tk1 => #{tk.inspect}" if $TOKEN_DEBUG
+    else
+      @read.push @unget_read.shift
+      tk = @tokens.shift
+      puts "get_tk2 => #{tk.inspect}" if $TOKEN_DEBUG
     end
 
-    def get_tk
-      tk = nil
-      if @tokens.empty?
-	tk = @scanner.token
-	@read.push @scanner.get_read
-	puts "get_tk1 => #{tk.inspect}" if $TOKEN_DEBUG
-      else
-	@read.push @unget_read.shift
-	tk = @tokens.shift
-	puts "get_tk2 => #{tk.inspect}" if $TOKEN_DEBUG
-      end
-
-      if tk.kind_of?(TkSYMBEG)
-        set_token_position(tk.line_no, tk.char_no)
-        tk1 = get_tk
-        if tk1.kind_of?(TkId) || tk1.kind_of?(TkOp) || tk1.kind_of?(TkSTRING)
-          if tk1.respond_to?(:name)
-            tk = Token(TkSYMBOL).set_text(":" + tk1.name)
-          else
-            tk = Token(TkSYMBOL).set_text(":" + tk1.text)
-          end
-          # remove the identifier we just read (we're about to
-          # replace it with a symbol)
-          @token_listeners.each do |obj|
-            obj.pop_token
-          end if @token_listeners
+    if tk.kind_of?(TkSYMBEG)
+      set_token_position(tk.line_no, tk.char_no)
+      tk1 = get_tk
+      if tk1.kind_of?(TkId) || tk1.kind_of?(TkOp) || tk1.kind_of?(TkSTRING)
+        if tk1.respond_to?(:name)
+          tk = Token(TkSYMBOL).set_text(":" + tk1.name)
         else
-          warn("':' not followed by identifier or operator")
-          tk = tk1
+          tk = Token(TkSYMBOL).set_text(":" + tk1.text)
         end
+        # remove the identifier we just read (we're about to
+        # replace it with a symbol)
+        @token_listeners.each do |obj|
+          obj.pop_token
+        end if @token_listeners
+      else
+        warn("':' not followed by identifier or operator")
+        tk = tk1
       end
+    end
 
-      # inform any listeners of our shiny new token
-      @token_listeners.each do |obj|
-        obj.add_token(tk)
-      end if @token_listeners
+    # inform any listeners of our shiny new token
+    @token_listeners.each do |obj|
+      obj.add_token(tk)
+    end if @token_listeners
 
-      tk
-    end
+    tk
+  end
 
-    def peek_tk
-      unget_tk(tk = get_tk)
-      tk
-    end
+  def peek_tk
+    unget_tk(tk = get_tk)
+    tk
+  end
 
-    def unget_tk(tk)
-      @tokens.unshift tk
-      @unget_read.unshift @read.pop
+  def unget_tk(tk)
+    @tokens.unshift tk
+    @unget_read.unshift @read.pop
 
-      # Remove this token from any listeners
-      @token_listeners.each do |obj|
-        obj.pop_token
-      end if @token_listeners
-    end
+    # Remove this token from any listeners
+    @token_listeners.each do |obj|
+      obj.pop_token
+    end if @token_listeners
+  end
 
-    def skip_tkspace(skip_nl = true)
-      tokens = []
-      while ((tk = get_tk).kind_of?(TkSPACE) ||
-	     (skip_nl && tk.kind_of?(TkNL)))
-	tokens.push tk
-      end
-      unget_tk(tk)
-      tokens
+  def skip_tkspace(skip_nl = true)
+    tokens = []
+    while ((tk = get_tk).kind_of?(TkSPACE) ||
+     (skip_nl && tk.kind_of?(TkNL)))
+      tokens.push tk
     end
+    unget_tk(tk)
+    tokens
+  end
 
-    def get_tkread
-      read = @read.join("")
-      @read = []
-      read
-    end
+  def get_tkread
+    read = @read.join("")
+    @read = []
+    read
+  end
 
-    def peek_read
-      @read.join('')
-    end
+  def peek_read
+    @read.join('')
+  end
 
-    NORMAL = "::"
-    SINGLE = "<<"
+  NORMAL = "::"
+  SINGLE = "<<"
 
-    # Look for the first comment in a file that isn't
-    # a shebang line.
+  ##
+  # Look for the first comment in a file that isn't a shebang line.
 
-    def collect_first_comment
-      skip_tkspace
-      res = ''
-      first_line = true
+  def collect_first_comment
+    skip_tkspace
+    res = ''
+    first_line = true
 
-      tk = get_tk
-      while tk.kind_of?(TkCOMMENT)
-        if first_line && tk.text[0,2] == "#!"
-          skip_tkspace
+    tk = get_tk
+    while tk.kind_of?(TkCOMMENT)
+      if first_line && tk.text[0,2] == "#!"
+        skip_tkspace
+        tk = get_tk
+      else
+        res << tk.text << "\n"
+        tk = get_tk
+        if tk.kind_of? TkNL
+          skip_tkspace(false)
           tk = get_tk
-        else
-          res << tk.text << "\n"
-          tk = get_tk
-          if tk.kind_of? TkNL
-            skip_tkspace(false)
-            tk = get_tk
-          end
         end
-        first_line = false
       end
-      unget_tk(tk)
-      res
+      first_line = false
     end
+    unget_tk(tk)
+    res
+  end
 
-    def parse_toplevel_statements(container)
-      comment = collect_first_comment
-      look_for_directives_in(container, comment)
-      container.comment = comment unless comment.empty?
-      parse_statements(container, NORMAL, nil, comment)
-    end
-    
-    def parse_statements(container, single=NORMAL, current_method=nil, comment='')
-      nest = 1
-      save_visibility = container.visibility
-      
+  def parse_toplevel_statements(container)
+    comment = collect_first_comment
+    look_for_directives_in(container, comment)
+    container.comment = comment unless comment.empty?
+    parse_statements(container, NORMAL, nil, comment)
+  end
+
+  def parse_statements(container, single=NORMAL, current_method=nil, comment='')
+    nest = 1
+    save_visibility = container.visibility
+
 #      if container.kind_of?(TopLevel)
 #      else
 #        comment = ''
 #      end
 
-      non_comment_seen = true
-      
-      while tk = get_tk
-        
-        keep_comment = false
-        
-        non_comment_seen = true unless tk.kind_of?(TkCOMMENT)
-        
-	case tk
+    non_comment_seen = true
 
-        when TkNL
-          skip_tkspace(true)   # Skip blanks and newlines
-          tk = get_tk
-          if tk.kind_of?(TkCOMMENT)
-            if non_comment_seen
-              comment = ''
-              non_comment_seen = false
+    while tk = get_tk
+      keep_comment = false
+
+      non_comment_seen = true unless tk.kind_of?(TkCOMMENT)
+
+      case tk
+      when TkNL
+        skip_tkspace(true)   # Skip blanks and newlines
+        tk = get_tk
+        if tk.kind_of?(TkCOMMENT)
+          if non_comment_seen
+            comment = ''
+            non_comment_seen = false
+          end
+          while tk.kind_of?(TkCOMMENT)
+            comment << tk.text << "\n"
+            tk = get_tk          # this is the newline
+            skip_tkspace(false)  # leading spaces
+            tk = get_tk
+          end
+          unless comment.empty?
+            look_for_directives_in(container, comment)
+            if container.done_documenting
+              container.ongoing_visibility = save_visibility
+              #                return
             end
-            while tk.kind_of?(TkCOMMENT)
-              comment << tk.text << "\n"
-              tk = get_tk          # this is the newline 
-              skip_tkspace(false)  # leading spaces
-              tk = get_tk
-            end
-            unless comment.empty?
-              look_for_directives_in(container, comment) 
-              if container.done_documenting
-                container.ongoing_visibility = save_visibility
-#                return
-              end
-            end
-            keep_comment = true
-          else
-            non_comment_seen = true
           end
-          unget_tk(tk)
           keep_comment = true
+        else
+          non_comment_seen = true
+        end
+        unget_tk(tk)
+        keep_comment = true
 
+      when TkCLASS
+        if container.document_children
+          parse_class(container, single, tk, comment)
+        else
+          nest += 1
+        end
 
-	when TkCLASS
-	  if container.document_children
-            parse_class(container, single, tk, comment)
-	  else
-	    nest += 1
-          end
+      when TkMODULE
+        if container.document_children
+          parse_module(container, single, tk, comment)
+        else
+          nest += 1
+        end
 
-	when TkMODULE
-	  if container.document_children
-            parse_module(container, single, tk, comment)
-	  else
-	    nest += 1
-          end
+      when TkDEF
+        if container.document_self
+          parse_method(container, single, tk, comment)
+        else
+          nest += 1
+        end
 
-	when TkDEF
-	  if container.document_self
-	    parse_method(container, single, tk, comment)
-	  else
-	    nest += 1
-          end
+      when TkCONSTANT
+        if container.document_self
+          parse_constant(container, single, tk, comment)
+        end
 
-        when TkCONSTANT
-          if container.document_self
-            parse_constant(container, single, tk, comment)
-          end
+      when TkALIAS
+        if container.document_self
+          parse_alias(container, single, tk, comment)
+        end
 
-	when TkALIAS
- 	  if container.document_self
-	    parse_alias(container, single, tk, comment)
-	  end
+      when TkYIELD
+        if current_method.nil?
+          warn("Warning: yield outside of method") if container.document_self
+        else
+          parse_yield(container, single, tk, current_method)
+        end
 
-        when TkYIELD
-          if current_method.nil?
-            warn("Warning: yield outside of method") if container.document_self
-          else
-            parse_yield(container, single, tk, current_method)
-          end
+        # Until and While can have a 'do', which shouldn't increas
+        # the nesting. We can't solve the general case, but we can
+        # handle most occurrences by ignoring a do at the end of a line
 
-          # Until and While can have a 'do', which shouldn't increas
-          # the nesting. We can't solve the general case, but we can
-          # handle most occurrences by ignoring a do at the end of a line
+      when  TkUNTIL, TkWHILE
+        nest += 1
+        puts "Found #{tk.class} in #{container.name}, nest = #{nest}, " +
+             "line #{tk.line_no}" if $DEBUG_RDOC
+        skip_optional_do_after_expression
 
-        when  TkUNTIL, TkWHILE
-          nest += 1
-          puts "FOUND #{tk.class} in #{container.name}, nest = #{nest}, " +
-            "line #{tk.line_no}" if $DEBUG_RDOC
-          skip_optional_do_after_expression
-
           # 'for' is trickier
-        when TkFOR
-          nest += 1
-          puts "FOUND #{tk.class} in #{container.name}, nest = #{nest}, " +
-            "line #{tk.line_no}" if $DEBUG_RDOC
-          skip_for_variable
-          skip_optional_do_after_expression
+      when TkFOR
+        nest += 1
+        puts "Found #{tk.class} in #{container.name}, nest = #{nest}, " +
+             "line #{tk.line_no}" if $DEBUG_RDOC
+        skip_for_variable
+        skip_optional_do_after_expression
 
-	when TkCASE, TkDO, TkIF, TkUNLESS, TkBEGIN
-	  nest += 1
-          puts "Found #{tk.class} in #{container.name}, nest = #{nest}, " +
-            "line #{tk.line_no}" if $DEBUG_RDOC
+      when TkCASE, TkDO, TkIF, TkUNLESS, TkBEGIN
+        nest += 1
+        puts "Found #{tk.class} in #{container.name}, nest = #{nest}, " +
+             "line #{tk.line_no}" if $DEBUG_RDOC
 
-	when TkIDENTIFIER
-          if nest == 1 and current_method.nil?
-            case tk.name
-            when "private", "protected", "public",
-                 "private_class_method", "public_class_method"
-              parse_visibility(container, single, tk)
-              keep_comment = true
-            when "attr"
-              parse_attr(container, single, tk, comment)
-            when /^attr_(reader|writer|accessor)$/, @options.extra_accessors
-              parse_attr_accessor(container, single, tk, comment)
-            when "alias_method"
-              if container.document_self
-	        parse_alias(container, single, tk, comment)
-	      end
+      when TkIDENTIFIER
+        if nest == 1 and current_method.nil?
+          case tk.name
+          when "private", "protected", "public",
+               "private_class_method", "public_class_method"
+               parse_visibility(container, single, tk)
+            keep_comment = true
+          when "attr"
+            parse_attr(container, single, tk, comment)
+          when /^attr_(reader|writer|accessor)$/, @options.extra_accessors
+            parse_attr_accessor(container, single, tk, comment)
+          when "alias_method"
+            if container.document_self
+              parse_alias(container, single, tk, comment)
             end
-	  end
-	  
-	  case tk.name
-	  when "require"
-	    parse_require(container, comment)
-	  when "include"
-	    parse_include(container, comment)
-	  end
-
-
-	when TkEND
-          nest -= 1
-          puts "Found 'end' in #{container.name}, nest = #{nest}, line #{tk.line_no}" if $DEBUG_RDOC
-          puts "Method = #{current_method.name}" if $DEBUG_RDOC and current_method
-	  if nest == 0
-            read_documentation_modifiers(container, CLASS_MODIFIERS)
-            container.ongoing_visibility = save_visibility
-            return
           end
+        end
 
-	end
+        case tk.name
+        when "require"
+          parse_require(container, comment)
+        when "include"
+          parse_include(container, comment)
+        end
 
-        comment = '' unless keep_comment
-	begin
-	  get_tkread
-	  skip_tkspace(false)
-	end while peek_tk == TkNL
 
+      when TkEND
+        nest -= 1
+        puts "Found 'end' in #{container.name}, nest = #{nest}, line #{tk.line_no}" if $DEBUG_RDOC
+        puts "Method = #{current_method.name}" if $DEBUG_RDOC and current_method
+        if nest == 0
+          read_documentation_modifiers container, RDoc::CLASS_MODIFIERS
+          container.ongoing_visibility = save_visibility
+          return
+        end
+
       end
+
+      comment = '' unless keep_comment
+
+      begin
+        get_tkread
+        skip_tkspace(false)
+      end while peek_tk == TkNL
     end
-    
-    def parse_class(container, single, tk, comment, &block)
-      progress("c")
+  end
 
-      @stats.num_classes += 1
+  def parse_class(container, single, tk, comment, &block)
+    progress("c")
 
-      container, name_t = get_class_or_module(container)
+    @stats.num_classes += 1
 
-      case name_t
-      when TkCONSTANT
-	name = name_t.name
-        superclass = "Object"
+    container, name_t = get_class_or_module(container)
 
-        if peek_tk.kind_of?(TkLT)
-          get_tk
-          skip_tkspace(true)
-          superclass = get_class_specification
-          superclass = "<unknown>" if superclass.empty?
-        end
+    case name_t
+    when TkCONSTANT
+      name = name_t.name
+      superclass = "Object"
 
-	if single == SINGLE
-	  cls_type = SingleClass
-	else
-	  cls_type = NormalClass
-	end
+      if peek_tk.kind_of?(TkLT)
+        get_tk
+        skip_tkspace(true)
+        superclass = get_class_specification
+        superclass = "<unknown>" if superclass.empty?
+      end
 
-        cls = container.add_class(cls_type, name, superclass)
-        read_documentation_modifiers(cls, CLASS_MODIFIERS)
-        cls.record_location(@top_level)
-	parse_statements(cls)
-        cls.comment = comment
+      if single == SINGLE
+        cls_type = RDoc::SingleClass
+      else
+        cls_type = RDoc::NormalClass
+      end
 
-      when TkLSHFT
-	case name = get_class_specification
-	when "self", container.name
-	  parse_statements(container, SINGLE, &block)
-	else
-          other = TopLevel.find_class_named(name)
-          unless other
-#            other = @top_level.add_class(NormalClass, name, nil)
-#            other.record_location(@top_level)
-#            other.comment = comment
-            other = NormalClass.new("Dummy", nil)
-          end
-          read_documentation_modifiers(other, CLASS_MODIFIERS)
-          parse_statements(other, SINGLE, &block)
-	end
+      cls = container.add_class cls_type, name, superclass
+      read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
+      cls.record_location(@top_level)
+      parse_statements(cls)
+      cls.comment = comment
 
+    when TkLSHFT
+      case name = get_class_specification
+      when "self", container.name
+        parse_statements(container, SINGLE, &block)
       else
-	warn("Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}")
+        other = RDoc::TopLevel.find_class_named(name)
+        unless other
+          #            other = @top_level.add_class(NormalClass, name, nil)
+          #            other.record_location(@top_level)
+          #            other.comment = comment
+          other = RDoc::NormalClass.new "Dummy", nil
+        end
+        read_documentation_modifiers other, RDoc::CLASS_MODIFIERS
+        parse_statements(other, SINGLE, &block)
       end
+
+    else
+      warn("Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}")
     end
+  end
 
-    def parse_module(container, single, tk, comment)
-      progress("m")
-      @stats.num_modules += 1
-      container, name_t  = get_class_or_module(container)
+  def parse_module(container, single, tk, comment)
+    progress("m")
+    @stats.num_modules += 1
+    container, name_t  = get_class_or_module(container)
 #      skip_tkspace
-      name = name_t.name
-      mod = container.add_module(NormalModule, name)
-      mod.record_location(@top_level)
-      read_documentation_modifiers(mod, CLASS_MODIFIERS)
-      parse_statements(mod)
-      mod.comment = comment
-    end
+    name = name_t.name
+    mod = container.add_module RDoc::NormalModule, name
+    mod.record_location @top_level
+    read_documentation_modifiers mod, RDoc::CLASS_MODIFIERS
+    parse_statements(mod)
+    mod.comment = comment
+  end
 
-    # Look for the name of a class of module (optionally with a leading :: or
-    # with :: separated named) and return the ultimate name and container
+  # Look for the name of a class of module (optionally with a leading :: or
+  # with :: separated named) and return the ultimate name and container
 
-    def get_class_or_module(container)
-      skip_tkspace
+  def get_class_or_module(container)
+    skip_tkspace
+    name_t = get_tk
+
+    # class ::A -> A is in the top level
+    if name_t.kind_of?(TkCOLON2)
       name_t = get_tk
+      container = @top_level
+    end
 
-      # class ::A -> A is in the top level
-      if name_t.kind_of?(TkCOLON2)
-        name_t = get_tk
-        container = @top_level
-      end
+    skip_tkspace(false)
 
-      skip_tkspace(false)
-
-      while peek_tk.kind_of?(TkCOLON2)
-        prev_container = container
-        container = container.find_module_named(name_t.name)
-        if !container
+    while peek_tk.kind_of?(TkCOLON2)
+      prev_container = container
+      container = container.find_module_named(name_t.name)
+      if !container
 #          warn("Couldn't find module #{name_t.name}")
-          container = prev_container.add_module(NormalModule, name_t.name)
-        end
-        get_tk
-        name_t = get_tk
+        container = prev_container.add_module RDoc::NormalModule, name_t.name
       end
-      skip_tkspace(false)
-      return [container, name_t]
+      get_tk
+      name_t = get_tk
     end
+    skip_tkspace(false)
+    return [container, name_t]
+  end
 
-    def parse_constant(container, single, tk, comment)
-      name = tk.name
-      skip_tkspace(false)
-      eq_tk = get_tk
+  def parse_constant(container, single, tk, comment)
+    name = tk.name
+    skip_tkspace(false)
+    eq_tk = get_tk
 
-      unless eq_tk.kind_of?(TkASSIGN)
-        unget_tk(eq_tk)
-        return
-      end
+    unless eq_tk.kind_of?(TkASSIGN)
+      unget_tk(eq_tk)
+      return
+    end
 
 
-      nest = 0
-      get_tkread
+    nest = 0
+    get_tkread
 
-      tk = get_tk
-      if tk.kind_of? TkGT
-        unget_tk(tk)
-        unget_tk(eq_tk)
-        return
-      end
+    tk = get_tk
+    if tk.kind_of? TkGT
+      unget_tk(tk)
+      unget_tk(eq_tk)
+      return
+    end
 
-      loop do
-        puts("Param: #{tk}, #{@scanner.continue} " +
-          "#{@scanner.lex_state} #{nest}")  if $DEBUG_RDOC
+    loop do
+      puts "Param: %p, %s %s %s" %
+        [tk.text, @scanner.continue, @scanner.lex_state, nest] if $DEBUG_RDOC
 
         case tk
         when TkSEMICOLON
@@ -1868,182 +1850,184 @@
           end
         end
         tk = get_tk
-      end
+    end
 
-      res = get_tkread.tr("\n", " ").strip
-      res = "" if res == ";"
-      con = Constant.new(name, res, comment)
-      read_documentation_modifiers(con, CONSTANT_MODIFIERS)
-      if con.document_self
-	container.add_constant(con)
-      end
+    res = get_tkread.tr("\n", " ").strip
+    res = "" if res == ";"
+
+    con = RDoc::Constant.new name, res, comment
+    read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS
+
+    if con.document_self
+      container.add_constant(con)
     end
+  end
 
-    def parse_method(container, single, tk, comment)
-      progress(".")
-      @stats.num_methods += 1
-      line_no = tk.line_no
-      column  = tk.char_no
-      
-      start_collecting_tokens
-      add_token(tk)
-      add_token_listener(self)
-      
-      @scanner.instance_eval{@lex_state = EXPR_FNAME}
-      skip_tkspace(false)
-      name_t = get_tk
-      back_tk = skip_tkspace
-      meth = nil
-      added_container = false
+  def parse_method(container, single, tk, comment)
+    progress(".")
+    @stats.num_methods += 1
+    line_no = tk.line_no
+    column  = tk.char_no
 
-      dot = get_tk
-      if dot.kind_of?(TkDOT) or dot.kind_of?(TkCOLON2)
-	@scanner.instance_eval{@lex_state = EXPR_FNAME}
-	skip_tkspace
-	name_t2 = get_tk
-	case name_t
-	when TkSELF
-	  name = name_t2.name
-	when TkCONSTANT
-          name = name_t2.name
-          prev_container = container
-          container = container.find_module_named(name_t.name)
-          if !container
-            added_container = true
-            obj = name_t.name.split("::").inject(Object) do |state, item|
-              state.const_get(item)
-            end rescue nil
+    start_collecting_tokens
+    add_token(tk)
+    add_token_listener(self)
 
-            type = obj.class == Class ? NormalClass : NormalModule
-            if not [Class, Module].include?(obj.class)
-              warn("Couldn't find #{name_t.name}. Assuming it's a module")
-            end
+    @scanner.instance_eval{@lex_state = EXPR_FNAME}
+    skip_tkspace(false)
+    name_t = get_tk
+    back_tk = skip_tkspace
+    meth = nil
+    added_container = false
 
-            if type == NormalClass then
-              container = prev_container.add_class(type, name_t.name, obj.superclass.name)
-            else
-              container = prev_container.add_module(type, name_t.name)
-            end
+    dot = get_tk
+    if dot.kind_of?(TkDOT) or dot.kind_of?(TkCOLON2)
+      @scanner.instance_eval{@lex_state = EXPR_FNAME}
+      skip_tkspace
+      name_t2 = get_tk
+      case name_t
+      when TkSELF
+        name = name_t2.name
+      when TkCONSTANT
+        name = name_t2.name
+        prev_container = container
+        container = container.find_module_named(name_t.name)
+        if !container
+          added_container = true
+          obj = name_t.name.split("::").inject(Object) do |state, item|
+            state.const_get(item)
+          end rescue nil
+
+          type = obj.class == Class ? RDoc::NormalClass : RDoc::NormalModule
+          if not [Class, Module].include?(obj.class)
+            warn("Couldn't find #{name_t.name}. Assuming it's a module")
           end
-	else
-	  # warn("Unexpected token '#{name_t2.inspect}'")
-	  # break
-          skip_method(container)
-          return
-	end
-	meth =  AnyMethod.new(get_tkread, name)
-        meth.singleton = true
-      else
-	unget_tk dot
-	back_tk.reverse_each do |token|
-	  unget_tk token
-	end
-	name = name_t.name
 
-        meth =  AnyMethod.new(get_tkread, name)
-        meth.singleton = (single == SINGLE)
+          if type == RDoc::NormalClass then
+            container = prev_container.add_class(type, name_t.name, obj.superclass.name)
+          else
+            container = prev_container.add_module(type, name_t.name)
+          end
+        end
+      else
+        # warn("Unexpected token '#{name_t2.inspect}'")
+        # break
+        skip_method(container)
+        return
       end
+      meth = RDoc::AnyMethod.new(get_tkread, name)
+      meth.singleton = true
+    else
+      unget_tk dot
+      back_tk.reverse_each do |token|
+        unget_tk token
+      end
+      name = name_t.name
 
-      remove_token_listener(self)
+      meth = RDoc::AnyMethod.new get_tkread, name
+      meth.singleton = (single == SINGLE)
+    end
 
-      meth.start_collecting_tokens
-      indent = TkSPACE.new(1,1)
-      indent.set_text(" " * column)
+    remove_token_listener(self)
 
-      meth.add_tokens([TkCOMMENT.new(line_no,
-                                     1,
-                                     "# File #{@top_level.file_absolute_name}, line #{line_no}"),
-                        NEWLINE_TOKEN,
-                        indent])
+    meth.start_collecting_tokens
+    indent = TkSPACE.new(1,1)
+    indent.set_text(" " * column)
 
-      meth.add_tokens(@token_stream)
+    meth.add_tokens([TkCOMMENT.new(line_no,
+                                   1,
+                                   "# File #{@top_level.file_absolute_name}, line #{line_no}"),
+                      NEWLINE_TOKEN,
+                      indent])
 
-      add_token_listener(meth)
+    meth.add_tokens(@token_stream)
 
-      @scanner.instance_eval{@continue = false}
-      parse_method_parameters(meth)
+    add_token_listener(meth)
 
-      if meth.document_self
-        container.add_method(meth)
-      elsif added_container
-        container.document_self = false
-      end
+    @scanner.instance_eval{@continue = false}
+    parse_method_parameters(meth)
 
-      # Having now read the method parameters and documentation modifiers, we
-      # now know whether we have to rename #initialize to ::new
+    if meth.document_self
+      container.add_method(meth)
+    elsif added_container
+      container.document_self = false
+    end
 
-      if name == "initialize" && !meth.singleton
-        if meth.dont_rename_initialize
-          meth.visibility = :protected
-        else
-          meth.singleton = true
-          meth.name = "new"
-          meth.visibility = :public
-        end
+    # Having now read the method parameters and documentation modifiers, we
+    # now know whether we have to rename #initialize to ::new
+
+    if name == "initialize" && !meth.singleton
+      if meth.dont_rename_initialize
+        meth.visibility = :protected
+      else
+        meth.singleton = true
+        meth.name = "new"
+        meth.visibility = :public
       end
-      
-      parse_statements(container, single, meth)
-      
-      remove_token_listener(meth)
+    end
 
-      # Look for a 'call-seq' in the comment, and override the
-      # normal parameter stuff
+    parse_statements(container, single, meth)
 
-      if comment.sub!(/:?call-seq:(.*?)^\s*\#?\s*$/m, '')
-        seq = $1
-        seq.gsub!(/^\s*\#\s*/, '')
-        meth.call_seq = seq
-      end
-      
-      meth.comment = comment
+    remove_token_listener(meth)
 
-    end
-    
-    def skip_method(container)
-      meth =  AnyMethod.new("", "anon")
-      parse_method_parameters(meth)
-      parse_statements(container, false, meth)
-    end
-    
-    # Capture the method's parameters. Along the way,
-    # look for a comment containing 
-    #
-    #    # yields: ....
-    #
-    # and add this as the block_params for the method
+    # Look for a 'call-seq' in the comment, and override the
+    # normal parameter stuff
 
-    def parse_method_parameters(method)
-      res = parse_method_or_yield_parameters(method)
-      res = "(" + res + ")" unless res[0] == ?(
-      method.params = res unless method.params
-      if method.block_params.nil?
-          skip_tkspace(false)
-	  read_documentation_modifiers(method, METHOD_MODIFIERS)
-      end
+    if comment.sub!(/:?call-seq:(.*?)^\s*\#?\s*$/m, '')
+      seq = $1
+      seq.gsub!(/^\s*\#\s*/, '')
+      meth.call_seq = seq
     end
 
-    def parse_method_or_yield_parameters(method=nil, modifiers=METHOD_MODIFIERS)
+    meth.comment = comment
+  end
+
+  def skip_method(container)
+    meth = RDoc::AnyMethod.new "", "anon"
+    parse_method_parameters(meth)
+    parse_statements(container, false, meth)
+  end
+
+  # Capture the method's parameters. Along the way, look for a comment
+  # containing.
+  #
+  #    # yields: ....
+  #
+  # and add this as the block_params for the method
+
+  def parse_method_parameters(method)
+    res = parse_method_or_yield_parameters(method)
+    res = "(" + res + ")" unless res[0] == ?(
+    method.params = res unless method.params
+    if method.block_params.nil?
       skip_tkspace(false)
-      tk = get_tk
+      read_documentation_modifiers method, RDoc::METHOD_MODIFIERS
+    end
+  end
 
-      # Little hack going on here. In the statement
-      #  f = 2*(1+yield)
-      # We see the RPAREN as the next token, so we need
-      # to exit early. This still won't catch all cases
-      # (such as "a = yield + 1"
-      end_token = case tk
-                  when TkLPAREN, TkfLPAREN
-                    TkRPAREN
-                  when TkRPAREN
-                    return ""
-                  else
-                    TkNL
-                  end
-      nest = 0
+  def parse_method_or_yield_parameters(method = nil,
+                                       modifiers = RDoc::METHOD_MODIFIERS)
+    skip_tkspace(false)
+    tk = get_tk
 
-      loop do
-        puts("Param: #{tk.inspect}, #{@scanner.continue} " +
-          "#{@scanner.lex_state} #{nest}")  if $DEBUG_RDOC
+    # Little hack going on here. In the statement
+    #  f = 2*(1+yield)
+    # We see the RPAREN as the next token, so we need
+    # to exit early. This still won't catch all cases
+    # (such as "a = yield + 1"
+    end_token = case tk
+                when TkLPAREN, TkfLPAREN
+                  TkRPAREN
+                when TkRPAREN
+                  return ""
+                else
+                  TkNL
+                end
+    nest = 0
+
+    loop do
+      puts "Param: %p, %s %s %s" %
+        [tk.text, @scanner.continue, @scanner.lex_state, nest] if $DEBUG_RDOC
         case tk
         when TkSEMICOLON
           break
@@ -2064,113 +2048,113 @@
             break unless @scanner.continue
           end
         when method && method.block_params.nil? && TkCOMMENT
-	  unget_tk(tk)
-	  read_documentation_modifiers(method, modifiers)
+          unget_tk(tk)
+          read_documentation_modifiers(method, modifiers)
         end
-        tk = get_tk
-      end
-      res = get_tkread.tr("\n", " ").strip
-      res = "" if res == ";"
-      res
+      tk = get_tk
     end
+    res = get_tkread.tr("\n", " ").strip
+    res = "" if res == ";"
+    res
+  end
 
-    # skip the var [in] part of a 'for' statement
-    def skip_for_variable
-      skip_tkspace(false)
-      tk = get_tk
-      skip_tkspace(false)
-      tk = get_tk
-      unget_tk(tk) unless tk.kind_of?(TkIN)
+  # skip the var [in] part of a 'for' statement
+  def skip_for_variable
+    skip_tkspace(false)
+    tk = get_tk
+    skip_tkspace(false)
+    tk = get_tk
+    unget_tk(tk) unless tk.kind_of?(TkIN)
+  end
+
+  # while, until, and for have an optional
+  def skip_optional_do_after_expression
+    skip_tkspace(false)
+    tk = get_tk
+    case tk
+    when TkLPAREN, TkfLPAREN
+      end_token = TkRPAREN
+    else
+      end_token = TkNL
     end
 
-    # while, until, and for have an optional 
-    def skip_optional_do_after_expression
-      skip_tkspace(false)
-      tk = get_tk
+    nest = 0
+    @scanner.instance_eval{@continue = false}
+
+    loop do
+      puts("\nWhile: #{tk.text.inspect}, #{@scanner.continue} " \
+           "#{@scanner.lex_state} #{nest}") if $DEBUG_RDOC
       case tk
+      when TkSEMICOLON
+        break
       when TkLPAREN, TkfLPAREN
-        end_token = TkRPAREN
-      else
-        end_token = TkNL
-      end
-
-      nest = 0
-      @scanner.instance_eval{@continue = false}
-
-      loop do
-        puts("\nWhile: #{tk}, #{@scanner.continue} " +
-          "#{@scanner.lex_state} #{nest}") if $DEBUG_RDOC
-        case tk
-        when TkSEMICOLON
-          break
-        when TkLPAREN, TkfLPAREN
-          nest += 1
-        when TkDO
-          break if nest.zero?
-        when end_token
-          if end_token == TkRPAREN
-            nest -= 1
-            break if @scanner.lex_state == EXPR_END and nest.zero?
-          else
-            break unless @scanner.continue
-          end
+        nest += 1
+      when TkDO
+        break if nest.zero?
+      when end_token
+        if end_token == TkRPAREN
+          nest -= 1
+          break if @scanner.lex_state == EXPR_END and nest.zero?
+        else
+          break unless @scanner.continue
         end
-        tk = get_tk
       end
-      skip_tkspace(false)
-      if peek_tk.kind_of? TkDO
-        get_tk
-      end
+      tk = get_tk
     end
-    
-    # Return a superclass, which can be either a constant
-    # of an expression
+    skip_tkspace(false)
+    if peek_tk.kind_of? TkDO
+      get_tk
+    end
+  end
 
-    def get_class_specification
-      tk = get_tk
-      return "self" if tk.kind_of?(TkSELF)
-        
-      res = ""
-      while tk.kind_of?(TkCOLON2) ||
-          tk.kind_of?(TkCOLON3)   ||
-          tk.kind_of?(TkCONSTANT)   
-        
-        res += tk.text
-        tk = get_tk
-      end
+  # Return a superclass, which can be either a constant
+  # of an expression
 
-      unget_tk(tk)
-      skip_tkspace(false)
+  def get_class_specification
+    tk = get_tk
+    return "self" if tk.kind_of?(TkSELF)
 
-      get_tkread # empty out read buffer
+    res = ""
+    while tk.kind_of?(TkCOLON2) ||
+        tk.kind_of?(TkCOLON3)   ||
+        tk.kind_of?(TkCONSTANT)
 
+      res += tk.text
       tk = get_tk
+    end
 
-      case tk
-      when TkNL, TkCOMMENT, TkSEMICOLON
-        unget_tk(tk)
-        return res
-      end
+    unget_tk(tk)
+    skip_tkspace(false)
 
-      res += parse_call_parameters(tk)
-      res
+    get_tkread # empty out read buffer
+
+    tk = get_tk
+
+    case tk
+    when TkNL, TkCOMMENT, TkSEMICOLON
+      unget_tk(tk)
+      return res
     end
 
-    def parse_call_parameters(tk)
+    res += parse_call_parameters(tk)
+    res
+  end
 
-      end_token = case tk
-                  when TkLPAREN, TkfLPAREN
-                    TkRPAREN
-                  when TkRPAREN
-                    return ""
-                  else
-                    TkNL
-                  end
-      nest = 0
+  def parse_call_parameters(tk)
 
-      loop do
-        puts("Call param: #{tk}, #{@scanner.continue} " +
-          "#{@scanner.lex_state} #{nest}") if $DEBUG_RDOC
+    end_token = case tk
+                when TkLPAREN, TkfLPAREN
+                  TkRPAREN
+                when TkRPAREN
+                  return ""
+                else
+                  TkNL
+                end
+    nest = 0
+
+    loop do
+      puts("Call param: #{tk}, #{@scanner.continue} " +
+        "#{@scanner.lex_state} #{nest}") if $DEBUG_RDOC
         case tk
         when TkSEMICOLON
           break
@@ -2184,215 +2168,210 @@
             break unless @scanner.continue
           end
         when TkCOMMENT
-	  unget_tk(tk)
-	  break
+          unget_tk(tk)
+          break
         end
         tk = get_tk
-      end
-      res = get_tkread.tr("\n", " ").strip
-      res = "" if res == ";"
-      res
     end
+    res = get_tkread.tr("\n", " ").strip
+    res = "" if res == ";"
+    res
+  end
 
+  # Parse a constant, which might be qualified by
+  # one or more class or module names
 
-    # Parse a constant, which might be qualified by
-    # one or more class or module names
+  def get_constant
+    res = ""
+    skip_tkspace(false)
+    tk = get_tk
 
-    def get_constant
-      res = ""
-      skip_tkspace(false)
+    while tk.kind_of?(TkCOLON2) ||
+        tk.kind_of?(TkCOLON3)   ||
+        tk.kind_of?(TkCONSTANT)
+
+      res += tk.text
       tk = get_tk
+    end
 
-      while tk.kind_of?(TkCOLON2) ||
-          tk.kind_of?(TkCOLON3)   ||
-          tk.kind_of?(TkCONSTANT)          
-        
-        res += tk.text
-        tk = get_tk
-      end
-
 #      if res.empty?
 #        warn("Unexpected token #{tk} in constant")
-#      end 
-      unget_tk(tk)
-      res
-    end
+#      end
+    unget_tk(tk)
+    res
+  end
 
-    # Get a constant that may be surrounded by parens
-    
-    def get_constant_with_optional_parens
-      skip_tkspace(false)
-      nest = 0
-      while (tk = peek_tk).kind_of?(TkLPAREN)  || tk.kind_of?(TkfLPAREN)
-        get_tk
-        skip_tkspace(true)
-        nest += 1
-      end
+  # Get a constant that may be surrounded by parens
 
-      name = get_constant
-
-      while nest > 0
-        skip_tkspace(true)
-        tk = get_tk
-        nest -= 1 if tk.kind_of?(TkRPAREN)
-      end
-      name
+  def get_constant_with_optional_parens
+    skip_tkspace(false)
+    nest = 0
+    while (tk = peek_tk).kind_of?(TkLPAREN)  || tk.kind_of?(TkfLPAREN)
+      get_tk
+      skip_tkspace(true)
+      nest += 1
     end
 
-    # Directives are modifier comments that can appear after class, module,
-    # or method names. For example
-    #
-    #   def fred    # :yields:  a, b
-    #
-    # or
-    #
-    #   class SM  # :nodoc:
-    #
-    # we return the directive name and any parameters as a two element array
-    
-    def read_directive(allowed)
+    name = get_constant
+
+    while nest > 0
+      skip_tkspace(true)
       tk = get_tk
-      puts "directive: #{tk.inspect}" if $DEBUG_RDOC
-      result = nil
-      if tk.kind_of?(TkCOMMENT) 
-        if tk.text =~ /\s*:?(\w+):\s*(.*)/
-          directive = $1.downcase
-          if allowed.include?(directive)
-            result = [directive, $2]
-          end
+      nest -= 1 if tk.kind_of?(TkRPAREN)
+    end
+    name
+  end
+
+  # Directives are modifier comments that can appear after class, module,
+  # or method names. For example:
+  #
+  #   def fred # :yields:  a, b
+  #
+  # or:
+  #
+  #   class MyClass # :nodoc:
+  #
+  # We return the directive name and any parameters as a two element array
+
+  def read_directive(allowed)
+    tk = get_tk
+    puts "directive: #{tk.text.inspect}" if $DEBUG_RDOC
+    result = nil
+    if tk.kind_of?(TkCOMMENT)
+      if tk.text =~ /\s*:?(\w+):\s*(.*)/
+        directive = $1.downcase
+        if allowed.include?(directive)
+          result = [directive, $2]
         end
-      else
-        unget_tk(tk)
       end
-      result
+    else
+      unget_tk(tk)
     end
+    result
+  end
 
-    
-    def read_documentation_modifiers(context, allow)
-      dir = read_directive(allow)
+  def read_documentation_modifiers(context, allow)
+    dir = read_directive(allow)
 
-      case dir[0]
+    case dir[0]
 
-      when "notnew", "not_new", "not-new"
-        context.dont_rename_initialize = true
+    when "notnew", "not_new", "not-new"
+      context.dont_rename_initialize = true
 
-      when "nodoc"
-        context.document_self = false
-	if dir[1].downcase == "all"
-	  context.document_children = false
-	end
+    when "nodoc"
+      context.document_self = false
+      if dir[1].downcase == "all"
+        context.document_children = false
+      end
 
-      when "doc"
-        context.document_self = true
-        context.force_documentation = true
+    when "doc"
+      context.document_self = true
+      context.force_documentation = true
 
-      when "yield", "yields"
-        unless context.params.nil?
-          context.params.sub!(/(,|)\s*&\w+/,'') # remove parameter &proc
-        end
-	context.block_params = dir[1]
+    when "yield", "yields"
+      unless context.params.nil?
+        context.params.sub!(/(,|)\s*&\w+/,'') # remove parameter &proc
+      end
+    context.block_params = dir[1]
 
-      when "arg", "args"
-        context.params = dir[1]
-      end if dir
-    end
+    when "arg", "args"
+      context.params = dir[1]
+    end if dir
+  end
 
-    
-    # Look for directives in a normal comment block:
-    #
-    #   #--       - don't display comment from this point forward
-    #  
-    #
-    # This routine modifies it's parameter
+  ##
+  # Look for directives in a normal comment block:
+  #
+  #   #--       - don't display comment from this point forward
+  #
+  # This routine modifies it's parameter
 
-    def look_for_directives_in(context, comment)
+  def look_for_directives_in(context, comment)
+    preprocess = RDoc::Markup::PreProcess.new(@input_file_name,
+                                              @options.rdoc_include)
 
-      preprocess = SM::PreProcess.new(@input_file_name,
-                                      @options.rdoc_include)
+    preprocess.handle(comment) do |directive, param|
+      case directive
+      when "stopdoc"
+        context.stop_doc
+        ""
+      when "startdoc"
+        context.start_doc
+        context.force_documentation = true
+        ""
 
-      preprocess.handle(comment) do |directive, param|
-        case directive
-        when "stopdoc"
-          context.stop_doc
-          ""
-        when "startdoc"
-          context.start_doc
-          context.force_documentation = true
-          ""
+      when "enddoc"
+        #context.done_documenting = true
+        #""
+        throw :enddoc
 
-        when "enddoc"
-          #context.done_documenting = true
-          #""
-          throw :enddoc
+      when "main"
+        @options.main_page = param
+        ""
 
-        when "main"
-          @options.main_page = param
-          ""
+      when "title"
+        @options.title = param
+        ""
 
-        when "title"
-          @options.title = param
-          ""
+      when "section"
+        context.set_current_section(param, comment)
+        comment.clear
+        break
 
-        when "section"
-          context.set_current_section(param, comment)
-          comment.clear
-          break 
-        else
-          warn "Unrecognized directive '#{directive}'"
-          break
-        end
+      else
+        warn "Unrecognized directive '#{directive}'"
+        break
       end
-
-      remove_private_comments(comment)
     end
 
-    def remove_private_comments(comment)
-      comment.gsub!(/^#--.*?^#\+\+/m, '')
-      comment.sub!(/^#--.*/m, '')
-    end
+    remove_private_comments(comment)
+  end
 
+  def remove_private_comments(comment)
+    comment.gsub!(/^#--.*?^#\+\+/m, '')
+    comment.sub!(/^#--.*/m, '')
+  end
 
+  def get_symbol_or_name
+    tk = get_tk
+    case tk
+    when  TkSYMBOL
+      tk.text.sub(/^:/, '')
+    when TkId, TkOp
+      tk.name
+    when TkSTRING
+      tk.text
+    else
+      raise "Name or symbol expected (got #{tk})"
+    end
+  end
 
-    def get_symbol_or_name
-      tk = get_tk
-      case tk
-      when  TkSYMBOL
-        tk.text.sub(/^:/, '')
-      when TkId, TkOp
-        tk.name
-      when TkSTRING
-        tk.text
-      else
-        raise "Name or symbol expected (got #{tk})"
-      end
+  def parse_alias(context, single, tk, comment)
+    skip_tkspace
+    if (peek_tk.kind_of? TkLPAREN)
+      get_tk
+      skip_tkspace
     end
-    
-    def parse_alias(context, single, tk, comment)
+    new_name = get_symbol_or_name
+    @scanner.instance_eval{@lex_state = EXPR_FNAME}
+    skip_tkspace
+    if (peek_tk.kind_of? TkCOMMA)
+      get_tk
       skip_tkspace
-      if (peek_tk.kind_of? TkLPAREN)
-        get_tk
-        skip_tkspace
-      end
-      new_name = get_symbol_or_name
-      @scanner.instance_eval{@lex_state = EXPR_FNAME}
-      skip_tkspace
-      if (peek_tk.kind_of? TkCOMMA)
-        get_tk
-        skip_tkspace
-      end
-      old_name = get_symbol_or_name
-
-      al = Alias.new(get_tkread, old_name, new_name, comment)
-      read_documentation_modifiers(al, ATTR_MODIFIERS)
-      if al.document_self
-	context.add_alias(al)
-      end
     end
+    old_name = get_symbol_or_name
 
-    def parse_yield_parameters
-      parse_method_or_yield_parameters
+    al = RDoc::Alias.new get_tkread, old_name, new_name, comment
+    read_documentation_modifiers al, RDoc::ATTR_MODIFIERS
+    if al.document_self
+      context.add_alias(al)
     end
+  end
 
+  def parse_yield_parameters
+    parse_method_or_yield_parameters
+  end
+
   def parse_yield(context, single, tk, method)
     if method.block_params.nil?
       get_tkread
@@ -2413,15 +2392,15 @@
     case tk
     when TkSTRING
       name = tk.text
-#    when TkCONSTANT, TkIDENTIFIER, TkIVAR, TkGVAR
-#      name = tk.name
+      #    when TkCONSTANT, TkIDENTIFIER, TkIVAR, TkGVAR
+      #      name = tk.name
     when TkDSTRING
       warn "Skipping require of dynamic string: #{tk.text}"
- #   else
- #     warn "'require' used as variable"
+      #   else
+      #     warn "'require' used as variable"
     end
     if name
-      context.add_require(Require.new(name, comment))
+      context.add_require(RDoc::Require.new(name, comment))
     else
       unget_tk(tk)
     end
@@ -2432,174 +2411,171 @@
       skip_tkspace_comment
       name = get_constant_with_optional_parens
       unless name.empty?
-        context.add_include(Include.new(name, comment))
+        context.add_include RDoc::Include.new(name, comment)
       end
       return unless peek_tk.kind_of?(TkCOMMA)
       get_tk
     end
   end
 
-    def get_bool
-      skip_tkspace
+  def get_bool
+    skip_tkspace
+    tk = get_tk
+    case tk
+    when TkTRUE
+      true
+    when TkFALSE, TkNIL
+      false
+    else
+      unget_tk tk
+      true
+    end
+  end
+
+  def parse_attr(context, single, tk, comment)
+    args = parse_symbol_arg(1)
+    if args.size > 0
+      name = args[0]
+      rw = "R"
+      skip_tkspace(false)
       tk = get_tk
-      case tk
-      when TkTRUE
-        true
-      when TkFALSE, TkNIL
-        false
+      if tk.kind_of? TkCOMMA
+        rw = "RW" if get_bool
       else
         unget_tk tk
-        true
       end
+      att = RDoc::Attr.new get_tkread, name, rw, comment
+      read_documentation_modifiers att, RDoc::ATTR_MODIFIERS
+      if att.document_self
+        context.add_attribute(att)
+      end
+    else
+      warn("'attr' ignored - looks like a variable")
     end
+  end
 
-    def parse_attr(context, single, tk, comment)
-      args = parse_symbol_arg(1)
-      if args.size > 0
-	name = args[0]
-        rw = "R"
-        skip_tkspace(false)
-        tk = get_tk
-        if tk.kind_of? TkCOMMA
-          rw = "RW" if get_bool
-        else
-          unget_tk tk
-        end
-	att = Attr.new(get_tkread, name, rw, comment)
-	read_documentation_modifiers(att, ATTR_MODIFIERS)
-	if att.document_self
-	  context.add_attribute(att)
-	end
-      else
-	warn("'attr' ignored - looks like a variable")
-      end    
+  def parse_visibility(container, single, tk)
+    singleton = (single == SINGLE)
+    vis = case tk.name
+          when "private"   then :private
+          when "protected" then :protected
+          when "public"    then :public
+          when "private_class_method"
+            singleton = true
+            :private
+          when "public_class_method"
+            singleton = true
+            :public
+          else raise "Invalid visibility: #{tk.name}"
+          end
 
+    skip_tkspace_comment(false)
+    case peek_tk
+      # Ryan Davis suggested the extension to ignore modifiers, because he
+      # often writes
+      #
+      #   protected unless $TESTING
+      #
+    when TkNL, TkUNLESS_MOD, TkIF_MOD
+      #        error("Missing argument") if singleton
+      container.ongoing_visibility = vis
+    else
+      args = parse_symbol_arg
+      container.set_visibility_for(args, vis, singleton)
     end
+  end
 
-    def parse_visibility(container, single, tk)
-      singleton = (single == SINGLE)
-      vis = case tk.name
-            when "private"   then :private
-            when "protected" then :protected
-            when "public"    then :public
-            when "private_class_method"
-              singleton = true
-              :private
-            when "public_class_method"
-              singleton = true
-              :public
-            else raise "Invalid visibility: #{tk.name}"
-            end
-            
-      skip_tkspace_comment(false)
-      case peek_tk
-        # Ryan Davis suggested the extension to ignore modifiers, because he
-        # often writes
-        #
-        #   protected unless $TESTING
-        #
-      when TkNL, TkUNLESS_MOD, TkIF_MOD
-#        error("Missing argument") if singleton        
-        container.ongoing_visibility = vis
-      else
-        args = parse_symbol_arg
-        container.set_visibility_for(args, vis, singleton)
-      end
-    end
+  def parse_attr_accessor(context, single, tk, comment)
+    args = parse_symbol_arg
+    read = get_tkread
+    rw = "?"
 
-    def parse_attr_accessor(context, single, tk, comment)
-      args = parse_symbol_arg
-      read = get_tkread
-      rw = "?"
+    # If nodoc is given, don't document any of them
 
-      # If nodoc is given, don't document any of them
+    tmp = RDoc::CodeObject.new
+    read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS
+    return unless tmp.document_self
 
-      tmp = CodeObject.new
-      read_documentation_modifiers(tmp, ATTR_MODIFIERS)
-      return unless tmp.document_self
+    case tk.name
+    when "attr_reader"   then rw = "R"
+    when "attr_writer"   then rw = "W"
+    when "attr_accessor" then rw = "RW"
+    else
+      rw = @options.extra_accessor_flags[tk.name]
+    end
 
-      case tk.name
-      when "attr_reader"   then rw = "R"
-      when "attr_writer"   then rw = "W"
-      when "attr_accessor" then rw = "RW"
-      else
-        rw = @options.extra_accessor_flags[tk.name]
-      end
-      
-      for name in args
-	att = Attr.new(get_tkread, name, rw, comment)
-        context.add_attribute(att)
-      end    
+    for name in args
+      att = RDoc::Attr.new get_tkread, name, rw, comment
+      context.add_attribute att
     end
+  end
 
-    def skip_tkspace_comment(skip_nl = true)
-      loop do
-        skip_tkspace(skip_nl)
-        return unless peek_tk.kind_of? TkCOMMENT
-        get_tk
-      end
+  def skip_tkspace_comment(skip_nl = true)
+    loop do
+      skip_tkspace(skip_nl)
+      return unless peek_tk.kind_of? TkCOMMENT
+      get_tk
     end
+  end
 
-    def parse_symbol_arg(no = nil)
+  def parse_symbol_arg(no = nil)
+    args = []
+    skip_tkspace_comment
+    case tk = get_tk
+    when TkLPAREN
+      loop do
+        skip_tkspace_comment
+        if tk1 = parse_symbol_in_arg
+          args.push tk1
+          break if no and args.size >= no
+        end
 
-      args = []
-      skip_tkspace_comment
-      case tk = get_tk
-      when TkLPAREN
-	loop do
-	  skip_tkspace_comment
-	  if tk1 = parse_symbol_in_arg
-	    args.push tk1
-	    break if no and args.size >= no
-	  end
-	  
-	  skip_tkspace_comment
-	  case tk2 = get_tk
-	  when TkRPAREN
-	    break
-	  when TkCOMMA
-	  else
-           warn("unexpected token: '#{tk2.inspect}'") if $DEBUG_RDOC
-	    break
-	  end
-	end
-      else
-	unget_tk tk
-	if tk = parse_symbol_in_arg
-	  args.push tk
-	  return args if no and args.size >= no
-	end
+        skip_tkspace_comment
+        case tk2 = get_tk
+        when TkRPAREN
+          break
+        when TkCOMMA
+        else
+          warn("unexpected token: '#{tk2.inspect}'") if $DEBUG_RDOC
+          break
+        end
+      end
+    else
+      unget_tk tk
+      if tk = parse_symbol_in_arg
+        args.push tk
+        return args if no and args.size >= no
+      end
 
-	loop do
-#	  skip_tkspace_comment(false)
-	  skip_tkspace(false)
+      loop do
+        #	  skip_tkspace_comment(false)
+        skip_tkspace(false)
 
-	  tk1 = get_tk
-	  unless tk1.kind_of?(TkCOMMA) 
-	    unget_tk tk1
-	    break
-	  end
-	  
-	  skip_tkspace_comment
-	  if tk = parse_symbol_in_arg
-	    args.push tk
-	    break if no and args.size >= no
-	  end
-	end
+        tk1 = get_tk
+        unless tk1.kind_of?(TkCOMMA)
+          unget_tk tk1
+          break
+        end
+
+        skip_tkspace_comment
+        if tk = parse_symbol_in_arg
+          args.push tk
+          break if no and args.size >= no
+        end
       end
-      args
     end
+    args
+  end
 
-    def parse_symbol_in_arg
-      case tk = get_tk
-      when TkSYMBOL
-        tk.text.sub(/^:/, '')
-      when TkSTRING
-	eval @read[-1]
-      else
-	warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG_RDOC
-	nil
-      end
+  def parse_symbol_in_arg
+    case tk = get_tk
+    when TkSYMBOL
+      tk.text.sub(/^:/, '')
+    when TkSTRING
+      eval @read[-1]
+    else
+      warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG_RDOC
+      nil
     end
   end
 
Index: lib/rdoc/parsers/parse_simple.rb
===================================================================
--- lib/rdoc/parsers/parse_simple.rb	(revision 15032)
+++ lib/rdoc/parsers/parse_simple.rb	(revision 15033)
@@ -1,41 +1,40 @@
-# Parse a non-source file. We basically take the whole thing 
-# as one big comment. If the first character in the file
-# is '#', we strip leading pound signs.
+require 'rdoc'
+require 'rdoc/code_objects'
+require 'rdoc/markup/preprocess'
 
+##
+# Parse a non-source file. We basically take the whole thing as one big
+# comment. If the first character in the file is '#', we strip leading pound
+# signs.
 
-require "rdoc/code_objects"
-require "rdoc/markup/simple_markup/preprocess"
+class RDoc::SimpleParser
 
-module RDoc
-  # See rdoc/parsers/parse_c.rb
+  ##
+  # Prepare to parse a plain file
 
-  class SimpleParser
-    
-    # prepare to parse a plain file
-    def initialize(top_level, file_name, body, options, stats)
-      
-      preprocess = SM::PreProcess.new(file_name, options.rdoc_include)
-      
-      preprocess.handle(body) do |directive, param|
-        $stderr.puts "Unrecognized directive '#{directive}' in #{file_name}"
-      end
-      
-      @body = body
-      @options = options
-      @top_level = top_level
-    end
-    
-    # Extract the file contents and attach them to the toplevel as a
-    # comment
-    
-    def scan
-      #    @body.gsub(/^(\s\n)+/, '')
-      @top_level.comment = remove_private_comments(@body)
-      @top_level
-    end
+  def initialize(top_level, file_name, body, options, stats)
+    preprocess = RDoc::Markup::PreProcess.new(file_name, options.rdoc_include)
 
-    def remove_private_comments(comment)
-      comment.gsub(/^--.*?^\+\+/m, '').sub(/^--.*/m, '')
+    preprocess.handle(body) do |directive, param|
+      warn "Unrecognized directive '#{directive}' in #{file_name}"
     end
+
+    @body = body
+    @options = options
+    @top_level = top_level
   end
+
+  ##
+  # Extract the file contents and attach them to the toplevel as a comment
+
+  def scan
+    @top_level.comment = remove_private_comments(@body)
+    @top_level
+  end
+
+  def remove_private_comments(comment)
+    comment.gsub(/^--[^-].*?^\+\+/m, '').sub(/^--.*/m, '')
+  end
+
 end
+
Index: lib/rdoc/code_objects.rb
===================================================================
--- lib/rdoc/code_objects.rb	(revision 15032)
+++ lib/rdoc/code_objects.rb	(revision 15033)
@@ -458,7 +458,7 @@
     
   end
 
-
+  ##
   # A TopLevel context is a source file
 
   class TopLevel < Context
@@ -470,7 +470,7 @@
     @@all_classes = {}
     @@all_modules = {}
 
-    def TopLevel::reset
+    def self.reset
       @@all_classes = {}
       @@all_modules = {}
     end
@@ -488,14 +488,15 @@
       nil
     end
 
-    # Adding a class or module to a TopLevel is special, as we only
-    # want one copy of a particular top-level class. For example,
-    # if both file A and file B implement class C, we only want one
-    # ClassModule object for C. This code arranges to share
-    # classes and modules between files.
+    ##
+    # Adding a class or module to a TopLevel is special, as we only want one
+    # copy of a particular top-level class. For example, if both file A and
+    # file B implement class C, we only want one ClassModule object for C.
+    # This code arranges to share classes and modules between files.
 
     def add_class_or_module(collection, class_type, name, superclass)
       cls = collection[name]
+
       if cls
         puts "Reusing class/module #{name}" if $DEBUG_RDOC
       else
@@ -504,23 +505,29 @@
         else
           all = @@all_classes
         end
+
         cls = all[name]
+
         if !cls
           cls = class_type.new(name, superclass)
-          all[name] = cls  unless @done_documenting
+          all[name] = cls unless @done_documenting
         end
-        puts "Adding class/module #{name} to #@name" if $DEBUG_RDOC
+
+        puts "Adding class/module #{name} to #{@name}" if $DEBUG_RDOC
+
         collection[name] = cls unless @done_documenting
+
         cls.parent = self
       end
+
       cls
     end
 
-    def TopLevel.all_classes_and_modules
+    def self.all_classes_and_modules
       @@all_classes.values + @@all_modules.values
     end
 
-    def TopLevel.find_class_named(name)
+    def self.find_class_named(name)
      @@all_classes.each_value do |c|
         res = c.find_class_named(name) 
         return res if res
@@ -538,12 +545,13 @@
       nil
     end
 
+    ##
     # Find a named module
+
     def find_module_named(name)
       find_class_or_module_named(name) || find_enclosing_module_named(name)
     end
 
-
   end
 
   # ClassModule is the base class for objects representing either a
Index: lib/rdoc/generator/html.rb
===================================================================
--- lib/rdoc/generator/html.rb	(revision 15032)
+++ lib/rdoc/generator/html.rb	(revision 15033)
@@ -1,7 +1,7 @@
 require 'fileutils'
 
 require 'rdoc/generator'
-require 'rdoc/markup/simple_markup/to_html'
+require 'rdoc/markup/to_html'
 
 module RDoc::Generator
 
@@ -34,12 +34,11 @@
   end
 
   ##
-  # Subclass of the SM::ToHtml class that supports looking
-  # up words in the AllReferences list. Those that are
-  # found (like AllReferences in this comment) will
-  # be hyperlinked
+  # Subclass of the RDoc::Markup::ToHtml class that supports looking up words
+  # in the AllReferences list. Those that are found (like AllReferences in
+  # this comment) will be hyperlinked
 
-  class HyperlinkHtml < SM::ToHtml
+  class HyperlinkHtml < RDoc::Markup::ToHtml
 
     ##
     # We need to record the html path of our caller so we can generate
@@ -161,13 +160,13 @@
 
     ##
     # Convert a string in markup format into HTML. We keep a cached
-    # SimpleMarkup object lying around after the first time we're
+    # RDoc::Markup object lying around after the first time we're
     # called per object.
 
     def markup(str, remove_para=false)
       return '' unless str
       unless defined? @markup
-        @markup = SM::SimpleMarkup.new
+        @markup = RDoc::Markup.new
 
         # class names, variable names, or instance variables
         @markup.add_special(/(
Index: lib/rdoc/generator/ri.rb
===================================================================
--- lib/rdoc/generator/ri.rb	(revision 15032)
+++ lib/rdoc/generator/ri.rb	(revision 15033)
@@ -1,5 +1,5 @@
 require 'rdoc/generator'
-require 'rdoc/markup/simple_markup/to_flow'
+require 'rdoc/markup/to_flow'
 
 require 'rdoc/ri/cache'
 require 'rdoc/ri/reader'
@@ -26,8 +26,8 @@
   def initialize(options) #:not-new:
     @options   = options
     @ri_writer = RDoc::RI::Writer.new "."
-    @markup    = SM::SimpleMarkup.new
-    @to_flow   = SM::ToFlow.new
+    @markup    = RDoc::Markup.new
+    @to_flow   = RDoc::Markup::ToFlow.new
 
     @generated = {}
   end
@@ -38,7 +38,7 @@
 
   def generate(toplevels)
     RDoc::TopLevel.all_classes_and_modules.each do |cls|
-      process_class(cls)
+      process_class cls
     end
   end
 
@@ -58,6 +58,7 @@
       cls_desc = RDoc::RI::ClassDescription.new
       cls_desc.superclass  = cls.superclass
     end
+
     cls_desc.name        = cls.name
     cls_desc.full_name   = cls.full_name
     cls_desc.comment     = markup(cls.comment)
Index: lib/rdoc/generator.rb
===================================================================
--- lib/rdoc/generator.rb	(revision 15032)
+++ lib/rdoc/generator.rb	(revision 15033)
@@ -1,7 +1,7 @@
 require 'cgi'
 require 'rdoc'
 require 'rdoc/options'
-require 'rdoc/markup/simple_markup'
+require 'rdoc/markup'
 require 'rdoc/template'
 
 module RDoc::Generator
Index: lib/rdoc/rdoc.rb
===================================================================
--- lib/rdoc/rdoc.rb	(revision 15032)
+++ lib/rdoc/rdoc.rb	(revision 15033)
@@ -5,6 +5,7 @@
 require 'rdoc/parsers/parse_f95.rb'
 require 'rdoc/parsers/parse_simple.rb'
 
+require 'rdoc/stats'
 require 'rdoc/options'
 
 require 'rdoc/diagram'
@@ -16,31 +17,6 @@
 module RDoc
 
   ##
-  # Simple stats collector
-
-  class Stats
-    attr_accessor :num_files, :num_classes, :num_modules, :num_methods
-    def initialize
-      @num_files = @num_classes = @num_modules = @num_methods = 0
-      @start = Time.now
-    end
-    def print
-      puts "Files:   #@num_files"
-      puts "Classes: #@num_classes"
-      puts "Modules: #@num_modules"
-      puts "Methods: #@num_methods"
-      puts "Elapsed: " + sprintf("%0.3fs", Time.now - @start)
-    end
-  end
-
-  ##
-  # Exception thrown by any rdoc error.
-
-  class Error < RuntimeError; end
-
-  RDocError = Error # :nodoc:
-
-  ##
   # Encapsulate the production of rdoc documentation. Basically
   # you can use this as you would invoke rdoc from the command
   # line:
@@ -192,22 +168,27 @@
     # for .document files.
 
     def list_files_in_directory(dir, options)
-      normalized_file_list(options, Dir.glob(File.join(dir, "*")), false, options.exclude)
+      files = Dir.glob File.join(dir, "*")
+
+      normalized_file_list options, files, false, options.exclude
     end
 
     ##
     # Parse each file on the command line, recursively entering directories.
 
     def parse_files(options)
-      file_info = []
-
       files = options.files
       files = ["."] if files.empty?
 
       file_list = normalized_file_list(options, files, true)
 
+      return [] if file_list.empty?
+
+      file_info = []
+      width = file_list.map { |name| name.length }.max + 1
+
       file_list.each do |fn|
-        $stderr.printf("\n%35s: ", File.basename(fn)) unless options.quiet
+        $stderr.printf("\n%*s: ", width, fn) unless options.quiet
 
         content = File.open(fn, "r:ascii-8bit") {|f| f.read}
         if /coding:\s*(\S+)/ =~ content[/\A(?:.*\n){0,2}/]
@@ -252,6 +233,7 @@
       unless options.all_one_file
         @last_created = setup_output_dir(options.op_dir, options.force_update)
       end
+
       start_time = Time.now
 
       file_info = parse_files(options)
Index: lib/rdoc/README
===================================================================
--- lib/rdoc/README	(revision 15032)
+++ lib/rdoc/README	(revision 15033)
@@ -1,38 +1,34 @@
 = RDOC - Ruby Documentation System
 
-This package contains Rdoc and SimpleMarkup. Rdoc is an application
-that produces documentation for one or more Ruby source files. We work
-similarly to JavaDoc, parsing the source, and extracting the
-definition for classes, modules, and methods (along with includes and
-requires).  We associate with these optional documentation contained
-in the immediately preceding comment block, and then render the result
-using a pluggable output formatter. (Currently, HTML is the only
-supported format. Markup is a library that converts plain text into
-various output formats. The Markup library is used to interpret the
-comment blocks that Rdoc uses to document methods, classes, and so on.
+This package contains RDoc and RDoc::Markup.  RDoc is an application that
+produces documentation for one or more Ruby source files.  We work similarly to
+JavaDoc, parsing the source, and extracting the definition for classes,
+modules, and methods (along with includes and requires).  We associate with
+these optional documentation contained in the immediately preceding comment
+block, and then render the result using a pluggable output formatter.
+RDoc::Markup is a library that converts plain text into various output formats.
+The markup library is used to interpret the comment blocks that RDoc uses to
+document methods, classes, and so on.
 
-This library contains two packages, rdoc itself and a text markup
-library, 'markup'. 
-
 == Roadmap
 
-* If you want to use Rdoc to create documentation for your Ruby source
-  files, read on.
-* If you want to include extensions written in C, see rdoc/parsers/parse_c.rb.
-* For information on the various markups available in comment
-  blocks, see markup/simple_markup.rb.
-* If you want to drive Rdoc programatically, see RDoc::RDoc.
-* If you want to use the library to format text blocks into HTML,
-  have a look at SM::SimpleMarkup.
+* If you want to use RDoc to create documentation for your Ruby source files,
+  read on.
+* If you want to include extensions written in C, see RDoc::C_Parser
+* For information on the various markups available in comment blocks, see
+  RDoc::Markup.
+* If you want to drive RDoc programatically, see RDoc::RDoc.
+* If you want to use the library to format text blocks into HTML, have a look
+  at RDoc::Markup.
 * If you want to try writing your own HTML output template, see
-  RDoc::Page.
+  RDoc::Generator::HTML
 
 == Summary
 
 Once installed, you can create documentation using the 'rdoc' command
 (the command is 'rdoc.bat' under Windows)
 
-  % rdoc [options]  [names...]
+  % rdoc [options] [names...]
 
 Type "rdoc --help" for an up-to-date option summary.
 
@@ -42,448 +38,195 @@
   % rdoc
 
 This command generates documentation for all the Ruby and C source
-files in and below the current directory. These will be stored in a
+files in and below the current directory.  These will be stored in a
 documentation tree starting in the subdirectory 'doc'.
 
 You can make this slightly more useful for your readers by having the
-index page contain the documentation for the primary file. In our
+index page contain the documentation for the primary file.  In our
 case, we could type
 
-  % rdoc --main rdoc/rdoc.rb
+  % rdoc --main rdoc.rb
 
 You'll find information on the various formatting tricks you can use
 in comment blocks in the documentation this generates.
 
-RDoc uses file extensions to determine how to process each file. File
-names ending <tt>.rb</tt> and <tt>.rbw</tt> are assumed to be Ruby
-source. Files ending <tt>.c</tt> are parsed as C files. All other
-files are assumed to contain just SimpleMarkup-style markup (with or
-without leading '#' comment markers). If directory names are passed to
-RDoc, they are scanned recursively for C and Ruby source files only.
+RDoc uses file extensions to determine how to process each file.  File names
+ending +.rb+ and <tt>.rbw</tt> are assumed to be Ruby source.  Files
+ending +.c+ are parsed as C files.  All other files are assumed to
+contain just Markup-style markup (with or without leading '#' comment markers).
+If directory names are passed to RDoc, they are scanned recursively for C and
+Ruby source files only.
 
-== Credits
-
-* The Ruby parser in rdoc/parse.rb is based heavily on the outstanding
-  work of Keiju ISHITSUKA of Nippon Rational Inc, who produced the Ruby
-  parser for irb and the rtags package.
-
-* Code to diagram classes and modules was written by Sergey A Yanovitsky
-  (Jah) of Enticla. 
-
-* Charset patch from MoonWolf.
-
-* Rich Kilmer wrote the kilmer.rb output template.
-
-* Dan Brickley led the design of the RDF format.
-
-== License
-
-RDoc is Copyright (c) 2001-2003 Dave Thomas, The Pragmatic Programmers.  It
-is free software, and may be redistributed under the terms specified
-in the README file of the Ruby distribution.
-
-= Usage
-
-RDoc is invoked from the command line using:
-
-   % rdoc <options> [name...]
-
-Files are parsed, and the information they contain collected, before
-any output is produced. This allows cross references between all files
-to be resolved. If a name is a directory, it is traversed. If no
-names are specified, all Ruby files in the current directory (and
-subdirectories) are processed.
-
-Options are:
-
-[<tt>--accessor</tt> <i>name[,name...]</i>]
-    specifies the name(s) of additional methods that should be treated
-    as if they were <tt>attr_</tt><i>xxx</i> methods. Specifying
-    "--accessor db_opt" means lines such as
-
-         db_opt :name, :age
-  
-    will get parsed and displayed in the documentation. Each name may have an
-    optional "=flagtext" appended, in which case the given flagtext will appear
-    where (for example) the 'rw' appears for attr_accessor.
-
-[<tt>--all</tt>]
-    include protected and private methods in the output (by default
-    only public methods are included)
-
-[<tt>--charset</tt> _charset_]
-    Set the character set for the generated HTML.
-
-[<tt>--diagram</tt>]
-    include diagrams showing modules and classes.  This is currently
-    an experimental feature, and may not be supported by all output
-    templates. You need dot V1.8.6 or later to use the --diagram
-    option correctly (http://www.research.att.com/sw/tools/graphviz/).
-
-[<tt>--exclude</tt> <i>pattern</i>]
-    exclude files and directories matching this pattern from processing
-
-[<tt>--extension</tt> <i>new=old</i>]
-    treat files ending <i>.new</i> as if they ended
-    <i>.old</i>. Saying '--extension cgi=rb' causes RDoc to treat .cgi
-    files as Ruby source.
-
-[<tt>fileboxes</tt>]
-    Classes are put in boxes which represents files, where these
-    classes reside. Classes shared between more than one file are
-    shown with list of files that sharing them.  Silently discarded if
-    --diagram is not given Experimental.
-
-[<tt>--fmt</tt> _fmt_]
-    generate output in a particular format.
-
-[<tt>--help</tt>]
-    generate a usage summary.
-
-[<tt>--help-output</tt>]
-    explain the various output options.
-
-[<tt>--image-format</tt> <i>gif/png/jpg/jpeg</i>]
-    sets output image format for diagrams. Can be png, gif, jpeg,
-    jpg. If this option is omitted, png is used. Requires --diagram.
-
-[<tt>--include</tt> <i>dir,...</i>]
-    specify one or more directories to be searched when satisfying
-    :+include+: directives. Multiple <tt>--include</tt> options may be
-    given. The directory containing the file currently being processed
-    is always searched.
-
-[<tt>--inline-source</tt>]
-    By default, the source code of methods is shown in a popup. With
-    this option, it's displayed inline.
-
-[<tt>line-numbers</tt>]
-    include line numbers in the source code
-
-[<tt>--main</tt> _name_]
-    the class of module _name_ will appear on the index page. If you
-    want to set a particular file as a main page (a README, for
-    example) simply specifiy its name as the first on the command
-    line.
-
-[<tt>--merge</tt>]
-    when generating _ri_ output, if classes being processed already
-    exist in the destination directory, merge in the current details
-    rather than overwrite them.
-
-[<tt>--one-file</tt>]
-    place all the output into a single file
-
-[<tt>--op</tt> _dir_]
-    set the output directory to _dir_ (the default is the directory
-    "doc")
-
-[<tt>--op-name</tt> _name_]
-    set the name of the output. Has no effect for HTML.
-    "doc")
-
-[<tt>--opname</tt> _name_]
-    set the output name (has no effect for HTML).
-
-[<tt>--promiscuous</tt>]
-    If a module or class is defined in more than one source file, and
-    you click on a particular file's name in the top navigation pane,
-    RDoc will normally only show you the inner classes and modules of
-    that class that are defined in the particular file. Using this
-    option makes it show all classes and modules defined in the class,
-    regardless of the file they were defined in.
-
-[<tt>--quiet</tt>]
-    do not display progress messages
-
-[<tt>--ri</tt>, <tt>--ri-site</tt>, _and_ <tt>--ri-system</tt>]
-    generate output than can be read by the _ri_ command-line tool.
-    By default --ri places its output in ~/.rdoc, --ri-site in
-    $datadir/ri/<ver>/site, and --ri-system in
-    $datadir/ri/<ver>/system. All can be overridden with a subsequent
-    --op option. All default directories are in ri's default search
-    path.
-
-[<tt>--show-hash</tt>]
-    A name of the form #name in a comment is a possible hyperlink to
-    an instance method name. When displayed, the '#' is removed unless
-    this option is specified
-
-[<tt>--style</tt> <i>stylesheet url</i>]
-    specifies the URL of an external stylesheet to use (rather than
-    generating one of our own)
-
-[<tt>tab-width</tt> _n_]
-    set the width of tab characters (default 8)
-
-[<tt>--template</tt> <i>name</i>]
-    specify an alternate template to use when generating output (the
-    default is 'standard'). This template should be in a directory
-    accessible via $: as rdoc/generator/xxxx_template, where 'xxxx'
-    depends on the output formatter.
-
-[<tt>--version</tt>]
-   display  RDoc's version
-
-[<tt>--webcvs</tt> _url_]
-    Specify a URL for linking to a web frontend to CVS. If the URL
-    contains a '\%s', the name of the current file will be
-    substituted; if the URL doesn't contain a '\%s', the filename will
-    be appended to it.
-
-= Example
-
-A typical small Ruby program commented using RDoc might be as follows. You
-can see the formatted result in EXAMPLE.rb and Anagram.
-
-      :include: EXAMPLE.rb
-
 = Markup
 
-Comment blocks can be written fairly naturally, either using '#' on
-successive lines of the comment, or by including the comment in 
-an =begin/=end block. If you use the latter form, the =begin line
-must be flagged with an RDoc tag:
+For information on how to make lists, hyperlinks, & etc. with RDoc, see
+RDoc::Markup.
 
+Comment blocks can be written fairly naturally, either using '#' on successive
+lines of the comment, or by including the comment in an =begin/=end block.  If
+you use the latter form, the =begin line must be flagged with an RDoc tag:
+
   =begin rdoc
-  Documentation to 
-  be processed by RDoc.
+  Documentation to be processed by RDoc.
+  
+  ...
   =end
 
-Paragraphs are lines that share the left margin. Text indented past
-this margin are formatted verbatim.
+RDoc stops processing comments if it finds a comment line containing '+#--+'.
+This can be used to separate external from internal comments, or to stop a
+comment being associated with a method, class, or module.  Commenting can be
+turned back on with a line that starts '+#+++'.
 
-1. Lists are typed as indented paragraphs with:
-   * a '*' or '-' (for bullet lists)
-   * a digit followed by a period for 
-     numbered lists
-   * an upper or lower case letter followed
-     by a period for alpha lists.
+  ##
+  # Extract the age and calculate the date-of-birth.
+  #--
+  # FIXME: fails if the birthday falls on February 29th
+  #++
+  # The DOB is returned as a Time object.
+  
+  def get_dob(person)
+    # ...
+  end
 
-   For example, the input that produced the above paragraph looked like
-       1. Lists are typed as indented 
-          paragraphs with:
-          * a '*' or '-' (for bullet lists)
-          * a digit followed by a period for 
-            numbered lists
-          * an upper or lower case letter followed
-            by a period for alpha lists.
+Names of classes, source files, and any method names containing an underscore
+or preceded by a hash character are automatically hyperlinked from comment text
+to their description. 
 
-2. Labeled lists (sometimes called description
-   lists) are typed using square brackets for the label.
-      [cat]   small domestic animal
-      [+cat+] command to copy standard input
+Method parameter lists are extracted and displayed with the method description.
+If a method calls +yield+, then the parameters passed to yield will also be
+displayed:
 
-3. Labeled lists may also be produced by putting a double colon
-   after the label. This sets the result in tabular form, so the
-   descriptions all line up. This was used to create the 'author'
-   block at the bottom of this description.
-      cat::   small domestic animal
-      +cat+:: command to copy standard input
+  def fred
+    ...
+    yield line, address
 
-   For both kinds of labeled lists, if the body text starts on the same
-   line as the label, then the start of that text determines the block
-   indent for the rest of the body. The text may also start on the line
-   following the label, indented from the start of the label. This is
-   often preferable if the label is long. Both the following are
-   valid labeled list entries:
+This will get documented as:
 
-      <tt>--output</tt> <i>name [, name]</i>::
-          specify the name of one or more output files. If multiple
-          files are present, the first is used as the index.
+  fred() { |line, address| ... }
 
-      <tt>--quiet:</tt>:: do not output the names, sizes, byte counts,
-                          index areas, or bit ratios of units as
-                          they are processed.
+You can override this using a comment containing ':yields: ...' immediately
+after the method definition
 
-4. Headings are entered using equals signs
+  def fred # :yields: index, position
+    # ...
+  
+    yield line, address
 
-      = Level One Heading
-      == Level Two Heading
-   and so on
+which will get documented as
 
-5. Rules (horizontal lines) are entered using three or
-   more hyphens.
+   fred() { |index, position| ... }
 
-6. Non-verbatim text can be marked up:
++:yields:+ is an example of a documentation directive.  These appear immediately
+after the start of the document element they are modifying.
 
-   _italic_::     \_word_ or \<em>text</em>
-   *bold*::       \*word* or \<b>text</b>
-   +typewriter+:: \+word+ or \<tt>text</tt>
+== Directives
 
-   The first form only works around 'words', where a word is a
-   sequence of upper and lower case letters and underscores. Putting a
-   backslash before inline markup stops it being interpreted, which is
-   how I created the table above:
+[+:nodoc:+ / +:nodoc:+ all]
+  Don't include this element in the documentation.  For classes
+  and modules, the methods, aliases, constants, and attributes
+  directly within the affected class or module will also be
+  omitted.  By default, though, modules and classes within that
+  class of module _will_ be documented.  This is turned off by
+  adding the +all+ modifier.
+  
+    module MyModule # :nodoc:
+      class Input
+      end
+    end
+    
+    module OtherModule # :nodoc: all
+      class Output
+      end
+    end
+  
+  In the above code, only class +MyModule::Input+ will be documented.
 
-     _italic_::     \_word_ or \<em>text</em>
-     *bold*::       \*word* or \<b>text</b>
-     +typewriter+:: \+word+ or \<tt>text</tt>
+[+:doc:+]
+  Force a method or attribute to be documented even if it wouldn't otherwise
+  be.  Useful if, for example, you want to include documentation of a
+  particular private method.
 
-7. Names of classes, source files, and any method names
-   containing an underscore or preceded by a hash
-   character are automatically hyperlinked from
-   comment text to their description. 
+[+:notnew:+]
+  Only applicable to the +initialize+ instance method.  Normally RDoc assumes
+  that the documentation and parameters for #initialize are actually for the
+  ::new method, and so fakes out a ::new for the class.  The :notnew: modifier
+  stops this.  Remember that #initialize is protected, so you won't see the
+  documentation unless you use the -a command line option.
 
-8. Hyperlinks to the web starting http:, mailto:, ftp:, or www. are
-   recognized. An HTTP url that references an external image file is
-   converted into an inline <IMG..>.  Hyperlinks starting 'link:' are
-   assumed to refer to local files whose path is relative to the --op
-   directory.
+Comment blocks can contain other directives:
 
-   Hyperlinks can also be of the form <tt>label</tt>[url], in which
-   case the label is used in the displayed text, and <tt>url</tt> is
-   used as the target. If <tt>label</tt> contains multiple words,
-   put it in braces: <em>{multi word label}[</em>url<em>]</em>.
-       
-9. Method parameter lists are extracted and displayed with
-   the method description. If a method calls +yield+, then
-   the parameters passed to yield will also be displayed:
+[+:section: title+]
+  Starts a new section in the output.  The title following +:section:+ is used
+  as the section heading, and the remainder of the comment containing the
+  section is used as introductory text.  Subsequent methods, aliases,
+  attributes, and classes will be documented in this section.  A :section:
+  comment block may have one or more lines before the :section: directive.
+  These will be removed, and any identical lines at the end of the block are
+  also removed.  This allows you to add visual cues such as:
+    
+    # ----------------------------------------
+    # :section: My Section
+    # This is the section that I wrote.
+    # See it glisten in the noon-day sun.
+    # ----------------------------------------
 
-      def fred
-        ...
-        yield line, address
+[+:call-seq:+]
+  Lines up to the next blank line in the comment are treated as the method's
+  calling sequence, overriding the default parsing of method parameters and
+  yield arguments.
 
-   This will get documented as
+[+:include:+ _filename_]
+  Include the contents of the named file at this point.  The file will be
+  searched for in the directories listed by the +--include+ option, or in the
+  current directory by default.  The contents of the file will be shifted to
+  have the same indentation as the ':' at the start of the :include: directive.
 
-      fred() { |line, address| ... }
+[+:title:+ _text_]
+  Sets the title for the document.  Equivalent to the --title command line
+  parameter.  (The command line parameter overrides any :title: directive in
+  the source).
 
-   You can override this using a comment containing 
-   ':yields: ...' immediately after the method definition
+[+:enddoc:+]
+  Document nothing further at the current level.
 
-      def fred      # :yields: index, position
-        ...
-        yield line, address
+[+:main:+ _name_]
+  Equivalent to the --main command line parameter.
 
-   which will get documented as
+[+:stopdoc:+ / +:startdoc:+]
+  Stop and start adding new documentation elements to the current container.
+  For example, if a class has a number of constants that you don't want to
+  document, put a +:stopdoc:+ before the first, and a +:startdoc:+ after the
+  last.  If you don't specifiy a +:startdoc:+ by the end of the container,
+  disables documentation for the entire class or module.
 
-       fred() { |index, position| ... }
+= Other stuff
 
+Author::   Dave Thomas <dave@p...>
 
-10. ':yields:' is an example of a documentation modifier. These appear
-    immediately after the start of the document element they are modifying.
-    Other modifiers include
+== Credits
 
-    [<tt>:nodoc:</tt><i>[all]</i>]
-         don't include this element in the documentation.  For classes
-         and modules, the methods, aliases, constants, and attributes
-         directly within the affected class or module will also be
-         omitted.  By default, though, modules and classes within that
-         class of module _will_ be documented. This is turned off by
-         adding the +all+ modifier.
+* The Ruby parser in rdoc/parse.rb is based heavily on the outstanding
+  work of Keiju ISHITSUKA of Nippon Rational Inc, who produced the Ruby
+  parser for irb and the rtags package.
 
-              module SM  #:nodoc:
-                class Input
-                end
-              end
-              module Markup #:nodoc: all
-                class Output
-                end
-              end
+* Code to diagram classes and modules was written by Sergey A Yanovitsky
+  (Jah) of Enticla. 
 
-         In the above code, only class <tt>SM::Input</tt> will be
-         documented.
+* Charset patch from MoonWolf.
 
-    [<tt>:doc:</tt>]
-         force a method or attribute to be documented even if it
-         wouldn't otherwise be. Useful if, for example, you want to
-         include documentation of a particular private method.
+* Rich Kilmer wrote the kilmer.rb output template.
 
-    [<tt>:notnew:</tt>]
-         only applicable to the +initialize+ instance method. Normally
-         RDoc assumes that the documentation and parameters for
-         #initialize are actually for the ::new method, and so fakes
-         out a ::new for the class. THe :notnew: modifier stops
-         this. Remember that #initialize is protected, so you won't
-         see the documentation unless you use the -a command line
-         option.
+* Dan Brickley led the design of the RDF format.
 
+== License
 
-11. RDoc stops processing comments if it finds a comment
-    line containing '<tt>#--</tt>'. This can be used to 
-    separate external from internal comments, or 
-    to stop a comment being associated with a method, 
-    class, or module. Commenting can be turned back on with
-    a line that starts '<tt>#++</tt>'.
+RDoc is Copyright (c) 2001-2003 Dave Thomas, The Pragmatic Programmers.  It
+is free software, and may be redistributed under the terms specified
+in the README file of the Ruby distribution.
 
-        # Extract the age and calculate the
-        # date-of-birth.
-        #--
-        # FIXME: fails if the birthday falls on
-        # February 29th
-        #++
-        # The DOB is returned as a Time object.
-
-        def get_dob(person)
-           ...
-
-12. Comment blocks can contain other directives:
-
-    [<tt>:section: title</tt>]
-        Starts a new section in the output. The title following
-	<tt>:section:</tt> is used as the section heading, and the
-	remainder of the comment containing the section is used as
-	introductory text. Subsequent methods, aliases, attributes,
-	and classes will be documented in this section. A :section:
-	comment block may have one or more lines before the :section:
-	directive. These will be removed, and any identical lines at
-	the end of the block are also removed. This allows you to add
-	visual cues such as
-
-           # ----------------------------------------
-	   # :section: My Section
-	   # This is the section that I wrote.
-	   # See it glisten in the noon-day sun.
-           # ----------------------------------------
-
-    [<tt>call-seq:</tt>]
-        lines up to the next blank line in the comment are treated as
-        the method's calling sequence, overriding the
-        default parsing of method parameters and yield arguments.
-
-    [<tt>:include:</tt><i>filename</i>] 
-         include the contents of the named file at this point. The
-         file will be searched for in the directories listed by
-         the <tt>--include</tt> option, or in the current
-         directory by default.  The contents of the file will be
-         shifted to have the same indentation as the ':' at the
-         start of the :include: directive.
-
-    [<tt>:title:</tt><i>text</i>]
-         Sets the title for the document. Equivalent to the --title command
-         line parameter. (The command line parameter overrides any :title:
-         directive in the source).
-
-    [<tt>:enddoc:</tt>]
-         Document nothing further at the current level.
-
-    [<tt>:main:</tt><i>name</i>]
-         Equivalent to the --main command line parameter.
-
-    [<tt>:stopdoc: / :startdoc:</tt>]
-         Stop and start adding new documentation elements to the
-         current container. For example, if a class has a number of
-         constants that you don't want to document, put a
-         <tt>:stopdoc:</tt> before the first, and a
-         <tt>:startdoc:</tt> after the last. If you don't specifiy a
-         <tt>:startdoc:</tt> by the end of the container, disables
-         documentation for the entire class or module.
-
-
----
-
-See also markup/simple_markup.rb.
-
-= Other stuff
-
-Author::   Dave Thomas <dave@p...>
-Requires:: Ruby 1.8.1 or later
-License::  Copyright (c) 2001-2003 Dave Thomas.
-           Released under the same license as Ruby.
-
 == Warranty
 
-This software is provided "as is" and without any express or
-implied warranties, including, without limitation, the implied
-warranties of merchantibility and fitness for a particular
-purpose.
+This software is provided "as is" and without any express or implied
+warranties, including, without limitation, the implied warranties of
+merchantibility and fitness for a particular purpose.
+
Index: lib/rdoc/markup/simple_markup.rb
===================================================================
--- lib/rdoc/markup/simple_markup.rb	(revision 15032)
+++ lib/rdoc/markup/simple_markup.rb	(revision 15033)
@@ -1,463 +0,0 @@
-require 'rdoc/markup/simple_markup/fragments'
-require 'rdoc/markup/simple_markup/lines.rb'
-
-##
-# SimpleMarkup parses plain text documents and attempts to decompose
-# them into their constituent parts. Some of these parts are high-level:
-# paragraphs, chunks of verbatim text, list entries and the like. Other
-# parts happen at the character level: a piece of bold text, a word in
-# code font. This markup is similar in spirit to that used on WikiWiki
-# webs, where folks create web pages using a simple set of formatting
-# rules.
-#
-# SimpleMarkup itself does no output formatting: this is left to a
-# different set of classes.
-#
-# SimpleMarkup is extendable at runtime: you can add new markup
-# elements to be recognised in the documents that SimpleMarkup parses.
-#
-# SimpleMarkup is intended to be the basis for a family of tools which
-# share the common requirement that simple, plain-text should be
-# rendered in a variety of different output formats and media. It is
-# envisaged that SimpleMarkup could be the basis for formating RDoc
-# style comment blocks, Wiki entries, and online FAQs.
-#
-# = Basic Formatting
-#
-# * SimpleMarkup looks for a document's natural left margin. This is
-#   used as the initial margin for the document.
-#
-# * Consecutive lines starting at this margin are considered to be a
-#   paragraph.
-#
-# * If a paragraph starts with a "*", "-", or with "<digit>.", then it is
-#   taken to be the start of a list. The margin in increased to be the
-#   first non-space following the list start flag. Subsequent lines
-#   should be indented to this new margin until the list ends. For
-#   example:
-#
-#      * this is a list with three paragraphs in
-#        the first item. This is the first paragraph.
-#
-#        And this is the second paragraph.
-#
-#        1. This is an indented, numbered list.
-#        2. This is the second item in that list
-#
-#        This is the third conventional paragraph in the
-#        first list item.
-#
-#      * This is the second item in the original list
-#
-# * You can also construct labeled lists, sometimes called description
-#   or definition lists. Do this by putting the label in square brackets
-#   and indenting the list body:
-#
-#       [cat]  a small furry mammal
-#              that seems to sleep a lot
-#
-#       [ant]  a little insect that is known
-#              to enjoy picnics
-#
-#   A minor variation on labeled lists uses two colons to separate the
-#   label from the list body:
-#
-#       cat::  a small furry mammal
-#              that seems to sleep a lot
-#
-#       ant::  a little insect that is known
-#              to enjoy picnics
-#
-#   This latter style guarantees that the list bodies' left margins are
-#   aligned: think of them as a two column table.
-#
-# * Any line that starts to the right of the current margin is treated
-#   as verbatim text. This is useful for code listings. The example of a
-#   list above is also verbatim text.
-#
-# * A line starting with an equals sign (=) is treated as a
-#   heading. Level one headings have one equals sign, level two headings
-#   have two,and so on.
-#
-# * A line starting with three or more hyphens (at the current indent)
-#   generates a horizontal rule. THe more hyphens, the thicker the rule
-#   (within reason, and if supported by the output device)
-#
-# * You can use markup within text (except verbatim) to change the
-#   appearance of parts of that text. Out of the box, SimpleMarkup
-#   supports word-based and general markup.
-#
-#   Word-based markup uses flag characters around individual words:
-#
-#   [\*word*]  displays word in a *bold* font
-#   [\_word_]  displays word in an _emphasized_ font
-#   [\+word+]  displays word in a +code+ font
-#
-#   General markup affects text between a start delimiter and and end
-#   delimiter. Not surprisingly, these delimiters look like HTML markup.
-#
-#   [\<b>text...</b>]    displays word in a *bold* font
-#   [\<em>text...</em>]  displays word in an _emphasized_ font
-#   [\<i>text...</i>]    displays word in an _emphasized_ font
-#   [\<tt>text...</tt>]  displays word in a +code+ font
-#
-#   Unlike conventional Wiki markup, general markup can cross line
-#   boundaries. You can turn off the interpretation of markup by
-#   preceding the first character with a backslash, so \\\<b>bold
-#   text</b> and \\\*bold* produce \<b>bold text</b> and \*bold
-#   respectively.
-#
-# = Using SimpleMarkup
-#
-# For information on using SimpleMarkup programatically, see SM::SimpleMarkup.
-#--
-# Author::   Dave Thomas,  dave@p...
-# Version::  0.0
-# License::  Ruby license
-
-module SM
-
-  # == Synopsis
-  #
-  # This code converts <tt>input_string</tt>, which is in the format
-  # described in markup/simple_markup.rb, to HTML. The conversion
-  # takes place in the +convert+ method, so you can use the same
-  # SimpleMarkup object to convert multiple input strings.
-  #
-  #   require 'rdoc/markup/simple_markup'
-  #   require 'rdoc/markup/simple_markup/to_html'
-  #
-  #   p = SM::SimpleMarkup.new
-  #   h = SM::ToHtml.new
-  #
-  #   puts p.convert(input_string, h)
-  #
-  # You can extend the SimpleMarkup parser to recognise new markup
-  # sequences, and to add special processing for text that matches a
-  # regular epxression. Here we make WikiWords significant to the parser,
-  # and also make the sequences {word} and \<no>text...</no> signify
-  # strike-through text. When then subclass the HTML output class to deal
-  # with these:
-  #
-  #   require 'rdoc/markup/simple_markup'
-  #   require 'rdoc/markup/simple_markup/to_html'
-  #
-  #   class WikiHtml < SM::ToHtml
-  #     def handle_special_WIKIWORD(special)
-  #       "<font color=red>" + special.text + "</font>"
-  #     end
-  #   end
-  #
-  #   p = SM::SimpleMarkup.new
-  #   p.add_word_pair("{", "}", :STRIKE)
-  #   p.add_html("no", :STRIKE)
-  #
-  #   p.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
-  #
-  #   h = WikiHtml.new
-  #   h.add_tag(:STRIKE, "<strike>", "</strike>")
-  #
-  #   puts "<body>" + p.convert(ARGF.read, h) + "</body>"
-
-  class SimpleMarkup
-
-    SPACE = ?\s
-
-    # List entries look like:
-    #   *       text
-    #   1.      text
-    #   [label] text
-    #   label:: text
-    #
-    # Flag it as a list entry, and work out the indent for subsequent lines
-
-    SIMPLE_LIST_RE = /^(
-                  (  \*          (?# bullet)
-                    |-           (?# bullet)
-                    |\d+\.       (?# numbered )
-                    |[A-Za-z]\.  (?# alphabetically numbered )
-                  )
-                  \s+
-                )\S/x
-
-    LABEL_LIST_RE = /^(
-                        (  \[.*?\]    (?# labeled  )
-                          |\S.*::     (?# note     )
-                        )(?:\s+|$)
-                      )/x
-
-    ##
-    # Take a block of text and use various heuristics to determine it's
-    # structure (paragraphs, lists, and so on). Invoke an event handler as we
-    # identify significant chunks.
-
-    def initialize
-      @am = AttributeManager.new
-      @output = nil
-    end
-
-    ##
-    # Add to the sequences used to add formatting to an individual word (such
-    # as *bold*). Matching entries will generate attibutes that the output
-    # formatters can recognize by their +name+.
-
-    def add_word_pair(start, stop, name)
-      @am.add_word_pair(start, stop, name)
-    end
-
-    ##
-    # Add to the sequences recognized as general markup.
-
-    def add_html(tag, name)
-      @am.add_html(tag, name)
-    end
-
-    ##
-    # Add to other inline sequences. For example, we could add WikiWords using
-    # something like:
-    #
-    #    parser.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
-    #
-    # Each wiki word will be presented to the output formatter via the
-    # accept_special method.
-
-    def add_special(pattern, name)
-      @am.add_special(pattern, name)
-    end
-
-    ##
-    # We take a string, split it into lines, work out the type of each line,
-    # and from there deduce groups of lines (for example all lines in a
-    # paragraph). We then invoke the output formatter using a Visitor to
-    # display the result.
-
-    def convert(str, op)
-      @lines = Lines.new(str.split(/\r?\n/).collect { |aLine| 
-                           Line.new(aLine) })
-      return "" if @lines.empty?
-      @lines.normalize
-      assign_types_to_lines
-      group = group_lines
-      # call the output formatter to handle the result
-      #      group.to_a.each {|i| p i}
-      group.accept(@am, op)
-    end
-
-    private
-
-    ##
-    # Look through the text at line indentation. We flag each line as being
-    # Blank, a paragraph, a list element, or verbatim text.
-
-    def assign_types_to_lines(margin = 0, level = 0)
-
-      while line = @lines.next
-        if line.isBlank?
-          line.stamp(Line::BLANK, level)
-          next
-        end
-        
-        # if a line contains non-blanks before the margin, then it must belong
-        # to an outer level
-
-        text = line.text
-        
-        for i in 0...margin
-          if text[i] != SPACE
-            @lines.unget
-            return
-          end
-        end
-
-        active_line = text[margin..-1]
-
-        # Rules (horizontal lines) look like
-        #
-        #  ---   (three or more hyphens)
-        #
-        # The more hyphens, the thicker the rule
-        #
-
-        if /^(---+)\s*$/ =~ active_line
-          line.stamp(Line::RULE, level, $1.length-2)
-          next
-        end
-
-        # Then look for list entries. First the ones that have to have
-        # text following them (* xxx, - xxx, and dd. xxx)
-
-        if SIMPLE_LIST_RE =~ active_line
-
-          offset = margin + $1.length
-          prefix = $2
-          prefix_length = prefix.length
-
-          flag = case prefix
-                 when "*","-" then ListBase::BULLET
-                 when /^\d/   then ListBase::NUMBER
-                 when /^[A-Z]/ then ListBase::UPPERALPHA
-                 when /^[a-z]/ then ListBase::LOWERALPHA
-                 else raise "Invalid List Type: #{self.inspect}"
-                 end
-
-          line.stamp(Line::LIST, level+1, prefix, flag)
-          text[margin, prefix_length] = " " * prefix_length
-          assign_types_to_lines(offset, level + 1)
-          next
-        end
-
-
-        if LABEL_LIST_RE =~ active_line
-          offset = margin + $1.length
-          prefix = $2
-          prefix_length = prefix.length
-
-          next if handled_labeled_list(line, level, margin, offset, prefix)
-        end
-
-        # Headings look like
-        # = Main heading
-        # == Second level
-        # === Third
-        #
-        # Headings reset the level to 0
-
-        if active_line[0] == ?= and active_line =~ /^(=+)\s*(.*)/
-          prefix_length = $1.length
-          prefix_length = 6 if prefix_length > 6
-          line.stamp(Line::HEADING, 0, prefix_length)
-          line.strip_leading(margin + prefix_length)
-          next
-        end
-        
-        # If the character's a space, then we have verbatim text,
-        # otherwise 
-
-        if active_line[0] == SPACE
-          line.strip_leading(margin) if margin > 0
-          line.stamp(Line::VERBATIM, level)
-        else
-          line.stamp(Line::PARAGRAPH, level)
-        end
-      end
-    end
-
-    ##
-    # Handle labeled list entries, We have a special case to deal with.
-    # Because the labels can be long, they force the remaining block of text
-    # over the to right:
-    #
-    #   this is a long label that I wrote:: and here is the
-    #                                       block of text with
-    #                                       a silly margin
-    #
-    # So we allow the special case. If the label is followed by nothing, and
-    # if the following line is indented, then we take the indent of that line
-    # as the new margin.
-    #
-    #   this is a long label that I wrote::
-    #       here is a more reasonably indented block which
-    #       will be attached to the label.
-    #
-
-    def handled_labeled_list(line, level, margin, offset, prefix)
-      prefix_length = prefix.length
-      text = line.text
-      flag = nil
-      case prefix
-      when /^\[/
-        flag = ListBase::LABELED
-        prefix = prefix[1, prefix.length-2]
-      when /:$/
-        flag = ListBase::NOTE
-        prefix.chop!
-      else raise "Invalid List Type: #{self.inspect}"
-      end
-      
-      # body is on the next line
-      
-      if text.length <= offset
-        original_line = line
-        line = @lines.next
-        return(false) unless line
-        text = line.text
-        
-        for i in 0..margin
-          if text[i] != SPACE
-            @lines.unget
-            return false
-          end
-        end
-        i = margin
-        i += 1 while text[i] == SPACE
-        if i >= text.length
-          @lines.unget
-          return false
-        else
-          offset = i
-          prefix_length = 0
-          @lines.delete(original_line)
-        end
-      end
-      
-      line.stamp(Line::LIST, level+1, prefix, flag)
-      text[margin, prefix_length] = " " * prefix_length
-      assign_types_to_lines(offset, level + 1)
-      return true
-    end
-
-    ##
-    # Return a block consisting of fragments which are paragraphs, list
-    # entries or verbatim text. We merge consecutive lines of the same type
-    # and level together. We are also slightly tricky with lists: the lines
-    # following a list introduction look like paragraph lines at the next
-    # level, and we remap them into list entries instead.
-
-    def group_lines
-      @lines.rewind
-
-      inList = false
-      wantedType = wantedLevel = nil
-
-      block = LineCollection.new
-      group = nil
-
-      while line = @lines.next
-        if line.level == wantedLevel and line.type == wantedType
-          group.add_text(line.text)
-        else
-          group = block.fragment_for(line)
-          block.add(group)
-          if line.type == Line::LIST
-            wantedType = Line::PARAGRAPH
-          else
-            wantedType = line.type
-          end
-          wantedLevel = line.type == Line::HEADING ? line.param : line.level
-        end
-      end
-
-      block.normalize
-      block
-    end
-
-    ##
-    # For debugging, we allow access to our line contents as text.
-
-    def content
-      @lines.as_text
-    end
-    public :content
-
-    ##
-    # For debugging, return the list of line types.
-
-    def get_line_types
-      @lines.line_types
-    end
-    public :get_line_types
-
-  end
-
-end
-
Index: lib/rdoc/markup/.document
===================================================================
--- lib/rdoc/markup/.document	(revision 15032)
+++ lib/rdoc/markup/.document	(revision 15033)
@@ -1,2 +0,0 @@
-simple_markup
-simple_markup.rb
Index: lib/rdoc/markup/inline.rb
===================================================================
--- lib/rdoc/markup/inline.rb	(revision 0)
+++ lib/rdoc/markup/inline.rb	(revision 15033)
@@ -0,0 +1,357 @@
+require 'rdoc/markup'
+
+class RDoc::Markup
+
+  ##
+  # We manage a set of attributes. Each attribute has a symbol name and a bit
+  # value.
+
+  class Attribute
+    SPECIAL = 1
+
+    @@name_to_bitmap = { :_SPECIAL_ => SPECIAL }
+    @@next_bitmap = 2
+
+    def Attribute.bitmap_for(name)
+      bitmap = @@name_to_bitmap[name]
+      if !bitmap
+        bitmap = @@next_bitmap
+        @@next_bitmap <<= 1
+        @@name_to_bitmap[name] = bitmap
+      end
+      bitmap
+    end
+
+    def Attribute.as_string(bitmap)
+      return "none" if bitmap.zero?
+      res = []
+      @@name_to_bitmap.each do |name, bit|
+        res << name if (bitmap & bit) != 0
+      end
+      res.join(",")
+    end
+
+    def Attribute.each_name_of(bitmap)
+      @@name_to_bitmap.each do |name, bit|
+        next if bit == SPECIAL
+        yield name.to_s if (bitmap & bit) != 0
+      end
+    end
+  end
+
+  ##
+  # An AttrChanger records a change in attributes. It contains a bitmap of the
+  # attributes to turn on, and a bitmap of those to turn off.
+
+  AttrChanger = Struct.new(:turn_on, :turn_off)
+
+  class AttrChanger
+    def to_s
+      "Attr: +#{Attribute.as_string(@turn_on)}/-#{Attribute.as_string(@turn_on)}"
+    end
+  end
+
+  ##
+  # An array of attributes which parallels the characters in a string.
+
+  class AttrSpan
+    def initialize(length)
+      @attrs = Array.new(length, 0)
+    end
+
+    def set_attrs(start, length, bits)
+      for i in start ... (start+length)
+        @attrs[i] |= bits
+      end
+    end
+
+    def [](n)
+      @attrs[n]
+    end
+  end
+
+  ##
+  # Hold details of a special sequence
+
+  class Special
+    attr_reader   :type
+    attr_accessor :text
+
+    def initialize(type, text)
+      @type, @text = type, text
+    end
+
+    def ==(o)
+      self.text == o.text && self.type == o.type
+    end
+
+    def to_s
+      "Special: type=#{type}, name=#{RDoc::Markup::Attribute.as_string type}, text=#{text.dump}"
+    end
+
+    def inspect
+      "#<RDoc::Markup::Special:0x%x @type=%p, name=%p @text=%p>" % [
+        object_id, @type, RDoc::Markup::Attribute.as_string(type), text.dump]
+    end
+  end
+
+  class AttributeManager
+
+    NULL = "\000".freeze
+
+    ##
+    # We work by substituting non-printing characters in to the text. For now
+    # I'm assuming that I can substitute a character in the range 0..8 for a 7
+    # bit character without damaging the encoded string, but this might be
+    # optimistic
+
+    A_PROTECT  = 004
+    PROTECT_ATTR  = A_PROTECT.chr
+
+    ##
+    # This maps delimiters that occur around words (such as *bold* or +tt+)
+    # where the start and end delimiters and the same. This lets us optimize
+    # the regexp
+
+    MATCHING_WORD_PAIRS = {}
+
+    ##
+    # And this is used when the delimiters aren't the same. In this case the
+    # hash maps a pattern to the attribute character
+
+    WORD_PAIR_MAP = {}
+
+    ##
+    # This maps HTML tags to the corresponding attribute char
+
+    HTML_TAGS = {}
+
+    ##
+    # And this maps _special_ sequences to a name. A special sequence is
+    # something like a WikiWord
+
+    SPECIAL = {}
+
+    ##
+    # Return an attribute object with the given turn_on and turn_off bits set
+
+    def attribute(turn_on, turn_off)
+      AttrChanger.new(turn_on, turn_off)
+    end
+
+    def change_attribute(current, new)
+      diff = current ^ new
+      attribute(new & diff, current & diff)
+    end
+
+    def changed_attribute_by_name(current_set, new_set)
+      current = new = 0
+      current_set.each {|name| current |= Attribute.bitmap_for(name) }
+      new_set.each {|name| new |= Attribute.bitmap_for(name) }
+      change_attribute(current, new)
+    end
+
+    def copy_string(start_pos, end_pos)
+      res = @str[start_pos...end_pos]
+      res.gsub!(/\000/, '')
+      res
+    end
+
+    ##
+    # Map attributes like <b>text</b>to the sequence
+    # \001\002<char>\001\003<char>, where <char> is a per-attribute specific
+    # character
+
+    def convert_attrs(str, attrs)
+      # first do matching ones
+      tags = MATCHING_WORD_PAIRS.keys.join("")
+      re = "(^|\\W)([#{tags}])([A-Za-z_]+?)\\2(\\W|\$)"
+#      re = "(^|\\W)([#{tags}])(\\S+?)\\2(\\W|\$)"
+      1 while str.gsub!(Regexp.new(re)) {
+        attr = MATCHING_WORD_PAIRS[$2];
+        attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr)
+        $1 + NULL*$2.length + $3 + NULL*$2.length + $4
+      }
+
+      # then non-matching
+      unless WORD_PAIR_MAP.empty?
+        WORD_PAIR_MAP.each do |regexp, attr|
+          str.gsub!(regexp) { 
+            attrs.set_attrs($`.length + $1.length, $2.length, attr)
+            NULL*$1.length + $2 + NULL*$3.length
+          }
+        end
+      end
+    end
+
+    def convert_html(str, attrs)
+      tags = HTML_TAGS.keys.join("|")
+      re = "<(#{tags})>(.*?)</\\1>"
+      1 while str.gsub!(Regexp.new(re, Regexp::IGNORECASE)) {
+        attr = HTML_TAGS[$1.downcase]
+        html_length = $1.length + 2
+        seq = NULL * html_length
+        attrs.set_attrs($`.length + html_length, $2.length, attr)
+        seq + $2 + seq + NULL
+      }
+    end
+
+    def convert_specials(str, attrs)
+      unless SPECIAL.empty?
+        SPECIAL.each do |regexp, attr|
+          str.scan(regexp) do
+            attrs.set_attrs($`.length, $&.length, attr | Attribute::SPECIAL)
+          end
+        end
+      end
+    end
+
+    ##
+    # A \ in front of a character that would normally be processed turns off
+    # processing. We do this by turning \< into <#{PROTECT}
+
+    PROTECTABLE = [ "<" << "\\" ]  #"
+
+
+    def mask_protected_sequences
+      protect_pattern = Regexp.new("\\\\([#{Regexp.escape(PROTECTABLE.join(''))}])")
+      @str.gsub!(protect_pattern, "\\1#{PROTECT_ATTR}")
+    end
+
+    def unmask_protected_sequences
+      @str.gsub!(/(.)#{PROTECT_ATTR}/, "\\1\000")
+    end
+
+    def initialize
+      add_word_pair("*", "*", :BOLD)
+      add_word_pair("_", "_", :EM)
+      add_word_pair("+", "+", :TT)
+
+      add_html("em", :EM)
+      add_html("i",  :EM)
+      add_html("b",  :BOLD)
+      add_html("tt",   :TT)
+      add_html("code", :TT)
+
+      add_special(/<!--(.*?)-->/, :COMMENT)
+    end
+
+    def add_word_pair(start, stop, name)
+      raise "Word flags may not start '<'" if start[0] == ?<
+      bitmap = Attribute.bitmap_for(name)
+      if start == stop
+        MATCHING_WORD_PAIRS[start] = bitmap
+      else
+        pattern = Regexp.new("(" + Regexp.escape(start) + ")" +
+#                             "([A-Za-z]+)" +
+                             "(\\S+)" +
+                             "(" + Regexp.escape(stop) +")")
+        WORD_PAIR_MAP[pattern] = bitmap
+      end
+      PROTECTABLE << start[0,1]
+      PROTECTABLE.uniq!
+    end
+
+    def add_html(tag, name)
+      HTML_TAGS[tag.downcase] = Attribute.bitmap_for(name)
+    end
+
+    def add_special(pattern, name)
+      SPECIAL[pattern] = Attribute.bitmap_for(name)
+    end
+
+    def flow(str)
+      @str = str
+
+      puts("Before flow, str='#{@str.dump}'") if $DEBUG_RDOC
+      mask_protected_sequences
+
+      @attrs = AttrSpan.new(@str.length)
+
+      puts("After protecting, str='#{@str.dump}'") if $DEBUG_RDOC
+      convert_attrs(@str, @attrs)
+      convert_html(@str, @attrs)
+      convert_specials(str, @attrs)
+      unmask_protected_sequences
+      puts("After flow, str='#{@str.dump}'") if $DEBUG_RDOC
+      return split_into_flow
+    end
+
+    def display_attributes
+      puts
+      puts @str.tr(NULL, "!")
+      bit = 1
+      16.times do |bno|
+        line = ""
+        @str.length.times do |i|
+          if (@attrs[i] & bit) == 0
+            line << " "
+          else
+            if bno.zero?
+              line << "S"
+            else
+              line << ("%d" % (bno+1))
+            end
+          end
+        end
+        puts(line) unless line =~ /^ *$/
+        bit <<= 1
+      end
+    end
+
+    def split_into_flow
+
+      display_attributes if $DEBUG_RDOC
+
+      res = []
+      current_attr = 0
+      str = ""
+
+      str_len = @str.length
+
+      # skip leading invisible text
+      i = 0
+      i += 1 while i < str_len and @str[i] == "\0"
+      start_pos = i
+
+      # then scan the string, chunking it on attribute changes
+      while i < str_len
+        new_attr = @attrs[i]
+        if new_attr != current_attr
+          if i > start_pos
+            res << copy_string(start_pos, i)
+            start_pos = i
+          end
+
+          res << change_attribute(current_attr, new_attr)
+          current_attr = new_attr
+
+          if (current_attr & Attribute::SPECIAL) != 0
+            i += 1 while i < str_len and (@attrs[i] & Attribute::SPECIAL) != 0
+            res << Special.new(current_attr, copy_string(start_pos, i))
+            start_pos = i
+            next
+          end
+        end
+
+        # move on, skipping any invisible characters
+        begin
+          i += 1
+        end while i < str_len and @str[i] == "\0"
+      end
+
+      # tidy up trailing text
+      if start_pos < str_len
+        res << copy_string(start_pos, str_len)
+      end
+
+      # and reset to all attributes off
+      res << change_attribute(current_attr, 0) if current_attr != 0
+
+      return res
+    end
+
+  end
+
+end
+

Property changes on: lib/rdoc/markup/inline.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/markup/to_latex.rb
===================================================================
--- lib/rdoc/markup/to_latex.rb	(revision 0)
+++ lib/rdoc/markup/to_latex.rb	(revision 15033)
@@ -0,0 +1,331 @@
+require 'rdoc/markup/fragments'
+require 'rdoc/markup/inline'
+
+require 'cgi'
+
+##
+# Convert SimpleMarkup to basic LaTeX report format.
+
+class RDoc::Markup::ToLaTeX
+
+  BS = "\020"   # \
+  OB = "\021"   # {
+  CB = "\022"   # }
+  DL = "\023"   # Dollar
+
+  BACKSLASH   = "#{BS}symbol#{OB}92#{CB}"
+  HAT         = "#{BS}symbol#{OB}94#{CB}"
+  BACKQUOTE   = "#{BS}symbol#{OB}0#{CB}"
+  TILDE       = "#{DL}#{BS}sim#{DL}"
+  LESSTHAN    = "#{DL}<#{DL}"
+  GREATERTHAN = "#{DL}>#{DL}"
+
+  def self.l(str)
+    str.tr('\\', BS).tr('{', OB).tr('}', CB).tr('$', DL)
+  end
+
+  def l(arg)
+    RDoc::Markup::ToLaTeX.l(arg)
+  end
+
+  LIST_TYPE_TO_LATEX = {
+    ListBase::BULLET =>  [ l("\\begin{itemize}"), l("\\end{itemize}") ],
+    ListBase::NUMBER =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\arabic" ],
+    ListBase::UPPERALPHA =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\Alph" ],
+    ListBase::LOWERALPHA =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\alph" ],
+    ListBase::LABELED => [ l("\\begin{description}"), l("\\end{description}") ],
+    ListBase::NOTE    => [
+      l("\\begin{tabularx}{\\linewidth}{@{} l X @{}}"), 
+      l("\\end{tabularx}") ],
+  }
+
+  InlineTag = Struct.new(:bit, :on, :off)
+
+  def initialize
+    init_tags
+    @list_depth = 0
+    @prev_list_types = []
+  end
+
+  ##
+  # Set up the standard mapping of attributes to LaTeX
+
+  def init_tags
+    @attr_tags = [
+      InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:BOLD), l("\\textbf{"), l("}")),
+      InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:TT),   l("\\texttt{"), l("}")),
+      InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:EM),   l("\\emph{"), l("}")),
+    ]
+  end
+
+  ##
+  # Escape a LaTeX string
+
+  def escape(str)
+$stderr.print "FE: ", str
+    s = str.
+       sub(/\s+$/, '').
+      gsub(/([_\${}&%#])/, "#{BS}\\1").
+      gsub(/\\/, BACKSLASH).
+      gsub(/\^/, HAT).
+      gsub(/~/,  TILDE).
+      gsub(/</,  LESSTHAN).
+      gsub(/>/,  GREATERTHAN).
+      gsub(/,,/, ",{},").
+      gsub(/\`/,  BACKQUOTE)
+$stderr.print "-> ", s, "\n"
+    s
+  end
+
+  ##
+  # Add a new set of LaTeX tags for an attribute. We allow
+  # separate start and end tags for flexibility
+
+  def add_tag(name, start, stop)
+    @attr_tags << InlineTag.new(RDoc::Markup::Attribute.bitmap_for(name), start, stop)
+  end
+
+  ##
+  # Here's the client side of the visitor pattern
+
+  def start_accepting
+    @res = ""
+    @in_list_entry = []
+  end
+
+  def end_accepting
+    @res.tr(BS, '\\').tr(OB, '{').tr(CB, '}').tr(DL, '$')
+  end
+
+  def accept_paragraph(am, fragment)
+    @res << wrap(convert_flow(am.flow(fragment.txt)))
+    @res << "\n"
+  end
+
+  def accept_verbatim(am, fragment)
+    @res << "\n\\begin{code}\n"
+    @res << fragment.txt.sub(/[\n\s]+\Z/, '')
+    @res << "\n\\end{code}\n\n"
+  end
+
+  def accept_rule(am, fragment)
+    size = fragment.param
+    size = 10 if size > 10
+    @res << "\n\n\\rule{\\linewidth}{#{size}pt}\n\n"
+  end
+
+  def accept_list_start(am, fragment)
+    @res << list_name(fragment.type, true) << "\n"
+    @in_list_entry.push false
+  end
+
+  def accept_list_end(am, fragment)
+    if tag = @in_list_entry.pop
+      @res << tag << "\n"
+    end
+    @res << list_name(fragment.type, false) << "\n"
+  end
+
+  def accept_list_item(am, fragment)
+    if tag = @in_list_entry.last
+      @res << tag << "\n"
+    end
+    @res << list_item_start(am, fragment)
+    @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
+    @in_list_entry[-1] = list_end_for(fragment.type)
+  end
+
+  def accept_blank_line(am, fragment)
+    # @res << "\n"
+  end
+
+  def accept_heading(am, fragment)
+    @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
+  end
+
+  ##
+  # This is a higher speed (if messier) version of wrap
+
+  def wrap(txt, line_len = 76)
+    res = ""
+    sp = 0
+    ep = txt.length
+    while sp < ep
+      # scan back for a space
+      p = sp + line_len - 1
+      if p >= ep
+        p = ep
+      else
+        while p > sp and txt[p] != ?\s
+          p -= 1
+        end
+        if p <= sp
+          p = sp + line_len
+          while p < ep and txt[p] != ?\s
+            p += 1
+          end
+        end
+      end
+      res << txt[sp...p] << "\n"
+      sp = p
+      sp += 1 while sp < ep and txt[sp] == ?\s
+    end
+    res
+  end
+
+  private
+
+  def on_tags(res, item)
+    attr_mask = item.turn_on
+    return if attr_mask.zero?
+
+    @attr_tags.each do |tag|
+      if attr_mask & tag.bit != 0
+        res << tag.on
+      end
+    end
+  end
+
+  def off_tags(res, item)
+    attr_mask = item.turn_off
+    return if attr_mask.zero?
+
+    @attr_tags.reverse_each do |tag|
+      if attr_mask & tag.bit != 0
+        res << tag.off
+      end
+    end
+  end
+
+  def convert_flow(flow)
+    res = ""
+    flow.each do |item|
+      case item
+      when String
+         $stderr.puts "Converting '#{item}'"
+        res << convert_string(item)
+      when AttrChanger
+        off_tags(res, item)
+        on_tags(res,  item)
+      when Special
+        res << convert_special(item)
+      else
+        raise "Unknown flow element: #{item.inspect}"
+      end
+    end
+    res
+  end
+
+  ##
+  # some of these patterns are taken from SmartyPants...
+
+  def convert_string(item)
+    escape(item).
+
+    # convert ... to elipsis (and make sure .... becomes .<elipsis>)
+      gsub(/\.\.\.\./, '.\ldots{}').gsub(/\.\.\./, '\ldots{}').
+
+    # convert single closing quote
+      gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1'" }.
+      gsub(%r{\'(?=\W|s\b)}) { "'" }.
+
+    # convert single opening quote
+      gsub(/'/, '`').
+
+    # convert double closing quote
+      gsub(%r{([^ \t\r\n\[\{\(])\"(?=\W)}) { "#$1''" }.
+
+    # convert double opening quote
+      gsub(/"/, "``").
+
+    # convert copyright
+      gsub(/\(c\)/, '\copyright{}')
+
+  end
+
+  def convert_special(special)
+    handled = false
+    Attribute.each_name_of(special.type) do |name|
+      method_name = "handle_special_#{name}"
+      if self.respond_to? method_name
+        special.text = send(method_name, special)
+        handled = true
+      end
+    end
+    raise "Unhandled special: #{special}" unless handled
+    special.text
+  end
+
+  def convert_heading(level, flow)
+    res =
+      case level
+      when 1 then "\\chapter{"
+      when 2 then "\\section{"
+      when 3 then "\\subsection{"
+      when 4 then "\\subsubsection{"
+      else  "\\paragraph{"
+      end +
+      convert_flow(flow) +
+      "}\n"
+  end
+
+  def list_name(list_type, is_open_tag)
+    tags = LIST_TYPE_TO_LATEX[list_type] || raise("Invalid list type: #{list_type.inspect}")
+    if tags[2] # enumerate
+      if is_open_tag
+        @list_depth += 1
+        if @prev_list_types[@list_depth] != tags[2]
+          case @list_depth
+          when 1
+            roman = "i"
+          when 2
+            roman = "ii"
+          when 3
+            roman = "iii"
+          when 4
+            roman = "iv"
+          else
+            raise("Too deep list: level #{@list_depth}")
+          end
+          @prev_list_types[@list_depth] = tags[2]
+          return l("\\renewcommand{\\labelenum#{roman}}{#{tags[2]}{enum#{roman}}}") + "\n" + tags[0]
+        end
+      else
+        @list_depth -= 1
+      end
+    end
+    tags[ is_open_tag ? 0 : 1]
+  end
+
+  def list_item_start(am, fragment)
+    case fragment.type
+    when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA,
+         ListBase::LOWERALPHA
+      "\\item "
+
+    when ListBase::LABELED
+      "\\item[" + convert_flow(am.flow(fragment.param)) + "] "
+
+    when ListBase::NOTE
+        convert_flow(am.flow(fragment.param)) + " & "
+    else
+      raise "Invalid list type"
+    end
+  end
+
+  def list_end_for(fragment_type)
+    case fragment_type
+    when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA,
+         ListBase::LOWERALPHA, ListBase::LABELED
+      ""
+    when ListBase::NOTE
+      "\\\\\n"
+    else
+      raise "Invalid list type"
+    end
+  end
+
+end
+
+d
+

Property changes on: lib/rdoc/markup/to_latex.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/markup/preprocess.rb
===================================================================
--- lib/rdoc/markup/preprocess.rb	(revision 0)
+++ lib/rdoc/markup/preprocess.rb	(revision 15033)
@@ -0,0 +1,71 @@
+require 'rdoc/markup'
+
+##
+# Handle common directives that can occur in a block of text:
+#
+# : include : filename
+
+class RDoc::Markup::PreProcess
+
+  def initialize(input_file_name, include_path)
+    @input_file_name = input_file_name
+    @include_path = include_path
+  end
+
+  ##
+  # Look for common options in a chunk of text. Options that we don't handle
+  # are passed back to our caller as |directive, param|
+
+  def handle(text)
+    text.gsub!(/^([ \t#]*):(\w+):\s*(.+)?\n/) do
+      prefix    = $1
+      directive = $2.downcase
+      param     = $3
+
+      case directive
+      when "include"
+        filename = param.split[0]
+        include_file(filename, prefix)
+
+      else
+        yield(directive, param)
+      end
+    end
+  end
+
+  private
+
+  ##
+  # Include a file, indenting it correctly.
+
+  def include_file(name, indent)
+    if full_name = find_include_file(name) then
+      content = File.open(full_name) {|f| f.read}
+      # strip leading '#'s, but only if all lines start with them
+      if content =~ /^[^#]/
+        content.gsub(/^/, indent)
+      else
+        content.gsub(/^#?/, indent)
+      end
+    else
+      $stderr.puts "Couldn't find file to include: '#{name}'"
+      ''
+    end
+  end
+
+  ##
+  # Look for the given file in the directory containing the current file,
+  # and then in each of the directories specified in the RDOC_INCLUDE path
+
+  def find_include_file(name)
+    to_search = [ File.dirname(@input_file_name) ].concat @include_path
+    to_search.each do |dir|
+      full_name = File.join(dir, name)
+      stat = File.stat(full_name) rescue next
+      return full_name if stat.readable?
+    end
+    nil
+  end
+
+end
+

Property changes on: lib/rdoc/markup/preprocess.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/markup/fragments.rb
===================================================================
--- lib/rdoc/markup/fragments.rb	(revision 0)
+++ lib/rdoc/markup/fragments.rb	(revision 15033)
@@ -0,0 +1,330 @@
+require 'rdoc/markup'
+require 'rdoc/markup/lines'
+
+class RDoc::Markup
+
+  ##
+  # A Fragment is a chunk of text, subclassed as a paragraph, a list
+  # entry, or verbatim text.
+
+  class Fragment
+    attr_reader   :level, :param, :txt
+    attr_accessor :type
+
+    def initialize(level, param, type, txt)
+      @level = level
+      @param = param
+      @type  = type
+      @txt   = ""
+      add_text(txt) if txt
+    end
+
+    def add_text(txt)
+      @txt << " " if @txt.length > 0
+      @txt << txt.tr_s("\n ", "  ").strip
+    end
+
+    def to_s
+      "L#@level: #{self.class.name.split('::')[-1]}\n#@txt"
+    end
+
+    ######
+    # This is a simple factory system that lets us associate fragement
+    # types (a string) with a subclass of fragment
+
+    TYPE_MAP = {}
+
+    def Fragment.type_name(name)
+      TYPE_MAP[name] = self
+    end
+
+    def Fragment.for(line)
+      klass =  TYPE_MAP[line.type] ||
+        raise("Unknown line type: '#{line.type.inspect}:' '#{line.text}'")
+      return klass.new(line.level, line.param, line.flag, line.text)
+    end
+  end
+
+  ##
+  # A paragraph is a fragment which gets wrapped to fit. We remove all
+  # newlines when we're created, and have them put back on output.
+
+  class Paragraph < Fragment
+    type_name Line::PARAGRAPH
+  end
+
+  class BlankLine < Paragraph
+    type_name Line::BLANK
+  end
+
+  class Heading < Paragraph
+    type_name Line::HEADING
+
+    def head_level
+      @param.to_i
+    end
+  end
+
+  ##
+  # A List is a fragment with some kind of label
+
+  class ListBase < Paragraph
+    # List types
+    BULLET  = :BULLET
+    NUMBER  = :NUMBER
+    UPPERALPHA  = :UPPERALPHA
+    LOWERALPHA  = :LOWERALPHA
+    LABELED = :LABELED
+    NOTE    = :NOTE
+  end
+
+  class ListItem < ListBase
+    type_name Line::LIST
+
+    #  def label
+    #    am = AttributeManager.new(@param)
+    #    am.flow
+    #  end
+  end
+
+  class ListStart < ListBase
+    def initialize(level, param, type)
+      super(level, param, type, nil)
+    end
+  end
+
+  class ListEnd < ListBase
+    def initialize(level, type)
+      super(level, "", type, nil)
+    end
+  end
+
+  ##
+  # Verbatim code contains lines that don't get wrapped.
+
+  class Verbatim < Fragment
+    type_name  Line::VERBATIM
+
+    def add_text(txt)
+      @txt << txt.chomp << "\n"
+    end
+
+  end
+
+  ##
+  # A horizontal rule
+
+  class Rule < Fragment
+    type_name Line::RULE
+  end
+
+  ##
+  # Collect groups of lines together. Each group will end up containing a flow
+  # of text.
+
+  class LineCollection
+
+    def initialize
+      @fragments = []
+    end
+
+    def add(fragment)
+      @fragments << fragment
+    end
+
+    def each(&b)
+      @fragments.each(&b)
+    end
+
+    def to_a # :nodoc:
+      @fragments.map {|fragment| fragment.to_s}
+    end
+
+    ##
+    # Factory for different fragment types
+
+    def fragment_for(*args)
+      Fragment.for(*args)
+    end
+
+    ##
+    # Tidy up at the end
+
+    def normalize
+      change_verbatim_blank_lines
+      add_list_start_and_ends
+      add_list_breaks
+      tidy_blank_lines
+    end
+
+    def to_s
+      @fragments.join("\n----\n")
+    end
+
+    def accept(am, visitor)
+      visitor.start_accepting
+
+      @fragments.each do |fragment|
+        case fragment
+        when Verbatim
+          visitor.accept_verbatim(am, fragment)
+        when Rule
+          visitor.accept_rule(am, fragment)
+        when ListStart
+          visitor.accept_list_start(am, fragment)
+        when ListEnd
+          visitor.accept_list_end(am, fragment)
+        when ListItem
+          visitor.accept_list_item(am, fragment)
+        when BlankLine
+          visitor.accept_blank_line(am, fragment)
+        when Heading
+          visitor.accept_heading(am, fragment)
+        when Paragraph
+          visitor.accept_paragraph(am, fragment)
+        end
+      end
+
+      visitor.end_accepting
+    end
+
+    private
+
+    # If you have:
+    #
+    #    normal paragraph text.
+    #
+    #       this is code
+    #   
+    #       and more code
+    #
+    # You'll end up with the fragments Paragraph, BlankLine, Verbatim,
+    # BlankLine, Verbatim, BlankLine, etc.
+    #
+    # The BlankLine in the middle of the verbatim chunk needs to be changed to
+    # a real verbatim newline, and the two verbatim blocks merged
+
+    def change_verbatim_blank_lines
+      frag_block = nil
+      blank_count = 0
+      @fragments.each_with_index do |frag, i|
+        if frag_block.nil?
+          frag_block = frag if Verbatim === frag
+        else
+          case frag
+          when Verbatim
+            blank_count.times { frag_block.add_text("\n") }
+            blank_count = 0
+            frag_block.add_text(frag.txt)
+            @fragments[i] = nil    # remove out current fragment
+          when BlankLine
+            if frag_block
+              blank_count += 1
+              @fragments[i] = nil
+            end
+          else
+            frag_block = nil
+            blank_count = 0
+          end
+        end
+      end
+      @fragments.compact!
+    end
+
+    ##
+    # List nesting is implicit given the level of indentation. Make it
+    # explicit, just to make life a tad easier for the output processors
+
+    def add_list_start_and_ends
+      level = 0
+      res = []
+      type_stack = []
+
+      @fragments.each do |fragment|
+        # $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}"
+        new_level = fragment.level
+        while (level < new_level)
+          level += 1
+          type = fragment.type
+          res << ListStart.new(level, fragment.param, type) if type
+          type_stack.push type
+          # $stderr.puts "Start: #{level}"
+        end
+
+        while level > new_level
+          type = type_stack.pop
+          res << ListEnd.new(level, type) if type
+          level -= 1
+          # $stderr.puts "End: #{level}, #{type}"
+        end
+
+        res << fragment
+        level = fragment.level
+      end
+      level.downto(1) do |i|
+        type = type_stack.pop
+        res << ListEnd.new(i, type) if type
+      end
+
+      @fragments = res
+    end
+
+    ##
+    # Inserts start/ends between list entries at the same level that have
+    # different element types
+
+    def add_list_breaks
+      res = @fragments
+
+      @fragments = []
+      list_stack = []
+
+      res.each do |fragment|
+        case fragment
+        when ListStart
+          list_stack.push fragment
+        when ListEnd
+          start = list_stack.pop
+          fragment.type = start.type
+        when ListItem
+          l = list_stack.last
+          if fragment.type != l.type
+            @fragments << ListEnd.new(l.level, l.type)
+            start = ListStart.new(l.level, fragment.param, fragment.type)
+            @fragments << start
+            list_stack.pop
+            list_stack.push start
+          end
+        else
+          ;
+        end
+        @fragments << fragment
+      end
+    end
+
+    ##
+    # Tidy up the blank lines:
+    # * change Blank/ListEnd into ListEnd/Blank
+    # * remove blank lines at the front
+
+    def tidy_blank_lines
+      (@fragments.size - 1).times do |i|
+        if @fragments[i].kind_of?(BlankLine) and 
+            @fragments[i+1].kind_of?(ListEnd)
+          @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i] 
+        end
+      end
+
+      # remove leading blanks
+      @fragments.each_with_index do |f, i|
+        break unless f.kind_of? BlankLine
+        @fragments[i] = nil
+      end
+
+      @fragments.compact!
+    end
+
+  end
+
+end
+

Property changes on: lib/rdoc/markup/fragments.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/markup/simple_markup/inline.rb
===================================================================
--- lib/rdoc/markup/simple_markup/inline.rb	(revision 15032)
+++ lib/rdoc/markup/simple_markup/inline.rb	(revision 15033)
@@ -1,355 +0,0 @@
-module SM
-
-  ##
-  # We manage a set of attributes. Each attribute has a symbol name and a bit
-  # value
-
-  class Attribute
-    SPECIAL = 1
-
-    @@name_to_bitmap = { :_SPECIAL_ => SPECIAL }
-    @@next_bitmap = 2
-
-    def Attribute.bitmap_for(name)
-      bitmap = @@name_to_bitmap[name]
-      if !bitmap
-        bitmap = @@next_bitmap
-        @@next_bitmap <<= 1
-        @@name_to_bitmap[name] = bitmap
-      end
-      bitmap
-    end
-
-    def Attribute.as_string(bitmap)
-      return "none" if bitmap.zero?
-      res = []
-      @@name_to_bitmap.each do |name, bit|
-        res << name if (bitmap & bit) != 0
-      end
-      res.join(",")
-    end
-
-    def Attribute.each_name_of(bitmap)
-      @@name_to_bitmap.each do |name, bit|
-        next if bit == SPECIAL
-        yield name.to_s if (bitmap & bit) != 0
-      end
-    end
-  end
-
-  ##
-  # An AttrChanger records a change in attributes. It contains a bitmap of the
-  # attributes to turn on, and a bitmap of those to turn off
-
-  AttrChanger = Struct.new(:turn_on, :turn_off)
-
-  class AttrChanger
-    def to_s
-      "Attr: +#{Attribute.as_string(@turn_on)}/-#{Attribute.as_string(@turn_on)}"
-    end
-  end
-
-  ##
-  # An array of attributes which parallels the characters in a string
-
-  class AttrSpan
-    def initialize(length)
-      @attrs = Array.new(length, 0)
-    end
-
-    def set_attrs(start, length, bits)
-      for i in start ... (start+length)
-        @attrs[i] |= bits
-      end
-    end
-
-    def [](n)
-      @attrs[n]
-    end
-  end
-
-  ##
-  # Hold details of a special sequence
-
-  class Special
-    attr_reader   :type
-    attr_accessor :text
-
-    def initialize(type, text)
-      @type, @text = type, text
-    end
-
-    def ==(o)
-      self.text == o.text && self.type == o.type
-    end
-
-    def to_s
-      "Special: type=#{type}, name=#{SM::Attribute.as_string type}, text=#{text.dump}"
-    end
-
-    def inspect
-      "#<SM::Special:0x%x @type=%p, name=%p @text=%p>" % [
-        object_id, @type, SM::Attribute.as_string(type), text.dump]
-    end
-  end
-
-  class AttributeManager
-
-    NULL = "\000".freeze
-
-    ##
-    # We work by substituting non-printing characters in to the text. For now
-    # I'm assuming that I can substitute a character in the range 0..8 for a 7
-    # bit character without damaging the encoded string, but this might be
-    # optimistic
-
-    A_PROTECT  = 004
-    PROTECT_ATTR  = A_PROTECT.chr
-
-    ##
-    # This maps delimiters that occur around words (such as *bold* or +tt+)
-    # where the start and end delimiters and the same. This lets us optimize
-    # the regexp
-
-    MATCHING_WORD_PAIRS = {}
-
-    ##
-    # And this is used when the delimiters aren't the same. In this case the
-    # hash maps a pattern to the attribute character
-
-    WORD_PAIR_MAP = {}
-
-    ##
-    # This maps HTML tags to the corresponding attribute char
-
-    HTML_TAGS = {}
-
-    ##
-    # And this maps _special_ sequences to a name. A special sequence is
-    # something like a WikiWord
-
-    SPECIAL = {}
-
-    ##
-    # Return an attribute object with the given turn_on and turn_off bits set
-
-    def attribute(turn_on, turn_off)
-      AttrChanger.new(turn_on, turn_off)
-    end
-
-    def change_attribute(current, new)
-      diff = current ^ new
-      attribute(new & diff, current & diff)
-    end
-
-    def changed_attribute_by_name(current_set, new_set)
-      current = new = 0
-      current_set.each {|name| current |= Attribute.bitmap_for(name) }
-      new_set.each {|name| new |= Attribute.bitmap_for(name) }
-      change_attribute(current, new)
-    end
-
-    def copy_string(start_pos, end_pos)
-      res = @str[start_pos...end_pos]
-      res.gsub!(/\000/, '')
-      res
-    end
-
-    ##
-    # Map attributes like <b>text</b>to the sequence
-    # \001\002<char>\001\003<char>, where <char> is a per-attribute specific
-    # character
-
-    def convert_attrs(str, attrs)
-      # first do matching ones
-      tags = MATCHING_WORD_PAIRS.keys.join("")
-      re = "(^|\\W)([#{tags}])([A-Za-z_]+?)\\2(\\W|\$)"
-#      re = "(^|\\W)([#{tags}])(\\S+?)\\2(\\W|\$)"
-      1 while str.gsub!(Regexp.new(re)) {
-        attr = MATCHING_WORD_PAIRS[$2];
-        attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr)
-        $1 + NULL*$2.length + $3 + NULL*$2.length + $4
-      }
-
-      # then non-matching
-      unless WORD_PAIR_MAP.empty?
-        WORD_PAIR_MAP.each do |regexp, attr|
-          str.gsub!(regexp) { 
-            attrs.set_attrs($`.length + $1.length, $2.length, attr)
-            NULL*$1.length + $2 + NULL*$3.length
-          }
-        end
-      end
-    end
-
-    def convert_html(str, attrs)
-      tags = HTML_TAGS.keys.join("|")
-      re = "<(#{tags})>(.*?)</\\1>"
-      1 while str.gsub!(Regexp.new(re, Regexp::IGNORECASE)) {
-        attr = HTML_TAGS[$1.downcase]
-        html_length = $1.length + 2
-        seq = NULL * html_length
-        attrs.set_attrs($`.length + html_length, $2.length, attr)
-        seq + $2 + seq + NULL
-      }
-    end
-
-    def convert_specials(str, attrs)
-      unless SPECIAL.empty?
-        SPECIAL.each do |regexp, attr|
-          str.scan(regexp) do
-            attrs.set_attrs($`.length, $&.length, attr | Attribute::SPECIAL)
-          end
-        end
-      end
-    end
-
-    ##
-    # A \ in front of a character that would normally be processed turns off
-    # processing. We do this by turning \< into <#{PROTECT}
-
-    PROTECTABLE = [ "<" << "\\" ]  #"
-
-
-    def mask_protected_sequences
-      protect_pattern = Regexp.new("\\\\([#{Regexp.escape(PROTECTABLE.join(''))}])")
-      @str.gsub!(protect_pattern, "\\1#{PROTECT_ATTR}")
-    end
-
-    def unmask_protected_sequences
-      @str.gsub!(/(.)#{PROTECT_ATTR}/, "\\1\000")
-    end
-
-    def initialize
-      add_word_pair("*", "*", :BOLD)
-      add_word_pair("_", "_", :EM)
-      add_word_pair("+", "+", :TT)
-
-      add_html("em", :EM)
-      add_html("i",  :EM)
-      add_html("b",  :BOLD)
-      add_html("tt",   :TT)
-      add_html("code", :TT)
-
-      add_special(/<!--(.*?)-->/, :COMMENT)
-    end
-
-    def add_word_pair(start, stop, name)
-      raise "Word flags may not start '<'" if start[0] == ?<
-      bitmap = Attribute.bitmap_for(name)
-      if start == stop
-        MATCHING_WORD_PAIRS[start] = bitmap
-      else
-        pattern = Regexp.new("(" + Regexp.escape(start) + ")" +
-#                             "([A-Za-z]+)" +
-                             "(\\S+)" +
-                             "(" + Regexp.escape(stop) +")")
-        WORD_PAIR_MAP[pattern] = bitmap
-      end
-      PROTECTABLE << start[0,1]
-      PROTECTABLE.uniq!
-    end
-
-    def add_html(tag, name)
-      HTML_TAGS[tag.downcase] = Attribute.bitmap_for(name)
-    end
-
-    def add_special(pattern, name)
-      SPECIAL[pattern] = Attribute.bitmap_for(name)
-    end
-
-    def flow(str)
-      @str = str
-
-      puts("Before flow, str='#{@str.dump}'") if $DEBUG_RDOC
-      mask_protected_sequences
-
-      @attrs = AttrSpan.new(@str.length)
-
-      puts("After protecting, str='#{@str.dump}'") if $DEBUG_RDOC
-      convert_attrs(@str, @attrs)
-      convert_html(@str, @attrs)
-      convert_specials(str, @attrs)
-      unmask_protected_sequences
-      puts("After flow, str='#{@str.dump}'") if $DEBUG_RDOC
-      return split_into_flow
-    end
-
-    def display_attributes
-      puts
-      puts @str.tr(NULL, "!")
-      bit = 1
-      16.times do |bno|
-        line = ""
-        @str.length.times do |i|
-          if (@attrs[i] & bit) == 0
-            line << " "
-          else
-            if bno.zero?
-              line << "S"
-            else
-              line << ("%d" % (bno+1))
-            end
-          end
-        end
-        puts(line) unless line =~ /^ *$/
-        bit <<= 1
-      end
-    end
-
-    def split_into_flow
-
-      display_attributes if $DEBUG_RDOC
-
-      res = []
-      current_attr = 0
-      str = ""
-
-      str_len = @str.length
-
-      # skip leading invisible text
-      i = 0
-      i += 1 while i < str_len and @str[i] == "\0"
-      start_pos = i
-
-      # then scan the string, chunking it on attribute changes
-      while i < str_len
-        new_attr = @attrs[i]
-        if new_attr != current_attr
-          if i > start_pos
-            res << copy_string(start_pos, i)
-            start_pos = i
-          end
-
-          res << change_attribute(current_attr, new_attr)
-          current_attr = new_attr
-
-          if (current_attr & Attribute::SPECIAL) != 0
-            i += 1 while i < str_len and (@attrs[i] & Attribute::SPECIAL) != 0
-            res << Special.new(current_attr, copy_string(start_pos, i))
-            start_pos = i
-            next
-          end
-        end
-
-        # move on, skipping any invisible characters
-        begin
-          i += 1
-        end while i < str_len and @str[i] == "\0"
-      end
-
-      # tidy up trailing text
-      if start_pos < str_len
-        res << copy_string(start_pos, str_len)
-      end
-
-      # and reset to all attributes off
-      res << change_attribute(current_attr, 0) if current_attr != 0
-
-      return res
-    end
-
-  end
-
-end
-
Index: lib/rdoc/markup/simple_markup/to_latex.rb
===================================================================
--- lib/rdoc/markup/simple_markup/to_latex.rb	(revision 15032)
+++ lib/rdoc/markup/simple_markup/to_latex.rb	(revision 15033)
@@ -1,332 +0,0 @@
-require 'rdoc/markup/simple_markup/fragments'
-require 'rdoc/markup/simple_markup/inline'
-
-require 'cgi'
-
-module SM
-
-  # Convert SimpleMarkup to basic LaTeX report format
-
-  class ToLaTeX
-
-    BS = "\020"   # \
-    OB = "\021"   # {
-    CB = "\022"   # }
-    DL = "\023"   # Dollar
-
-    BACKSLASH   = "#{BS}symbol#{OB}92#{CB}"
-    HAT         = "#{BS}symbol#{OB}94#{CB}"
-    BACKQUOTE   = "#{BS}symbol#{OB}0#{CB}"
-    TILDE       = "#{DL}#{BS}sim#{DL}"
-    LESSTHAN    = "#{DL}<#{DL}"
-    GREATERTHAN = "#{DL}>#{DL}"
-
-    def self.l(str)
-      str.tr('\\', BS).tr('{', OB).tr('}', CB).tr('$', DL)
-    end
-
-    def l(arg)
-      SM::ToLaTeX.l(arg)
-    end
-
-    LIST_TYPE_TO_LATEX = {
-      ListBase::BULLET =>  [ l("\\begin{itemize}"), l("\\end{itemize}") ],
-      ListBase::NUMBER =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\arabic" ],
-      ListBase::UPPERALPHA =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\Alph" ],
-      ListBase::LOWERALPHA =>  [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\alph" ],
-      ListBase::LABELED => [ l("\\begin{description}"), l("\\end{description}") ],
-      ListBase::NOTE    => [
-        l("\\begin{tabularx}{\\linewidth}{@{} l X @{}}"), 
-        l("\\end{tabularx}") ],
-    }
-
-    InlineTag = Struct.new(:bit, :on, :off)
-
-    def initialize
-      init_tags
-      @list_depth = 0
-      @prev_list_types = []
-    end
-
-    ##
-    # Set up the standard mapping of attributes to LaTeX
-
-    def init_tags
-      @attr_tags = [
-        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), l("\\textbf{"), l("}")),
-        InlineTag.new(SM::Attribute.bitmap_for(:TT),   l("\\texttt{"), l("}")),
-        InlineTag.new(SM::Attribute.bitmap_for(:EM),   l("\\emph{"), l("}")),
-      ]
-    end
-
-    ##
-    # Escape a LaTeX string
-
-    def escape(str)
-# $stderr.print "FE: ", str
-      s = str.
-#        sub(/\s+$/, '').
-        gsub(/([_\${}&%#])/, "#{BS}\\1").
-        gsub(/\\/, BACKSLASH).
-        gsub(/\^/, HAT).
-        gsub(/~/,  TILDE).
-        gsub(/</,  LESSTHAN).
-        gsub(/>/,  GREATERTHAN).
-        gsub(/,,/, ",{},").
-        gsub(/\`/,  BACKQUOTE)
-# $stderr.print "-> ", s, "\n"
-      s
-    end
-
-    ##
-    # Add a new set of LaTeX tags for an attribute. We allow
-    # separate start and end tags for flexibility
-
-    def add_tag(name, start, stop)
-      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)
-    end
-
-    ##
-    # Here's the client side of the visitor pattern
-
-    def start_accepting
-      @res = ""
-      @in_list_entry = []
-    end
-
-    def end_accepting
-      @res.tr(BS, '\\').tr(OB, '{').tr(CB, '}').tr(DL, '$')
-    end
-
-    def accept_paragraph(am, fragment)
-      @res << wrap(convert_flow(am.flow(fragment.txt)))
-      @res << "\n"
-    end
-
-    def accept_verbatim(am, fragment)
-      @res << "\n\\begin{code}\n"
-      @res << fragment.txt.sub(/[\n\s]+\Z/, '')
-      @res << "\n\\end{code}\n\n"
-    end
-
-    def accept_rule(am, fragment)
-      size = fragment.param
-      size = 10 if size > 10
-      @res << "\n\n\\rule{\\linewidth}{#{size}pt}\n\n"
-    end
-
-    def accept_list_start(am, fragment)
-      @res << list_name(fragment.type, true) << "\n"
-      @in_list_entry.push false
-    end
-
-    def accept_list_end(am, fragment)
-      if tag = @in_list_entry.pop
-        @res << tag << "\n"
-      end
-      @res << list_name(fragment.type, false) << "\n"
-    end
-
-    def accept_list_item(am, fragment)
-      if tag = @in_list_entry.last
-        @res << tag << "\n"
-      end
-      @res << list_item_start(am, fragment)
-      @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
-      @in_list_entry[-1] = list_end_for(fragment.type)
-    end
-
-    def accept_blank_line(am, fragment)
-      # @res << "\n"
-    end
-
-    def accept_heading(am, fragment)
-      @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
-    end
-
-    ##
-    # This is a higher speed (if messier) version of wrap
-
-    def wrap(txt, line_len = 76)
-      res = ""
-      sp = 0
-      ep = txt.length
-      while sp < ep
-        # scan back for a space
-        p = sp + line_len - 1
-        if p >= ep
-          p = ep
-        else
-          while p > sp and txt[p] != ?\s
-            p -= 1
-          end
-          if p <= sp
-            p = sp + line_len
-            while p < ep and txt[p] != ?\s
-              p += 1
-            end
-          end
-        end
-        res << txt[sp...p] << "\n"
-        sp = p
-        sp += 1 while sp < ep and txt[sp] == ?\s
-      end
-      res
-    end
-
-    private
-
-    def on_tags(res, item)
-      attr_mask = item.turn_on
-      return if attr_mask.zero?
-
-      @attr_tags.each do |tag|
-        if attr_mask & tag.bit != 0
-          res << tag.on
-        end
-      end
-    end
-
-    def off_tags(res, item)
-      attr_mask = item.turn_off
-      return if attr_mask.zero?
-
-      @attr_tags.reverse_each do |tag|
-        if attr_mask & tag.bit != 0
-          res << tag.off
-        end
-      end
-    end
-
-    def convert_flow(flow)
-      res = ""
-      flow.each do |item|
-        case item
-        when String
-#          $stderr.puts "Converting '#{item}'"
-          res << convert_string(item)
-        when AttrChanger
-          off_tags(res, item)
-          on_tags(res,  item)
-        when Special
-          res << convert_special(item)
-        else
-          raise "Unknown flow element: #{item.inspect}"
-        end
-      end
-      res
-    end
-
-    ##
-    # some of these patterns are taken from SmartyPants...
-
-    def convert_string(item)
-      escape(item).
-
-      # convert ... to elipsis (and make sure .... becomes .<elipsis>)
-        gsub(/\.\.\.\./, '.\ldots{}').gsub(/\.\.\./, '\ldots{}').
-
-      # convert single closing quote
-        gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1'" }.
-        gsub(%r{\'(?=\W|s\b)}) { "'" }.
-
-      # convert single opening quote
-        gsub(/'/, '`').
-
-      # convert double closing quote
-        gsub(%r{([^ \t\r\n\[\{\(])\"(?=\W)}) { "#$1''" }.
-
-      # convert double opening quote
-        gsub(/"/, "``").
-
-      # convert copyright
-        gsub(/\(c\)/, '\copyright{}')
-
-    end
-
-    def convert_special(special)
-      handled = false
-      Attribute.each_name_of(special.type) do |name|
-        method_name = "handle_special_#{name}"
-        if self.respond_to? method_name
-          special.text = send(method_name, special)
-          handled = true
-        end
-      end
-      raise "Unhandled special: #{special}" unless handled
-      special.text
-    end
-
-    def convert_heading(level, flow)
-      res =
-        case level
-        when 1 then "\\chapter{"
-        when 2 then "\\section{"
-        when 3 then "\\subsection{"
-        when 4 then "\\subsubsection{"
-        else  "\\paragraph{"
-        end +
-        convert_flow(flow) +
-        "}\n"
-    end
-
-    def list_name(list_type, is_open_tag)
-      tags = LIST_TYPE_TO_LATEX[list_type] || raise("Invalid list type: #{list_type.inspect}")
-      if tags[2] # enumerate
-        if is_open_tag
-          @list_depth += 1
-          if @prev_list_types[@list_depth] != tags[2]
-            case @list_depth
-            when 1
-              roman = "i"
-            when 2
-              roman = "ii"
-            when 3
-              roman = "iii"
-            when 4
-              roman = "iv"
-            else
-              raise("Too deep list: level #{@list_depth}")
-            end
-            @prev_list_types[@list_depth] = tags[2]
-            return l("\\renewcommand{\\labelenum#{roman}}{#{tags[2]}{enum#{roman}}}") + "\n" + tags[0]
-          end
-        else
-          @list_depth -= 1
-        end
-      end
-      tags[ is_open_tag ? 0 : 1]
-    end
-
-    def list_item_start(am, fragment)
-      case fragment.type
-      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA,
-           ListBase::LOWERALPHA
-        "\\item "
-
-      when ListBase::LABELED
-        "\\item[" + convert_flow(am.flow(fragment.param)) + "] "
-
-      when ListBase::NOTE
-          convert_flow(am.flow(fragment.param)) + " & "
-      else
-        raise "Invalid list type"
-      end
-    end
-
-    def list_end_for(fragment_type)
-      case fragment_type
-      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA,
-           ListBase::LOWERALPHA, ListBase::LABELED
-        ""
-      when ListBase::NOTE
-        "\\\\\n"
-      else
-        raise "Invalid list type"
-      end
-    end
-
-  end
-
-end
-
Index: lib/rdoc/markup/simple_markup/preprocess.rb
===================================================================
--- lib/rdoc/markup/simple_markup/preprocess.rb	(revision 15032)
+++ lib/rdoc/markup/simple_markup/preprocess.rb	(revision 15033)
@@ -1,73 +0,0 @@
-module SM
-
-  ##
-  # Handle common directives that can occur in a block of text:
-  #
-  # : include : filename
-
-  class PreProcess
-
-    def initialize(input_file_name, include_path)
-      @input_file_name = input_file_name
-      @include_path = include_path
-    end
-
-    ##
-    # Look for common options in a chunk of text. Options that we don't handle
-    # are passed back to our caller as |directive, param|
-
-    def handle(text)
-      text.gsub!(/^([ \t#]*):(\w+):\s*(.+)?\n/) do
-        prefix    = $1
-        directive = $2.downcase
-        param     = $3
-
-        case directive
-        when "include"
-          filename = param.split[0]
-          include_file(filename, prefix)
-
-        else
-          yield(directive, param)
-        end
-      end
-    end
-
-    private
-
-    ##
-    # Include a file, indenting it correctly.
-
-    def include_file(name, indent)
-      if (full_name = find_include_file(name))
-        content = File.open(full_name) {|f| f.read}
-        # strip leading '#'s, but only if all lines start with them
-        if content =~ /^[^#]/
-          content.gsub(/^/, indent)
-        else
-          content.gsub(/^#?/, indent)
-        end
-      else
-        $stderr.puts "Couldn't find file to include: '#{name}'"
-        ''
-      end
-    end
-
-    ##
-    # Look for the given file in the directory containing the current file,
-    # and then in each of the directories specified in the RDOC_INCLUDE path
-
-    def find_include_file(name)
-      to_search = [ File.dirname(@input_file_name) ].concat @include_path
-      to_search.each do |dir|
-        full_name = File.join(dir, name)
-        stat = File.stat(full_name) rescue next
-        return full_name if stat.readable?
-      end
-      nil
-    end
-
-  end
-
-end
-
Index: lib/rdoc/markup/simple_markup/fragments.rb
===================================================================
--- lib/rdoc/markup/simple_markup/fragments.rb	(revision 15032)
+++ lib/rdoc/markup/simple_markup/fragments.rb	(revision 15033)
@@ -1,329 +0,0 @@
-require 'rdoc/markup/simple_markup/lines.rb'
-
-module SM
-
-  ##
-  # A Fragment is a chunk of text, subclassed as a paragraph, a list
-  # entry, or verbatim text.
-
-  class Fragment
-    attr_reader   :level, :param, :txt
-    attr_accessor :type
-
-    def initialize(level, param, type, txt)
-      @level = level
-      @param = param
-      @type  = type
-      @txt   = ""
-      add_text(txt) if txt
-    end
-
-    def add_text(txt)
-      @txt << " " if @txt.length > 0
-      @txt << txt.tr_s("\n ", "  ").strip
-    end
-
-    def to_s
-      "L#@level: #{self.class.name.split('::')[-1]}\n#@txt"
-    end
-
-    ######
-    # This is a simple factory system that lets us associate fragement
-    # types (a string) with a subclass of fragment
-
-    TYPE_MAP = {}
-
-    def Fragment.type_name(name)
-      TYPE_MAP[name] = self
-    end
-
-    def Fragment.for(line)
-      klass =  TYPE_MAP[line.type] ||
-        raise("Unknown line type: '#{line.type.inspect}:' '#{line.text}'")
-      return klass.new(line.level, line.param, line.flag, line.text)
-    end
-  end
-
-  ##
-  # A paragraph is a fragment which gets wrapped to fit. We remove all
-  # newlines when we're created, and have them put back on output.
-
-  class Paragraph < Fragment
-    type_name Line::PARAGRAPH
-  end
-
-  class BlankLine < Paragraph
-    type_name Line::BLANK
-  end
-
-  class Heading < Paragraph
-    type_name Line::HEADING
-
-    def head_level
-      @param.to_i
-    end
-  end
-
-  ##
-  # A List is a fragment with some kind of label
-
-  class ListBase < Paragraph
-    # List types
-    BULLET  = :BULLET
-    NUMBER  = :NUMBER
-    UPPERALPHA  = :UPPERALPHA
-    LOWERALPHA  = :LOWERALPHA
-    LABELED = :LABELED
-    NOTE    = :NOTE
-  end
-
-  class ListItem < ListBase
-    type_name Line::LIST
-
-    #  def label
-    #    am = AttributeManager.new(@param)
-    #    am.flow
-    #  end
-  end
-
-  class ListStart < ListBase
-    def initialize(level, param, type)
-      super(level, param, type, nil)
-    end
-  end
-
-  class ListEnd < ListBase
-    def initialize(level, type)
-      super(level, "", type, nil)
-    end
-  end
-
-  ##
-  # Verbatim code contains lines that don't get wrapped.
-
-  class Verbatim < Fragment
-    type_name  Line::VERBATIM
-
-    def add_text(txt)
-      @txt << txt.chomp << "\n"
-    end
-
-  end
-
-  ##
-  # A horizontal rule
-
-  class Rule < Fragment
-    type_name Line::RULE
-  end
-
-  ##
-  # Collect groups of lines together. Each group will end up containing a flow
-  # of text
-
-  class LineCollection
-
-    def initialize
-      @fragments = []
-    end
-
-    def add(fragment)
-      @fragments << fragment
-    end
-
-    def each(&b)
-      @fragments.each(&b)
-    end
-
-    def to_a # :nodoc:
-      @fragments.map {|fragment| fragment.to_s}
-    end
-
-    ##
-    # Factory for different fragment types
-
-    def fragment_for(*args)
-      Fragment.for(*args)
-    end
-
-    ##
-    # Tidy up at the end
-
-    def normalize
-      change_verbatim_blank_lines
-      add_list_start_and_ends
-      add_list_breaks
-      tidy_blank_lines
-    end
-
-    def to_s
-      @fragments.join("\n----\n")
-    end
-
-    def accept(am, visitor)
-      visitor.start_accepting
-
-      @fragments.each do |fragment|
-        case fragment
-        when Verbatim
-          visitor.accept_verbatim(am, fragment)
-        when Rule
-          visitor.accept_rule(am, fragment)
-        when ListStart
-          visitor.accept_list_start(am, fragment)
-        when ListEnd
-          visitor.accept_list_end(am, fragment)
-        when ListItem
-          visitor.accept_list_item(am, fragment)
-        when BlankLine
-          visitor.accept_blank_line(am, fragment)
-        when Heading
-          visitor.accept_heading(am, fragment)
-        when Paragraph
-          visitor.accept_paragraph(am, fragment)
-        end
-      end
-
-      visitor.end_accepting
-    end
-
-    private
-
-    # If you have:
-    #
-    #    normal paragraph text.
-    #
-    #       this is code
-    #   
-    #       and more code
-    #
-    # You'll end up with the fragments Paragraph, BlankLine, Verbatim,
-    # BlankLine, Verbatim, BlankLine, etc.
-    #
-    # The BlankLine in the middle of the verbatim chunk needs to be changed to
-    # a real verbatim newline, and the two verbatim blocks merged
-
-    def change_verbatim_blank_lines
-      frag_block = nil
-      blank_count = 0
-      @fragments.each_with_index do |frag, i|
-        if frag_block.nil?
-          frag_block = frag if Verbatim === frag
-        else
-          case frag
-          when Verbatim
-            blank_count.times { frag_block.add_text("\n") }
-            blank_count = 0
-            frag_block.add_text(frag.txt)
-            @fragments[i] = nil    # remove out current fragment
-          when BlankLine
-            if frag_block
-              blank_count += 1
-              @fragments[i] = nil
-            end
-          else
-            frag_block = nil
-            blank_count = 0
-          end
-        end
-      end
-      @fragments.compact!
-    end
-
-    ##
-    # List nesting is implicit given the level of indentation. Make it
-    # explicit, just to make life a tad easier for the output processors
-
-    def add_list_start_and_ends
-      level = 0
-      res = []
-      type_stack = []
-
-      @fragments.each do |fragment|
-        # $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}"
-        new_level = fragment.level
-        while (level < new_level)
-          level += 1
-          type = fragment.type
-          res << ListStart.new(level, fragment.param, type) if type
-          type_stack.push type
-          # $stderr.puts "Start: #{level}"
-        end
-
-        while level > new_level
-          type = type_stack.pop
-          res << ListEnd.new(level, type) if type
-          level -= 1
-          # $stderr.puts "End: #{level}, #{type}"
-        end
-
-        res << fragment
-        level = fragment.level
-      end
-      level.downto(1) do |i|
-        type = type_stack.pop
-        res << ListEnd.new(i, type) if type
-      end
-
-      @fragments = res
-    end
-
-    ##
-    # Inserts start/ends between list entries at the same level that have
-    # different element types
-
-    def add_list_breaks
-      res = @fragments
-
-      @fragments = []
-      list_stack = []
-
-      res.each do |fragment|
-        case fragment
-        when ListStart
-          list_stack.push fragment
-        when ListEnd
-          start = list_stack.pop
-          fragment.type = start.type
-        when ListItem
-          l = list_stack.last
-          if fragment.type != l.type
-            @fragments << ListEnd.new(l.level, l.type)
-            start = ListStart.new(l.level, fragment.param, fragment.type)
-            @fragments << start
-            list_stack.pop
-            list_stack.push start
-          end
-        else
-          ;
-        end
-        @fragments << fragment
-      end
-    end
-
-    ##
-    # Tidy up the blank lines:
-    # * change Blank/ListEnd into ListEnd/Blank
-    # * remove blank lines at the front
-
-    def tidy_blank_lines
-      (@fragments.size - 1).times do |i|
-        if @fragments[i].kind_of?(BlankLine) and 
-            @fragments[i+1].kind_of?(ListEnd)
-          @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i] 
-        end
-      end
-
-      # remove leading blanks
-      @fragments.each_with_index do |f, i|
-        break unless f.kind_of? BlankLine
-        @fragments[i] = nil
-      end
-
-      @fragments.compact!
-    end
-
-  end
-
-end
-
Index: lib/rdoc/markup/simple_markup/to_html.rb
===================================================================
--- lib/rdoc/markup/simple_markup/to_html.rb	(revision 15032)
+++ lib/rdoc/markup/simple_markup/to_html.rb	(revision 15033)
@@ -1,287 +0,0 @@
-require 'rdoc/markup/simple_markup/fragments'
-require 'rdoc/markup/simple_markup/inline'
-
-require 'cgi'
-
-module SM
-
-  class ToHtml
-
-    LIST_TYPE_TO_HTML = {
-      ListBase::BULLET =>  [ "<ul>", "</ul>" ],
-      ListBase::NUMBER =>  [ "<ol>", "</ol>" ],
-      ListBase::UPPERALPHA =>  [ "<ol>", "</ol>" ],
-      ListBase::LOWERALPHA =>  [ "<ol>", "</ol>" ],
-      ListBase::LABELED => [ "<dl>", "</dl>" ],
-      ListBase::NOTE    => [ "<table>", "</table>" ],
-    }
-
-    InlineTag = Struct.new(:bit, :on, :off)
-
-    def initialize
-      init_tags
-    end
-
-    ##
-    # Set up the standard mapping of attributes to HTML tags
-
-    def init_tags
-      @attr_tags = [
-        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
-        InlineTag.new(SM::Attribute.bitmap_for(:TT),   "<tt>", "</tt>"),
-        InlineTag.new(SM::Attribute.bitmap_for(:EM),   "<em>", "</em>"),
-      ]
-    end
-
-    ##
-    # Add a new set of HTML tags for an attribute. We allow separate start and
-    # end tags for flexibility.
-
-    def add_tag(name, start, stop)
-      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)
-    end
-
-    ##
-    # Given an HTML tag, decorate it with class information and the like if
-    # required. This is a no-op in the base class, but is overridden in HTML
-    # output classes that implement style sheets.
-
-    def annotate(tag)
-      tag
-    end
-
-    ##
-    # Here's the client side of the visitor pattern
-
-    def start_accepting
-      @res = ""
-      @in_list_entry = []
-    end
-
-    def end_accepting
-      @res
-    end
-
-    def accept_paragraph(am, fragment)
-      @res << annotate("<p>") + "\n"
-      @res << wrap(convert_flow(am.flow(fragment.txt)))
-      @res << annotate("</p>") + "\n"
-    end
-
-    def accept_verbatim(am, fragment)
-      @res << annotate("<pre>") + "\n"
-      @res << CGI.escapeHTML(fragment.txt)
-      @res << annotate("</pre>") << "\n"
-    end
-
-    def accept_rule(am, fragment)
-      size = fragment.param
-      size = 10 if size > 10
-      @res << "<hr size=\"#{size}\"></hr>"
-    end
-
-    def accept_list_start(am, fragment)
-      @res << html_list_name(fragment.type, true) << "\n"
-      @in_list_entry.push false
-    end
-
-    def accept_list_end(am, fragment)
-      if tag = @in_list_entry.pop
-        @res << annotate(tag) << "\n"
-      end
-      @res << html_list_name(fragment.type, false) << "\n"
-    end
-
-    def accept_list_item(am, fragment)
-      if tag = @in_list_entry.last
-        @res << annotate(tag) << "\n"
-      end
-      @res << list_item_start(am, fragment)
-      @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
-      @in_list_entry[-1] = list_end_for(fragment.type)
-    end
-
-    def accept_blank_line(am, fragment)
-      # @res << annotate("<p />") << "\n"
-    end
-
-    def accept_heading(am, fragment)
-      @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
-    end
-
-    ##
-    # This is a higher speed (if messier) version of wrap
-
-    def wrap(txt, line_len = 76)
-      res = ""
-      sp = 0
-      ep = txt.length
-      while sp < ep
-        # scan back for a space
-        p = sp + line_len - 1
-        if p >= ep
-          p = ep
-        else
-          while p > sp and txt[p] != ?\s
-            p -= 1
-          end
-          if p <= sp
-            p = sp + line_len
-            while p < ep and txt[p] != ?\s
-              p += 1
-            end
-          end
-        end
-        res << txt[sp...p] << "\n"
-        sp = p
-        sp += 1 while sp < ep and txt[sp] == ?\s
-      end
-      res
-    end
-
-    private
-
-    def on_tags(res, item)
-      attr_mask = item.turn_on
-      return if attr_mask.zero?
-
-      @attr_tags.each do |tag|
-        if attr_mask & tag.bit != 0
-          res << annotate(tag.on)
-        end
-      end
-    end
-
-    def off_tags(res, item)
-      attr_mask = item.turn_off
-      return if attr_mask.zero?
-
-      @attr_tags.reverse_each do |tag|
-        if attr_mask & tag.bit != 0
-          res << annotate(tag.off)
-        end
-      end
-    end
-
-    def convert_flow(flow)
-      res = ""
-      flow.each do |item|
-        case item
-        when String
-          res << convert_string(item)
-        when AttrChanger
-          off_tags(res, item)
-          on_tags(res,  item)
-        when Special
-          res << convert_special(item)
-        else
-          raise "Unknown flow element: #{item.inspect}"
-        end
-      end
-      res
-    end
-
-    ##
-    # some of these patterns are taken from SmartyPants...
-
-    def convert_string(item)
-      CGI.escapeHTML(item).
-
-      # convert -- to em-dash, (-- to en-dash)
-        gsub(/---?/, '&#8212;'). #gsub(/--/, '&#8211;').
-
-      # convert ... to elipsis (and make sure .... becomes .<elipsis>)
-        gsub(/\.\.\.\./, '.&#8230;').gsub(/\.\.\./, '&#8230;').
-
-      # convert single closing quote
-        gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1&#8217;" }.
-        gsub(%r{\'(?=\W|s\b)}) { "&#8217;" }.
-
-      # convert single opening quote
-        gsub(/'/, '&#8216;').
-
-      # convert double closing quote
-        gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}) { "#$1&#8221;" }.
-
-      # convert double opening quote
-        gsub(/'/, '&#8220;').
-
-      # convert copyright
-        gsub(/\(c\)/, '&#169;').
-
-      # convert and registered trademark
-        gsub(/\(r\)/, '&#174;')
-
-    end
-
-    def convert_special(special)
-      handled = false
-      Attribute.each_name_of(special.type) do |name|
-        method_name = "handle_special_#{name}"
-        if self.respond_to? method_name
-          special.text = send(method_name, special)
-          handled = true
-        end
-      end
-      raise "Unhandled special: #{special}" unless handled
-      special.text
-    end
-
-    def convert_heading(level, flow)
-      res =
-        annotate("<h#{level}>") +
-        convert_flow(flow) +
-        annotate("</h#{level}>\n")
-    end
-
-    def html_list_name(list_type, is_open_tag)
-      tags = LIST_TYPE_TO_HTML[list_type] || raise("Invalid list type: #{list_type.inspect}")
-      annotate(tags[ is_open_tag ? 0 : 1])
-    end
-
-    def list_item_start(am, fragment)
-      case fragment.type
-      when ListBase::BULLET, ListBase::NUMBER
-        annotate("<li>")
-
-      when ListBase::UPPERALPHA
-        annotate("<li type=\"A\">")
-
-      when ListBase::LOWERALPHA
-        annotate("<li type=\"a\">")
-
-      when ListBase::LABELED
-        annotate("<dt>") +
-          convert_flow(am.flow(fragment.param)) +
-          annotate("</dt>") +
-          annotate("<dd>")
-
-      when ListBase::NOTE
-        annotate("<tr>") +
-          annotate("<td valign=\"top\">") +
-          convert_flow(am.flow(fragment.param)) +
-          annotate("</td>") +
-          annotate("<td>")
-      else
-        raise "Invalid list type"
-      end
-    end
-
-    def list_end_for(fragment_type)
-      case fragment_type
-      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA,
-           ListBase::LOWERALPHA
-        "</li>"
-      when ListBase::LABELED
-        "</dd>"
-      when ListBase::NOTE
-        "</td></tr>"
-      else
-        raise "Invalid list type"
-      end
-    end
-
-  end
-
-end
-
Index: lib/rdoc/markup/simple_markup/to_flow.rb
===================================================================
--- lib/rdoc/markup/simple_markup/to_flow.rb	(revision 15032)
+++ lib/rdoc/markup/simple_markup/to_flow.rb	(revision 15033)
@@ -1,182 +0,0 @@
-require 'rdoc/markup/simple_markup/fragments'
-require 'rdoc/markup/simple_markup/inline'
-require 'cgi'
-
-module SM
-
-  module Flow
-    P = Struct.new(:body)
-    VERB = Struct.new(:body)
-    RULE = Struct.new(:width)
-    class LIST
-      attr_reader :type, :contents
-      def initialize(type)
-        @type = type
-        @contents = []
-      end
-      def <<(stuff)
-        @contents << stuff
-      end
-    end
-    LI = Struct.new(:label, :body)
-    H = Struct.new(:level, :text)
-  end
-
-  class ToFlow
-    LIST_TYPE_TO_HTML = {
-      SM::ListBase::BULLET     =>  [ "<ul>", "</ul>" ],
-      SM::ListBase::NUMBER     =>  [ "<ol>", "</ol>" ],
-      SM::ListBase::UPPERALPHA =>  [ "<ol>", "</ol>" ],
-      SM::ListBase::LOWERALPHA =>  [ "<ol>", "</ol>" ],
-      SM::ListBase::LABELED    =>  [ "<dl>", "</dl>" ],
-      SM::ListBase::NOTE       =>  [ "<table>", "</table>" ],
-    }
-
-    InlineTag = Struct.new(:bit, :on, :off)
-
-    def initialize
-      init_tags
-    end
-
-    ##
-    # Set up the standard mapping of attributes to HTML tags
-
-    def init_tags
-      @attr_tags = [
-        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
-        InlineTag.new(SM::Attribute.bitmap_for(:TT),   "<tt>", "</tt>"),
-        InlineTag.new(SM::Attribute.bitmap_for(:EM),   "<em>", "</em>"),
-      ]
-    end
-
-    ##
-    # Add a new set of HTML tags for an attribute. We allow separate start and
-    # end tags for flexibility
-
-    def add_tag(name, start, stop)
-      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)
-    end
-
-    ##
-    # Given an HTML tag, decorate it with class information and the like if
-    # required. This is a no-op in the base class, but is overridden in HTML
-    # output classes that implement style sheets
-
-    def annotate(tag)
-      tag
-    end
-
-    ##
-    # Here's the client side of the visitor pattern
-
-    def start_accepting
-      @res = []
-      @list_stack = []
-    end
-
-    def end_accepting
-      @res
-    end
-
-    def accept_paragraph(am, fragment)
-      @res << Flow::P.new((convert_flow(am.flow(fragment.txt))))
-    end
-
-    def accept_verbatim(am, fragment)
-      @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt))))
-    end
-
-    def accept_rule(am, fragment)
-      size = fragment.param
-      size = 10 if size > 10
-      @res << Flow::RULE.new(size)
-    end
-
-    def accept_list_start(am, fragment)
-      @list_stack.push(@res)
-      list = Flow::LIST.new(fragment.type)
-      @res << list
-      @res = list
-    end
-
-    def accept_list_end(am, fragment)
-      @res = @list_stack.pop
-    end
-
-    def accept_list_item(am, fragment)
-      @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt)))
-    end
-
-    def accept_blank_line(am, fragment)
-      # @res << annotate("<p />") << "\n"
-    end
-
-    def accept_heading(am, fragment)
-      @res << Flow::H.new(fragment.head_level, convert_flow(am.flow(fragment.txt)))
-    end
-
-    private
-
-    def on_tags(res, item)
-      attr_mask = item.turn_on
-      return if attr_mask.zero?
-
-      @attr_tags.each do |tag|
-        if attr_mask & tag.bit != 0
-          res << annotate(tag.on)
-        end
-      end
-    end
-
-    def off_tags(res, item)
-      attr_mask = item.turn_off
-      return if attr_mask.zero?
-
-      @attr_tags.reverse_each do |tag|
-        if attr_mask & tag.bit != 0
-          res << annotate(tag.off)
-        end
-      end
-    end
-
-    def convert_flow(flow)
-      res = ""
-      flow.each do |item|
-        case item
-        when String
-          res << convert_string(item)
-        when AttrChanger
-          off_tags(res, item)
-          on_tags(res,  item)
-        when Special
-          res << convert_special(item)
-        else
-          raise "Unknown flow element: #{item.inspect}"
-        end
-      end
-      res
-    end
-
-    def convert_string(item)
-      CGI.escapeHTML(item)
-    end
-
-    def convert_special(special)
-      handled = false
-      Attribute.each_name_of(special.type) do |name|
-        method_name = "handle_special_#{name}"
-        if self.respond_to? method_name
-          special.text = send(method_name, special)
-          handled = true
-        end
-      end
-
-      raise "Unhandled special: #{special}" unless handled
-
-      special.text
-    end
-
-  end
-
-end
-
Index: lib/rdoc/markup/simple_markup/lines.rb
===================================================================
--- lib/rdoc/markup/simple_markup/lines.rb	(revision 15032)
+++ lib/rdoc/markup/simple_markup/lines.rb	(revision 15033)
@@ -1,152 +0,0 @@
-module SM
-
-  ##
-  # We store the lines we're working on as objects of class Line.  These
-  # contain the text of the line, along with a flag indicating the line type,
-  # and an indentation level.
-
-  class Line
-    INFINITY = 9999
-
-    BLANK     = :BLANK
-    HEADING   = :HEADING
-    LIST      = :LIST
-    RULE      = :RULE
-    PARAGRAPH = :PARAGRAPH
-    VERBATIM  = :VERBATIM
-    
-    # line type
-    attr_accessor :type
-
-    # The indentation nesting level
-    attr_accessor :level
-
-    # The contents
-    attr_accessor :text
-
-    # A prefix or parameter. For LIST lines, this is
-    # the text that introduced the list item (the label)
-    attr_accessor  :param
-
-    # A flag. For list lines, this is the type of the list
-    attr_accessor :flag
-
-    # the number of leading spaces
-    attr_accessor :leading_spaces
-
-    # true if this line has been deleted from the list of lines
-    attr_accessor :deleted
-    
-
-    def initialize(text)
-      @text    = text.dup
-      @deleted = false
-
-      # expand tabs
-      1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)}  && $~ #`
-
-      # Strip trailing whitespace
-      @text.sub!(/\s+$/, '')
-
-      # and look for leading whitespace
-      if @text.length > 0
-        @text =~ /^(\s*)/
-        @leading_spaces = $1.length
-      else
-        @leading_spaces = INFINITY
-      end
-    end
-
-    # Return true if this line is blank
-    def isBlank?
-      @text.length.zero?
-    end
-
-    # stamp a line with a type, a level, a prefix, and a flag
-    def stamp(type, level, param="", flag=nil)
-      @type, @level, @param, @flag = type, level, param, flag
-    end
-
-    ##
-    # Strip off the leading margin
-    #
-
-    def strip_leading(size)
-      if @text.size > size
-        @text[0,size] = ""
-      else
-        @text = ""
-      end
-    end
-
-    def to_s
-      "#@type#@level: #@text"
-    end
-  end
-
-  ##
-  # A container for all the lines
-
-  class Lines
-
-    include Enumerable
-
-    attr_reader :lines # :nodoc:
-
-    def initialize(lines)
-      @lines = lines
-      rewind
-    end
-
-    def empty?
-      @lines.size.zero?
-    end
-
-    def each
-      @lines.each do |line|
-        yield line unless line.deleted
-      end
-    end
-
-#    def [](index)
-#      @lines[index]
-#    end
-
-    def rewind
-      @nextline = 0
-    end
-
-    def next
-      begin
-        res = @lines[@nextline]
-        @nextline += 1 if @nextline < @lines.size
-      end while res and res.deleted and @nextline < @lines.size
-      res
-    end
-
-    def unget
-      @nextline -= 1
-    end
-
-    def delete(a_line)
-      a_line.deleted = true
-    end
-
-    def normalize
-      margin = @lines.collect{|l| l.leading_spaces}.min
-      margin = 0 if margin == Line::INFINITY
-      @lines.each {|line| line.strip_leading(margin) } if margin > 0
-    end
-
-    def as_text
-      @lines.map {|l| l.text}.join("\n")
-    end
-
-    def line_types
-      @lines.map {|l| l.type }
-    end
-
-  end
-
-end
-
Index: lib/rdoc/markup/to_html.rb
===================================================================
--- lib/rdoc/markup/to_html.rb	(revision 0)
+++ lib/rdoc/markup/to_html.rb	(revision 15033)
@@ -0,0 +1,286 @@
+require 'rdoc/markup/fragments'
+require 'rdoc/markup/inline'
+
+require 'cgi'
+
+class RDoc::Markup::ToHtml
+
+  LIST_TYPE_TO_HTML = {
+    RDoc::Markup::ListBase::BULLET =>  [ "<ul>", "</ul>" ],
+    RDoc::Markup::ListBase::NUMBER =>  [ "<ol>", "</ol>" ],
+    RDoc::Markup::ListBase::UPPERALPHA =>  [ "<ol>", "</ol>" ],
+    RDoc::Markup::ListBase::LOWERALPHA =>  [ "<ol>", "</ol>" ],
+    RDoc::Markup::ListBase::LABELED => [ "<dl>", "</dl>" ],
+    RDoc::Markup::ListBase::NOTE    => [ "<table>", "</table>" ],
+  }
+
+  InlineTag = Struct.new(:bit, :on, :off)
+
+  def initialize
+    init_tags
+  end
+
+  ##
+  # Set up the standard mapping of attributes to HTML tags
+
+  def init_tags
+    @attr_tags = [
+      InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
+      InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:TT),   "<tt>", "</tt>"),
+      InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:EM),   "<em>", "</em>"),
+    ]
+  end
+
+  ##
+  # Add a new set of HTML tags for an attribute. We allow separate start and
+  # end tags for flexibility.
+
+  def add_tag(name, start, stop)
+    @attr_tags << InlineTag.new(RDoc::Markup::Attribute.bitmap_for(name), start, stop)
+  end
+
+  ##
+  # Given an HTML tag, decorate it with class information and the like if
+  # required. This is a no-op in the base class, but is overridden in HTML
+  # output classes that implement style sheets.
+
+  def annotate(tag)
+    tag
+  end
+
+  ##
+  # Here's the client side of the visitor pattern
+
+  def start_accepting
+    @res = ""
+    @in_list_entry = []
+  end
+
+  def end_accepting
+    @res
+  end
+
+  def accept_paragraph(am, fragment)
+    @res << annotate("<p>") + "\n"
+    @res << wrap(convert_flow(am.flow(fragment.txt)))
+    @res << annotate("</p>") + "\n"
+  end
+
+  def accept_verbatim(am, fragment)
+    @res << annotate("<pre>") + "\n"
+    @res << CGI.escapeHTML(fragment.txt)
+    @res << annotate("</pre>") << "\n"
+  end
+
+  def accept_rule(am, fragment)
+    size = fragment.param
+    size = 10 if size > 10
+    @res << "<hr size=\"#{size}\"></hr>"
+  end
+
+  def accept_list_start(am, fragment)
+    @res << html_list_name(fragment.type, true) << "\n"
+    @in_list_entry.push false
+  end
+
+  def accept_list_end(am, fragment)
+    if tag = @in_list_entry.pop
+      @res << annotate(tag) << "\n"
+    end
+    @res << html_list_name(fragment.type, false) << "\n"
+  end
+
+  def accept_list_item(am, fragment)
+    if tag = @in_list_entry.last
+      @res << annotate(tag) << "\n"
+    end
+    @res << list_item_start(am, fragment)
+    @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
+    @in_list_entry[-1] = list_end_for(fragment.type)
+  end
+
+  def accept_blank_line(am, fragment)
+    # @res << annotate("<p />") << "\n"
+  end
+
+  def accept_heading(am, fragment)
+    @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
+  end
+
+  ##
+  # This is a higher speed (if messier) version of wrap
+
+  def wrap(txt, line_len = 76)
+    res = ""
+    sp = 0
+    ep = txt.length
+    while sp < ep
+      # scan back for a space
+      p = sp + line_len - 1
+      if p >= ep
+        p = ep
+      else
+        while p > sp and txt[p] != ?\s
+          p -= 1
+        end
+        if p <= sp
+          p = sp + line_len
+          while p < ep and txt[p] != ?\s
+            p += 1
+          end
+        end
+      end
+      res << txt[sp...p] << "\n"
+      sp = p
+      sp += 1 while sp < ep and txt[sp] == ?\s
+    end
+    res
+  end
+
+  private
+
+  def on_tags(res, item)
+    attr_mask = item.turn_on
+    return if attr_mask.zero?
+
+    @attr_tags.each do |tag|
+      if attr_mask & tag.bit != 0
+        res << annotate(tag.on)
+      end
+    end
+  end
+
+  def off_tags(res, item)
+    attr_mask = item.turn_off
+    return if attr_mask.zero?
+
+    @attr_tags.reverse_each do |tag|
+      if attr_mask & tag.bit != 0
+        res << annotate(tag.off)
+      end
+    end
+  end
+
+  def convert_flow(flow)
+    res = ""
+
+    flow.each do |item|
+      case item
+      when String
+        res << convert_string(item)
+      when RDoc::Markup::AttrChanger
+        off_tags(res, item)
+        on_tags(res,  item)
+      when RDoc::Markup::Special
+        res << convert_special(item)
+      else
+        raise "Unknown flow element: #{item.inspect}"
+      end
+    end
+
+    res
+  end
+
+  ##
+  # some of these patterns are taken from SmartyPants...
+
+  def convert_string(item)
+    CGI.escapeHTML(item).
+
+    # convert -- to em-dash, (-- to en-dash)
+      gsub(/---?/, '&#8212;'). #gsub(/--/, '&#8211;').
+
+    # convert ... to elipsis (and make sure .... becomes .<elipsis>)
+      gsub(/\.\.\.\./, '.&#8230;').gsub(/\.\.\./, '&#8230;').
+
+    # convert single closing quote
+      gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1&#8217;" }.
+      gsub(%r{\'(?=\W|s\b)}) { "&#8217;" }.
+
+    # convert single opening quote
+      gsub(/'/, '&#8216;').
+
+    # convert double closing quote
+      gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}) { "#$1&#8221;" }.
+
+    # convert double opening quote
+      gsub(/'/, '&#8220;').
+
+    # convert copyright
+      gsub(/\(c\)/, '&#169;').
+
+    # convert and registered trademark
+      gsub(/\(r\)/, '&#174;')
+
+  end
+
+  def convert_special(special)
+    handled = false
+    RDoc::Markup::Attribute.each_name_of(special.type) do |name|
+      method_name = "handle_special_#{name}"
+      if self.respond_to? method_name
+        special.text = send(method_name, special)
+        handled = true
+      end
+    end
+    raise "Unhandled special: #{special}" unless handled
+    special.text
+  end
+
+  def convert_heading(level, flow)
+    res =
+      annotate("<h#{level}>") +
+      convert_flow(flow) +
+      annotate("</h#{level}>\n")
+  end
+
+  def html_list_name(list_type, is_open_tag)
+    tags = LIST_TYPE_TO_HTML[list_type] || raise("Invalid list type: #{list_type.inspect}")
+    annotate(tags[ is_open_tag ? 0 : 1])
+  end
+
+  def list_item_start(am, fragment)
+    case fragment.type
+    when RDoc::Markup::ListBase::BULLET, RDoc::Markup::ListBase::NUMBER then
+      annotate("<li>")
+
+    when RDoc::Markup::ListBase::UPPERALPHA then
+      annotate("<li type=\"A\">")
+
+    when RDoc::Markup::ListBase::LOWERALPHA then
+      annotate("<li type=\"a\">")
+
+    when RDoc::Markup::ListBase::LABELED then
+      annotate("<dt>") +
+        convert_flow(am.flow(fragment.param)) +
+        annotate("</dt>") +
+        annotate("<dd>")
+
+    when RDoc::Markup::ListBase::NOTE then
+      annotate("<tr>") +
+        annotate("<td valign=\"top\">") +
+        convert_flow(am.flow(fragment.param)) +
+        annotate("</td>") +
+        annotate("<td>")
+    else
+      raise "Invalid list type"
+    end
+  end
+
+  def list_end_for(fragment_type)
+    case fragment_type
+    when RDoc::Markup::ListBase::BULLET, RDoc::Markup::ListBase::NUMBER,
+         RDoc::Markup::ListBase::UPPERALPHA,
+         RDoc::Markup::ListBase::LOWERALPHA then
+      "</li>"
+    when RDoc::Markup::ListBase::LABELED then
+      "</dd>"
+    when RDoc::Markup::ListBase::NOTE then
+      "</td></tr>"
+    else
+      raise "Invalid list type"
+    end
+  end
+
+end
+

Property changes on: lib/rdoc/markup/to_html.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/markup/to_flow.rb
===================================================================
--- lib/rdoc/markup/to_flow.rb	(revision 0)
+++ lib/rdoc/markup/to_flow.rb	(revision 15033)
@@ -0,0 +1,182 @@
+require 'rdoc/markup/fragments'
+require 'rdoc/markup/inline'
+require 'cgi'
+
+class RDoc::Markup
+
+  module Flow
+    P = Struct.new(:body)
+    VERB = Struct.new(:body)
+    RULE = Struct.new(:width)
+    class LIST
+      attr_reader :type, :contents
+      def initialize(type)
+        @type = type
+        @contents = []
+      end
+      def <<(stuff)
+        @contents << stuff
+      end
+    end
+    LI = Struct.new(:label, :body)
+    H = Struct.new(:level, :text)
+  end
+
+  class ToFlow
+    LIST_TYPE_TO_HTML = {
+      RDoc::Markup::ListBase::BULLET     =>  [ "<ul>", "</ul>" ],
+      RDoc::Markup::ListBase::NUMBER     =>  [ "<ol>", "</ol>" ],
+      RDoc::Markup::ListBase::UPPERALPHA =>  [ "<ol>", "</ol>" ],
+      RDoc::Markup::ListBase::LOWERALPHA =>  [ "<ol>", "</ol>" ],
+      RDoc::Markup::ListBase::LABELED    =>  [ "<dl>", "</dl>" ],
+      RDoc::Markup::ListBase::NOTE       =>  [ "<table>", "</table>" ],
+    }
+
+    InlineTag = Struct.new(:bit, :on, :off)
+
+    def initialize
+      init_tags
+    end
+
+    ##
+    # Set up the standard mapping of attributes to HTML tags
+
+    def init_tags
+      @attr_tags = [
+        InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
+        InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:TT),   "<tt>", "</tt>"),
+        InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:EM),   "<em>", "</em>"),
+      ]
+    end
+
+    ##
+    # Add a new set of HTML tags for an attribute. We allow separate start and
+    # end tags for flexibility
+
+    def add_tag(name, start, stop)
+      @attr_tags << InlineTag.new(RDoc::Markup::Attribute.bitmap_for(name), start, stop)
+    end
+
+    ##
+    # Given an HTML tag, decorate it with class information and the like if
+    # required. This is a no-op in the base class, but is overridden in HTML
+    # output classes that implement style sheets
+
+    def annotate(tag)
+      tag
+    end
+
+    ##
+    # Here's the client side of the visitor pattern
+
+    def start_accepting
+      @res = []
+      @list_stack = []
+    end
+
+    def end_accepting
+      @res
+    end
+
+    def accept_paragraph(am, fragment)
+      @res << Flow::P.new((convert_flow(am.flow(fragment.txt))))
+    end
+
+    def accept_verbatim(am, fragment)
+      @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt))))
+    end
+
+    def accept_rule(am, fragment)
+      size = fragment.param
+      size = 10 if size > 10
+      @res << Flow::RULE.new(size)
+    end
+
+    def accept_list_start(am, fragment)
+      @list_stack.push(@res)
+      list = Flow::LIST.new(fragment.type)
+      @res << list
+      @res = list
+    end
+
+    def accept_list_end(am, fragment)
+      @res = @list_stack.pop
+    end
+
+    def accept_list_item(am, fragment)
+      @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt)))
+    end
+
+    def accept_blank_line(am, fragment)
+      # @res << annotate("<p />") << "\n"
+    end
+
+    def accept_heading(am, fragment)
+      @res << Flow::H.new(fragment.head_level, convert_flow(am.flow(fragment.txt)))
+    end
+
+    private
+
+    def on_tags(res, item)
+      attr_mask = item.turn_on
+      return if attr_mask.zero?
+
+      @attr_tags.each do |tag|
+        if attr_mask & tag.bit != 0
+          res << annotate(tag.on)
+        end
+      end
+    end
+
+    def off_tags(res, item)
+      attr_mask = item.turn_off
+      return if attr_mask.zero?
+
+      @attr_tags.reverse_each do |tag|
+        if attr_mask & tag.bit != 0
+          res << annotate(tag.off)
+        end
+      end
+    end
+
+    def convert_flow(flow)
+      res = ""
+      flow.each do |item|
+        case item
+        when String
+          res << convert_string(item)
+        when AttrChanger
+          off_tags(res, item)
+          on_tags(res,  item)
+        when Special
+          res << convert_special(item)
+        else
+          raise "Unknown flow element: #{item.inspect}"
+        end
+      end
+      res
+    end
+
+    def convert_string(item)
+      CGI.escapeHTML(item)
+    end
+
+    def convert_special(special)
+      handled = false
+      Attribute.each_name_of(special.type) do |name|
+        method_name = "handle_special_#{name}"
+        if self.respond_to? method_name
+          special.text = send(method_name, special)
+          handled = true
+        end
+      end
+
+      raise "Unhandled special: #{special}" unless handled
+
+      special.text
+    end
+
+  end
+
+end
+

Property changes on: lib/rdoc/markup/to_flow.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/markup/lines.rb
===================================================================
--- lib/rdoc/markup/lines.rb	(revision 0)
+++ lib/rdoc/markup/lines.rb	(revision 15033)
@@ -0,0 +1,150 @@
+class RDoc::Markup
+
+  ##
+  # We store the lines we're working on as objects of class Line.  These
+  # contain the text of the line, along with a flag indicating the line type,
+  # and an indentation level.
+
+  class Line
+    INFINITY = 9999
+
+    BLANK     = :BLANK
+    HEADING   = :HEADING
+    LIST      = :LIST
+    RULE      = :RULE
+    PARAGRAPH = :PARAGRAPH
+    VERBATIM  = :VERBATIM
+
+    # line type
+    attr_accessor :type
+
+    # The indentation nesting level
+    attr_accessor :level
+
+    # The contents
+    attr_accessor :text
+
+    # A prefix or parameter. For LIST lines, this is
+    # the text that introduced the list item (the label)
+    attr_accessor  :param
+
+    # A flag. For list lines, this is the type of the list
+    attr_accessor :flag
+
+    # the number of leading spaces
+    attr_accessor :leading_spaces
+
+    # true if this line has been deleted from the list of lines
+    attr_accessor :deleted
+
+    def initialize(text)
+      @text    = text.dup
+      @deleted = false
+
+      # expand tabs
+      1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)}  && $~ #`
+
+      # Strip trailing whitespace
+      @text.sub!(/\s+$/, '')
+
+      # and look for leading whitespace
+      if @text.length > 0
+        @text =~ /^(\s*)/
+        @leading_spaces = $1.length
+      else
+        @leading_spaces = INFINITY
+      end
+    end
+
+    # Return true if this line is blank
+    def isBlank?
+      @text.length.zero?
+    end
+
+    # stamp a line with a type, a level, a prefix, and a flag
+    def stamp(type, level, param="", flag=nil)
+      @type, @level, @param, @flag = type, level, param, flag
+    end
+
+    ##
+    # Strip off the leading margin
+
+    def strip_leading(size)
+      if @text.size > size
+        @text[0,size] = ""
+      else
+        @text = ""
+      end
+    end
+
+    def to_s
+      "#@type#@level: #@text"
+    end
+  end
+
+  ##
+  # A container for all the lines.
+
+  class Lines
+
+    include Enumerable
+
+    attr_reader :lines # :nodoc:
+
+    def initialize(lines)
+      @lines = lines
+      rewind
+    end
+
+    def empty?
+      @lines.size.zero?
+    end
+
+    def each
+      @lines.each do |line|
+        yield line unless line.deleted
+      end
+    end
+
+#    def [](index)
+#      @lines[index]
+#    end
+
+    def rewind
+      @nextline = 0
+    end
+
+    def next
+      begin
+        res = @lines[@nextline]
+        @nextline += 1 if @nextline < @lines.size
+      end while res and res.deleted and @nextline < @lines.size
+      res
+    end
+
+    def unget
+      @nextline -= 1
+    end
+
+    def delete(a_line)
+      a_line.deleted = true
+    end
+
+    def normalize
+      margin = @lines.collect{|l| l.leading_spaces}.min
+      margin = 0 if margin == Line::INFINITY
+      @lines.each {|line| line.strip_leading(margin) } if margin > 0
+    end
+
+    def as_text
+      @lines.map {|l| l.text}.join("\n")
+    end
+
+    def line_types
+      @lines.map {|l| l.type }
+    end
+
+  end
+
+end
+

Property changes on: lib/rdoc/markup/lines.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/stats.rb
===================================================================
--- lib/rdoc/stats.rb	(revision 0)
+++ lib/rdoc/stats.rb	(revision 15033)
@@ -0,0 +1,25 @@
+require 'rdoc'
+
+##
+# Simple stats collector
+
+class RDoc::Stats
+
+  attr_accessor :num_files, :num_classes, :num_modules, :num_methods
+
+  def initialize
+    @num_files = @num_classes = @num_modules = @num_methods = 0
+    @start = Time.now
+  end
+
+  def print
+    puts "Files:   #@num_files"
+    puts "Classes: #@num_classes"
+    puts "Modules: #@num_modules"
+    puts "Methods: #@num_methods"
+    puts "Elapsed: " + sprintf("%0.3fs", Time.now - @start)
+  end
+
+end
+
+

Property changes on: lib/rdoc/stats.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/markup.rb
===================================================================
--- lib/rdoc/markup.rb	(revision 0)
+++ lib/rdoc/markup.rb	(revision 15033)
@@ -0,0 +1,466 @@
+require 'rdoc'
+
+##
+# RDoc::Markup parses plain text documents and attempts to decompose them into
+# their constituent parts.  Some of these parts are high-level: paragraphs,
+# chunks of verbatim text, list entries and the like.  Other parts happen at
+# the character level: a piece of bold text, a word in code font.  This markup
+# is similar in spirit to that used on WikiWiki webs, where folks create web
+# pages using a simple set of formatting rules.
+#
+# RDoc::Markup itself does no output formatting: this is left to a different
+# set of classes.
+#
+# RDoc::Markup is extendable at runtime: you can add new markup elements to be
+# recognised in the documents that RDoc::Markup parses.
+#
+# RDoc::Markup is intended to be the basis for a family of tools which share
+# the common requirement that simple, plain-text should be rendered in a
+# variety of different output formats and media.  It is envisaged that
+# RDoc::Markup could be the basis for formating RDoc style comment blocks,
+# Wiki entries, and online FAQs.
+#
+# = Basic Formatting
+#
+# * RDoc::Markup looks for a document's natural left margin.  This is
+#   used as the initial margin for the document.
+#
+# * Consecutive lines starting at this margin are considered to be a
+#   paragraph.
+#
+# * If a paragraph starts with a "*", "-", or with "<digit>.", then it is
+#   taken to be the start of a list.  The margin in increased to be the
+#   first non-space following the list start flag.  Subsequent lines
+#   should be indented to this new margin until the list ends.  For
+#   example:
+#
+#      * this is a list with three paragraphs in
+#        the first item.  This is the first paragraph.
+#
+#        And this is the second paragraph.
+#
+#        1. This is an indented, numbered list.
+#        2. This is the second item in that list
+#
+#        This is the third conventional paragraph in the
+#        first list item.
+#
+#      * This is the second item in the original list
+#
+# * You can also construct labeled lists, sometimes called description
+#   or definition lists.  Do this by putting the label in square brackets
+#   and indenting the list body:
+#
+#       [cat]  a small furry mammal
+#              that seems to sleep a lot
+#
+#       [ant]  a little insect that is known
+#              to enjoy picnics
+#
+#   A minor variation on labeled lists uses two colons to separate the
+#   label from the list body:
+#
+#       cat::  a small furry mammal
+#              that seems to sleep a lot
+#
+#       ant::  a little insect that is known
+#              to enjoy picnics
+#
+#   This latter style guarantees that the list bodies' left margins are
+#   aligned: think of them as a two column table.
+#
+# * Any line that starts to the right of the current margin is treated
+#   as verbatim text.  This is useful for code listings.  The example of a
+#   list above is also verbatim text.
+#
+# * A line starting with an equals sign (=) is treated as a
+#   heading.  Level one headings have one equals sign, level two headings
+#   have two,and so on.
+#
+# * A line starting with three or more hyphens (at the current indent)
+#   generates a horizontal rule.  The more hyphens, the thicker the rule
+#   (within reason, and if supported by the output device)
+#
+# * You can use markup within text (except verbatim) to change the
+#   appearance of parts of that text.  Out of the box, RDoc::Markup
+#   supports word-based and general markup.
+#
+#   Word-based markup uses flag characters around individual words:
+#
+#   [\*word*]  displays word in a *bold* font
+#   [\_word_]  displays word in an _emphasized_ font
+#   [\+word+]  displays word in a +code+ font
+#
+#   General markup affects text between a start delimiter and and end
+#   delimiter.  Not surprisingly, these delimiters look like HTML markup.
+#
+#   [\<b>text...</b>]    displays word in a *bold* font
+#   [\<em>text...</em>]  displays word in an _emphasized_ font
+#   [\<i>text...</i>]    displays word in an _emphasized_ font
+#   [\<tt>text...</tt>]  displays word in a +code+ font
+#
+#   Unlike conventional Wiki markup, general markup can cross line
+#   boundaries.  You can turn off the interpretation of markup by
+#   preceding the first character with a backslash, so \\\<b>bold
+#   text</b> and \\\*bold* produce \<b>bold text</b> and \*bold
+#   respectively.
+#
+# * Hyperlinks to the web starting http:, mailto:, ftp:, or www. are
+#   recognized.  An HTTP url that references an external image file is
+#   converted into an inline <IMG..>.  Hyperlinks starting 'link:' are
+#   assumed to refer to local files whose path is relative to the --op
+#   directory.
+#
+#   Hyperlinks can also be of the form <tt>label</tt>[url], in which
+#   case the label is used in the displayed text, and <tt>url</tt> is
+#   used as the target.  If <tt>label</tt> contains multiple words,
+#   put it in braces: <em>{multi word label}[</em>url<em>]</em>.
+#
+# == Synopsis
+#
+# This code converts <tt>input_string</tt> to HTML.  The conversion
+# takes place in the +convert+ method, so you can use the same
+# RDoc::Markup object to convert multiple input strings.
+#
+#   require 'rdoc/markup'
+#   require 'rdoc/markup/to_html'
+#   
+#   p = RDoc::Markup.new
+#   h = RDoc::Markup::ToHtml.new
+#   
+#   puts p.convert(input_string, h)
+#
+# You can extend the RDoc::Markup parser to recognise new markup
+# sequences, and to add special processing for text that matches a
+# regular epxression.  Here we make WikiWords significant to the parser,
+# and also make the sequences {word} and \<no>text...</no> signify
+# strike-through text.  When then subclass the HTML output class to deal
+# with these:
+#
+#   require 'rdoc/markup'
+#   require 'rdoc/markup/to_html'
+#   
+#   class WikiHtml < RDoc::Markup::ToHtml
+#     def handle_special_WIKIWORD(special)
+#       "<font color=red>" + special.text + "</font>"
+#     end
+#   end
+#   
+#   p = RDoc::Markup.new
+#   p.add_word_pair("{", "}", :STRIKE)
+#   p.add_html("no", :STRIKE)
+#   
+#   p.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
+#   
+#   h = WikiHtml.new
+#   h.add_tag(:STRIKE, "<strike>", "</strike>")
+#   
+#   puts "<body>" + p.convert(ARGF.read, h) + "</body>"
+#
+#--
+# Author::   Dave Thomas,  dave@p...
+# Version::  0.0
+# License::  Ruby license
+
+class RDoc::Markup
+
+  SPACE = ?\s
+
+  # List entries look like:
+  #   *       text
+  #   1.      text
+  #   [label] text
+  #   label:: text
+  #
+  # Flag it as a list entry, and work out the indent for subsequent lines
+
+  SIMPLE_LIST_RE = /^(
+                (  \*          (?# bullet)
+                  |-           (?# bullet)
+                  |\d+\.       (?# numbered )
+                  |[A-Za-z]\.  (?# alphabetically numbered )
+                )
+                \s+
+              )\S/x
+
+  LABEL_LIST_RE = /^(
+                      (  \[.*?\]    (?# labeled  )
+                        |\S.*::     (?# note     )
+                      )(?:\s+|$)
+                    )/x
+
+  ##
+  # Take a block of text and use various heuristics to determine it's
+  # structure (paragraphs, lists, and so on).  Invoke an event handler as we
+  # identify significant chunks.
+
+  def initialize
+    @am = AttributeManager.new
+    @output = nil
+  end
+
+  ##
+  # Add to the sequences used to add formatting to an individual word (such
+  # as *bold*).  Matching entries will generate attibutes that the output
+  # formatters can recognize by their +name+.
+
+  def add_word_pair(start, stop, name)
+    @am.add_word_pair(start, stop, name)
+  end
+
+  ##
+  # Add to the sequences recognized as general markup.
+
+  def add_html(tag, name)
+    @am.add_html(tag, name)
+  end
+
+  ##
+  # Add to other inline sequences.  For example, we could add WikiWords using
+  # something like:
+  #
+  #    parser.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
+  #
+  # Each wiki word will be presented to the output formatter via the
+  # accept_special method.
+
+  def add_special(pattern, name)
+    @am.add_special(pattern, name)
+  end
+
+  ##
+  # We take a string, split it into lines, work out the type of each line,
+  # and from there deduce groups of lines (for example all lines in a
+  # paragraph).  We then invoke the output formatter using a Visitor to
+  # display the result.
+
+  def convert(str, op)
+    @lines = Lines.new(str.split(/\r?\n/).collect { |aLine|
+                         Line.new(aLine) })
+    return "" if @lines.empty?
+    @lines.normalize
+    assign_types_to_lines
+    group = group_lines
+    # call the output formatter to handle the result
+    #      group.to_a.each {|i| p i}
+    group.accept(@am, op)
+  end
+
+  private
+
+  ##
+  # Look through the text at line indentation.  We flag each line as being
+  # Blank, a paragraph, a list element, or verbatim text.
+
+  def assign_types_to_lines(margin = 0, level = 0)
+
+    while line = @lines.next
+      if line.isBlank?
+        line.stamp(Line::BLANK, level)
+        next
+      end
+
+      # if a line contains non-blanks before the margin, then it must belong
+      # to an outer level
+
+      text = line.text
+
+      for i in 0...margin
+        if text[i] != SPACE
+          @lines.unget
+          return
+        end
+      end
+
+      active_line = text[margin..-1]
+
+      # Rules (horizontal lines) look like
+      #
+      #  ---   (three or more hyphens)
+      #
+      # The more hyphens, the thicker the rule
+      #
+
+      if /^(---+)\s*$/ =~ active_line
+        line.stamp(Line::RULE, level, $1.length-2)
+        next
+      end
+
+      # Then look for list entries.  First the ones that have to have
+      # text following them (* xxx, - xxx, and dd. xxx)
+
+      if SIMPLE_LIST_RE =~ active_line
+
+        offset = margin + $1.length
+        prefix = $2
+        prefix_length = prefix.length
+
+        flag = case prefix
+               when "*","-" then ListBase::BULLET
+               when /^\d/   then ListBase::NUMBER
+               when /^[A-Z]/ then ListBase::UPPERALPHA
+               when /^[a-z]/ then ListBase::LOWERALPHA
+               else raise "Invalid List Type: #{self.inspect}"
+               end
+
+        line.stamp(Line::LIST, level+1, prefix, flag)
+        text[margin, prefix_length] = " " * prefix_length
+        assign_types_to_lines(offset, level + 1)
+        next
+      end
+
+
+      if LABEL_LIST_RE =~ active_line
+        offset = margin + $1.length
+        prefix = $2
+        prefix_length = prefix.length
+
+        next if handled_labeled_list(line, level, margin, offset, prefix)
+      end
+
+      # Headings look like
+      # = Main heading
+      # == Second level
+      # === Third
+      #
+      # Headings reset the level to 0
+
+      if active_line[0] == ?= and active_line =~ /^(=+)\s*(.*)/
+        prefix_length = $1.length
+        prefix_length = 6 if prefix_length > 6
+        line.stamp(Line::HEADING, 0, prefix_length)
+        line.strip_leading(margin + prefix_length)
+        next
+      end
+
+      # If the character's a space, then we have verbatim text,
+      # otherwise
+
+      if active_line[0] == SPACE
+        line.strip_leading(margin) if margin > 0
+        line.stamp(Line::VERBATIM, level)
+      else
+        line.stamp(Line::PARAGRAPH, level)
+      end
+    end
+  end
+
+  ##
+  # Handle labeled list entries, We have a special case to deal with.
+  # Because the labels can be long, they force the remaining block of text
+  # over the to right:
+  #
+  #   this is a long label that I wrote:: and here is the
+  #                                       block of text with
+  #                                       a silly margin
+  #
+  # So we allow the special case.  If the label is followed by nothing, and
+  # if the following line is indented, then we take the indent of that line
+  # as the new margin.
+  #
+  #   this is a long label that I wrote::
+  #       here is a more reasonably indented block which
+  #       will be attached to the label.
+  #
+
+  def handled_labeled_list(line, level, margin, offset, prefix)
+    prefix_length = prefix.length
+    text = line.text
+    flag = nil
+    case prefix
+    when /^\[/
+      flag = ListBase::LABELED
+      prefix = prefix[1, prefix.length-2]
+    when /:$/
+      flag = ListBase::NOTE
+      prefix.chop!
+    else raise "Invalid List Type: #{self.inspect}"
+    end
+
+    # body is on the next line
+
+    if text.length <= offset
+      original_line = line
+      line = @lines.next
+      return(false) unless line
+      text = line.text
+
+      for i in 0..margin
+        if text[i] != SPACE
+          @lines.unget
+          return false
+        end
+      end
+      i = margin
+      i += 1 while text[i] == SPACE
+      if i >= text.length
+        @lines.unget
+        return false
+      else
+        offset = i
+        prefix_length = 0
+        @lines.delete(original_line)
+      end
+    end
+
+    line.stamp(Line::LIST, level+1, prefix, flag)
+    text[margin, prefix_length] = " " * prefix_length
+    assign_types_to_lines(offset, level + 1)
+    return true
+  end
+
+  ##
+  # Return a block consisting of fragments which are paragraphs, list
+  # entries or verbatim text.  We merge consecutive lines of the same type
+  # and level together.  We are also slightly tricky with lists: the lines
+  # following a list introduction look like paragraph lines at the next
+  # level, and we remap them into list entries instead.
+
+  def group_lines
+    @lines.rewind
+
+    inList = false
+    wantedType = wantedLevel = nil
+
+    block = LineCollection.new
+    group = nil
+
+    while line = @lines.next
+      if line.level == wantedLevel and line.type == wantedType
+        group.add_text(line.text)
+      else
+        group = block.fragment_for(line)
+        block.add(group)
+        if line.type == Line::LIST
+          wantedType = Line::PARAGRAPH
+        else
+          wantedType = line.type
+        end
+        wantedLevel = line.type == Line::HEADING ? line.param : line.level
+      end
+    end
+
+    block.normalize
+    block
+  end
+
+  ##
+  # For debugging, we allow access to our line contents as text.
+
+  def content
+    @lines.as_text
+  end
+  public :content
+
+  ##
+  # For debugging, return the list of line types.
+
+  def get_line_types
+    @lines.line_types
+  end
+  public :get_line_types
+
+end
+
+require 'rdoc/markup/fragments'
+require 'rdoc/markup/lines'

Property changes on: lib/rdoc/markup.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: lib/rdoc/ri/reader.rb
===================================================================
--- lib/rdoc/ri/reader.rb	(revision 15032)
+++ lib/rdoc/ri/reader.rb	(revision 15033)
@@ -1,7 +1,7 @@
 require 'rdoc/ri'
 require 'rdoc/ri/descriptions'
 require 'rdoc/ri/writer'
-require 'rdoc/markup/simple_markup/to_flow'
+require 'rdoc/markup/to_flow'
 
 class RDoc::RI::Reader
 
Index: lib/rdoc/ri/formatter.rb
===================================================================
--- lib/rdoc/ri/formatter.rb	(revision 15032)
+++ lib/rdoc/ri/formatter.rb	(revision 15033)
@@ -99,17 +99,17 @@
   def display_list(list)
     case list.type
 
-    when SM::ListBase::BULLET
+    when RDoc::Markup::ListBase::BULLET
       prefixer = proc { |ignored| @indent + "*   " }
 
-    when SM::ListBase::NUMBER,
-      SM::ListBase::UPPERALPHA,
-      SM::ListBase::LOWERALPHA
+    when RDoc::Markup::ListBase::NUMBER,
+      RDoc::Markup::ListBase::UPPERALPHA,
+      RDoc::Markup::ListBase::LOWERALPHA
 
       start = case list.type
-              when SM::ListBase::NUMBER      then 1
-              when  SM::ListBase::UPPERALPHA then 'A'
-              when SM::ListBase::LOWERALPHA  then 'a'
+              when RDoc::Markup::ListBase::NUMBER      then 1
+              when RDoc::Markup::ListBase::UPPERALPHA then 'A'
+              when RDoc::Markup::ListBase::LOWERALPHA  then 'a'
               end
       prefixer = proc do |ignored|
         res = @indent + "#{start}.".ljust(4)
@@ -117,15 +117,15 @@
         res
       end
 
-    when SM::ListBase::LABELED
+    when RDoc::Markup::ListBase::LABELED
       prefixer = proc do |li|
         li.label
       end
 
-    when SM::ListBase::NOTE
+    when RDoc::Markup::ListBase::NOTE
       longest = 0
       list.contents.each do |item|
-        if item.kind_of?(SM::Flow::LI) && item.label.length > longest
+        if item.kind_of?(RDoc::Markup::Flow::LI) && item.label.length > longest
           longest = item.label.length
         end
       end
@@ -140,7 +140,7 @@
     end
 
     list.contents.each do |item|
-      if item.kind_of? SM::Flow::LI
+      if item.kind_of? RDoc::Markup::Flow::LI
         prefix = prefixer.call(item)
         display_flow_item(item, prefix)
       else
@@ -153,20 +153,20 @@
 
   def display_flow_item(item, prefix=@indent)
     case item
-    when SM::Flow::P, SM::Flow::LI
+    when RDoc::Markup::Flow::P, RDoc::Markup::Flow::LI
       wrap(conv_html(item.body), prefix)
       blankline
 
-    when SM::Flow::LIST
+    when RDoc::Markup::Flow::LIST
       display_list(item)
 
-    when SM::Flow::VERB
+    when RDoc::Markup::Flow::VERB
       display_verbatim_flow_item(item, @indent)
 
-    when SM::Flow::H
+    when RDoc::Markup::Flow::H
       display_heading(conv_html(item.text), item.level, @indent)
 
-    when SM::Flow::RULE
+    when RDoc::Markup::Flow::RULE
       draw_line
 
     else
@@ -508,23 +508,23 @@
 
   def display_list(list)
     case list.type
-    when SM::ListBase::BULLET
+    when RDoc::Markup::ListBase::BULLET
       list_type = "ul"
       prefixer = proc { |ignored| "<li>" }
 
-    when SM::ListBase::NUMBER,
-      SM::ListBase::UPPERALPHA,
-      SM::ListBase::LOWERALPHA
+    when RDoc::Markup::ListBase::NUMBER,
+      RDoc::Markup::ListBase::UPPERALPHA,
+      RDoc::Markup::ListBase::LOWERALPHA
       list_type = "ol"
       prefixer = proc { |ignored| "<li>" }
 
-    when SM::ListBase::LABELED
+    when RDoc::Markup::ListBase::LABELED
       list_type = "dl"
       prefixer = proc do |li|
           "<dt><b>" + escape(li.label) + "</b><dd>"
       end
 
-    when SM::ListBase::NOTE
+    when RDoc::Markup::ListBase::NOTE
       list_type = "table"
       prefixer = proc do |li|
           %{<tr valign="top"><td>#{li.label.gsub(/ /, '&nbsp;')}</td><td>}
@@ -535,7 +535,7 @@
 
     print "<#{list_type}>"
     list.contents.each do |item|
-      if item.kind_of? SM::Flow::LI
+      if item.kind_of? RDoc::Markup::Flow::LI
         prefix = prefixer.call(item)
         print prefix
         display_flow_item(item, prefix)
Index: lib/rdoc/ri/display.rb
===================================================================
--- lib/rdoc/ri/display.rb	(revision 15032)
+++ lib/rdoc/ri/display.rb	(revision 15033)
@@ -26,7 +26,7 @@
 
 ##
 # A paging display module. Uses the RDoc::RI::Formatter class to do the actual
-# presentation
+# presentation.
 
 class RDoc::RI::DefaultDisplay
 
Index: lib/rdoc/ri/descriptions.rb
===================================================================
--- lib/rdoc/ri/descriptions.rb	(revision 15032)
+++ lib/rdoc/ri/descriptions.rb	(revision 15033)
@@ -1,5 +1,5 @@
 require 'yaml'
-require 'rdoc/markup/simple_markup/fragments'
+require 'rdoc/markup/fragments'
 require 'rdoc/ri'
 
 #--
@@ -91,7 +91,7 @@
       @comment = old.comment
     else
       unless old.comment.nil? or old.comment.empty? then
-        @comment << SM::Flow::RULE.new
+        @comment << RDoc::Markup::Flow::RULE.new
         @comment.concat old.comment
       end
     end
Index: lib/rdoc/ri/driver.rb
===================================================================
--- lib/rdoc/ri/driver.rb	(revision 15032)
+++ lib/rdoc/ri/driver.rb	(revision 15033)
@@ -6,8 +6,8 @@
 require 'rdoc/ri/formatter'
 require 'rdoc/ri/display'
 require 'fileutils'
-require 'rdoc/markup/simple_markup'
-require 'rdoc/markup/simple_markup/to_flow'
+require 'rdoc/markup'
+require 'rdoc/markup/to_flow'
 
 class RDoc::RI::Driver
 
@@ -222,7 +222,7 @@
     return @class_cache if @class_cache
 
     newest = map_dirs('created.rid', :all) do |f|
-      File.mtime f if test ?f, f 
+      File.mtime f if test ?f, f
     end.max
 
     up_to_date = (File.exist?(class_cache_file_path) and
@@ -341,7 +341,7 @@
   end
 
   def read_yaml(path)
-    YAML.load File.read(path).gsub(/ \!ruby\/(object|struct):(RDoc|RI).*/, '')
+    YAML.load File.read(path).gsub(/ \!ruby\/(object|struct):(RDoc::RI|RI).*/, '')
   end
 
   def run
Index: bin/rdoc
===================================================================
--- bin/rdoc	(revision 15032)
+++ bin/rdoc	(revision 15033)
@@ -8,59 +8,14 @@
 #
 #  $Revision$
 
-## Transitional Hack ####
-#
-#  RDoc was initially distributed independently, and installed
-#  itself into <prefix>/lib/ruby/site_ruby/<ver>/rdoc...
-#
-#  Now that RDoc is part of the distribution, it's installed into
-#  <prefix>/lib/ruby/<ver>, which unfortunately appears later in the
-#  search path. This means that if you have previously installed RDoc,
-#  and then install from ruby-lang, you'll pick up the old one by
-#  default. This hack checks for the condition, and readjusts the
-#  search path if necessary.
-
-def adjust_for_existing_rdoc(path)
-
-  $stderr.puts %{
-  It seems as if you have a previously-installed RDoc in
-  the directory #{path}.
-
-  Because this is now out-of-date, you might want to consider
-  removing the directories:
-
-    #{File.join(path, "rdoc")}
-
-  and
-
-    #{File.join(path, "markup")}
-
-  }
-
-  # Move all the site_ruby directories to the end
-  p $:
-  $:.replace($:.partition {|path| /site_ruby/ !~ path}.flatten)
-  p $:
-end
-
-$:.each do |path|
-  if /site_ruby/ =~ path
-    rdoc_path = File.join(path, 'rdoc', 'rdoc.rb')
-    if File.exist?(rdoc_path)
-      adjust_for_existing_rdoc(path)
-      break
-    end
-  end
-end
-
-## End of Transitional Hack ##
-
-
 require 'rdoc/rdoc'
 
 begin
   r = RDoc::RDoc.new
   r.document ARGV
+rescue Interrupt
+  $stderr.puts
+  $stderr.puts "Interrupted"
 rescue RDoc::Error => e
   $stderr.puts e.message
   exit 1

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]