<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>ext/redcloth_scan/redcloth_attributes.rb.rl</filename>
    </added>
    <added>
      <filename>ext/redcloth_scan/redcloth_common.rb.rl</filename>
    </added>
    <added>
      <filename>ext/redcloth_scan/redcloth_inline.rb.rl</filename>
    </added>
    <added>
      <filename>ext/redcloth_scan/redcloth_scan.rb.rl</filename>
    </added>
    <added>
      <filename>lib/tasks/pureruby.rake</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -5,9 +5,11 @@ ext/redcloth_scan/*.so
 ext/redcloth_scan/*.jar
 ext/redcloth_scan/*.class
 ext/redcloth_scan/*.java
+ext/redcloth_scan/redcloth_*.rb
 lib/*.bundle
 lib/*.so
 lib/*.jar
+lib/redcloth_scan.rb
 doc/rdoc/*
 tmp/*
 pkg/*</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,7 @@
 === Edge
 
+* Added a pure-ruby version of the parser for times when you can't compile the C or Java extensions.  You should avoid using it if at all possible because it is 32 times slower (and has some other problems, too)! [Jason Garber]
+
 * Ignore spaces and tabs on blank lines between blocks. #120 [Jason Garber]
 
 * Allow HTML tags with quoted attributes to be inside link text.  To do this, I had to remove the possibility that attributes in HTML tags could have spaces around the equals sign or unquoted attributes.  This change also greatly expands the complexity of the state machine, so compilation takes a long time. Sorry. [Jason Garber]</diff>
      <filename>CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -6,15 +6,19 @@ ext/redcloth_scan/extconf.rb
 ext/redcloth_scan/redcloth.h
 ext/redcloth_scan/redcloth_attributes.c.rl
 ext/redcloth_scan/redcloth_attributes.java.rl
+ext/redcloth_scan/redcloth_attributes.rb.rl
 ext/redcloth_scan/redcloth_attributes.rl
 ext/redcloth_scan/redcloth_common.c.rl
 ext/redcloth_scan/redcloth_common.java.rl
+ext/redcloth_scan/redcloth_common.rb.rl
 ext/redcloth_scan/redcloth_common.rl
 ext/redcloth_scan/redcloth_inline.c.rl
 ext/redcloth_scan/redcloth_inline.java.rl
+ext/redcloth_scan/redcloth_inline.rb.rl
 ext/redcloth_scan/redcloth_inline.rl
 ext/redcloth_scan/redcloth_scan.c.rl
 ext/redcloth_scan/redcloth_scan.java.rl
+ext/redcloth_scan/redcloth_scan.rb.rl
 ext/redcloth_scan/redcloth_scan.rl
 extras/ragel_profiler.rb
 lib/case_sensitive_require/RedCloth.rb
@@ -26,6 +30,7 @@ lib/redcloth/formatters/latex_entities.yml
 lib/redcloth/textile_doc.rb
 lib/redcloth/version.rb
 lib/redcloth.rb
+lib/tasks/pureruby.rake
 Manifest
 Rakefile
 README</diff>
      <filename>Manifest</filename>
    </modified>
    <modified>
      <diff>@@ -2,12 +2,13 @@ require 'lib/redcloth/version'
 require 'rubygems'
 gem 'echoe', '&gt;= 3.0.1'
 require 'echoe'
+Dir[&quot;#{File.dirname(__FILE__)}/lib/tasks/*.rake&quot;].sort.each { |ext| load(ext) }
 
 e = Echoe.new('RedCloth', RedCloth::VERSION.to_s) do |p|
   p.summary = RedCloth::DESCRIPTION
   p.author = &quot;Jason Garber&quot;
   p.email = 'redcloth-upwards@rubyforge.org'
-  p.clean_pattern += ['ext/redcloth_scan/**/*.{bundle,so,obj,pdb,lib,def,exp,c,o,xml,class,jar,java}', 'lib/*.{bundle,so,o,obj,pdb,lib,def,exp,jar}', 'ext/redcloth_scan/Makefile']
+  p.clean_pattern += ['ext/redcloth_scan/**/*.{bundle,so,obj,pdb,lib,def,exp,c,o,xml,class,jar,java}', 'lib/*.{bundle,so,o,obj,pdb,lib,def,exp,jar}', 'ext/redcloth_scan/**/redcloth_*.rb', 'lib/redcloth_scan.rb', 'ext/redcloth_scan/Makefile']
   p.url = &quot;http://redcloth.org&quot;
   p.project = &quot;redcloth&quot;
   p.rdoc_pattern = ['README', 'COPING', 'CHANGELOG', 'lib/**/*.rb', 'doc/**/*.rdoc']
@@ -20,10 +21,14 @@ e = Echoe.new('RedCloth', RedCloth::VERSION.to_s) do |p|
     p.platform = 'x86-mswin32-60'
   elsif Platform.java?
     p.platform = 'universal-java'
+  elsif RUBY_PLATFORM == 'pureruby'
+    p.platform = 'ruby'
   end
   
   if RUBY_PLATFORM =~ /mingw|mswin|java/
     p.need_tar_gz = false
+  elsif RUBY_PLATFORM == 'pureruby'
+    p.need_gem = false
   else
     p.need_zip = true
     p.need_tar_gz = true
@@ -36,6 +41,8 @@ e = Echoe.new('RedCloth', RedCloth::VERSION.to_s) do |p|
       self.files += ['lib/redcloth_scan.so']
     when /java/
       self.files += ['lib/redcloth_scan.jar']
+    when 'pureruby'
+      self.files += ['lib/redcloth_scan.rb']
     else
       self.files += %w[attributes inline scan].map {|f| &quot;ext/redcloth_scan/redcloth_#{f}.c&quot;}
     end
@@ -45,7 +52,9 @@ e = Echoe.new('RedCloth', RedCloth::VERSION.to_s) do |p|
 
 end
 
-#### Pre-compiled extensions for alternative platforms
+def remove_other_platforms
+  Dir[&quot;lib/redcloth_scan.{bundle,so,jar,rb}&quot;].each { |file| rm file }
+end
 
 def move_extensions
   Dir[&quot;ext/**/*.{bundle,so,jar}&quot;].each { |file| mv file, &quot;lib/&quot; }
@@ -75,6 +84,7 @@ when /mingw/
       ruby &quot;-I. extconf.rb&quot;
       system(PLATFORM =~ /mswin/ ? 'nmake' : 'make')
     end
+    remove_other_platforms
     move_extensions
     rm &quot;#{ext}/rbconfig.rb&quot;
   end
@@ -86,9 +96,19 @@ when /java/
     sources = FileList[&quot;#{ext}/**/*.java&quot;].join(' ')
     sh &quot;javac -target 1.5 -source 1.5 -d #{ext} #{java_classpath_arg} #{sources}&quot;
     sh &quot;jar cf lib/redcloth_scan.jar -C #{ext} .&quot;
+    remove_other_platforms
     move_extensions
   end
   
+when /pureruby/
+  filename = &quot;lib/redcloth_scan.rb&quot;
+  file filename =&gt; FileList[&quot;#{ext}/redcloth_scan.rb&quot;, &quot;#{ext}/redcloth_inline.rb&quot;, &quot;#{ext}/redcloth_attributes.rb&quot;] do |task|
+    
+    remove_other_platforms
+    sources = task.prerequisites.join(' ')
+    sh &quot;cat #{sources} &gt; #{filename}&quot;
+  end
+  
 else
   filename = &quot;#{ext}/redcloth_scan.#{Config::CONFIG['DLEXT']}&quot;
   file filename =&gt; FileList[&quot;#{ext}/redcloth_scan.c&quot;, &quot;#{ext}/redcloth_inline.c&quot;, &quot;#{ext}/redcloth_attributes.c&quot;]
@@ -97,8 +117,21 @@ end
 task :compile =&gt; [filename]
 
 def ragel(target_file, source_file)
-  host_language = (target_file =~ /java$/) ? &quot;J&quot; : &quot;C&quot;
-  code_style = (host_language == &quot;C&quot;) ? &quot; -&quot; + (@code_style || &quot;T0&quot;) : &quot;&quot;
+  host_language = case target_file
+  when /java$/
+    &quot;J&quot;
+  when /rb$/
+    &quot;R&quot;
+  else
+    &quot;C&quot;
+  end
+  preferred_code_style = case host_language
+  when &quot;R&quot;
+    &quot;F1&quot;
+  else
+    &quot;T0&quot;
+  end
+  code_style = &quot; -&quot; + (@code_style || preferred_code_style)
   ensure_ragel_version(target_file) do
     sh %{ragel #{source_file} -#{host_language}#{code_style} -o #{target_file}}
   end
@@ -129,23 +162,39 @@ file &quot;#{ext}/RedclothAttributes.java&quot; =&gt;  [&quot;#{ext}/redcloth_attributes.java.rl&quot;,
   ragel &quot;#{ext}/RedclothAttributes.java&quot;, &quot;#{ext}/redcloth_attributes.java.rl&quot;
 end
 
+# Ragel-generated pureruby files
+file &quot;#{ext}/redcloth_scan.rb&quot; =&gt;  [&quot;#{ext}/redcloth_scan.rb.rl&quot;,   &quot;#{ext}/redcloth_scan.rl&quot;, &quot;#{ext}/redcloth_common.rb.rl&quot;,   &quot;#{ext}/redcloth_common.rl&quot;] do
+  ragel &quot;#{ext}/redcloth_scan.rb&quot;, &quot;#{ext}/redcloth_scan.rb.rl&quot;
+end
+file &quot;#{ext}/redcloth_inline.rb&quot; =&gt;  [&quot;#{ext}/redcloth_inline.rb.rl&quot;,   &quot;#{ext}/redcloth_inline.rl&quot;, &quot;#{ext}/redcloth_common.rb.rl&quot;,   &quot;#{ext}/redcloth_common.rl&quot;] do
+  ragel &quot;#{ext}/redcloth_inline.rb&quot;, &quot;#{ext}/redcloth_inline.rb.rl&quot;
+end
+file &quot;#{ext}/redcloth_attributes.rb&quot; =&gt;  [&quot;#{ext}/redcloth_attributes.rb.rl&quot;,   &quot;#{ext}/redcloth_attributes.rl&quot;, &quot;#{ext}/redcloth_common.rb.rl&quot;,   &quot;#{ext}/redcloth_common.rl&quot;] do
+  ragel &quot;#{ext}/redcloth_attributes.rb&quot;, &quot;#{ext}/redcloth_attributes.rb.rl&quot;
+end
+
 
 #### Optimization
 
+# C/Ruby code styles
 RAGEL_CODE_GENERATION_STYLES = {
   'T0' =&gt; &quot;Table driven FSM (default)&quot;,
   'T1' =&gt; &quot;Faster table driven FSM&quot;,
   'F0' =&gt; &quot;Flat table driven FSM&quot;,
-  'F1' =&gt; &quot;Faster flat table-driven FSM&quot;,
+  'F1' =&gt; &quot;Faster flat table-driven FSM&quot;
+}
+# C only code styles
+RAGEL_CODE_GENERATION_STYLES.merge!({
   'G0' =&gt; &quot;Goto-driven FSM&quot;,
   'G1' =&gt; &quot;Faster goto-driven FSM&quot;,
   'G2' =&gt; &quot;Really fast goto-driven FSM&quot;
-}
+}) if RUBY_PLATFORM !~ /pureruby/
 
 desc &quot;Find the fastest code generation style for Ragel&quot;
 task :optimize do
   require 'extras/ragel_profiler'
   results = []
+  
   RAGEL_CODE_GENERATION_STYLES.each do |style, name|
     @code_style = style
     profiler = RagelProfiler.new(style + &quot; &quot; + name)
@@ -162,7 +211,7 @@ task :optimize do
     profiler.measure(:test) do
       Rake::Task['test'].invoke
     end
-    profiler.ext_size(ext_so)
+    profiler.ext_size(filename)
     
   end
   puts RagelProfiler.results</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -51,6 +51,8 @@ VALUE red_pass_code(VALUE, VALUE, VALUE, ID);
 /* parser macros */
 #define CLEAR_REGS()   regs = rb_hash_new();
 #define RESET_REG()    reg = NULL
+#define MARK()         reg = p;
+#define MARK_B()       bck = p;
 #define CAT(H)         rb_str_cat(H, ts, te-ts)
 #define CLEAR(H)       H = STR_NEW2(&quot;&quot;)
 #define RSTRIP_BANG(H)      rb_funcall(H, rb_intern(&quot;rstrip!&quot;), 0)
@@ -62,7 +64,7 @@ VALUE red_pass_code(VALUE, VALUE, VALUE, ID);
 #define PARSE_ATTR(A)  red_parse_attr(self, regs, ID2SYM(rb_intern(A)))
 #define PARSE_LINK_ATTR(A)  red_parse_link_attr(self, regs, ID2SYM(rb_intern(A)))
 #define PARSE_IMAGE_ATTR(A)  red_parse_image_attr(self, regs, ID2SYM(rb_intern(A)))
-#define PASS_CODE(H, A, T, O) rb_str_append(H, red_pass_code(self, regs, ID2SYM(rb_intern(A)), rb_intern(T)))
+#define PASS_CODE(H, A, T) rb_str_append(H, red_pass_code(self, regs, ID2SYM(rb_intern(A)), rb_intern(T)))
 #define ADD_BLOCK() \
   rb_str_append(html, red_block(self, regs, block, refs)); \
   extend = Qnil; \
@@ -70,11 +72,11 @@ VALUE red_pass_code(VALUE, VALUE, VALUE, ID);
   CLEAR_REGS()
 #define ADD_EXTENDED_BLOCK()    rb_str_append(html, red_block(self, regs, block, refs)); CLEAR(block);
 #define END_EXTENDED()     extend = Qnil; CLEAR_REGS();
-#define IS_NOT_EXTENDED()     NIL_P(extend)
 #define ADD_BLOCKCODE()    rb_str_append(html, red_blockcode(self, regs, block)); CLEAR(block); CLEAR_REGS()
 #define ADD_EXTENDED_BLOCKCODE()    rb_str_append(html, red_blockcode(self, regs, block)); CLEAR(block);
 #define ASET(T, V)     rb_hash_aset(regs, ID2SYM(rb_intern(T)), STR_NEW2(V));
 #define AINC(T)        red_inc(regs, ID2SYM(rb_intern(T)));
+#define INC(N)         N++;
 #define SET_ATTRIBUTES() \
   SET_ATTRIBUTE(&quot;class_buf&quot;, &quot;class&quot;); \
   SET_ATTRIBUTE(&quot;id_buf&quot;, &quot;id&quot;); \
@@ -141,6 +143,9 @@ VALUE red_pass_code(VALUE, VALUE, VALUE, ID);
 #define STORE_LINK_ALIAS() \
   rb_hash_aset(refs_found, rb_hash_aref(regs, ID2SYM(rb_intern(&quot;text&quot;))), rb_hash_aref(regs, ID2SYM(rb_intern(&quot;href&quot;))))
 #define CLEAR_LIST() list_layout = rb_ary_new()
+#define SET_LIST_TYPE(T) list_type = T;
+#define NEST() nest ++;
+#define RESET_NEST() nest = 0;
 #define LIST_ITEM() \
     int aint = 0; \
     VALUE aval = rb_ary_entry(list_index, nest-1); \
@@ -152,9 +157,9 @@ VALUE red_pass_code(VALUE, VALUE, VALUE, ID);
     if (nest &gt; RARRAY_LEN(list_layout)) \
     { \
       sprintf(listm, &quot;%s_open&quot;, list_type); \
-      if (list_continue == 1) \
+      if (!NIL_P(rb_hash_aref(regs, ID2SYM(rb_intern(&quot;list_continue&quot;))))) \
       { \
-        list_continue = 0; \
+        rb_hash_aset(regs, ID2SYM(rb_intern(&quot;list_continue&quot;)), Qnil); \
         rb_hash_aset(regs, ID2SYM(rb_intern(&quot;start&quot;)), rb_ary_entry(list_index, nest-1)); \
       } \
       else \</diff>
      <filename>ext/redcloth_scan/redcloth.h</filename>
    </modified>
    <modified>
      <diff>@@ -14,5 +14,7 @@
   action starts_phrase {
     p == orig_p || *(p-1) == '\r' || *(p-1) == '\n' || *(p-1) == '\f' || *(p-1) == ' '
   }
+  action extended { !NIL_P(extend) }
+  action not_extended { NIL_P(extend) }
   
 }%%;
\ No newline at end of file</diff>
      <filename>ext/redcloth_scan/redcloth_common.c.rl</filename>
    </modified>
    <modified>
      <diff>@@ -14,5 +14,7 @@
   action starts_phrase {
     p == orig_p || data[(p-1)] == '\r' || data[(p-1)] == '\n' || data[(p-1)] == '\f' || data[(p-1)] == ' '
   }
+  action extended { !extend.isNil() }
+  action not_extended { extend.isNil() }
 
 }%%;</diff>
      <filename>ext/redcloth_scan/redcloth_common.java.rl</filename>
    </modified>
    <modified>
      <diff>@@ -2,8 +2,8 @@
 
   machine redcloth_common;
 
-  action A { reg = p; }
-  action B { bck = p; }
+  action A { MARK(); }
+  action B { MARK_B(); }
   action T { STORE(&quot;text&quot;); }
   action X { CLEAR_REGS(); RESET_REG(); }
   action cat { CAT(block); }
@@ -34,7 +34,7 @@
   S = ( S_CSPN | S_RSPN )* ;
   C = ( C_CLAS | C_STYL | C_LNGE )* ;
   D = ( D_HEADER ) ;
-  N_CONT = &quot;_&quot; %{ list_continue = 1; };
+  N_CONT = &quot;_&quot; %{ ASET(&quot;list_continue&quot;, &quot;true&quot;); };
   N_NUM = digit+ &gt;A %{ STORE(&quot;start&quot;); };
   N = ( N_CONT | N_NUM )? ;
   PUNCT = ( &quot;!&quot; | '&quot;' | &quot;#&quot; | &quot;$&quot; | &quot;%&quot; | &quot;&amp;&quot; | &quot;'&quot; | &quot;,&quot; | &quot;-&quot; | &quot;.&quot; | &quot;/&quot; | &quot;:&quot; | &quot;;&quot; | &quot;=&quot; | &quot;?&quot; | &quot;\\&quot; | &quot;^&quot; | &quot;`&quot; | &quot;|&quot; | &quot;~&quot; | &quot;[&quot; | &quot;]&quot; | &quot;(&quot; | &quot;)&quot; | &quot;&lt;&quot; ) ;</diff>
      <filename>ext/redcloth_scan/redcloth_common.rl</filename>
    </modified>
    <modified>
      <diff>@@ -29,7 +29,7 @@ red_parse_attr(VALUE self, VALUE regs, VALUE ref)
 {
   VALUE txt = rb_hash_aref(regs, ref);
   VALUE new_regs = redcloth_attributes(self, txt);
-  return rb_funcall(regs, rb_intern(&quot;update&quot;), 1, new_regs);
+  return rb_funcall(regs, rb_intern(&quot;merge!&quot;), 1, new_regs);
 }
 
 VALUE
@@ -38,7 +38,7 @@ red_parse_link_attr(VALUE self, VALUE regs, VALUE ref)
   VALUE txt = rb_hash_aref(regs, ref);
   VALUE new_regs = red_parse_title(redcloth_link_attributes(self, txt), ref);
   
-  return rb_funcall(regs, rb_intern(&quot;update&quot;), 1, new_regs);
+  return rb_funcall(regs, rb_intern(&quot;merge!&quot;), 1, new_regs);
 }
 
 VALUE</diff>
      <filename>ext/redcloth_scan/redcloth_inline.c.rl</filename>
    </modified>
    <modified>
      <diff>@@ -48,13 +48,13 @@ public class RedclothInline extends RedclothScanService.Base {
   public IRubyObject red_parse_attr(IRubyObject self, IRubyObject regs, IRubyObject ref) {
     IRubyObject txt = ((RubyHash)regs).aref(ref);
     IRubyObject new_regs = RedclothAttributes.attributes(self, txt);
-    return regs.callMethod(runtime.getCurrentContext(), &quot;update&quot;, new_regs);
+    return regs.callMethod(runtime.getCurrentContext(), &quot;merge!&quot;, new_regs);
   }
 
   public IRubyObject red_parse_link_attr(IRubyObject self, IRubyObject regs, IRubyObject ref) {
     IRubyObject txt = ((RubyHash)regs).aref(ref);
     IRubyObject new_regs = red_parse_title(RedclothAttributes.link_attributes(self, txt), ref);
-    return regs.callMethod(runtime.getCurrentContext(), &quot;update&quot;, new_regs);
+    return regs.callMethod(runtime.getCurrentContext(), &quot;merge!&quot;, new_regs);
   }
 
   public IRubyObject red_parse_image_attr(IRubyObject self, IRubyObject regs, IRubyObject ref) {</diff>
      <filename>ext/redcloth_scan/redcloth_inline.java.rl</filename>
    </modified>
    <modified>
      <diff>@@ -109,7 +109,7 @@
     link { PARSE_LINK_ATTR(&quot;name&quot;); PASS(block, &quot;name&quot;, &quot;link&quot;); };
     bracketed_link { PARSE_LINK_ATTR(&quot;name&quot;); PASS(block, &quot;name&quot;, &quot;link&quot;); };
     
-    code { PARSE_ATTR(&quot;text&quot;); PASS_CODE(block, &quot;text&quot;, &quot;code&quot;, opts); };
+    code { PARSE_ATTR(&quot;text&quot;); PASS_CODE(block, &quot;text&quot;, &quot;code&quot;); };
     code_tag_start { CAT(block); fgoto code_tag; };
     notextile { INLINE(block, &quot;notextile&quot;); };
     strong { PARSE_ATTR(&quot;text&quot;); PASS(block, &quot;text&quot;, &quot;strong&quot;); };</diff>
      <filename>ext/redcloth_scan/redcloth_inline.rl</filename>
    </modified>
    <modified>
      <diff>@@ -42,7 +42,6 @@ redcloth_transform(self, p, pe, refs)
   VALUE list_layout = Qnil;
   char *list_type = NULL;
   VALUE list_index = rb_ary_new();
-  int list_continue = 0;
   VALUE plain_block; SET_PLAIN_BLOCK(&quot;p&quot;);
   VALUE extend = Qnil;
   char listm[10] = &quot;&quot;;</diff>
      <filename>ext/redcloth_scan/redcloth_scan.c.rl</filename>
    </modified>
    <modified>
      <diff>@@ -31,6 +31,18 @@ public class RedclothScanService implements BasicLibraryService {
       list_layout = runtime.newArray();
     }
     
+    public void SET_LIST_TYPE(String T) {
+      list_type = T;
+    }
+    
+    public void NEST() {
+      nest ++;
+    }
+    
+    public void RESET_NEST() {
+      nest = 0;
+    }
+    
    public void LIST_ITEM() {
      int aint = 0;
      IRubyObject aval = ((RubyArray)list_index).entry(nest-1);
@@ -41,8 +53,8 @@ public class RedclothScanService implements BasicLibraryService {
 
      if(nest &gt; ((RubyArray)list_layout).getLength()) {
        listm = list_type + &quot;_open&quot;;       
-       if(list_continue == 1) {
-         list_continue = 0;
+       if( !((RubyHash)regs).aref(runtime.newSymbol(&quot;list_continue&quot;)).isNil() ) {
+         ((RubyHash)regs).aset(runtime.newSymbol(&quot;list_continue&quot;), runtime.getNil());
          ((RubyHash)regs).aset(runtime.newSymbol(&quot;start&quot;), ((RubyArray)list_index).entry(nest-1));
        } else {
          IRubyObject start = ((RubyHash)regs).aref(runtime.newSymbol(&quot;start&quot;));
@@ -226,6 +238,14 @@ public class RedclothScanService implements BasicLibraryService {
       reg = -1;
     }
 
+    public void MARK() {
+      reg = p;
+    }
+
+    public void MARK_B() {
+      bck = p;
+    }
+
     public void CAT(IRubyObject H) {
       ((RubyString)H).cat(data, ts, te-ts);
     }
@@ -272,15 +292,15 @@ public class RedclothScanService implements BasicLibraryService {
       red_inc(regs, runtime.newSymbol(T));
     }
 
+    public void INC(int N) {
+      N++;
+    }
+
     public void END_EXTENDED() {
       extend = runtime.getNil();
       CLEAR_REGS();
     }
 
-    public boolean IS_NOT_EXTENDED() {
-      return extend.isNil();
-    }
-
     public void ASET(String T, String V) {
       ((RubyHash)regs).aset(runtime.newSymbol(T), runtime.newString(V));
     }
@@ -326,7 +346,6 @@ public class RedclothScanService implements BasicLibraryService {
     public IRubyObject list_layout;
     public String list_type = null;
     public IRubyObject list_index;
-    public int list_continue = 0;
     public IRubyObject plain_block;
     public IRubyObject extend;
     public String listm = &quot;&quot;;</diff>
      <filename>ext/redcloth_scan/redcloth_scan.java.rl</filename>
    </modified>
    <modified>
      <diff>@@ -16,20 +16,20 @@
   pre_block_start = ( &quot;pre&quot; &gt;A %{ STORE(&quot;type&quot;); } A C :&gt; &quot;.&quot; ( &quot;.&quot; %extend | &quot;&quot; ) &quot; &quot;+ ) ;
   bc_start = ( &quot;bc&quot; &gt;A %{ STORE(&quot;type&quot;); } A C :&gt; &quot;.&quot; ( &quot;.&quot; %extend | &quot;&quot; ) &quot; &quot;+ ) ;
   bq_start = ( &quot;bq&quot; &gt;A %{ STORE(&quot;type&quot;); } A C :&gt; &quot;.&quot; ( &quot;.&quot; %extend | &quot;&quot; ) ( &quot;:&quot; %A uri %{ STORE(&quot;cite&quot;); } )? &quot; &quot;+ ) ;
-  non_ac_btype = ( &quot;bq&quot; | &quot;bc&quot; | &quot;pre&quot; | &quot;notextile&quot; );
+  non_ac_btype = ( &quot;bq&quot; | &quot;bc&quot; | &quot;pre&quot; | &quot;notextile&quot; | &quot;table&quot; );
   btype = (alpha alnum*) -- (non_ac_btype | &quot;fn&quot; digit+);
   block_start = ( btype &gt;A %{ STORE(&quot;type&quot;); } A C :&gt; &quot;.&quot; ( &quot;.&quot; %extend | &quot;&quot; ) &quot; &quot;+ ) &gt;B %{ STORE_B(&quot;fallback&quot;); };
   all_btypes = btype | non_ac_btype;
-  next_block_start = ( all_btypes A_noactions C_noactions :&gt; &quot;.&quot;+ &quot; &quot; ) &gt;A @{ p = reg - 1; } ;
+  next_block_start = ( all_btypes A_noactions C_noactions :&gt; &quot;.&quot;+ &quot; &quot; ) &gt;A @{ fexec(reg); } ;
   double_return = LF [ \t]* LF ;
   block_end = ( double_return | EOF );
   ftype = ( &quot;fn&quot; &gt;A %{ STORE(&quot;type&quot;); } digit+ &gt;A %{ STORE(&quot;id&quot;); } ) ;
   footnote_start = ( ftype A C :&gt; dotspace ) ;
-  ul = &quot;*&quot; %{nest++; list_type = &quot;ul&quot;;};
-  ol = &quot;#&quot; %{nest++; list_type = &quot;ol&quot;;};
+  ul = &quot;*&quot; %{NEST(); SET_LIST_TYPE(&quot;ul&quot;);};
+  ol = &quot;#&quot; %{NEST(); SET_LIST_TYPE(&quot;ol&quot;);};
   ul_start  = ( ul | ol )* ul A C :&gt; &quot; &quot;+   ;
   ol_start  = ( ul | ol )* ol N A C :&gt; &quot; &quot;+ ;
-  list_start  = &quot; &quot;* ( ul_start | ol_start ) &gt;{nest = 0;} ;
+  list_start  = &quot; &quot;* ( ul_start | ol_start ) &gt;{RESET_NEST();} ;
   dt_start = &quot;-&quot; . &quot; &quot;+ ;
   dd_start = &quot;:=&quot; ;
   long_dd  = dd_start &quot; &quot;* LF %{ ADD_BLOCK(); ASET(&quot;type&quot;, &quot;dd&quot;); } any+ &gt;A %{ TRANSFORM(&quot;text&quot;); } :&gt;&gt; &quot;=:&quot; ;
@@ -41,7 +41,7 @@
   # image lookahead
   IMG_A_LEFT = &quot;&lt;&quot; %{ ASET(&quot;float&quot;, &quot;left&quot;); } ;
   IMG_A_RIGHT = &quot;&gt;&quot; %{ ASET(&quot;float&quot;, &quot;right&quot;); } ;
-  aligned_image = ( &quot;[&quot;? &quot;!&quot; (IMG_A_LEFT | IMG_A_RIGHT) ) &gt;A @{ p = reg - 1; } ;
+  aligned_image = ( &quot;[&quot;? &quot;!&quot; (IMG_A_LEFT | IMG_A_RIGHT) ) &gt;A @{ fexec(reg); } ;
   
   # html blocks
   BlockTagName = Name - (&quot;pre&quot; | &quot;notextile&quot; | &quot;a&quot; | &quot;applet&quot; | &quot;basefont&quot; | &quot;bdo&quot; | &quot;br&quot; | &quot;font&quot; | &quot;iframe&quot; | &quot;img&quot; | &quot;map&quot; | &quot;object&quot; | &quot;param&quot; | &quot;embed&quot; | &quot;q&quot; | &quot;script&quot; | &quot;span&quot; | &quot;sub&quot; | &quot;sup&quot; | &quot;abbr&quot; | &quot;acronym&quot; | &quot;cite&quot; | &quot;code&quot; | &quot;del&quot; | &quot;dfn&quot; | &quot;em&quot; | &quot;ins&quot; | &quot;kbd&quot; | &quot;samp&quot; | &quot;strong&quot; | &quot;var&quot; | &quot;b&quot; | &quot;big&quot; | &quot;i&quot; | &quot;s&quot; | &quot;small&quot; | &quot;strike&quot; | &quot;tt&quot; | &quot;u&quot;);
@@ -51,7 +51,7 @@
   html_start = indent &gt;B %{STORE_B(&quot;indent_before_start&quot;);} block_start_tag &gt;B %{STORE_B(&quot;start_tag&quot;);}  indent &gt;B %{STORE_B(&quot;indent_after_start&quot;);} ;
   html_end = indent &gt;B %{STORE_B(&quot;indent_before_end&quot;);} block_end_tag &gt;B %{STORE_B(&quot;end_tag&quot;);} (indent LF?) &gt;B %{STORE_B(&quot;indent_after_end&quot;);} ;
   standalone_html = indent (block_start_tag | block_empty_tag | block_end_tag) indent (LF+ | EOF);
-  html_end_terminating_block = ( LF indent block_end_tag ) &gt;A @{ p = reg - 1; } ;
+  html_end_terminating_block = ( LF indent block_end_tag ) &gt;A @{ fexec(reg); } ;
 
   # tables
   para = ( default+ ) -- LF ;
@@ -73,28 +73,11 @@
   *|;
   
   pre_block := |*
-    EOF { 
-      ADD_BLOCKCODE(); 
-      fgoto main; 
-    };
-    double_return { 
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCKCODE(); 
-        fgoto main; 
-      } else { 
-        ADD_EXTENDED_BLOCKCODE(); 
-      } 
-    };
-    double_return next_block_start { 
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCKCODE(); 
-        fgoto main; 
-      } else { 
-        ADD_EXTENDED_BLOCKCODE(); 
-        END_EXTENDED(); 
-        fgoto main; 
-      } 
-    };
+    EOF { ADD_BLOCKCODE(); fgoto main; };
+    double_return when extended { ADD_EXTENDED_BLOCKCODE(); };
+    double_return when not_extended { ADD_BLOCKCODE(); fgoto main; } ;
+    double_return next_block_start when extended { ADD_EXTENDED_BLOCKCODE(); END_EXTENDED(); fgoto main; };
+    double_return next_block_start when not_extended { ADD_BLOCKCODE(); fgoto main; };
     default =&gt; esc_pre;
   *|;
 
@@ -110,33 +93,11 @@
   *|;
   
   notextile_block := |*
-    EOF {
-      ADD_BLOCK();
-      fgoto main;
-    };
-    double_return {
-      if (IS_NOT_EXTENDED()) {
-        ADD_BLOCK();
-        CAT(html);
-        fgoto main;
-      } else {
-        CAT(block);
-        ADD_EXTENDED_BLOCK();
-        CAT(html);
-      }
-    };
-    double_return next_block_start {
-      if (IS_NOT_EXTENDED()) {
-        ADD_BLOCK();
-        CAT(html);
-        fgoto main;
-      } else {
-        CAT(block);
-        ADD_EXTENDED_BLOCK();
-        END_EXTENDED();
-        fgoto main; 
-      } 
-    };
+    EOF { ADD_BLOCK(); fgoto main; };
+    double_return when extended { CAT(block); ADD_EXTENDED_BLOCK(); CAT(html); };
+    double_return when not_extended { ADD_BLOCK(); CAT(html); fgoto main; } ;
+    double_return next_block_start when extended { CAT(block); ADD_EXTENDED_BLOCK(); END_EXTENDED(); fgoto main; };
+    double_return next_block_start when not_extended { ADD_BLOCK(); CAT(html); fgoto main; };
     default =&gt; cat;
   *|;
  
@@ -146,123 +107,34 @@
   *|;
 
   bc := |*
-    EOF { 
-      ADD_BLOCKCODE(); 
-      INLINE(html, &quot;bc_close&quot;); 
-      SET_PLAIN_BLOCK(&quot;p&quot;);
-      fgoto main;
-    };
-    double_return { 
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCKCODE(); 
-        INLINE(html, &quot;bc_close&quot;); 
-        SET_PLAIN_BLOCK(&quot;p&quot;);
-        fgoto main; 
-      } else { 
-        ADD_EXTENDED_BLOCKCODE(); 
-        CAT(html); 
-      } 
-    };
-    double_return next_block_start { 
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCKCODE(); 
-        INLINE(html, &quot;bc_close&quot;); 
-        SET_PLAIN_BLOCK(&quot;p&quot;);
-        fgoto main; 
-      } else { 
-        ADD_EXTENDED_BLOCKCODE(); 
-        CAT(html); 
-        RSTRIP_BANG(html);
-        INLINE(html, &quot;bc_close&quot;); 
-        SET_PLAIN_BLOCK(&quot;p&quot;);
-        END_EXTENDED(); 
-        fgoto main; 
-      } 
-    };
+    EOF {  ADD_BLOCKCODE();  INLINE(html, &quot;bc_close&quot;);  SET_PLAIN_BLOCK(&quot;p&quot;); fgoto main; };
+    double_return when extended { ADD_EXTENDED_BLOCKCODE(); CAT(html); };
+    double_return when not_extended { ADD_BLOCKCODE(); INLINE(html, &quot;bc_close&quot;); SET_PLAIN_BLOCK(&quot;p&quot;); fgoto main; };
+    double_return next_block_start when extended { ADD_EXTENDED_BLOCKCODE(); CAT(html); RSTRIP_BANG(html); INLINE(html, &quot;bc_close&quot;); SET_PLAIN_BLOCK(&quot;p&quot;); END_EXTENDED(); fgoto main; };
+    double_return next_block_start when not_extended { ADD_BLOCKCODE(); INLINE(html, &quot;bc_close&quot;); SET_PLAIN_BLOCK(&quot;p&quot;); fgoto main; };
     default =&gt; esc_pre;
   *|;
 
   bq := |*
-    EOF { 
-      ADD_BLOCK(); 
-      INLINE(html, &quot;bq_close&quot;); 
-      fgoto main; 
-    };
-    double_return { 
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCK(); 
-        INLINE(html, &quot;bq_close&quot;); 
-        fgoto main; 
-      } else { 
-        ADD_EXTENDED_BLOCK(); 
-      } 
-    };
-    double_return next_block_start { 
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCK(); 
-        INLINE(html, &quot;bq_close&quot;); 
-        fgoto main; 
-      } else {
-        ADD_EXTENDED_BLOCK(); 
-        INLINE(html, &quot;bq_close&quot;); 
-        END_EXTENDED(); 
-        fgoto main; 
-      }
-    };
-    html_end_terminating_block { 
-        if (IS_NOT_EXTENDED()) { 
-          ADD_BLOCK(); 
-          INLINE(html, &quot;bq_close&quot;); 
-          fgoto main; 
-        } else {
-          ADD_EXTENDED_BLOCK(); 
-          INLINE(html, &quot;bq_close&quot;); 
-          END_EXTENDED(); 
-          fgoto main; 
-        }
-      };
+    EOF { ADD_BLOCK(); INLINE(html, &quot;bq_close&quot;); fgoto main; };
+    double_return when extended { ADD_EXTENDED_BLOCK(); };
+    double_return when not_extended { ADD_BLOCK(); INLINE(html, &quot;bq_close&quot;); fgoto main; };
+    double_return next_block_start when extended { ADD_EXTENDED_BLOCK(); INLINE(html, &quot;bq_close&quot;); END_EXTENDED(); fgoto main; };
+    double_return next_block_start when not_extended { ADD_BLOCK(); INLINE(html, &quot;bq_close&quot;); fgoto main; };
+    html_end_terminating_block when extended { ADD_EXTENDED_BLOCK(); INLINE(html, &quot;bq_close&quot;); END_EXTENDED(); fgoto main; };
+    html_end_terminating_block when not_extended { ADD_BLOCK(); INLINE(html, &quot;bq_close&quot;); fgoto main; };
     default =&gt; cat;
   *|;
 
   block := |*
-    EOF { 
-      ADD_BLOCK(); 
-      fgoto main;
-    };
-    double_return {
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCK(); 
-        fgoto main; 
-      } else { 
-        ADD_EXTENDED_BLOCK(); 
-      } 
-    };
-    double_return next_block_start { 
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCK(); 
-        fgoto main; 
-      } else { 
-        ADD_EXTENDED_BLOCK(); 
-        END_EXTENDED(); 
-        fgoto main; 
-      }      
-    };
-    html_end_terminating_block { 
-      if (IS_NOT_EXTENDED()) { 
-        ADD_BLOCK(); 
-        fgoto main; 
-      } else { 
-        ADD_EXTENDED_BLOCK(); 
-        END_EXTENDED(); 
-        fgoto main; 
-      }      
-    };
-    LF list_start { 
-      ADD_BLOCK(); 
-      CLEAR_LIST(); 
-      LIST_ITEM(); 
-      fgoto list; 
-    };
+    EOF { ADD_BLOCK(); fgoto main; };
+    double_return when extended { ADD_EXTENDED_BLOCK(); };
+    double_return when not_extended { ADD_BLOCK(); fgoto main; };
+    double_return next_block_start when extended { ADD_EXTENDED_BLOCK(); END_EXTENDED(); fgoto main; };
+    double_return next_block_start when not_extended { ADD_BLOCK(); fgoto main; };
+    html_end_terminating_block when extended { ADD_EXTENDED_BLOCK(); END_EXTENDED(); fgoto main; };
+    html_end_terminating_block when not_extended { ADD_BLOCK(); fgoto main; };
+    LF list_start { ADD_BLOCK(); CLEAR_LIST(); LIST_ITEM(); fgoto list; };
     
     default =&gt; cat;
   *|;
@@ -274,7 +146,7 @@
 
   list := |*
     LF list_start   { ADD_BLOCK(); LIST_ITEM(); };
-    block_end       { ADD_BLOCK(); nest = 0; LIST_CLOSE(); fgoto main; };
+    block_end       { ADD_BLOCK(); RESET_NEST(); LIST_CLOSE(); fgoto main; };
     default =&gt; cat;
   *|;
 
@@ -301,7 +173,7 @@
     footnote_start  { fgoto footnote; };
     horizontal_rule { INLINE(html, &quot;hr&quot;); };
     list_start      { CLEAR_LIST(); LIST_ITEM(); fgoto list; };
-    dl_start        { p = ts; INLINE(html, &quot;dl_open&quot;); ASET(&quot;type&quot;, &quot;dt&quot;); fgoto dl; };
+    dl_start        { fexec(ts + 1); INLINE(html, &quot;dl_open&quot;); ASET(&quot;type&quot;, &quot;dt&quot;); fgoto dl; };
     table           { INLINE(table, &quot;table_close&quot;); DONE(table); fgoto block; };
     link_alias      { STORE_LINK_ALIAS(); DONE(block); };
     aligned_image   { RESET_TYPE(); fgoto block; };</diff>
      <filename>ext/redcloth_scan/redcloth_scan.rl</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ class RagelProfiler
   COMMANDS =  { :compile =&gt; %w(ragel rlgen-cd gcc-4.0 gnumake cc1),
                 :test    =&gt; %w(ruby) }
                 
-  FIELDS = %w(compile_time compile_max_rss test_time test_max_rss ext_so_size)
+  FIELDS = %w(compile_time compile_max_rss test_time test_max_rss file_size)
                 
   @@results = {}
 
@@ -32,8 +32,8 @@ class RagelProfiler
     store_result(type, &quot;max_rss&quot;, t[:max])
   end
   
-  def ext_size(ext_so)
-    store_result(:ext_so, &quot;size&quot;, File.size(ext_so) / MEM_CONVERSION)
+  def ext_size(file)
+    store_result(:file, &quot;size&quot;, File.size(file) / MEM_CONVERSION)
   end
   
   def self.results</diff>
      <filename>extras/ragel_profiler.rb</filename>
    </modified>
    <modified>
      <diff>@@ -267,7 +267,12 @@ module RedCloth::Formatters::LATEX
     period = opts[:text].slice!(/\.$/)
     &quot;$#{opts[:text]}$#{period}&quot;
   end
-
+  
+  # TODO: what do we do with HTML?
+  def inline_html(opts)
+    opts[:text] || &quot;&quot;
+  end
+  
   private
 
   def escape(text)</diff>
      <filename>lib/redcloth/formatters/latex.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>0142eb1eea0f723e8710b37851d58b2b6301bc51</id>
    </parent>
  </parents>
  <author>
    <name>Jason Garber</name>
    <email>jg@jasongarber.com</email>
  </author>
  <url>http://github.com/jgarber/redcloth/commit/11f8f8a799afa537715c1abd931ba86a4036f3ab</url>
  <id>11f8f8a799afa537715c1abd931ba86a4036f3ab</id>
  <committed-date>2009-03-16T13:18:56-07:00</committed-date>
  <authored-date>2009-03-16T13:18:56-07:00</authored-date>
  <message>Added a pure-ruby version of the parser for times when you can't compile the C or Java extensions.  You should avoid using it if at all possible because it is 32 times slower (and has some other problems, too)!

Squashed commit of the following:

commit d82359a74e543a6c25f5783983926c117045e0bb
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Mon Mar 16 14:44:20 2009 -0400

    Update with best code style for pureruby (result of optimization was F1)

commit aa01f61fb075a50d44c29f0831c6b2cb3ee90bee
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Mon Mar 16 13:17:32 2009 -0400

    Fix latex double-escaping some characters in pureruby parser

commit 7a09a7c25b2087d9b6f658b3d57443668cc41ef8
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Mon Mar 16 09:08:08 2009 -0400

    Update profiler so rake pureruby optimize works

commit ffd93efc1228be4e245bde536518f60bd47aa6be
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 12:26:46 2009 -0400

    cleanup unneeded eof variable

commit dc1b0f89d1ff868c285ad1d0eaa2e494757950ea
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 11:46:30 2009 -0400

    Fix custom tag fallback

commit e10c378f57a232915efc42f8d78859aae55b7a0a
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 11:35:41 2009 -0400

    Fixed attributes getting escaped multiple times because of passing by reference

commit 20c50513f521299d1917fcefa7fb2aaaf149117e
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 11:13:12 2009 -0400

    fix list continuation (hope JRuby works; can't test from this machine)

commit 5000560e28945910d41b580bd3bb01fb75167536
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 10:31:03 2009 -0400

    Fix attribute parser running the wrong machine

commit 71d7f9d1c0fcd654b39c41de3a341e8f6d95c400
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 10:12:03 2009 -0400

    Fix TRANSFORM macro

commit 9824be7410ef9224c80227105059e732f9a908a3
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 10:02:42 2009 -0400

    Fixed comparison error when @reg was not set

commit 0f32766aa906bad9514198eab9694cee369d7cd5
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 09:43:56 2009 -0400

    Fix backup attributes not being set in regs properly.

commit 65a45406a8b81b2be5c43b8fb172b6129214e9d4
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 09:16:07 2009 -0400

    Fixed definition lists

commit 8441dc220d351264f6f7357eb681402d17d4e0fe
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 08:55:35 2009 -0400

    Fix capture of title/alt

commit c6b44a228c5d248e91fefa61da7da350279d10a3
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 08:27:59 2009 -0400

    Fix ignore action

commit 091fb62632ce21ef75fbd3575a185c7427461aa8
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Sun Mar 15 03:04:35 2009 -0400

    Fixed lists and lookaheads, among other things.

commit 6d38837050d593db29d40d059e884ea3e0fd5b21
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Fri Mar 13 16:41:20 2009 -0400

    Fix it up just a bit.

commit 96a54a7188c73c670d11e75e4177de4a39e944bb
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Fri Mar 13 15:36:27 2009 -0400

    Switch back to instances, but with class methods for invoking.  Nearly working now.

commit 2437f528ffc5ca1f30f9774c2c8fe025e6216468
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Thu Mar 12 17:16:34 2009 -0400

    Converted scanners to class methods &amp; class variables. Nearly works.

commit 3d7c554e7cfca60c7f7a1fcc69b1cbfce54038d6
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Thu Mar 12 14:32:51 2009 -0400

    Almost working.  Maybe should convert them to class methods, though.

commit c375474f4f2773458cb0b4b50c6ea5c3a49cca71
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Tue Mar 10 16:42:32 2009 -0400

    Convert the rest to ruby and hook lots of things up.  Still not working, though.

commit 1b379c147b0b90aa314117014308f3d215b1c3b0
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Mon Mar 9 12:32:53 2009 -0400

    wip

commit 3393bb4a9a0e59cb2455f68844e93b9ec4ba82b2
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Mon Mar 9 09:31:47 2009 -0400

    wip (15 minutes)

commit ebfbe336bff92ec85fa7d7a5602f4670b5598606
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Fri Mar 6 08:22:50 2009 -0500

    Add files that were missing before.  WIP on parser macros. (15 min)

commit e7a92338f3c2417b763bb9f8c8e75a733bb453f7
Author: Jason Garber &lt;jg@jasongarber.com&gt;
Date:   Fri Mar 6 08:10:46 2009 -0500

    Converted everything to pure Ruby.  Haven't tested yet, though. (100 minutes)</message>
  <tree>ffd69a99d13366634bf886ee775bc3fcaf5e923e</tree>
  <committer>
    <name>Jason Garber</name>
    <email>jg@jasongarber.com</email>
  </committer>
</commit>
