rapi_doc 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.project ADDED
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projectDescription>
3
+ <name>rapi_doc</name>
4
+ <comment></comment>
5
+ <projects>
6
+ </projects>
7
+ <buildSpec>
8
+ <buildCommand>
9
+ <name>com.aptana.ide.core.unifiedBuilder</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
13
+ </buildSpec>
14
+ <natures>
15
+ <nature>com.aptana.ruby.core.rubynature</nature>
16
+ </natures>
17
+ </projectDescription>
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm ruby-1.9.2-p180@rapidoc --create
1
+ rvm ruby-1.9.2@rapidoc --create
data/Gemfile CHANGED
@@ -4,12 +4,14 @@ source "http://rubygems.org"
4
4
  # gem "activesupport", ">= 2.3.5"
5
5
 
6
6
  gem 'activesupport', '>= 2.1'
7
+ gem 'haml'
8
+ gem 'rdoc'
7
9
 
8
10
  # Add dependencies to develop your gem here.
9
11
  # Include everything needed to run rake, tests, features, etc.
10
12
  group :development do
11
- gem "rspec", "~> 2.7.0"
12
- gem "bundler", "~> 1.0.0"
13
- gem "jeweler", "~> 1.6.4"
13
+ gem "rspec", ">= 2.7.0"
14
+ gem "bundler", ">= 1.0.0"
15
+ gem "jeweler", ">= 1.6.4"
14
16
  gem "rcov", ">= 0"
15
17
  end
data/Gemfile.lock CHANGED
@@ -5,13 +5,17 @@ GEM
5
5
  multi_json (~> 1.0)
6
6
  diff-lcs (1.1.3)
7
7
  git (1.2.5)
8
+ haml (3.1.4)
8
9
  jeweler (1.6.4)
9
10
  bundler (~> 1.0)
10
11
  git (>= 1.2.5)
11
12
  rake
13
+ json (1.6.6)
12
14
  multi_json (1.0.4)
13
15
  rake (0.9.2.2)
14
16
  rcov (0.9.11)
17
+ rdoc (3.12)
18
+ json (~> 1.4)
15
19
  rspec (2.7.0)
16
20
  rspec-core (~> 2.7.0)
17
21
  rspec-expectations (~> 2.7.0)
@@ -26,7 +30,9 @@ PLATFORMS
26
30
 
27
31
  DEPENDENCIES
28
32
  activesupport (>= 2.1)
29
- bundler (~> 1.0.0)
30
- jeweler (~> 1.6.4)
33
+ bundler (>= 1.0.0)
34
+ haml
35
+ jeweler (>= 1.6.4)
31
36
  rcov
32
- rspec (~> 2.7.0)
37
+ rdoc
38
+ rspec (>= 2.7.0)
data/README.md CHANGED
@@ -13,19 +13,78 @@ Installation
13
13
  Usage
14
14
  =====
15
15
 
16
- Run `rake rapi_doc:setup` to generate config and layout files.
17
-
18
- Modify config file by adding your controllers, e.g.:
19
-
20
- books:
21
- location: "/books"
22
- controller_name: "books_controller.rb"
16
+ Run `rake rapi_doc:setup` to generate default Haml template files along with default styles.
17
+ These files are in `<application folder>/config/rapi_doc` folder.
23
18
 
24
19
  Then invoke the generation by calling:
25
20
 
26
21
  `rake rapi_doc:generate`
27
22
 
28
- Documentation Example
23
+ It will analyze `rake routes` output and find the controller files in app/controllers directory that may have the annotation.
24
+ It will confirm from the user whether he/she wants the plugin to look for annotations in each of these files.
25
+ For files confirmed by the user, it will parse the annotations and generate the HTML output using the template files and styles
26
+ in the `config/rapi_doc` folder.
27
+
28
+ `rake rapi_doc:clean`
29
+ will remove the documentation thus generated.
30
+
31
+ `rake rapi_doc:distclean`
32
+ will remove the documentation and also the Haml template files and styles created by the `rake rapi_doc:setup`
33
+
34
+
35
+ Markup Reference
36
+ ================
37
+
38
+ Controller methods and controllers themselves are documented by annotating them with "method markers" and
39
+ "resource markers" enclosed in "apidoc" comments, similar to that in RDoc.
40
+
41
+ # =begin apidoc
42
+ ... method markers
43
+ # =end
44
+
45
+ A] Method markers
46
+ -----------------
47
+
48
+ Method markers are specified like this:
49
+
50
+ # <<method-marker-name>:: <method-marker-value>
51
+
52
+ All method markers are optional.
53
+
54
+ # method: HTTP request type such as GET or POST
55
+ # access: access restrictions such as FREE, RESTRICTED for paid subscribers, etc
56
+ # return: list of return data-formats like [JSON|XML] and what the return data means
57
+ # param: name and type of the parameter expected
58
+ # output: output format like JSON, XML. It is recommended that it should include an example of such data.
59
+ # Each output marker must end with ::output-end:: on a separate line.
60
+ # request: a request generating code example
61
+ # response: a response processing code example
62
+
63
+ You can define your own custom method markers as well.
64
+ They will be available as the instance variables against which the _resource_method.html.erb template
65
+ will be evaluated.
66
+
67
+ Any other information that needs to be shown in the view can be specified in the apidoc comments as well.
68
+ It will be shown under the "Description" section for the method in the view.
69
+
70
+
71
+ B] Resource markers
72
+ -------------------
73
+
74
+ A resource, which is normally a controller object, can also be annotated with apidoc comments.
75
+
76
+ Method markers are specified the same way as the method markers:
77
+
78
+ # <<method-marker-name>:: <method-marker-value>
79
+ #
80
+ # xml: xml representation of the resource
81
+ # json: json representation
82
+
83
+ Just like in method marker, any other information that needs to be shown in the view can be specified in the apidoc comments as well.
84
+ It will be shown under the "Description" section for the method in the view.
85
+
86
+
87
+ C] Documentation Example
29
88
  ---------------------
30
89
 
31
90
  # =begin apidoc
@@ -63,14 +122,66 @@ Documentation Example
63
122
  # Get a list of all books in the system with pagination. Defaults to 10 per page
64
123
  # =end
65
124
 
66
-
67
- Layout
68
- ------
69
125
 
70
- Documentation layout is located at `config/rapi_doc/layout.html.erb`.
126
+
127
+ Haml Templates and styles
128
+ =========================
129
+
130
+ Resource and resource method annotations are available as instance and local variables in Haml templates.
131
+ Here are the listing of variables available. But the best way to understand it is to look at the default
132
+ Haml templates generated by `rake rapi_doc:setup` in `config/rapi_doc` folder.
133
+
134
+
135
+ A] Resource Method
136
+ ------------------
137
+
138
+ @resource_name: Resource name
139
+ @method_order: the numerical order of the method
140
+ @content: All Misc info
141
+ @url: url
142
+ @access: public/privileged, etc
143
+ @return: the data format of the info
144
+ @params: params expected by this api
145
+ @outputs: array of [output_format, output example], for example, [json, ....json output.. ]
146
+ @request: example of the data expected
147
+ @response: example of the response
148
+
149
+
150
+ B] Resource
151
+ -----------
152
+
153
+ @name: name
154
+ @xml: xml representation of the resource
155
+ @json: json representation
156
+ @function_blocks: Array of resource method objects described above
157
+
158
+
159
+ Following instance variables are only available in the index template described below (and not in the resource Haml template)
160
+ @resource_methods: Array of HTML generated for each of the methods.
161
+ @resource_header: HTML generated for the resource
162
+
163
+
164
+ C] Index
165
+ --------
166
+
167
+ resource_docs: all the resource objects, whose instance variables are described above.
168
+ As mentioned before, for each resource, the HTML generated for the resource itself is available in @resource_header
169
+ and HTML generated for each of its methods is available in @resource_methods array.
170
+
171
+
172
+
173
+ D] Documentaton Output
174
+ ----------------------
175
+
176
+ Documentation generated is located in `public/apidoc` directory.
177
+
178
+ index.html: contains the HTML
179
+ styles.css: CSS styles
180
+ scripts.js: contains the script used to search within the documentation.
181
+
71
182
 
72
183
  Credit
73
184
  ======
74
185
 
75
186
  * Based on RAPI Doc by Jaap van der Meer found here: http://code.google.com/p/rapidoc/
76
- * https://github.com/sabman/rapi_doc
187
+ * https://github.com/sabman/rapi_doc
data/Rakefile CHANGED
@@ -18,10 +18,12 @@ Jeweler::Tasks.new do |gem|
18
18
  gem.homepage = "http://github.com/elc/rapi_doc"
19
19
  gem.license = "MIT"
20
20
  gem.summary = %Q{Rails API Doc Generator}
21
- gem.description = %Q{Rails API Doc Generator}
21
+ gem.description = %Q{Rails API Doc Generator. Parses the apidoc annotations to generate HTML pages.}
22
22
  gem.email = "hchoroomi@gmail.com"
23
- gem.authors = ["Husein Choroomi", "Adinda Praditya"]
23
+ gem.authors = ["Husein Choroomi", "Adinda Praditya", "Salil Wadnerkar"]
24
24
  # dependencies defined in Gemfile
25
+ gem.add_dependency 'haml'
26
+ gem.add_dependency 'rdoc'
25
27
  end
26
28
  Jeweler::RubygemsDotOrgTasks.new
27
29
 
@@ -42,8 +44,8 @@ end
42
44
 
43
45
  task :default => :test
44
46
 
45
- require 'rake/rdoctask'
46
- Rake::RDocTask.new do |rdoc|
47
+ require 'rdoc/task'
48
+ RDoc::Task.new do |rdoc|
47
49
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
50
 
49
51
  rdoc.rdoc_dir = 'rdoc'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
data/autoscan.log ADDED
File without changes
data/configure.scan ADDED
@@ -0,0 +1,17 @@
1
+ # -*- Autoconf -*-
2
+ # Process this file with autoconf to produce a configure script.
3
+
4
+ AC_PREREQ(2.61)
5
+ AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
6
+
7
+ # Checks for programs.
8
+
9
+ # Checks for libraries.
10
+
11
+ # Checks for header files.
12
+
13
+ # Checks for typedefs, structures, and compiler characteristics.
14
+
15
+ # Checks for library functions.
16
+
17
+ AC_OUTPUT
data/lib/rapi_doc.rb CHANGED
@@ -1,76 +1,100 @@
1
- require 'erb'
1
+ require 'haml'
2
2
  require 'fileutils'
3
- require 'doc_util'
4
- require 'resource_doc'
5
- require 'rapi_config'
6
- require 'rapi_doc/railtie' if defined?(Rails)
3
+ require_relative 'rapi_doc/resource_doc'
4
+ require_relative 'rapi_doc/rapi_config'
5
+ require_relative 'rapi_doc/railtie' if defined?(Rails)
7
6
 
8
7
  module RapiDoc
9
- class RAPIDoc
8
+ module RAPIDoc
10
9
 
11
10
  include RapiConfig
11
+ include FileUtils::Verbose # so that each mv/cp/mkdir gets printed and user is aware of what is happening
12
12
 
13
- # Initalize the ApiDocGenerator
14
- def initialize(resources)
15
- puts "Apidoc started..."
16
- @resources = resources
17
- generate_templates!
18
- move_structure!
19
- puts "Finished."
13
+ def create_structure!
14
+ File.directory?(config_dir) || mkdir(config_dir)
15
+ Dir["#{template_dir}/*.*"].each do |template_file|
16
+ target_file = config_dir(File.basename(template_file))
17
+ cp template_file, config_dir if not File.exist? target_file
18
+ end
20
19
  end
21
20
 
22
- # Iterates over the resources creates views for them.
23
- # Creates an index file
24
- def generate_templates!
21
+ # Reads 'rake routes' output and gets the controller info
22
+ def get_controller_info!
23
+ controller_info = {}
24
+ routes = Dir.chdir(::Rails.root.to_s) { `rake routes` }
25
+ routes.split("\n").each do |entry|
26
+ method, url, controller_action = entry.split.slice(-3, 3)
27
+ controller, action = controller_action.split('#')
28
+ puts "For \"#{controller}\", found action \"#{action}\" with #{method} at \"#{url}\""
29
+ controller_info[controller] ||= []
30
+ controller_info[controller] << [action, method, url]
31
+ end
32
+ controller_info
33
+ end
25
34
 
26
- @resources.each do |r|
27
- r.parse_apidoc!
28
- r.generate_view!(@resources, temp_dir)
35
+ def get_resources!
36
+ #yml = get_config || []
37
+ #yml.collect { |key, val| ResourceDoc.new(key, val["location"], controller_dir(val["controller_name"])) }
38
+ controller_info = get_controller_info!
39
+ resources = []
40
+ controller_info.each do |controller, action_entries|
41
+ #controller_class = controller.capitalize + 'Controller'
42
+ controller_location = controller_dir(controller + '_controller.rb')
43
+ controller_base_routes = action_entries.select do |action, method, url|
44
+ url.index('/', 1).nil?
45
+ end
46
+ # base urls differ only by the method [GET or POST]. So, any one will do.
47
+ controller_url = controller_base_routes[0][2].gsub(/\(.*\)/, '') # omit the trailing format
48
+ #controller_methods = controller_base_routes.map { |action, method, url| method }
49
+ if block_given?
50
+ controller_include = yield [controller, controller_url, controller_location]
51
+ else
52
+ controller_include = true
53
+ end
54
+ resources << ResourceDoc.new(controller, controller_url, controller_location) if controller_include
29
55
  end
30
- generate_index!
31
- copy_styles!
56
+ resources
32
57
  end
33
58
 
34
- # generate the index file for the api views
35
- def generate_index!
36
- template = ""
37
- @page_type2 = 'dudul'
38
- File.open(class_layout_file(:target)).each { |line| template << line }
39
- parsed = ERB.new(template).result(binding)
40
- File.open(File.join(temp_dir, "class.html"), 'w') { |file| file.write parsed }
59
+ # Generates views and their index in a temp directory
60
+ def generate_templates!(resource_docs)
61
+ generate_resource_templates!(resource_docs)
62
+ copy_styles!
41
63
  end
42
64
 
65
+ # Moves the generated files in the temp directory to target directory
43
66
  def move_structure!
44
- target_folder = "#{::Rails.root.to_s}/public/apidoc/"
45
- Dir.mkdir(target_folder) if (!File.directory?(target_folder))
67
+ Dir.mkdir(target_dir) if (!File.directory?(target_dir))
68
+ # Only want to move the .html, .css, .png and .js files, not the .haml templates.
69
+ html_css_files = temp_dir("*.{html,css,js,png}")
70
+ Dir[html_css_files].each { |f| mv f, target_dir }
71
+ end
46
72
 
47
- # Copy the frameset & main files
48
- FileUtils.cp frameset_file(:target), target_folder + 'index.html'
49
- FileUtils.cp main_file(:target), target_folder + 'main.html'
73
+ # Removes the generated files
74
+ def remove_structure!
75
+ rm_rf target_dir
76
+ end
50
77
 
51
- Dir.new(temp_dir).each do |d|
52
- if d =~ /^[a-zA-Z]+\.(html|css)$/ # Only want to copy over the .html files, not the .erb templates
53
- FileUtils.cp File.join(temp_dir + d), target_folder + d
54
- end
78
+ # Remove all files - config and generated
79
+ def remove_all!
80
+ remove_structure!
81
+ rm_rf config_dir
82
+ end
55
83
 
56
- #Clean up the no longer needed files
57
- filepath = "#{temp_dir}/#{d}"
58
- File.delete(filepath) unless File.directory?(filepath)
59
- end
84
+ # Creates views for the resources
85
+ def generate_resource_templates!(resource_docs)
86
+ class_template = IO.read(template_dir('_resource_header.html.haml'))
87
+ method_template = IO.read(template_dir('_resource_method.html.haml'))
88
+ resource_docs.each { |resource| resource.parse_apidoc!(class_template, method_template) }
89
+ template = IO.read(config_dir('index.html.haml'))
90
+ parsed = Haml::Engine.new(template).render(Object.new, :resource_docs => resource_docs)
91
+ File.open(temp_dir("index.html"), 'w') { |file| file.write parsed }
60
92
  end
61
93
 
62
94
  def copy_styles!
63
- Dir[File.join(File.dirname(__FILE__), '..', 'templates/*')].each do |f|
64
- if f =~ /[\/a-zA-Z\.]+\.css$/i
65
- FileUtils.cp f, temp_dir
66
- end
67
- end
95
+ css_js_files = config_dir("*.{css,js,png}")
96
+ Dir[css_js_files].each { |f| cp f, temp_dir }
68
97
  end
69
98
 
70
- private
71
-
72
- def temp_dir
73
- @temp_dir ||= "#{Dir.mktmpdir("apidoc")}/"
74
- end
75
99
  end
76
100
  end
@@ -0,0 +1,71 @@
1
+ module RapiDoc
2
+ # This class holds methods about a doc.
3
+ class MethodDoc
4
+ attr_accessor :scope, :method_order, :content, :request, :response, :outputs, :params
5
+
6
+ def initialize(resource_name, type, order)
7
+ @resource_name = resource_name
8
+ @scope = type
9
+ @method_order = order
10
+ @content = ""
11
+ @request = ""
12
+ @response = ""
13
+ @outputs = {}
14
+ @params = []
15
+ end
16
+
17
+ def process_line(line, current_scope)
18
+ #puts "In scope #{current_scope} processing: #{line}"
19
+ new_scope = current_scope
20
+ case current_scope
21
+ when :response
22
+ if line =~ /::response-end::/
23
+ new_scope = :function
24
+ else
25
+ @response << line
26
+ end
27
+ when :request
28
+ if line =~ /::request-end::/
29
+ new_scope = :function
30
+ else
31
+ @request << line
32
+ end
33
+ when :output # append output
34
+ if line =~ /::output-end::/
35
+ new_scope = :function
36
+ else
37
+ last_output_key = @outputs.keys.last
38
+ @outputs[last_output_key] << ERB::Util.html_escape(line)
39
+ end
40
+ when :class, :function
41
+ result = line.scan(/(\w+)\:\:\s*(.+)/)
42
+ if not result.empty?
43
+ key, value = result[0]
44
+ case key
45
+ when "response", "request"
46
+ new_scope = key.to_sym
47
+ when "output"
48
+ new_scope = key.to_sym
49
+ @outputs[value] = '' # add the new output format as a key
50
+ when "param"
51
+ @params << value
52
+ else # user wants this new shiny variable whose name is the key with value = value
53
+ instance_variable_set("@#{key}".to_sym, value)
54
+ define_singleton_method(key.to_sym) { value } # define accessor for the templates to read it
55
+ end
56
+ else
57
+ # add line to block
58
+ @content << line
59
+ end
60
+ else
61
+ raise ParsingException, "logic error: unknown current scope #{current_scope}"
62
+ end
63
+ new_scope
64
+ end
65
+
66
+ def get_binding
67
+ binding
68
+ end
69
+
70
+ end
71
+ end