sinatra-docdsl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/docdsl.rb +194 -0
  2. metadata +48 -0
data/lib/docdsl.rb ADDED
@@ -0,0 +1,194 @@
1
+ module Sinatra
2
+ module DocDsl
3
+
4
+ class PageDoc
5
+ attr_accessor :the_title,:the_header,:the_footer,:the_introduction
6
+
7
+ def initialize(&block)
8
+ @the_title='DocDSL Documentation'
9
+ @the_header="API"
10
+ @the_introduction="API Documentation for this resource"
11
+ @the_footer="Powered by <strong>Sinatra DocDSL</strong>"
12
+
13
+ if(block)
14
+ if block.arity == 1
15
+ block(self)
16
+ else
17
+ instance_eval(&block)
18
+ end
19
+ end
20
+ end
21
+
22
+ def title(t)
23
+ @the_title=t
24
+ end
25
+
26
+ def header(h)
27
+ @the_header=h
28
+ end
29
+
30
+ def footer(f)
31
+ @the_footer=f
32
+ end
33
+
34
+ def introduction(i)
35
+ @the_introduction=i
36
+ end
37
+ end
38
+
39
+ class DocEntry
40
+ attr_accessor :desc,:params,:paths,:query_params,:headers,:the_payload,:the_response
41
+
42
+ def initialize(description, &block)
43
+ @paths=[]
44
+ @desc=description
45
+ @params={}
46
+ @query_params={}
47
+ @headers={}
48
+ @the_payload=nil
49
+ @the_response=nil
50
+ if(block)
51
+ if block.arity == 1
52
+ block(self)
53
+ else
54
+ instance_eval(&block)
55
+ end
56
+ end
57
+ end
58
+
59
+ def <<(path)
60
+ self.paths << path
61
+ end
62
+
63
+ def to_s
64
+ self.inspect
65
+ end
66
+
67
+ def inspect
68
+ "#{@paths.join(', ')} # #{@desc}"
69
+ end
70
+
71
+ def describe(desc)
72
+ @desc=desc
73
+ end
74
+
75
+ def payload(desc)
76
+ @the_payload=desc
77
+ end
78
+
79
+ def response(desc)
80
+ @the_response=desc
81
+ end
82
+
83
+ def param(name,desc)
84
+ @params[name]=desc
85
+ end
86
+
87
+ def header(name,desc)
88
+ @headers[name]=desc
89
+ end
90
+
91
+ def query_param(name,desc)
92
+ @query_params[name]=desc
93
+ end
94
+
95
+ end
96
+
97
+ def self.registered(app)
98
+ app.get '/doc' do
99
+ app.instance_eval { render_docs_page(@docs) }
100
+ end
101
+ end
102
+
103
+ def page(&block)
104
+ @page_doc = PageDoc.new(&block)
105
+ end
106
+
107
+ def documentation(description,&block)
108
+ @last_doc=DocEntry.new(description,&block)
109
+ (@docs ||= []) << @last_doc
110
+ end
111
+
112
+ def method_added(method)
113
+ # don't document /doc
114
+ return if method.to_s =~ /(^(GET|HEAD) \/doc\z)/
115
+ # document the method and nullify last_doc so that a new one gets created for the next method
116
+ if method.to_s =~ /(GET|POST|PUT|DELETE|UPDATE|HEAD)/ && @last_doc
117
+ @last_doc << method
118
+ @last_doc = nil
119
+ end
120
+ super
121
+ end
122
+
123
+ def render_docs_list(entries)
124
+ entries.inject('') { | markup, entry|
125
+ path = entry.paths.join(', ')
126
+ if entry.params.length >0
127
+ params = entry.params.inject("<h3>Url Parameters</h3>\n<dl>") { |li,(k,v)|
128
+ li << "<dt>:%s</dt><dd>%s</dd>" % [k,v]
129
+ }
130
+ params << "</dl>\n"
131
+ end
132
+ params ||= ''
133
+
134
+ if entry.query_params.length >0
135
+ query_params = entry.query_params.inject("<h3>Query Parameters</h3>\n<dl>") { |li,(k,v)|
136
+ li << "<dt>:%s</dt><dd>%s</dd>" % [k,v]
137
+ }
138
+ query_params << "</dl>\n"
139
+ end
140
+ query_params ||=''
141
+
142
+
143
+ if entry.query_params.length >0
144
+ headers = entry.headers.inject("<h3>Header Parameters</h3>\n<dl>") { |li,(k,v)|
145
+ li << "<dt>:%s</dt><dd>%s</dd>" % [k,v]
146
+ }
147
+ headers << "</dl>\n"
148
+ end
149
+ headers ||= ''
150
+
151
+ if entry.the_payload
152
+ payload="<dt>Payload</dt><dd>#{entry.the_payload}</dd>"
153
+ end
154
+ payload ||=''
155
+ if entry.the_response
156
+ response="<dt>Payload</dt><dd>#{entry.the_response}</dd>"
157
+ end
158
+ response ||=''
159
+
160
+ markup << "<h2>%s</h2>\n<p>%s</p>\n%s%s%s%s%s" % [path, entry.desc, params, query_params, headers,payload,response]
161
+ } << ""
162
+ end
163
+
164
+ def render_docs_page(entries)
165
+ begin
166
+ @page_doc ||= PageDoc.new
167
+ body= <<-HTML
168
+ <html>
169
+ <head>
170
+ <title>#{@page_doc.the_title}</title>
171
+ <style type="text/css">
172
+ #container{width:960px; margin:1em auto; font-family:monaco, monospace;}
173
+ dt{ background:#f5f5f5; font-weight:bold; float:left; margin-right:1em; }
174
+ dd{ margin-left:1em; }
175
+ </style>
176
+ </head>
177
+ <body>
178
+ <div id="container">
179
+ <h1 id="title">#{@page_doc.the_header}</h1>
180
+ <p>#{@page_doc.the_introduction}</p>
181
+
182
+ #{render_docs_list(entries)}
183
+ <p>#{@page_doc.the_footer}</p>
184
+ </div>
185
+ </body>
186
+ </html>
187
+ HTML
188
+ rescue => e
189
+ puts e.to_s
190
+ end
191
+ [200,body]
192
+ end
193
+ end
194
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-docdsl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jilles van Gurp
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-31 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A simple DSL for documenting Sinatra apps and generating a /doc endpoint in a sinatra resource
15
+ email: incoming@jillesvangurp.xom
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/docdsl.rb
21
+ homepage: https://github.com/jillesvangurp/sinatra-docdsl
22
+ licenses: []
23
+ post_install_message:
24
+ rdoc_options: []
25
+ require_paths:
26
+ - lib
27
+ required_ruby_version: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: !binary |-
32
+ MA==
33
+ none: false
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: !binary |-
39
+ MA==
40
+ none: false
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 1.8.24
44
+ signing_key:
45
+ specification_version: 3
46
+ summary: Documentation DSL for Sinatra
47
+ test_files: []
48
+ has_rdoc: