spacedocs 0.0.2
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/README.md +29 -0
- data/dox/History.md +57 -0
- data/dox/Makefile +24 -0
- data/dox/Readme.md +332 -0
- data/dox/bin/dox +47 -0
- data/dox/index.js +2 -0
- data/dox/lib/dox.js +286 -0
- data/dox/lib/utils.js +15 -0
- data/dox/package.json +16 -0
- data/dox/test/dox.test.js +287 -0
- data/dox/test/fixtures/a.js +12 -0
- data/dox/test/fixtures/b.js +26 -0
- data/dox/test/fixtures/c.js +266 -0
- data/dox/test/fixtures/d.js +15 -0
- data/dox/test/fixtures/titles.js +14 -0
- data/lib/assets/stylesheets/spacedocs/docs.css.sass +155 -0
- data/lib/spacedocs/engine.rb +6 -0
- data/lib/spacedocs/version.rb +3 -0
- data/lib/spacedocs.rb +215 -0
- data/source/class.html.haml +98 -0
- data/source/index.html.haml +16 -0
- metadata +73 -0
@@ -0,0 +1,266 @@
|
|
1
|
+
|
2
|
+
/*!
|
3
|
+
* Dox
|
4
|
+
* Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
5
|
+
* MIT Licensed
|
6
|
+
*/
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Module dependencies.
|
10
|
+
*/
|
11
|
+
|
12
|
+
var markdown = require('github-flavored-markdown').parse;
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Library version.
|
16
|
+
*/
|
17
|
+
|
18
|
+
exports.version = '0.0.5';
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Parse comments in the given string of `js`.
|
22
|
+
*
|
23
|
+
* @param {String} js
|
24
|
+
* @return {Array}
|
25
|
+
* @see exports.parseComment
|
26
|
+
* @api public
|
27
|
+
*/
|
28
|
+
|
29
|
+
exports.parseComments = function(js){
|
30
|
+
var comments = []
|
31
|
+
, comment
|
32
|
+
, buf = ''
|
33
|
+
, ignore
|
34
|
+
, within
|
35
|
+
, code;
|
36
|
+
|
37
|
+
for (var i = 0, len = js.length; i < len; ++i) {
|
38
|
+
// start comment
|
39
|
+
if ('/' == js[i] && '*' == js[i+1]) {
|
40
|
+
// code following previous comment
|
41
|
+
if (buf.trim().length) {
|
42
|
+
comment = comments[comments.length - 1];
|
43
|
+
comment.code = code = buf.trim();
|
44
|
+
comment.ctx = exports.parseCodeContext(code);
|
45
|
+
buf = '';
|
46
|
+
}
|
47
|
+
i += 2;
|
48
|
+
within = true;
|
49
|
+
ignore = '!' == js[i];
|
50
|
+
// end comment
|
51
|
+
} else if ('*' == js[i] && '/' == js[i+1]) {
|
52
|
+
i += 2;
|
53
|
+
buf = buf.replace(/^ *\* ?/gm, '');
|
54
|
+
var comment = exports.parseComment(buf);
|
55
|
+
comment.ignore = ignore;
|
56
|
+
comments.push(comment);
|
57
|
+
within = ignore = false;
|
58
|
+
buf = '';
|
59
|
+
// buffer comment or code
|
60
|
+
} else {
|
61
|
+
buf += js[i];
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
// trailing code
|
66
|
+
if (buf.trim().length) {
|
67
|
+
comment = comments[comments.length - 1];
|
68
|
+
code = buf.trim();
|
69
|
+
comment.code = code;
|
70
|
+
}
|
71
|
+
|
72
|
+
return comments;
|
73
|
+
};
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Parse the given comment `str`.
|
77
|
+
*
|
78
|
+
* The comment object returned contains the following:
|
79
|
+
*
|
80
|
+
* - `tags` array of tag objects
|
81
|
+
* - `description` the first line of the comment
|
82
|
+
* - `body` lines following the description
|
83
|
+
* - `content` both the description and the body
|
84
|
+
* - `isPrivate` true when "@api private" is used
|
85
|
+
*
|
86
|
+
* @param {String} str
|
87
|
+
* @return {Object}
|
88
|
+
* @see exports.parseTag
|
89
|
+
* @api public
|
90
|
+
*/
|
91
|
+
|
92
|
+
exports.parseComment = function(str) {
|
93
|
+
str = str.trim();
|
94
|
+
var comment = { tags: [] }
|
95
|
+
, description = {};
|
96
|
+
|
97
|
+
// parse comment body
|
98
|
+
description.full = str.split('@')[0].replace(/^([\w ]+):/gm, '## $1');
|
99
|
+
description.summary = description.full.split('\n\n')[0];
|
100
|
+
description.body = description.full.split('\n\n').slice(1).join('\n\n');
|
101
|
+
comment.description = description;
|
102
|
+
|
103
|
+
// parse tags
|
104
|
+
if (~str.indexOf('@')) {
|
105
|
+
var tags = '@' + str.split('@').slice(1).join('@');
|
106
|
+
comment.tags = tags.split('\n').map(exports.parseTag);
|
107
|
+
comment.isPrivate = comment.tags.some(function(tag){
|
108
|
+
return 'api' == tag.type && 'private' == tag.visibility;
|
109
|
+
})
|
110
|
+
}
|
111
|
+
|
112
|
+
// markdown
|
113
|
+
description.full = markdown(escape(description.full));
|
114
|
+
description.summary = markdown(escape(description.summary));
|
115
|
+
description.body = markdown(escape(description.body));
|
116
|
+
|
117
|
+
return comment;
|
118
|
+
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* Parse tag string "@param {Array} name description" etc.
|
122
|
+
*
|
123
|
+
* @param {String}
|
124
|
+
* @return {Object}
|
125
|
+
* @api public
|
126
|
+
*/
|
127
|
+
|
128
|
+
exports.parseTag = function(str) {
|
129
|
+
var tag = {}
|
130
|
+
, parts = str.split(/ +/)
|
131
|
+
, type = tag.type = parts.shift().replace('@', '');
|
132
|
+
|
133
|
+
/* shouldn't fail */
|
134
|
+
switch (type) { // asfasdfasdf /** /////
|
135
|
+
case 'param':
|
136
|
+
tag.types = exports.parseTagTypes(parts.shift());
|
137
|
+
tag.name = parts.shift() || '';
|
138
|
+
tag.description = parts.join(' ');
|
139
|
+
break;
|
140
|
+
case 'return':
|
141
|
+
tag.types = exports.parseTagTypes(parts.shift());
|
142
|
+
tag.description = parts.join(' ');
|
143
|
+
break;
|
144
|
+
case 'see':
|
145
|
+
if (~str.indexOf('http')) {
|
146
|
+
tag.title = parts.length > 1
|
147
|
+
? parts.shift()
|
148
|
+
: '';
|
149
|
+
tag.url = parts.join(' ');
|
150
|
+
} else {
|
151
|
+
tag.local = parts.join(' ');
|
152
|
+
}
|
153
|
+
case 'api':
|
154
|
+
tag.visibility = parts.shift();
|
155
|
+
break;
|
156
|
+
case 'type':
|
157
|
+
tag.types = exports.parseTagTypes(parts.shift());
|
158
|
+
break;
|
159
|
+
}
|
160
|
+
|
161
|
+
return tag;
|
162
|
+
}
|
163
|
+
|
164
|
+
/**
|
165
|
+
* Parse tag type string "{Array|Object}" etc.
|
166
|
+
*
|
167
|
+
* @param {String} str
|
168
|
+
* @return {Array}
|
169
|
+
* @api public
|
170
|
+
*/
|
171
|
+
|
172
|
+
exports.parseTagTypes = function(str) {
|
173
|
+
return str
|
174
|
+
.replace(/[{}]/g, '')
|
175
|
+
.split(/ *[|,\/] */);
|
176
|
+
};
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Parse the context from the given `str` of js.
|
180
|
+
*
|
181
|
+
* This method attempts to discover the context
|
182
|
+
* for the comment based on it's code. Currently
|
183
|
+
* supports:
|
184
|
+
*
|
185
|
+
* - function statements
|
186
|
+
* - function expressions
|
187
|
+
* - prototype methods
|
188
|
+
* - prototype properties
|
189
|
+
* - methods
|
190
|
+
* - properties
|
191
|
+
* - declarations
|
192
|
+
*
|
193
|
+
* @param {String} str
|
194
|
+
* @return {Object}
|
195
|
+
* @api public
|
196
|
+
*/
|
197
|
+
|
198
|
+
exports.parseCodeContext = function(str){
|
199
|
+
var str = str.split('\n')[0];
|
200
|
+
|
201
|
+
// function statement
|
202
|
+
if (/^function (\w+)\(/.exec(str)) {
|
203
|
+
return {
|
204
|
+
type: 'function'
|
205
|
+
, name: RegExp.$1
|
206
|
+
};
|
207
|
+
// function expression
|
208
|
+
} else if (/^var *(\w+) *= *function/.exec(str)) {
|
209
|
+
return {
|
210
|
+
type: 'function'
|
211
|
+
, name: RegExp.$1
|
212
|
+
};
|
213
|
+
// prototype method
|
214
|
+
} else if (/^(\w+)\.prototype\.(\w+) *= *function/.exec(str)) {
|
215
|
+
return {
|
216
|
+
type: 'method'
|
217
|
+
, constructor: RegExp.$1
|
218
|
+
, name: RegExp.$2
|
219
|
+
};
|
220
|
+
// prototype property
|
221
|
+
} else if (/^(\w+)\.prototype\.(\w+) *= *([^\n;]+)/.exec(str)) {
|
222
|
+
return {
|
223
|
+
type: 'property'
|
224
|
+
, constructor: RegExp.$1
|
225
|
+
, name: RegExp.$2
|
226
|
+
, value: RegExp.$3
|
227
|
+
};
|
228
|
+
// method
|
229
|
+
} else if (/^(\w+)\.(\w+) *= *function/.exec(str)) {
|
230
|
+
return {
|
231
|
+
type: 'method'
|
232
|
+
, receiver: RegExp.$1
|
233
|
+
, name: RegExp.$2
|
234
|
+
};
|
235
|
+
// property
|
236
|
+
} else if (/^(\w+)\.(\w+) *= *([^\n;]+)/.exec(str)) {
|
237
|
+
return {
|
238
|
+
type: 'property'
|
239
|
+
, receiver: RegExp.$1
|
240
|
+
, name: RegExp.$2
|
241
|
+
, value: RegExp.$3
|
242
|
+
};
|
243
|
+
// declaration
|
244
|
+
} else if (/^var +(\w+) *= *([^\n;]+)/.exec(str)) {
|
245
|
+
return {
|
246
|
+
type: 'declaration'
|
247
|
+
, name: RegExp.$1
|
248
|
+
, value: RegExp.$2
|
249
|
+
};
|
250
|
+
}
|
251
|
+
};
|
252
|
+
|
253
|
+
/**
|
254
|
+
* Escape the given `html`.
|
255
|
+
*
|
256
|
+
* @param {String} html
|
257
|
+
* @return {String}
|
258
|
+
* @api private
|
259
|
+
*/
|
260
|
+
|
261
|
+
function escape(html){
|
262
|
+
return String(html)
|
263
|
+
.replace(/&(?!\w+;)/g, '&')
|
264
|
+
.replace(/</g, '<')
|
265
|
+
.replace(/>/g, '>');
|
266
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
/**
|
3
|
+
* Parse tag type string "{Array|Object}" etc.
|
4
|
+
*
|
5
|
+
* @name is arbitrary
|
6
|
+
* @param {String} str
|
7
|
+
* @return {Array}
|
8
|
+
* @api public
|
9
|
+
*/
|
10
|
+
|
11
|
+
exports.parseTagTypes = function(str) {
|
12
|
+
return str
|
13
|
+
.replace(/[{}]/g, '')
|
14
|
+
.split(/ *[|,\/] */);
|
15
|
+
};
|
@@ -0,0 +1,155 @@
|
|
1
|
+
@import compass/css3
|
2
|
+
|
3
|
+
$width: 600px
|
4
|
+
|
5
|
+
html
|
6
|
+
color: #222
|
7
|
+
height: 100%
|
8
|
+
|
9
|
+
body
|
10
|
+
+background-image(linear-gradient(135deg, rgba(0, 0, 0, 0.05) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0.05) 75%, transparent 75%, transparent))
|
11
|
+
-webkit-background-size: 4px 4px
|
12
|
+
|
13
|
+
font-family: 'Lucida Grande', Arial, sans-serif
|
14
|
+
font-size: 13px
|
15
|
+
height: 100%
|
16
|
+
margin: 0
|
17
|
+
|
18
|
+
.method_list
|
19
|
+
+border-radius(5px)
|
20
|
+
+box-shadow(rgba(0,0,0,0.15) 0 0 15px)
|
21
|
+
|
22
|
+
position: fixed
|
23
|
+
top: 20px
|
24
|
+
right: 20px
|
25
|
+
background-color: white
|
26
|
+
border: 1px solid rgba(0, 0, 0, 0.3)
|
27
|
+
max-width: 210px
|
28
|
+
text-align: center
|
29
|
+
margin: 0
|
30
|
+
padding: 0.25em 0.5em
|
31
|
+
|
32
|
+
h3
|
33
|
+
text-align: center
|
34
|
+
margin: 0
|
35
|
+
margin-top: 0.5em
|
36
|
+
|
37
|
+
a
|
38
|
+
color: #222
|
39
|
+
display: inline-block
|
40
|
+
padding: 0.4em 0.5em
|
41
|
+
text-decoration: none
|
42
|
+
|
43
|
+
nav
|
44
|
+
+background-image(linear-gradient(45deg, rgba(0, 0, 0, 0.05) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0.05) 75%, transparent 75%, transparent))
|
45
|
+
+box-shadow(rgba(0, 0, 0, 0.15) -1px 0 4px inset)
|
46
|
+
-webkit-background-size: 12px 12px
|
47
|
+
display: inline-block
|
48
|
+
width: 130px
|
49
|
+
height: 100%
|
50
|
+
border-right: 1px solid rgba(0, 0, 0, 0.2)
|
51
|
+
background-color: rgba(0, 0, 0, 0.15)
|
52
|
+
padding: 0.5em 0
|
53
|
+
position: fixed
|
54
|
+
left: 0
|
55
|
+
overflow: auto
|
56
|
+
top: 0
|
57
|
+
|
58
|
+
a
|
59
|
+
+box-sizing(border-box)
|
60
|
+
|
61
|
+
border: 1px solid transparent
|
62
|
+
color: #222
|
63
|
+
display: block
|
64
|
+
text-decoration: none
|
65
|
+
padding: 0.5em 0 0.5em 1em
|
66
|
+
|
67
|
+
&.active
|
68
|
+
+border-left-radius(5px)
|
69
|
+
+box-shadow(rgba(0, 0, 0, 0.2) 0 0 4px)
|
70
|
+
|
71
|
+
background-image: -webkit-linear-gradient(135deg, rgba(0, 0, 0, 0.05) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0.05) 75%, transparent 75%, transparent)
|
72
|
+
background-color: white
|
73
|
+
background-size: 4px 4px
|
74
|
+
padding: 0.5em 0 0.5em 0.5em
|
75
|
+
margin-left: 0.5em
|
76
|
+
border-right: 1px white
|
77
|
+
border: 1px solid rgba(0, 0, 0, 0.3)
|
78
|
+
border-right: 1px solid rgba(0, 0, 0, 0.15)
|
79
|
+
|
80
|
+
.documentation
|
81
|
+
display: inline-block
|
82
|
+
max-width: $width
|
83
|
+
padding-left: 145px
|
84
|
+
vertical-align: top
|
85
|
+
|
86
|
+
a, a:active, a:visited, a:hover
|
87
|
+
color: #307EB6
|
88
|
+
|
89
|
+
h1, h2, h3, h4, h5
|
90
|
+
display: inline-block
|
91
|
+
margin: 0
|
92
|
+
|
93
|
+
h1
|
94
|
+
font-size: 1.5em
|
95
|
+
|
96
|
+
p
|
97
|
+
margin: 0.5em 0
|
98
|
+
|
99
|
+
ul
|
100
|
+
margin: 0
|
101
|
+
padding-left: 1em
|
102
|
+
list-style: none
|
103
|
+
|
104
|
+
li
|
105
|
+
padding-top: 0.5em
|
106
|
+
|
107
|
+
.returns
|
108
|
+
p
|
109
|
+
margin-left: 1em
|
110
|
+
|
111
|
+
section
|
112
|
+
margin-bottom: 0.75em
|
113
|
+
|
114
|
+
.source pre
|
115
|
+
display: none
|
116
|
+
|
117
|
+
.toggle_source
|
118
|
+
cursor: pointer
|
119
|
+
|
120
|
+
pre
|
121
|
+
margin: 0.5em 0
|
122
|
+
|
123
|
+
.param_name
|
124
|
+
font-style: italic
|
125
|
+
|
126
|
+
.description
|
127
|
+
margin-left: 1em
|
128
|
+
|
129
|
+
p code
|
130
|
+
+border-radius(4px)
|
131
|
+
+box-shadow(rgba(0, 0, 0, 0.15) 0 0 4px inset)
|
132
|
+
|
133
|
+
background-color: #EEE
|
134
|
+
border: 1px solid rgba(0, 0, 0, 0.2)
|
135
|
+
padding: 0 0.3em
|
136
|
+
|
137
|
+
.description, .source
|
138
|
+
pre
|
139
|
+
+border-radius(4px)
|
140
|
+
+box-shadow(rgba(0, 0, 0, 0.15) 0 0 4px inset)
|
141
|
+
+box-sizing(border-box)
|
142
|
+
|
143
|
+
border: 1px solid rgba(0, 0, 0, 0.2)
|
144
|
+
background-color: #EEE
|
145
|
+
max-width: $width
|
146
|
+
padding: 0.5em 1em
|
147
|
+
|
148
|
+
hr
|
149
|
+
margin-left: 1px
|
150
|
+
margin-top: 1em
|
151
|
+
margin-bottom: 1em
|
152
|
+
max-width: $width
|
153
|
+
|
154
|
+
&:last-child
|
155
|
+
display: none
|
data/lib/spacedocs.rb
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
require 'haml'
|
3
|
+
require 'json'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Spacedocs
|
7
|
+
class << self
|
8
|
+
def doc(project_dir, file)
|
9
|
+
tilt_path = File.dirname(__FILE__)
|
10
|
+
|
11
|
+
#TODO Dangerous
|
12
|
+
json = %x[dox < "#{File.join project_dir, file}"]
|
13
|
+
|
14
|
+
doc_json = JSON.parse json
|
15
|
+
|
16
|
+
processed_data = process_data doc_json
|
17
|
+
|
18
|
+
template = Tilt.new(File.join tilt_path, "../source/class.html.haml")
|
19
|
+
index_template = Tilt.new(File.join tilt_path, "../source/index.html.haml")
|
20
|
+
|
21
|
+
files = {}
|
22
|
+
|
23
|
+
class_data = processed_data[:docs_data]
|
24
|
+
|
25
|
+
class_data.each_key do |namespace|
|
26
|
+
files[namespace] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
docs_dir = File.join(project_dir, 'docs')
|
30
|
+
|
31
|
+
FileUtils.rm_rf docs_dir
|
32
|
+
FileUtils.mkdir_p docs_dir
|
33
|
+
|
34
|
+
if __FILE__ == $0
|
35
|
+
File.open("source/index.html", 'w') do |f|
|
36
|
+
f.write(index_template.render self, { class_names: files.keys, dev: true })
|
37
|
+
end
|
38
|
+
|
39
|
+
files.each_key do |file_name|
|
40
|
+
methods = class_data[file_name]['methods']
|
41
|
+
|
42
|
+
File.open("source/#{file_name}.html", 'w') do |f|
|
43
|
+
f.write(template.render self, {
|
44
|
+
class_name: file_name,
|
45
|
+
method_list: methods.keys,
|
46
|
+
methods: methods,
|
47
|
+
class_names: files.keys,
|
48
|
+
class_summary: class_data[file_name]['summary'],
|
49
|
+
dev: true
|
50
|
+
})
|
51
|
+
end
|
52
|
+
end
|
53
|
+
else
|
54
|
+
File.open(File.join(project_dir, "docs/index.html"), 'w') do |f|
|
55
|
+
f.write(index_template.render self, { class_names: files.keys })
|
56
|
+
end
|
57
|
+
|
58
|
+
files.each_key do |file_name|
|
59
|
+
methods = class_data[file_name]['methods']
|
60
|
+
|
61
|
+
File.open(File.join(project_dir, "docs/#{file_name}.html"), 'w') do |f|
|
62
|
+
f.write(template.render self, {
|
63
|
+
class_name: file_name,
|
64
|
+
method_list: methods.keys,
|
65
|
+
methods: methods,
|
66
|
+
class_names: files.keys,
|
67
|
+
class_summary: class_data[file_name]['summary'],
|
68
|
+
dev: false
|
69
|
+
})
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
def tags_named(name, tags)
|
77
|
+
tags.map do |tag|
|
78
|
+
tag['string'] if tag['type'] == name
|
79
|
+
end.compact
|
80
|
+
end
|
81
|
+
|
82
|
+
def method_of_data(tags)
|
83
|
+
tags_named('methodOf', tags)
|
84
|
+
end
|
85
|
+
|
86
|
+
def name_data(tags)
|
87
|
+
tags_named('name', tags)
|
88
|
+
end
|
89
|
+
|
90
|
+
def format_class_name(name)
|
91
|
+
if name.end_with?('#')
|
92
|
+
name[0...-1]
|
93
|
+
else
|
94
|
+
name
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def params_data(tags)
|
99
|
+
tags.each_with_object({}) do |tag, hash|
|
100
|
+
if tag['type'] == 'param'
|
101
|
+
hash["#{tag['name'].gsub(/[\[\]]/, '')}"] = {
|
102
|
+
"type" => tag['types'].join(', '),
|
103
|
+
"description" => tag['description'],
|
104
|
+
"optional" => tag['name'].start_with?('[')
|
105
|
+
}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def returns_data(tags)
|
111
|
+
tags.map do |tag|
|
112
|
+
if tag['type'] == 'returns'
|
113
|
+
description = tag['string'].split ' '
|
114
|
+
|
115
|
+
type = description.shift.gsub(/[{}]/, '')
|
116
|
+
remaining = description.join ' '
|
117
|
+
|
118
|
+
{ "type" => type, "description" => remaining }
|
119
|
+
end
|
120
|
+
end.compact
|
121
|
+
end
|
122
|
+
|
123
|
+
def see_data(tags)
|
124
|
+
tags_named('see', tags)
|
125
|
+
end
|
126
|
+
|
127
|
+
def class_name_data(tags)
|
128
|
+
class_names = []
|
129
|
+
|
130
|
+
tags.each do |tag|
|
131
|
+
class_names << format_class_name(tag['string']) if tag['type'] == 'methodOf'
|
132
|
+
|
133
|
+
if ['constructor', 'namespace'].include? tag['type']
|
134
|
+
tags.each do |tag|
|
135
|
+
class_names << tag['string'] if tag['type'] == 'name'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class_names.first
|
141
|
+
end
|
142
|
+
|
143
|
+
def process_data(json)
|
144
|
+
class_names = []
|
145
|
+
tags_list = []
|
146
|
+
docs_data = {}
|
147
|
+
module_map = {}
|
148
|
+
class_summaries = {}
|
149
|
+
|
150
|
+
json.each do |item|
|
151
|
+
tags = item['tags']
|
152
|
+
|
153
|
+
tags.each do |tag|
|
154
|
+
if ['constructor', 'namespace'].include? tag['type']
|
155
|
+
class_summaries[class_name_data(tags)] ||= {}
|
156
|
+
class_summaries[class_name_data(tags)]['description'] ||= {}
|
157
|
+
|
158
|
+
class_summaries[class_name_data(tags)]['description']['summary'] = item['description']['summary'] || ""
|
159
|
+
class_summaries[class_name_data(tags)]['description']['body'] = item['description']['body'] || ""
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
tags_list << tags
|
164
|
+
|
165
|
+
name = name_data(tags).first
|
166
|
+
returns = returns_data(tags).first || {}
|
167
|
+
see = see_data(tags).first || ""
|
168
|
+
method_of = method_of_data(tags).first
|
169
|
+
params = params_data(tags)
|
170
|
+
|
171
|
+
class_names << class_name_data(tags)
|
172
|
+
|
173
|
+
if name && method_of
|
174
|
+
if method_of.end_with?('#')
|
175
|
+
name = "##{name}"
|
176
|
+
method_of = method_of[0...-1]
|
177
|
+
else
|
178
|
+
name = ".#{name}"
|
179
|
+
end
|
180
|
+
|
181
|
+
module_map[method_of] ||= {}
|
182
|
+
module_map[method_of][name] = {
|
183
|
+
"summary" => item['description']['summary'],
|
184
|
+
"code_sample" => item['description']['body'],
|
185
|
+
"source" => item['code'],
|
186
|
+
"parameters" => params,
|
187
|
+
"returns" => returns,
|
188
|
+
"see" => see
|
189
|
+
}
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
class_names = class_names.compact.flatten.uniq.sort
|
194
|
+
|
195
|
+
class_names.each do |source_class|
|
196
|
+
method_data = module_map[source_class] || {}
|
197
|
+
|
198
|
+
docs_data[source_class] = {
|
199
|
+
'summary' => class_summaries[source_class],
|
200
|
+
'methods' => method_data
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
# File.open("source/sanity.json", 'w') do |f|
|
205
|
+
# f.write(JSON.pretty_generate(docs_data))
|
206
|
+
# end
|
207
|
+
|
208
|
+
return { docs_data: docs_data, class_names: class_names }
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
if __FILE__ == $0
|
214
|
+
Spacedocs.doc 'projects/6', 'game.js'
|
215
|
+
end
|