From fecf23b1643346f13a2fcf2d562063c36ec23109 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Thu, 4 Jul 2013 17:04:43 +0200
Subject: [PATCH 01/21] Ignore swp files.

---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index 94424fbc..8d585992 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ tmp
 example/docs
 example/public/docs
 *.gem
+*.swp

From 842a9756c417ccb1f49185ef3500c7afa2dc1ccb Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Fri, 5 Jul 2013 15:02:49 +0200
Subject: [PATCH 02/21] Generate api docs in json, combined_text and html.

---
 example/spec/spec_helper.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/example/spec/spec_helper.rb b/example/spec/spec_helper.rb
index 868d2fb1..f617c197 100644
--- a/example/spec/spec_helper.rb
+++ b/example/spec/spec_helper.rb
@@ -33,7 +33,7 @@
 end
 
 RspecApiDocumentation.configure do |config|
-  config.format = [:json, :combined_text]
+  config.format = [:json, :combined_text, :html]
   config.curl_host = 'http://localhost:3000'
   config.api_name = "Example App API"
 end

From 397bd37758e5ff0606ed70a4cb45ca3f7c159c9e Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Fri, 5 Jul 2013 15:03:01 +0200
Subject: [PATCH 03/21] Added a GeneralMarkupWriter class as parent of
 HtmlWriter to prepare Textile and Markdown writers.

---
 lib/rspec_api_documentation.rb                |  1 +
 .../writers/general_markup_writer.rb          | 44 +++++++++++++++++++
 .../writers/html_writer.rb                    | 27 ++++--------
 3 files changed, 54 insertions(+), 18 deletions(-)
 create mode 100644 lib/rspec_api_documentation/writers/general_markup_writer.rb

diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb
index 23124a7b..a0b04241 100644
--- a/lib/rspec_api_documentation.rb
+++ b/lib/rspec_api_documentation.rb
@@ -28,6 +28,7 @@ module RspecApiDocumentation
   module Writers
     extend ActiveSupport::Autoload
 
+    autoload :GeneralMarkupWriter
     autoload :HtmlWriter
     autoload :JsonWriter
     autoload :JsonIodocsWriter
diff --git a/lib/rspec_api_documentation/writers/general_markup_writer.rb b/lib/rspec_api_documentation/writers/general_markup_writer.rb
new file mode 100644
index 00000000..2c0d5615
--- /dev/null
+++ b/lib/rspec_api_documentation/writers/general_markup_writer.rb
@@ -0,0 +1,44 @@
+require 'mustache'
+
+module RspecApiDocumentation
+  module Writers
+    class GeneralMarkupWriter
+      attr_accessor :index, :configuration
+
+      INDEX_FILE_NAME = 'index'
+      
+      def initialize(index, configuration)
+        self.index = index
+        self.configuration = configuration
+      end
+
+      def self.write(index, configuration)
+        writer = new(index, configuration)
+        writer.write
+      end
+      
+      def write
+        File.open(configuration.docs_dir.join(index_file_name + '.' + extension), "w+") do |f|
+          f.write markup_index_class.new(index, configuration).render
+        end
+
+        index.examples.each do |example|
+          markup_example = markup_example_class.new(example, configuration)
+          FileUtils.mkdir_p(configuration.docs_dir.join(markup_example.dirname))
+
+          File.open(configuration.docs_dir.join(markup_example.dirname, markup_example.filename), "w+") do |f|
+            f.write markup_example.render
+          end
+        end
+      end
+
+      def index_file_name
+        INDEX_FILE_NAME
+      end
+
+      def extension
+        raise 'Parent class. This method should not be called.'
+      end
+    end
+  end
+end
diff --git a/lib/rspec_api_documentation/writers/html_writer.rb b/lib/rspec_api_documentation/writers/html_writer.rb
index 2728ddb1..5fc9940b 100644
--- a/lib/rspec_api_documentation/writers/html_writer.rb
+++ b/lib/rspec_api_documentation/writers/html_writer.rb
@@ -2,30 +2,21 @@
 
 module RspecApiDocumentation
   module Writers
-    class HtmlWriter
+    class HtmlWriter < GeneralMarkupWriter
       attr_accessor :index, :configuration
 
-      def initialize(index, configuration)
-        self.index = index
-        self.configuration = configuration
+      EXTENSION = 'html'
+
+      def markup_index_class
+        HtmlIndex
       end
 
-      def self.write(index, configuration)
-        writer = new(index, configuration)
-        writer.write
+      def markup_example_class
+        HtmlExample
       end
 
-      def write
-        File.open(configuration.docs_dir.join("index.html"), "w+") do |f|
-          f.write HtmlIndex.new(index, configuration).render
-        end
-        index.examples.each do |example|
-          html_example = HtmlExample.new(example, configuration)
-          FileUtils.mkdir_p(configuration.docs_dir.join(html_example.dirname))
-          File.open(configuration.docs_dir.join(html_example.dirname, html_example.filename), "w+") do |f|
-            f.write html_example.render
-          end
-        end
+      def extension
+        EXTENSION
       end
     end
 

From c789f44ea05be5308ca2639f5a2678f62ce1ee1e Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Fri, 5 Jul 2013 16:28:03 +0200
Subject: [PATCH 04/21] Moved HtmlIndex and HtmlExample to a dedicated module
 Views.

---
 lib/rspec_api_documentation.rb                |  7 ++
 .../views/html_example.rb                     | 54 +++++++++++++
 .../views/html_index.rb                       | 26 +++++++
 .../writers/general_markup_writer.rb          |  2 -
 .../writers/html_writer.rb                    | 76 +------------------
 spec/views/html_example_spec.rb               | 24 ++++++
 spec/writers/html_writer_spec.rb              | 21 -----
 7 files changed, 113 insertions(+), 97 deletions(-)
 create mode 100644 lib/rspec_api_documentation/views/html_example.rb
 create mode 100644 lib/rspec_api_documentation/views/html_index.rb
 create mode 100644 spec/views/html_example_spec.rb

diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb
index a0b04241..a1bd9de5 100644
--- a/lib/rspec_api_documentation.rb
+++ b/lib/rspec_api_documentation.rb
@@ -37,6 +37,13 @@ module Writers
     autoload :CombinedJsonWriter
   end
 
+  module Views
+    extend ActiveSupport::Autoload
+
+    autoload :HtmlIndex
+    autoload :HtmlExample
+  end
+
   def self.configuration
     @configuration ||= Configuration.new
   end
diff --git a/lib/rspec_api_documentation/views/html_example.rb b/lib/rspec_api_documentation/views/html_example.rb
new file mode 100644
index 00000000..188bc936
--- /dev/null
+++ b/lib/rspec_api_documentation/views/html_example.rb
@@ -0,0 +1,54 @@
+require 'mustache'
+
+module RspecApiDocumentation
+  module Views
+    class HtmlExample < Mustache
+      def initialize(example, configuration)
+        @example = example
+        @host = configuration.curl_host
+        self.template_path = configuration.template_path
+        self.template_name = "rspec_api_documentation/html_example"
+      end
+
+      def method_missing(method, *args, &block)
+        @example.send(method, *args, &block)
+      end
+
+      def respond_to?(method, include_private = false)
+        super || @example.respond_to?(method, include_private)
+      end
+
+      def dirname
+        resource_name.downcase.gsub(/\s+/, '_')
+      end
+
+      def filename
+        basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
+        basename = Digest::MD5.new.update(description).to_s if basename.blank?
+        "#{basename}.html"
+      end
+
+      def requests
+        super.map do |hash|
+          hash[:request_headers_text] = format_hash(hash[:request_headers])
+          hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters])
+          hash[:response_headers_text] = format_hash(hash[:response_headers])
+          if @host
+            hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
+          else
+            hash[:curl] = nil
+          end
+          hash
+        end
+      end
+
+      private
+      def format_hash(hash = {})
+        return nil unless hash.present?
+        hash.collect do |k, v|
+          "#{k}: #{v}"
+        end.join("\n")
+      end
+    end
+  end
+end
diff --git a/lib/rspec_api_documentation/views/html_index.rb b/lib/rspec_api_documentation/views/html_index.rb
new file mode 100644
index 00000000..a01fa1ff
--- /dev/null
+++ b/lib/rspec_api_documentation/views/html_index.rb
@@ -0,0 +1,26 @@
+require 'mustache'
+
+module RspecApiDocumentation
+  module Views
+    class HtmlIndex < Mustache
+      def initialize(index, configuration)
+        @index = index
+        @configuration = configuration
+        self.template_path = configuration.template_path
+        self.template_name = "rspec_api_documentation/html_index"
+      end
+
+      def api_name
+        @configuration.api_name
+      end
+
+      def sections
+        RspecApiDocumentation::Writers::IndexWriter.sections(examples, @configuration)
+      end
+
+      def examples
+        @index.examples.map { |example| HtmlExample.new(example, @configuration) }
+      end
+    end
+  end
+end
diff --git a/lib/rspec_api_documentation/writers/general_markup_writer.rb b/lib/rspec_api_documentation/writers/general_markup_writer.rb
index 2c0d5615..93c94d05 100644
--- a/lib/rspec_api_documentation/writers/general_markup_writer.rb
+++ b/lib/rspec_api_documentation/writers/general_markup_writer.rb
@@ -1,5 +1,3 @@
-require 'mustache'
-
 module RspecApiDocumentation
   module Writers
     class GeneralMarkupWriter
diff --git a/lib/rspec_api_documentation/writers/html_writer.rb b/lib/rspec_api_documentation/writers/html_writer.rb
index 5fc9940b..32348a95 100644
--- a/lib/rspec_api_documentation/writers/html_writer.rb
+++ b/lib/rspec_api_documentation/writers/html_writer.rb
@@ -1,5 +1,3 @@
-require 'mustache'
-
 module RspecApiDocumentation
   module Writers
     class HtmlWriter < GeneralMarkupWriter
@@ -8,86 +6,16 @@ class HtmlWriter < GeneralMarkupWriter
       EXTENSION = 'html'
 
       def markup_index_class
-        HtmlIndex
+        RspecApiDocumentation::Views::HtmlIndex
       end
 
       def markup_example_class
-        HtmlExample
+        RspecApiDocumentation::Views::HtmlExample
       end
 
       def extension
         EXTENSION
       end
     end
-
-    class HtmlIndex < Mustache
-      def initialize(index, configuration)
-        @index = index
-        @configuration = configuration
-        self.template_path = configuration.template_path
-        self.template_name = "rspec_api_documentation/html_index"
-      end
-
-      def api_name
-        @configuration.api_name
-      end
-
-      def sections
-        IndexWriter.sections(examples, @configuration)
-      end
-
-      def examples
-        @index.examples.map { |example| HtmlExample.new(example, @configuration) }
-      end
-    end
-
-    class HtmlExample < Mustache
-      def initialize(example, configuration)
-        @example = example
-        @host = configuration.curl_host
-        self.template_path = configuration.template_path
-        self.template_name = "rspec_api_documentation/html_example"
-      end
-
-      def method_missing(method, *args, &block)
-        @example.send(method, *args, &block)
-      end
-
-      def respond_to?(method, include_private = false)
-        super || @example.respond_to?(method, include_private)
-      end
-
-      def dirname
-        resource_name.downcase.gsub(/\s+/, '_')
-      end
-
-      def filename
-        basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
-        basename = Digest::MD5.new.update(description).to_s if basename.blank?
-        "#{basename}.html"
-      end
-
-      def requests
-        super.map do |hash|
-          hash[:request_headers_text] = format_hash(hash[:request_headers])
-          hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters])
-          hash[:response_headers_text] = format_hash(hash[:response_headers])
-          if @host
-            hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
-          else
-            hash[:curl] = nil
-          end
-          hash
-        end
-      end
-
-      private
-      def format_hash(hash = {})
-        return nil unless hash.present?
-        hash.collect do |k, v|
-          "#{k}: #{v}"
-        end.join("\n")
-      end
-    end
   end
 end
diff --git a/spec/views/html_example_spec.rb b/spec/views/html_example_spec.rb
new file mode 100644
index 00000000..98c85d8c
--- /dev/null
+++ b/spec/views/html_example_spec.rb
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+require 'spec_helper'
+
+describe RspecApiDocumentation::Views::HtmlExample do
+  let(:metadata) { {} }
+  let(:group) { RSpec::Core::ExampleGroup.describe("Orders", metadata) }
+  let(:example) { group.example("Ordering a cup of coffee") {} }
+  let(:configuration) { RspecApiDocumentation::Configuration.new }
+  let(:html_example) { described_class.new(example, configuration) }
+
+  it "should have downcased filename" do
+    html_example.filename.should == "ordering_a_cup_of_coffee.html"
+  end
+
+  describe "multi charctor example name" do
+    let(:label) { "コーヒーが順番で並んでいること" }
+    let(:example) { group.example(label) {} }
+
+    it "should have downcased filename" do
+      filename = Digest::MD5.new.update(label).to_s
+      html_example.filename.should == filename + ".html"
+    end
+  end
+end
diff --git a/spec/writers/html_writer_spec.rb b/spec/writers/html_writer_spec.rb
index 89eaeafb..c4ccfb20 100644
--- a/spec/writers/html_writer_spec.rb
+++ b/spec/writers/html_writer_spec.rb
@@ -33,24 +33,3 @@
   end
 end
 
-describe RspecApiDocumentation::Writers::HtmlExample do
-  let(:metadata) { {} }
-  let(:group) { RSpec::Core::ExampleGroup.describe("Orders", metadata) }
-  let(:example) { group.example("Ordering a cup of coffee") {} }
-  let(:configuration) { RspecApiDocumentation::Configuration.new }
-  let(:html_example) { described_class.new(example, configuration) }
-
-  it "should have downcased filename" do
-    html_example.filename.should == "ordering_a_cup_of_coffee.html"
-  end
-
-  describe "multi charctor example name" do
-    let(:label) { "コーヒーが順番で並んでいること" }
-    let(:example) { group.example(label) {} }
-
-    it "should have downcased filename" do
-      filename = Digest::MD5.new.update(label).to_s
-      html_example.filename.should == filename + ".html"
-    end
-  end
-end

From 6174372e24360feca318e88586518d81c376dbb1 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Fri, 5 Jul 2013 16:56:17 +0200
Subject: [PATCH 05/21] Added MarkupIndex and MarkupExample for views as parent
 of HtmlIndex and HtmlExample.

---
 lib/rspec_api_documentation.rb                |  2 +
 .../views/html_example.rb                     | 50 ++--------------
 .../views/html_index.rb                       | 20 +------
 .../views/markup_example.rb                   | 58 +++++++++++++++++++
 .../views/markup_index.rb                     | 25 ++++++++
 5 files changed, 93 insertions(+), 62 deletions(-)
 create mode 100644 lib/rspec_api_documentation/views/markup_example.rb
 create mode 100644 lib/rspec_api_documentation/views/markup_index.rb

diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb
index a1bd9de5..9961841b 100644
--- a/lib/rspec_api_documentation.rb
+++ b/lib/rspec_api_documentation.rb
@@ -40,6 +40,8 @@ module Writers
   module Views
     extend ActiveSupport::Autoload
 
+    autoload :MarkupIndex
+    autoload :MarkupExample
     autoload :HtmlIndex
     autoload :HtmlExample
   end
diff --git a/lib/rspec_api_documentation/views/html_example.rb b/lib/rspec_api_documentation/views/html_example.rb
index 188bc936..6b0f6009 100644
--- a/lib/rspec_api_documentation/views/html_example.rb
+++ b/lib/rspec_api_documentation/views/html_example.rb
@@ -1,53 +1,15 @@
-require 'mustache'
-
 module RspecApiDocumentation
   module Views
-    class HtmlExample < Mustache
+    class HtmlExample < MarkupExample
+      EXTENSION = 'html'
+
       def initialize(example, configuration)
-        @example = example
-        @host = configuration.curl_host
-        self.template_path = configuration.template_path
+        super
         self.template_name = "rspec_api_documentation/html_example"
       end
 
-      def method_missing(method, *args, &block)
-        @example.send(method, *args, &block)
-      end
-
-      def respond_to?(method, include_private = false)
-        super || @example.respond_to?(method, include_private)
-      end
-
-      def dirname
-        resource_name.downcase.gsub(/\s+/, '_')
-      end
-
-      def filename
-        basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
-        basename = Digest::MD5.new.update(description).to_s if basename.blank?
-        "#{basename}.html"
-      end
-
-      def requests
-        super.map do |hash|
-          hash[:request_headers_text] = format_hash(hash[:request_headers])
-          hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters])
-          hash[:response_headers_text] = format_hash(hash[:response_headers])
-          if @host
-            hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
-          else
-            hash[:curl] = nil
-          end
-          hash
-        end
-      end
-
-      private
-      def format_hash(hash = {})
-        return nil unless hash.present?
-        hash.collect do |k, v|
-          "#{k}: #{v}"
-        end.join("\n")
+      def extension
+        EXTENSION
       end
     end
   end
diff --git a/lib/rspec_api_documentation/views/html_index.rb b/lib/rspec_api_documentation/views/html_index.rb
index a01fa1ff..c4f8a8bd 100644
--- a/lib/rspec_api_documentation/views/html_index.rb
+++ b/lib/rspec_api_documentation/views/html_index.rb
@@ -1,26 +1,10 @@
-require 'mustache'
-
 module RspecApiDocumentation
   module Views
-    class HtmlIndex < Mustache
+    class HtmlIndex < MarkupIndex
       def initialize(index, configuration)
-        @index = index
-        @configuration = configuration
-        self.template_path = configuration.template_path
+        super
         self.template_name = "rspec_api_documentation/html_index"
       end
-
-      def api_name
-        @configuration.api_name
-      end
-
-      def sections
-        RspecApiDocumentation::Writers::IndexWriter.sections(examples, @configuration)
-      end
-
-      def examples
-        @index.examples.map { |example| HtmlExample.new(example, @configuration) }
-      end
     end
   end
 end
diff --git a/lib/rspec_api_documentation/views/markup_example.rb b/lib/rspec_api_documentation/views/markup_example.rb
new file mode 100644
index 00000000..6f9c72cb
--- /dev/null
+++ b/lib/rspec_api_documentation/views/markup_example.rb
@@ -0,0 +1,58 @@
+require 'mustache'
+
+module RspecApiDocumentation
+  module Views
+    class MarkupExample < Mustache
+      def initialize(example, configuration)
+        @example = example
+        @host = configuration.curl_host
+        self.template_path = configuration.template_path
+      end
+      
+      def method_missing(method, *args, &block)
+        @example.send(method, *args, &block)
+      end
+
+      def respond_to?(method, include_private = false)
+        super || @example.respond_to?(method, include_private)
+      end
+
+      def dirname
+        resource_name.downcase.gsub(/\s+/, '_')
+      end
+      
+      def filename
+        basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
+        basename = Digest::MD5.new.update(description).to_s if basename.blank?
+        "#{basename}.#{extension}"
+      end
+      
+      def requests
+        super.map do |hash|
+          hash[:request_headers_text] = format_hash(hash[:request_headers])
+          hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters])
+          hash[:response_headers_text] = format_hash(hash[:response_headers])
+          if @host
+            hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
+          else
+            hash[:curl] = nil
+          end
+          hash
+        end
+      end
+      
+      def extension
+        raise 'Parent class. This method should not be called.'
+      end
+
+      private
+
+      def format_hash(hash = {})
+        return nil unless hash.present?
+        hash.collect do |k, v|
+          "#{k}: #{v}"
+        end.join("\n")
+      end
+    end
+  end
+end
diff --git a/lib/rspec_api_documentation/views/markup_index.rb b/lib/rspec_api_documentation/views/markup_index.rb
new file mode 100644
index 00000000..b0a3646b
--- /dev/null
+++ b/lib/rspec_api_documentation/views/markup_index.rb
@@ -0,0 +1,25 @@
+require 'mustache'
+
+module RspecApiDocumentation
+  module Views
+    class MarkupIndex < Mustache
+      def initialize(index, configuration)
+        @index = index
+        @configuration = configuration
+        self.template_path = configuration.template_path
+      end
+      
+      def api_name
+        @configuration.api_name
+      end
+
+      def sections
+        RspecApiDocumentation::Writers::IndexWriter.sections(examples, @configuration)
+      end
+
+      def examples
+        @index.examples.map { |example| HtmlExample.new(example, @configuration) }
+      end
+    end
+  end
+end

From 1a74b2aa6cf3fbb31052c86b006097fc4156b990 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Mon, 8 Jul 2013 00:42:27 +0200
Subject: [PATCH 06/21] Added textile views and writer.

---
 lib/rspec_api_documentation.rb                |  3 ++
 .../views/textile_example.rb                  | 16 +++++++++
 .../views/textile_index.rb                    | 10 ++++++
 .../writers/textile_writer.rb                 | 21 +++++++++++
 spec/writers/textile_writer_spec.rb           | 35 +++++++++++++++++++
 5 files changed, 85 insertions(+)
 create mode 100644 lib/rspec_api_documentation/views/textile_example.rb
 create mode 100644 lib/rspec_api_documentation/views/textile_index.rb
 create mode 100644 lib/rspec_api_documentation/writers/textile_writer.rb
 create mode 100644 spec/writers/textile_writer_spec.rb

diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb
index 9961841b..a8bfcca4 100644
--- a/lib/rspec_api_documentation.rb
+++ b/lib/rspec_api_documentation.rb
@@ -30,6 +30,7 @@ module Writers
 
     autoload :GeneralMarkupWriter
     autoload :HtmlWriter
+    autoload :TextileWriter
     autoload :JsonWriter
     autoload :JsonIodocsWriter
     autoload :IndexWriter
@@ -44,6 +45,8 @@ module Views
     autoload :MarkupExample
     autoload :HtmlIndex
     autoload :HtmlExample
+    autoload :TextileIndex
+    autoload :TextileExample
   end
 
   def self.configuration
diff --git a/lib/rspec_api_documentation/views/textile_example.rb b/lib/rspec_api_documentation/views/textile_example.rb
new file mode 100644
index 00000000..f872697b
--- /dev/null
+++ b/lib/rspec_api_documentation/views/textile_example.rb
@@ -0,0 +1,16 @@
+module RspecApiDocumentation
+  module Views
+    class TextileExample < MarkupExample
+      EXTENSION = 'textile'
+
+      def initialize(example, configuration)
+        super
+        self.template_name = "rspec_api_documentation/textile_example"
+      end
+
+      def extension
+        EXTENSION
+      end
+    end
+  end
+end
diff --git a/lib/rspec_api_documentation/views/textile_index.rb b/lib/rspec_api_documentation/views/textile_index.rb
new file mode 100644
index 00000000..eaca2f38
--- /dev/null
+++ b/lib/rspec_api_documentation/views/textile_index.rb
@@ -0,0 +1,10 @@
+module RspecApiDocumentation
+  module Views
+    class TextileIndex < MarkupIndex
+      def initialize(index, configuration)
+        super
+        self.template_name = "rspec_api_documentation/textile_index"
+      end
+    end
+  end
+end
diff --git a/lib/rspec_api_documentation/writers/textile_writer.rb b/lib/rspec_api_documentation/writers/textile_writer.rb
new file mode 100644
index 00000000..6b79b209
--- /dev/null
+++ b/lib/rspec_api_documentation/writers/textile_writer.rb
@@ -0,0 +1,21 @@
+module RspecApiDocumentation
+  module Writers
+    class TextileWriter < GeneralMarkupWriter
+      attr_accessor :index, :configuration
+
+      EXTENSION = 'textile'
+
+      def markup_index_class
+        RspecApiDocumentation::Views::TextileIndex
+      end
+
+      def markup_example_class
+        RspecApiDocumentation::Views::TextileExample
+      end
+
+      def extension
+        EXTENSION
+      end
+    end
+  end
+end
diff --git a/spec/writers/textile_writer_spec.rb b/spec/writers/textile_writer_spec.rb
new file mode 100644
index 00000000..8b3ab5af
--- /dev/null
+++ b/spec/writers/textile_writer_spec.rb
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+require 'spec_helper'
+
+describe RspecApiDocumentation::Writers::TextileWriter do
+  let(:index) { RspecApiDocumentation::Index.new }
+  let(:configuration) { RspecApiDocumentation::Configuration.new }
+  
+  describe ".write" do
+    let(:writer) { stub }
+
+    it "should build a new writer and write the docs" do
+      described_class.stub!(:new).with(index, configuration).and_return(writer)
+      writer.should_receive(:write)
+      described_class.write(index, configuration)
+    end
+  end
+  
+  describe "#write" do
+    let(:writer) { described_class.new(index, configuration) }
+
+    before do
+      template_dir = File.join(configuration.template_path, "rspec_api_documentation")
+      FileUtils.mkdir_p(template_dir)
+      File.open(File.join(template_dir, "textile_index.mustache"), "w+") { |f| f << "{{ mustache }}" }
+      FileUtils.mkdir_p(configuration.docs_dir)
+    end
+
+    it "should write the index" do
+      writer.write
+      index_file = File.join(configuration.docs_dir, "index.textile")
+      File.exists?(index_file).should be_true
+    end
+  end
+
+end

From a3780d1863cb21a3fd74179985243b5883ff83ee Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Sun, 28 Jul 2013 19:37:19 +0200
Subject: [PATCH 07/21] Textile Index and Example mustache templates with
 Textile Index Cucumber Feature and Steps.

---
 features/textile_documentation.feature        | 98 +++++++++++++++++++
 .../textile_example.mustache                  |  0
 .../textile_index.mustache                    |  9 ++
 3 files changed, 107 insertions(+)
 create mode 100644 features/textile_documentation.feature
 create mode 100644 templates/rspec_api_documentation/textile_example.mustache
 create mode 100644 templates/rspec_api_documentation/textile_index.mustache

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
new file mode 100644
index 00000000..bc86b9bc
--- /dev/null
+++ b/features/textile_documentation.feature
@@ -0,0 +1,98 @@
+Feature: Generate Textile documentation from test examples
+
+  Background:
+    Given a file named "app.rb" with:
+      """
+      class App
+        def self.call(env)
+          request = Rack::Request.new(env)
+          response = Rack::Response.new
+          response["Content-Type"] = "application/json"
+          response.write({ "hello" => request.params["target"] }.to_json)
+          response.finish
+        end
+      end
+      """
+    And   a file named "app_spec.rb" with:
+      """
+      require "rspec_api_documentation"
+      require "rspec_api_documentation/dsl"
+
+      RspecApiDocumentation.configure do |config|
+        config.app = App
+        config.api_name = "Example API"
+        config.format = :textile
+      end
+
+      resource "Greetings" do
+        get "/greetings" do
+          parameter :target, "The thing you want to greet"
+
+          example "Greeting your favorite gem" do
+            do_request :target => "rspec_api_documentation"
+
+            response_headers["Content-Type"].should eq("application/json")
+            status.should eq(200)
+            response_body.should eq('{"hello":"rspec_api_documentation"}')
+          end
+        end
+      end
+      """
+    When  I run `rspec app_spec.rb --require ./app.rb --format RspecApiDocumentation::ApiFormatter`
+
+  Scenario: Output helpful progress to the console
+    Then  the output should contain:
+      """
+      Generating API Docs
+        Greetings
+        GET /greetings
+          * Greeting your favorite gem
+      """
+    And   the output should contain "1 example, 0 failures"
+    And   the exit status should be 0
+
+  Scenario: Index file should look like we expect
+    Then the file "docs/index.textile" should contain exactly:
+    """
+    h1. Example API
+
+    h2. Greetings
+
+    * "Greeting your favorite gem":greetings/greeting_your_favorite_gem.html
+
+    """
+
+  # Scenario: Create an index of all API examples, including all resources
+  #   When  I open the index
+  #   Then  I should see the following resources:
+  #     | Greetings |
+  #   And   I should see the api name "Example API"
+
+  # Scenario: Example HTML documentation includes the parameters
+  #   When  I open the index
+  #   And   I navigate to "Greeting your favorite gem"
+  #   Then  I should see the following parameters:
+  #     | name   | description                 |
+  #     | target | The thing you want to greet |
+
+  # Scenario: Example HTML documentation includes the request information
+  #   When  I open the index
+  #   And   I navigate to "Greeting your favorite gem"
+  #   Then  I should see the route is "GET /greetings?target=rspec_api_documentation"
+  #   And   I should see the following request headers:
+  #     | Host   | example.org |
+  #     | Cookie |             |
+  #   And   I should see the following query parameters:
+  #     | target | rspec_api_documentation |
+
+  # Scenario: Example HTML documentation includes the response information
+  #   When  I open the index
+  #   And   I navigate to "Greeting your favorite gem"
+  #   Then  I should see the response status is "200 OK"
+  #   And   I should see the following response headers:
+  #     | Content-Type   | application/json |
+  #     | Content-Length | 35               |
+  #   And   I should see the following response body:
+  #     """
+  #     {"hello":"rspec_api_documentation"}
+  #     """
diff --git a/templates/rspec_api_documentation/textile_example.mustache b/templates/rspec_api_documentation/textile_example.mustache
new file mode 100644
index 00000000..e69de29b
diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache
new file mode 100644
index 00000000..53ef0da6
--- /dev/null
+++ b/templates/rspec_api_documentation/textile_index.mustache
@@ -0,0 +1,9 @@
+h1. {{ api_name }}
+
+{{# sections }}
+h2. {{ resource_name }}
+
+{{# examples }}
+* "{{ description }}":{{ dirname }}/{{ filename }}
+{{/ examples }}
+{{/ sections }}

From c03d6c8efca09ea1febcfce45cca7499a9f71161 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Mon, 29 Jul 2013 17:35:55 +0200
Subject: [PATCH 08/21] Added additional test cases in
 textile_documentation.feature.

---
 features/textile_documentation.feature        | 34 ++++++++++++++++++-
 .../textile_index.mustache                    |  1 +
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index bc86b9bc..de4f465f 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -35,6 +35,28 @@ Feature: Generate Textile documentation from test examples
             status.should eq(200)
             response_body.should eq('{"hello":"rspec_api_documentation"}')
           end
+
+          example "Greeting nothing" do
+            do_request :target => ""
+
+            response_headers["Content-Type"].should eq("application/json")
+            status.should eq(200)
+            response_body.should eq('{"hello":""}')
+          end
+        end
+      end
+
+      resource "Cucumbers" do
+        get "/cucumbers" do
+          parameter :target, "The thing in which you want to eat cucumbers"
+
+          example "Eating cucumbers in a bowl" do
+            do_request :target => "bowl"
+
+            response_headers["Content-Type"].should eq("application/json")
+            status.should eq(200)
+            response_body.should eq('{"hello":"bowl"}')
+          end
         end
       end
       """
@@ -47,8 +69,12 @@ Feature: Generate Textile documentation from test examples
         Greetings
         GET /greetings
           * Greeting your favorite gem
+          * Greeting nothing
+        Cucumbers
+        GET /cucumbers
+          * Eating cucumbers in a bowl
       """
-    And   the output should contain "1 example, 0 failures"
+    And   the output should contain "3 examples, 0 failures"
     And   the exit status should be 0
 
   Scenario: Index file should look like we expect
@@ -56,10 +82,16 @@ Feature: Generate Textile documentation from test examples
     """
     h1. Example API
 
+    h2. Cucumbers
+
+    * "Eating cucumbers in a bowl":cucumbers/eating_cucumbers_in_a_bowl.html
+
     h2. Greetings
 
+    * "Greeting nothing":greetings/greeting_nothing.html
     * "Greeting your favorite gem":greetings/greeting_your_favorite_gem.html
 
+
     """
 
   # Scenario: Create an index of all API examples, including all resources
diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache
index 53ef0da6..cbb93d57 100644
--- a/templates/rspec_api_documentation/textile_index.mustache
+++ b/templates/rspec_api_documentation/textile_index.mustache
@@ -6,4 +6,5 @@ h2. {{ resource_name }}
 {{# examples }}
 * "{{ description }}":{{ dirname }}/{{ filename }}
 {{/ examples }}
+
 {{/ sections }}

From 3a717fc6777be7cfeee787d6fae2800aefc0774d Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Fri, 2 Aug 2013 10:36:12 +0200
Subject: [PATCH 09/21] Remove links in textile index towards textile examples
 pages.

---
 features/textile_documentation.feature                   | 6 +++---
 templates/rspec_api_documentation/textile_index.mustache | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index de4f465f..a4e23ca4 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -84,12 +84,12 @@ Feature: Generate Textile documentation from test examples
 
     h2. Cucumbers
 
-    * "Eating cucumbers in a bowl":cucumbers/eating_cucumbers_in_a_bowl.html
+    * Eating cucumbers in a bowl
 
     h2. Greetings
 
-    * "Greeting nothing":greetings/greeting_nothing.html
-    * "Greeting your favorite gem":greetings/greeting_your_favorite_gem.html
+    * Greeting nothing
+    * Greeting your favorite gem
 
 
     """
diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache
index cbb93d57..78d15ec2 100644
--- a/templates/rspec_api_documentation/textile_index.mustache
+++ b/templates/rspec_api_documentation/textile_index.mustache
@@ -4,7 +4,7 @@ h1. {{ api_name }}
 h2. {{ resource_name }}
 
 {{# examples }}
-* "{{ description }}":{{ dirname }}/{{ filename }}
+* {{ description }}
 {{/ examples }}
 
 {{/ sections }}

From c16e673bf9a0e78e15b5a0194757802c8e3e5b08 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Fri, 2 Aug 2013 14:56:20 +0200
Subject: [PATCH 10/21] First version of the textile_example mustache template.

---
 features/textile_documentation.feature        |  6 ++
 .../textile_example.mustache                  | 71 +++++++++++++++++++
 2 files changed, 77 insertions(+)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index a4e23ca4..a639051c 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -27,6 +27,7 @@ Feature: Generate Textile documentation from test examples
       resource "Greetings" do
         get "/greetings" do
           parameter :target, "The thing you want to greet"
+          required_parameters :target
 
           example "Greeting your favorite gem" do
             do_request :target => "rspec_api_documentation"
@@ -94,6 +95,11 @@ Feature: Generate Textile documentation from test examples
 
     """
 
+  Scenario: Example 'Greeting nothing' file should look like we expect
+    Then the file "docs/greetings/greeting_nothing.textile" should contain exactly:
+    """
+    """
+
   # Scenario: Create an index of all API examples, including all resources
   #   When  I open the index
   #   Then  I should see the following resources:
diff --git a/templates/rspec_api_documentation/textile_example.mustache b/templates/rspec_api_documentation/textile_example.mustache
index e69de29b..9abe17f9 100644
--- a/templates/rspec_api_documentation/textile_example.mustache
+++ b/templates/rspec_api_documentation/textile_example.mustache
@@ -0,0 +1,71 @@
+h1. {{ resource_name }} API
+
+h2. {{ description }}
+
+h3. {{ http_method }} {{ route }}
+
+{{# explanation }}
+{{ explanation }}
+
+{{/ explanation }}
+
+{{# has_parameters? }}
+
+h3. Parameters
+{{# parameters }}
+
+Name : {{ name }} {{# required }} *- required -* {{/ required }}
+Description : {{ description }}
+
+{{/ parameters }}
+{{/ has_parameters? }}
+
+{{# requests }}
+h3. Request
+
+h4. Headers
+
+<pre>{{ request_headers_text }}</pre>
+
+h4. Route
+
+<pre>{{ request_method }} {{ request_path }}</pre>
+
+{{# request_query_parameters_text }}
+h4. Query Parameters
+
+<pre>{{ request_query_parameters_text }}</pre>
+{{/ request_query_parameters_text }}
+
+{{# request_body }}
+h4. Body
+
+<pre>{{{ request_body }}}</pre>
+{{/ request_body }}
+
+{{# curl }}
+h4. cURL
+
+<pre class="request">{{ curl }}</pre>
+{{/ curl }}
+
+{{# response_status }}
+h3. Response
+
+h4. Headers
+
+<pre>{{ response_headers_text }}</pre>
+
+h4. Status
+
+<pre>{{ response_status }} {{ response_status_text}}</pre>
+
+{{# response_body }}
+h4. Body
+
+<pre>{{{ response_body }}}</pre>
+{{/ response_body }}
+{{/ response_status }}
+
+{{/ requests }}
+

From 1800a645dc9464b1bbe99e6f0723fb87bcc7b69b Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Sat, 3 Aug 2013 18:54:05 +0200
Subject: [PATCH 11/21] Cucumber steps definitions written for basic textile
 example.

---
 features/textile_documentation.feature        | 85 +++++++++++--------
 .../textile_example.mustache                  |  5 +-
 2 files changed, 49 insertions(+), 41 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index a639051c..ada0988c 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -95,42 +95,53 @@ Feature: Generate Textile documentation from test examples
 
     """
 
-  Scenario: Example 'Greeting nothing' file should look like we expect
-    Then the file "docs/greetings/greeting_nothing.textile" should contain exactly:
-    """
+  Scenario: Example 'Greeting your favorite gem' file should look like we expect
+    Then the file "docs/greetings/greeting_your_favorite_gem.textile" should contain exactly:
     """
+    h1. Greetings API
+
+    h2. Greeting your favorite gem
+
+    h3. GET /greetings
+
+
+    h3. Parameters
+
+    Name : target  *- required -*
+    Description : The thing you want to greet
+
+    h3. Request
+
+    h4. Headers
+
+    <pre>Host: example.org
+    Cookie: </pre>
+
+    h4. Route
+
+    <pre>GET /greetings?target=rspec_api_documentation</pre>
+
+    h4. Query Parameters
+
+    <pre>target: rspec_api_documentation</pre>
 
-  # Scenario: Create an index of all API examples, including all resources
-  #   When  I open the index
-  #   Then  I should see the following resources:
-  #     | Greetings |
-  #   And   I should see the api name "Example API"
-
-  # Scenario: Example HTML documentation includes the parameters
-  #   When  I open the index
-  #   And   I navigate to "Greeting your favorite gem"
-  #   Then  I should see the following parameters:
-  #     | name   | description                 |
-  #     | target | The thing you want to greet |
-
-  # Scenario: Example HTML documentation includes the request information
-  #   When  I open the index
-  #   And   I navigate to "Greeting your favorite gem"
-  #   Then  I should see the route is "GET /greetings?target=rspec_api_documentation"
-  #   And   I should see the following request headers:
-  #     | Host   | example.org |
-  #     | Cookie |             |
-  #   And   I should see the following query parameters:
-  #     | target | rspec_api_documentation |
-
-  # Scenario: Example HTML documentation includes the response information
-  #   When  I open the index
-  #   And   I navigate to "Greeting your favorite gem"
-  #   Then  I should see the response status is "200 OK"
-  #   And   I should see the following response headers:
-  #     | Content-Type   | application/json |
-  #     | Content-Length | 35               |
-  #   And   I should see the following response body:
-  #     """
-  #     {"hello":"rspec_api_documentation"}
-  #     """
+
+
+    h3. Response
+
+    h4. Headers
+
+    <pre>Content-Type: application/json
+    Content-Length: 35</pre>
+
+    h4. Status
+
+    <pre>200 OK</pre>
+
+    h4. Body
+
+    <pre>{"hello":"rspec_api_documentation"}</pre>
+
+
+
+    """
diff --git a/templates/rspec_api_documentation/textile_example.mustache b/templates/rspec_api_documentation/textile_example.mustache
index 9abe17f9..9dc2e55c 100644
--- a/templates/rspec_api_documentation/textile_example.mustache
+++ b/templates/rspec_api_documentation/textile_example.mustache
@@ -6,17 +6,14 @@ h3. {{ http_method }} {{ route }}
 
 {{# explanation }}
 {{ explanation }}
-
 {{/ explanation }}
 
 {{# has_parameters? }}
-
 h3. Parameters
 {{# parameters }}
 
-Name : {{ name }} {{# required }} *- required -* {{/ required }}
+Name : {{ name }} {{# required }} *- required -*{{/ required }}
 Description : {{ description }}
-
 {{/ parameters }}
 {{/ has_parameters? }}
 

From 47502e4fe39d67f3fe8ffbecca233e17ae2a3795 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Thu, 15 Aug 2013 16:37:47 +0200
Subject: [PATCH 12/21] Use Sinatra dummy app for
 textile_documentation.feature.

---
 features/textile_documentation.feature | 30 ++++++++++++++++----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index ada0988c..1276dcdc 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -3,13 +3,19 @@ Feature: Generate Textile documentation from test examples
   Background:
     Given a file named "app.rb" with:
       """
-      class App
-        def self.call(env)
-          request = Rack::Request.new(env)
-          response = Rack::Response.new
-          response["Content-Type"] = "application/json"
-          response.write({ "hello" => request.params["target"] }.to_json)
-          response.finish
+      require 'sinatra'
+
+      class App < Sinatra::Base
+        get '/greetings' do
+          content_type :json
+
+          [200, { 'hello' => params[:target] }.to_json ]
+        end
+
+        get '/cucumbers' do
+          content_type :json
+
+          [200, { 'hello' => params[:target] }.to_json ]
         end
       end
       """
@@ -32,7 +38,7 @@ Feature: Generate Textile documentation from test examples
           example "Greeting your favorite gem" do
             do_request :target => "rspec_api_documentation"
 
-            response_headers["Content-Type"].should eq("application/json")
+            response_headers["Content-Type"].should eq("application/json;charset=utf-8")
             status.should eq(200)
             response_body.should eq('{"hello":"rspec_api_documentation"}')
           end
@@ -40,7 +46,7 @@ Feature: Generate Textile documentation from test examples
           example "Greeting nothing" do
             do_request :target => ""
 
-            response_headers["Content-Type"].should eq("application/json")
+            response_headers["Content-Type"].should eq("application/json;charset=utf-8")
             status.should eq(200)
             response_body.should eq('{"hello":""}')
           end
@@ -54,7 +60,7 @@ Feature: Generate Textile documentation from test examples
           example "Eating cucumbers in a bowl" do
             do_request :target => "bowl"
 
-            response_headers["Content-Type"].should eq("application/json")
+            response_headers["Content-Type"].should eq("application/json;charset=utf-8")
             status.should eq(200)
             response_body.should eq('{"hello":"bowl"}')
           end
@@ -131,7 +137,9 @@ Feature: Generate Textile documentation from test examples
 
     h4. Headers
 
-    <pre>Content-Type: application/json
+    <pre>X-Frame-Options: sameorigin
+    X-XSS-Protection: 1; mode=block
+    Content-Type: application/json;charset=utf-8
     Content-Length: 35</pre>
 
     h4. Status

From e5defdb38618d1b950b4b20bd819ac881fa91074 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Sun, 18 Aug 2013 17:13:04 +0200
Subject: [PATCH 13/21] Rewrote the spec dummy api and its related api spec.

---
 features/textile_documentation.feature | 120 ++++++++++++++++++-------
 1 file changed, 87 insertions(+), 33 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index 1276dcdc..f26e9018 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -6,16 +6,33 @@ Feature: Generate Textile documentation from test examples
       require 'sinatra'
 
       class App < Sinatra::Base
-        get '/greetings' do
+        get '/orders' do
           content_type :json
 
-          [200, { 'hello' => params[:target] }.to_json ]
+          [200, [{ name: 'Order 1', amount: 9.99, description: nil },
+                 { name: 'Order 2', amount: 100.0, description: 'A great order' }].to_json]
         end
 
-        get '/cucumbers' do
+        get '/orders/:id' do
           content_type :json
 
-          [200, { 'hello' => params[:target] }.to_json ]
+          [200, { order: { name: 'Order 1', amount: 100.0, description: 'A great order' } }.to_json]
+        end
+
+        post '/orders' do
+          201
+        end
+
+        put '/orders/:id' do
+          200
+        end
+
+        delete '/orders/:id' do
+          200
+        end
+
+        get '/help' do
+          [200, 'Welcome Henry !']
         end
       end
       """
@@ -30,41 +47,71 @@ Feature: Generate Textile documentation from test examples
         config.format = :textile
       end
 
-      resource "Greetings" do
-        get "/greetings" do
-          parameter :target, "The thing you want to greet"
-          required_parameters :target
-
-          example "Greeting your favorite gem" do
-            do_request :target => "rspec_api_documentation"
+      resource 'Orders' do
+        get '/orders' do
 
-            response_headers["Content-Type"].should eq("application/json;charset=utf-8")
+          example_request 'Getting a list of orders' do
             status.should eq(200)
-            response_body.should eq('{"hello":"rspec_api_documentation"}')
+            response_body.should eq('[{"name":"Order 1","amount":9.99,"description":null},{"name":"Order 2","amount":100.0,"description":"A great order"}]')
           end
+        end
 
-          example "Greeting nothing" do
-            do_request :target => ""
+        get '/orders/:id' do
+          let(:id) { 1 }
 
-            response_headers["Content-Type"].should eq("application/json;charset=utf-8")
+          example_request 'Getting a specific order' do
             status.should eq(200)
-            response_body.should eq('{"hello":""}')
+            response_body.should == '{"order":{"name":"Order 1","amount":100.0,"description":"A great order"}}'
           end
         end
-      end
 
-      resource "Cucumbers" do
-        get "/cucumbers" do
-          parameter :target, "The thing in which you want to eat cucumbers"
+        post '/orders' do
+          parameter :name, 'Name of order'
+          parameter :amount, 'Amount paid'
+          parameter :description, 'Some comments on the order'
 
-          example "Eating cucumbers in a bowl" do
-            do_request :target => "bowl"
+          required_parameters :name, :amount
 
-            response_headers["Content-Type"].should eq("application/json;charset=utf-8")
+          let(:name) { "Order 3" }
+          let(:amount) { 33.0 }
+
+          example_request 'Creating an order' do
+            status.should == 201
+          end
+        end
+
+        put '/orders/:id' do
+          parameter :name, 'Name of order'
+          parameter :amount, 'Amount paid'
+          parameter :description, 'Some comments on the order'
+
+          required_parameters :name, :amount
+
+          let(:id) { 2 }
+          let(:name) { "Updated name" }
+
+          example_request 'Updating an order' do
+            status.should == 200
+          end
+        end
+
+        delete "/orders/:id" do
+          let(:id) { 1 }
+
+          example_request "Deleting an order" do
+            status.should == 200
+          end
+        end
+      end
+
+      resource 'Help' do
+        get '/help' do
+          example_request 'Getting welcome message' do
             status.should eq(200)
-            response_body.should eq('{"hello":"bowl"}')
+            response_body.should == 'Welcome Henry !'
           end
         end
+
       end
       """
     When  I run `rspec app_spec.rb --require ./app.rb --format RspecApiDocumentation::ApiFormatter`
@@ -73,15 +120,22 @@ Feature: Generate Textile documentation from test examples
     Then  the output should contain:
       """
       Generating API Docs
-        Greetings
-        GET /greetings
-          * Greeting your favorite gem
-          * Greeting nothing
-        Cucumbers
-        GET /cucumbers
-          * Eating cucumbers in a bowl
+        Orders
+        GET /orders
+          * Getting a list of orders
+        GET /orders/:id
+          * Getting a specific order
+        POST /orders
+          * Creating an order
+        PUT /orders/:id
+          * Updating an order
+        DELETE /orders/:id
+          * Deleting an order
+        Help
+        GET /help
+          * Getting welcome message
       """
-    And   the output should contain "3 examples, 0 failures"
+    And   the output should contain "6 examples, 0 failures"
     And   the exit status should be 0
 
   Scenario: Index file should look like we expect

From 1e9ed3fba4c71a814cec32da0f45d49509a0e30a Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Sun, 18 Aug 2013 17:17:43 +0200
Subject: [PATCH 14/21] In textile_documentation.feature, contents retested
 with new api.

---
 features/textile_documentation.feature | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index f26e9018..28aec71b 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -143,14 +143,17 @@ Feature: Generate Textile documentation from test examples
     """
     h1. Example API
 
-    h2. Cucumbers
+    h2. Help
 
-    * Eating cucumbers in a bowl
+    * Getting welcome message
 
-    h2. Greetings
+    h2. Orders
 
-    * Greeting nothing
-    * Greeting your favorite gem
+    * Creating an order
+    * Deleting an order
+    * Getting a list of orders
+    * Getting a specific order
+    * Updating an order
 
 
     """

From 3904c77762396a916ddabdce8bdc35b97f3f9bdf Mon Sep 17 00:00:00 2001
From: Jonathan Pares <j.pares@alphalink.fr>
Date: Mon, 19 Aug 2013 08:41:32 +0200
Subject: [PATCH 15/21] Check contents of 'Creating an order' example file in
 textile_documentation feature.

---
 features/textile_documentation.feature | 36 ++++++++++++++------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index 28aec71b..2be8875e 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -158,36 +158,43 @@ Feature: Generate Textile documentation from test examples
 
     """
 
-  Scenario: Example 'Greeting your favorite gem' file should look like we expect
-    Then the file "docs/greetings/greeting_your_favorite_gem.textile" should contain exactly:
+  Scenario: Example 'Creating an order' file should look like we expect
+    Then the file "docs/orders/creating_an_order.textile" should contain exactly:
     """
-    h1. Greetings API
+    h1. Orders API
 
-    h2. Greeting your favorite gem
+    h2. Creating an order
 
-    h3. GET /greetings
+    h3. POST /orders
 
 
     h3. Parameters
 
-    Name : target  *- required -*
-    Description : The thing you want to greet
+    Name : name  *- required -*
+    Description : Name of order
+
+    Name : amount  *- required -*
+    Description : Amount paid
+
+    Name : description 
+    Description : Some comments on the order
 
     h3. Request
 
     h4. Headers
 
     <pre>Host: example.org
+    Content-Type: application/x-www-form-urlencoded
     Cookie: </pre>
 
     h4. Route
 
-    <pre>GET /greetings?target=rspec_api_documentation</pre>
+    <pre>POST /orders</pre>
 
-    h4. Query Parameters
 
-    <pre>target: rspec_api_documentation</pre>
+    h4. Body
 
+    <pre>name=Order+3&amount=33.0</pre>
 
 
     h3. Response
@@ -196,16 +203,13 @@ Feature: Generate Textile documentation from test examples
 
     <pre>X-Frame-Options: sameorigin
     X-XSS-Protection: 1; mode=block
-    Content-Type: application/json;charset=utf-8
-    Content-Length: 35</pre>
+    Content-Type: text/html;charset=utf-8
+    Content-Length: 0</pre>
 
     h4. Status
 
-    <pre>200 OK</pre>
-
-    h4. Body
+    <pre>201 Created</pre>
 
-    <pre>{"hello":"rspec_api_documentation"}</pre>
 
 
 

From ae1eeb97a2a794762ce54a7dbcca69c2ddc1c754 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Mon, 19 Aug 2013 09:32:40 +0200
Subject: [PATCH 16/21] Added scenarios to test presence of generated examples
 textile for new test api.

---
 features/textile_documentation.feature | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index 2be8875e..82f8a625 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -214,3 +214,20 @@ Feature: Generate Textile documentation from test examples
 
 
     """
+
+  Scenario: Example 'Deleting an order' file should exist
+    Then the file "docs/orders/deleting_an_order.textile" should exist
+
+  Scenario: Example 'Getting a list of orders' file should exist
+    Then the file "docs/orders/getting_a_list_of_orders.textile" should exist
+
+  Scenario: Example 'Getting a specific order' file should exist
+    Then the file "docs/orders/getting_a_specific_order.textile" should exist
+
+  Scenario: Example 'Updating an order' file should exist
+    Then the file "docs/orders/updating_an_order.textile" should exist
+
+  Scenario: Example 'Getting welcome message' file should exist
+    Then the file "docs/help/getting_welcome_message.textile" should exist
+
+

From 1a99d050d7dbd7bc3cb08d6e6ac6d04e934cde9a Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Tue, 20 Aug 2013 15:57:52 +0200
Subject: [PATCH 17/21] Corrections on scenarios in
 textile_documentation.feature to test presence of generated examples.

---
 features/textile_documentation.feature | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index 82f8a625..30f1619b 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -215,19 +215,19 @@ Feature: Generate Textile documentation from test examples
 
     """
 
-  Scenario: Example 'Deleting an order' file should exist
-    Then the file "docs/orders/deleting_an_order.textile" should exist
+  Scenario: Example 'Deleting an order' file should be created
+    Then a file named "docs/orders/deleting_an_order.textile" should exist
 
-  Scenario: Example 'Getting a list of orders' file should exist
-    Then the file "docs/orders/getting_a_list_of_orders.textile" should exist
+  Scenario: Example 'Getting a list of orders' file should be created
+    Then a file named "docs/orders/getting_a_list_of_orders.textile" should exist
 
-  Scenario: Example 'Getting a specific order' file should exist
-    Then the file "docs/orders/getting_a_specific_order.textile" should exist
+  Scenario: Example 'Getting a specific order' file should be created
+    Then a file named "docs/orders/getting_a_specific_order.textile" should exist
 
-  Scenario: Example 'Updating an order' file should exist
-    Then the file "docs/orders/updating_an_order.textile" should exist
+  Scenario: Example 'Updating an order' file should be created
+    Then a file named "docs/orders/updating_an_order.textile" should exist
 
-  Scenario: Example 'Getting welcome message' file should exist
-    Then the file "docs/help/getting_welcome_message.textile" should exist
+  Scenario: Example 'Getting welcome message' file should be created
+    Then a file named "docs/help/getting_welcome_message.textile" should exist
 
 

From 655329435c12a81ad52183aa46c67dfd6292a319 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Tue, 20 Aug 2013 16:14:40 +0200
Subject: [PATCH 18/21] Added TextileWriter test cases in
 api_documentation_spec.rb.

---
 spec/api_documentation_spec.rb | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/spec/api_documentation_spec.rb b/spec/api_documentation_spec.rb
index 1c1087c3..47ab8676 100644
--- a/spec/api_documentation_spec.rb
+++ b/spec/api_documentation_spec.rb
@@ -60,14 +60,16 @@
   describe "#writers" do
     class RspecApiDocumentation::Writers::HtmlWriter; end
     class RspecApiDocumentation::Writers::JsonWriter; end
+    class RspecApiDocumentation::Writers::TextileWriter; end
 
     context "multiple" do
       before do
-        configuration.format = [:html, :json]
+        configuration.format = [:html, :json, :textile]
       end
 
       it "should return the classes from format" do
-        subject.writers.should == [RspecApiDocumentation::Writers::HtmlWriter, RspecApiDocumentation::Writers::JsonWriter]
+        subject.writers.should == [RspecApiDocumentation::Writers::HtmlWriter, RspecApiDocumentation::Writers::JsonWriter,
+                                   RspecApiDocumentation::Writers::TextileWriter]
       end
     end
 
@@ -85,14 +87,16 @@ class RspecApiDocumentation::Writers::JsonWriter; end
   describe "#write" do
     let(:html_writer) { stub }
     let(:json_writer) { stub }
+    let(:textile_writer) { stub }
 
     before do
-      subject.stub!(:writers => [html_writer, json_writer])
+      subject.stub!(:writers => [html_writer, json_writer, textile_writer])
     end
 
     it "should write the docs in each format" do
       html_writer.should_receive(:write).with(subject.index, configuration)
       json_writer.should_receive(:write).with(subject.index, configuration)
+      textile_writer.should_receive(:write).with(subject.index, configuration)
       subject.write
     end
   end

From 48690633eb74169db4b6e4188fc87f1e8706aa74 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Fri, 30 Aug 2013 10:40:13 +0200
Subject: [PATCH 19/21] Updated textile_documentation.feature with the latest
 DSL and path generation changes.

---
 features/textile_documentation.feature | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index 30f1619b..9b30c263 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -66,12 +66,10 @@ Feature: Generate Textile documentation from test examples
         end
 
         post '/orders' do
-          parameter :name, 'Name of order'
-          parameter :amount, 'Amount paid'
+          parameter :name, 'Name of order', :required => true
+          parameter :amount, 'Amount paid', :required => true
           parameter :description, 'Some comments on the order'
 
-          required_parameters :name, :amount
-
           let(:name) { "Order 3" }
           let(:amount) { 33.0 }
 
@@ -81,12 +79,10 @@ Feature: Generate Textile documentation from test examples
         end
 
         put '/orders/:id' do
-          parameter :name, 'Name of order'
-          parameter :amount, 'Amount paid'
+          parameter :name, 'Name of order', :required => true
+          parameter :amount, 'Amount paid', :required => true
           parameter :description, 'Some comments on the order'
 
-          required_parameters :name, :amount
-
           let(:id) { 2 }
           let(:name) { "Updated name" }
 
@@ -139,7 +135,7 @@ Feature: Generate Textile documentation from test examples
     And   the exit status should be 0
 
   Scenario: Index file should look like we expect
-    Then the file "docs/index.textile" should contain exactly:
+    Then the file "doc/api/index.textile" should contain exactly:
     """
     h1. Example API
 
@@ -159,7 +155,7 @@ Feature: Generate Textile documentation from test examples
     """
 
   Scenario: Example 'Creating an order' file should look like we expect
-    Then the file "docs/orders/creating_an_order.textile" should contain exactly:
+    Then the file "doc/api/orders/creating_an_order.textile" should contain exactly:
     """
     h1. Orders API
 
@@ -216,18 +212,18 @@ Feature: Generate Textile documentation from test examples
     """
 
   Scenario: Example 'Deleting an order' file should be created
-    Then a file named "docs/orders/deleting_an_order.textile" should exist
+    Then a file named "doc/api/orders/deleting_an_order.textile" should exist
 
   Scenario: Example 'Getting a list of orders' file should be created
-    Then a file named "docs/orders/getting_a_list_of_orders.textile" should exist
+    Then a file named "doc/api/orders/getting_a_list_of_orders.textile" should exist
 
   Scenario: Example 'Getting a specific order' file should be created
-    Then a file named "docs/orders/getting_a_specific_order.textile" should exist
+    Then a file named "doc/api/orders/getting_a_specific_order.textile" should exist
 
   Scenario: Example 'Updating an order' file should be created
-    Then a file named "docs/orders/updating_an_order.textile" should exist
+    Then a file named "doc/api/orders/updating_an_order.textile" should exist
 
   Scenario: Example 'Getting welcome message' file should be created
-    Then a file named "docs/help/getting_welcome_message.textile" should exist
+    Then a file named "doc/api/help/getting_welcome_message.textile" should exist
 
 

From 5cd4d3ab3ce5dd0df13ff03547cd4f400e8601d3 Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Fri, 30 Aug 2013 11:52:04 +0200
Subject: [PATCH 20/21] Fix in MarkupIndex that should not use HtmlExample.

---
 lib/rspec_api_documentation/views/html_index.rb    | 4 ++++
 lib/rspec_api_documentation/views/markup_index.rb  | 4 ----
 lib/rspec_api_documentation/views/textile_index.rb | 4 ++++
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/lib/rspec_api_documentation/views/html_index.rb b/lib/rspec_api_documentation/views/html_index.rb
index c4f8a8bd..3a56ccd4 100644
--- a/lib/rspec_api_documentation/views/html_index.rb
+++ b/lib/rspec_api_documentation/views/html_index.rb
@@ -5,6 +5,10 @@ def initialize(index, configuration)
         super
         self.template_name = "rspec_api_documentation/html_index"
       end
+      
+      def examples
+        @index.examples.map { |example| HtmlExample.new(example, @configuration) }
+      end
     end
   end
 end
diff --git a/lib/rspec_api_documentation/views/markup_index.rb b/lib/rspec_api_documentation/views/markup_index.rb
index b0a3646b..f0bd6c3d 100644
--- a/lib/rspec_api_documentation/views/markup_index.rb
+++ b/lib/rspec_api_documentation/views/markup_index.rb
@@ -16,10 +16,6 @@ def api_name
       def sections
         RspecApiDocumentation::Writers::IndexWriter.sections(examples, @configuration)
       end
-
-      def examples
-        @index.examples.map { |example| HtmlExample.new(example, @configuration) }
-      end
     end
   end
 end
diff --git a/lib/rspec_api_documentation/views/textile_index.rb b/lib/rspec_api_documentation/views/textile_index.rb
index eaca2f38..d6aeb6ef 100644
--- a/lib/rspec_api_documentation/views/textile_index.rb
+++ b/lib/rspec_api_documentation/views/textile_index.rb
@@ -5,6 +5,10 @@ def initialize(index, configuration)
         super
         self.template_name = "rspec_api_documentation/textile_index"
       end
+      
+      def examples
+        @index.examples.map { |example| TextileExample.new(example, @configuration) }
+      end
     end
   end
 end

From c8819f6841faab5e50036ea103df80dab4e86a1e Mon Sep 17 00:00:00 2001
From: Jonathan Pares <jonathan.pares@gmail.com>
Date: Fri, 30 Aug 2013 11:52:45 +0200
Subject: [PATCH 21/21] Added links to textile examples in textile index.

---
 features/textile_documentation.feature               | 12 ++++++------
 .../rspec_api_documentation/textile_index.mustache   |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature
index 9b30c263..fa668d7d 100644
--- a/features/textile_documentation.feature
+++ b/features/textile_documentation.feature
@@ -141,15 +141,15 @@ Feature: Generate Textile documentation from test examples
 
     h2. Help
 
-    * Getting welcome message
+    * "Getting welcome message":help/getting_welcome_message.textile
 
     h2. Orders
 
-    * Creating an order
-    * Deleting an order
-    * Getting a list of orders
-    * Getting a specific order
-    * Updating an order
+    * "Creating an order":orders/creating_an_order.textile
+    * "Deleting an order":orders/deleting_an_order.textile
+    * "Getting a list of orders":orders/getting_a_list_of_orders.textile
+    * "Getting a specific order":orders/getting_a_specific_order.textile
+    * "Updating an order":orders/updating_an_order.textile
 
 
     """
diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache
index 78d15ec2..cbb93d57 100644
--- a/templates/rspec_api_documentation/textile_index.mustache
+++ b/templates/rspec_api_documentation/textile_index.mustache
@@ -4,7 +4,7 @@ h1. {{ api_name }}
 h2. {{ resource_name }}
 
 {{# examples }}
-* {{ description }}
+* "{{ description }}":{{ dirname }}/{{ filename }}
 {{/ examples }}
 
 {{/ sections }}