jsduck 3.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/Rakefile +73 -41
- data/js-classes/String.js +10 -8
- data/jsduck.gemspec +2 -2
- data/lib/jsduck/accessors.rb +3 -0
- data/lib/jsduck/aggregator.rb +34 -1
- data/lib/jsduck/api_exporter.rb +48 -0
- data/lib/jsduck/app.rb +47 -182
- data/lib/jsduck/app_data.rb +34 -0
- data/lib/jsduck/{exporter.rb → app_exporter.rb} +21 -19
- data/lib/jsduck/categories.rb +13 -62
- data/lib/jsduck/class.rb +23 -9
- data/lib/jsduck/class_formatter.rb +2 -2
- data/lib/jsduck/class_writer.rb +49 -0
- data/lib/jsduck/doc_formatter.rb +16 -8
- data/lib/jsduck/doc_parser.rb +42 -36
- data/lib/jsduck/examples.rb +9 -5
- data/lib/jsduck/file_categories.rb +65 -0
- data/lib/jsduck/full_exporter.rb +29 -0
- data/lib/jsduck/guides.rb +12 -10
- data/lib/jsduck/images.rb +2 -2
- data/lib/jsduck/index_html.rb +67 -0
- data/lib/jsduck/inherit_doc.rb +75 -0
- data/lib/jsduck/js_parser.rb +8 -1
- data/lib/jsduck/lint.rb +9 -9
- data/lib/jsduck/logger.rb +64 -6
- data/lib/jsduck/merger.rb +29 -25
- data/lib/jsduck/null_object.rb +19 -0
- data/lib/jsduck/options.rb +46 -20
- data/lib/jsduck/renderer.rb +24 -18
- data/lib/jsduck/search_data.rb +2 -2
- data/lib/jsduck/source_writer.rb +19 -6
- data/lib/jsduck/stats.rb +103 -0
- data/lib/jsduck/template_dir.rb +51 -0
- data/lib/jsduck/videos.rb +9 -6
- data/lib/jsduck/welcome.rb +14 -8
- data/opt/extjs-welcome.html +74 -0
- data/opt/touch-iframe.html +85 -0
- data/opt/touch-welcome.html +122 -0
- metadata +401 -389
- data/bin/stats +0 -92
- data/lib/jsduck/aliases.rb +0 -54
data/README.md
CHANGED
@@ -12,7 +12,7 @@ API documentation generator for Sencha JavaScript frameworks.
|
|
12
12
|
|
13
13
|
JsDuck aims to be a better documentation generator for [Ext JS][] than
|
14
14
|
the old [ext-doc][] was. It is used by Sencha to document [Ext JS
|
15
|
-
4][ext4-docs], [Sencha Touch][
|
15
|
+
4][ext4-docs], [Sencha Touch][touch2-docs] and [several other][other-docs]
|
16
16
|
products.
|
17
17
|
|
18
18
|
The highlights of JSDuck are [Markdown][] support and keeping you DRY
|
data/Rakefile
CHANGED
@@ -154,42 +154,17 @@ class JsDuckRunner
|
|
154
154
|
@options += options
|
155
155
|
end
|
156
156
|
|
157
|
-
def add_sdk
|
158
|
-
|
157
|
+
def add_sdk
|
159
158
|
head_html = <<-EOHTML
|
160
159
|
<link rel="canonical" href="http://docs.sencha.com/ext-js/4-0/" />
|
161
|
-
<meta name="description" content="Ext JS 4.0 API Documentation from Sencha. Class documentation, Guides and Videos on how to create Javascript applications with Ext JS 4"
|
160
|
+
<meta name="description" content="Ext JS 4.0 API Documentation from Sencha. Class documentation, Guides and Videos on how to create Javascript applications with Ext JS 4" />
|
162
161
|
EOHTML
|
163
162
|
|
164
|
-
if mode == 'export'
|
165
|
-
|
166
|
-
relative_sdk_path = "../"
|
167
|
-
|
168
|
-
["template-min/extIframe.html", "template-min/welcome.html"].each do |file|
|
169
|
-
html = IO.read(file);
|
170
|
-
|
171
|
-
out = []
|
172
|
-
|
173
|
-
html.each_line do |line|
|
174
|
-
out << line.sub(/((src|href)="extjs\/)/, '\2="' + relative_sdk_path)
|
175
|
-
end
|
176
|
-
|
177
|
-
File.open(file, 'w') {|f| f.write(out) }
|
178
|
-
end
|
179
|
-
|
180
|
-
head_html = <<-EOHTML
|
181
|
-
<script type="text/javascript">
|
182
|
-
Docs.exampleBaseUrl = "#{relative_sdk_path}examples/";
|
183
|
-
</script>
|
184
|
-
EOHTML
|
185
|
-
|
186
|
-
end
|
187
|
-
|
188
163
|
@options += [
|
189
164
|
"--title", "Sencha Docs - Ext JS 4.0",
|
190
165
|
"--head-html", head_html,
|
191
166
|
"--footer", "Ext JS 4.0.7 Docs - Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> rev #{revision}",
|
192
|
-
"--welcome", "
|
167
|
+
"--welcome", "opt/extjs-welcome.html",
|
193
168
|
"--guides", "#{@sdk_dir}/extjs/docs/guides.json",
|
194
169
|
"--videos", "#{@sdk_dir}/extjs/docs/videos.json",
|
195
170
|
"--examples", "#{@sdk_dir}/extjs/examples/examples.json",
|
@@ -199,13 +174,53 @@ class JsDuckRunner
|
|
199
174
|
"--builtin-classes",
|
200
175
|
"--images", "#{@sdk_dir}/extjs/docs/resources",
|
201
176
|
"--images", "#{@sdk_dir}/platform/docs/resources",
|
177
|
+
"--stats",
|
202
178
|
"#{@sdk_dir}/extjs/src",
|
203
179
|
"#{@sdk_dir}/platform/src",
|
204
180
|
"#{@sdk_dir}/platform/core/src",
|
181
|
+
"#{@sdk_dir}/extjs/examples/ux",
|
205
182
|
]
|
206
183
|
end
|
207
184
|
|
185
|
+
def add_relative_examples_path
|
186
|
+
@options += ["--head-html", <<-EOHTML]
|
187
|
+
<script type="text/javascript">
|
188
|
+
Docs.exampleBaseUrl = "#{relative_sdk_path}examples/";
|
189
|
+
</script>
|
190
|
+
EOHTML
|
191
|
+
end
|
192
|
+
|
193
|
+
# Enables comments when CORS is supported by browser.
|
194
|
+
# This excludes Opera and IE < 8
|
195
|
+
def add_comments(db_name)
|
196
|
+
comments_base_url = "http://projects.sencha.com/auth"
|
197
|
+
@options += ["--head-html", <<-EOHTML]
|
198
|
+
<script type="text/javascript">
|
199
|
+
Docs.enableComments = ("withCredentials" in new XMLHttpRequest()) || (typeof XDomainRequest !== "undefined");
|
200
|
+
Docs.baseUrl = "#{comments_base_url}";
|
201
|
+
Docs.commentsDb = "#{db_name}";
|
202
|
+
</script>
|
203
|
+
EOHTML
|
204
|
+
end
|
205
|
+
|
206
|
+
# For export of ExtJS, reference extjs from the parent dir
|
207
|
+
def make_paths_relative
|
208
|
+
relative_sdk_path = "../"
|
209
|
+
["#{@out_dir}/eg-iframe.html", "#{@out_dir}/index.html"].each do |file|
|
210
|
+
out = []
|
211
|
+
IO.read(file).each_line do |line|
|
212
|
+
out << line.sub(/((src|href)="extjs\/)/, '\2="' + relative_sdk_path)
|
213
|
+
end
|
214
|
+
File.open(file, 'w') {|f| f.write(out) }
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
208
218
|
def add_ext3
|
219
|
+
head_html = <<-EOHTML
|
220
|
+
<link rel="canonical" href="http://docs.sencha.com/ext-js/3-4/" />
|
221
|
+
<meta name="description" content="Ext JS 3.4 API Documentation from Sencha. Class documentation, Guides and Videos on how to create Javascript applications with Ext JS 3.4" />
|
222
|
+
EOHTML
|
223
|
+
|
209
224
|
@options += [
|
210
225
|
"--title", "Sencha Docs - Ext JS 3.4",
|
211
226
|
"--footer", "Ext JS 3.4 Docs - Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> revison #{revision}",
|
@@ -240,7 +255,7 @@ class JsDuckRunner
|
|
240
255
|
def add_touch
|
241
256
|
head_html = <<-EOHTML
|
242
257
|
<link rel="canonical" href="http://docs.sencha.com/touch/1-1/" />
|
243
|
-
<meta name="description" content="Sencha Touch 1.1 API Documentation from Sencha. Documentation on how to create Javascript applications with Sencha Touch"
|
258
|
+
<meta name="description" content="Sencha Touch 1.1 API Documentation from Sencha. Documentation on how to create Javascript applications with Sencha Touch" />
|
244
259
|
EOHTML
|
245
260
|
|
246
261
|
@options += [
|
@@ -262,7 +277,7 @@ class JsDuckRunner
|
|
262
277
|
def add_touch2
|
263
278
|
head_html = <<-EOHTML
|
264
279
|
<link rel="canonical" href="http://docs.sencha.com/touch/2-0/" />
|
265
|
-
<meta name="description" content="Sencha Touch 2.0 API Documentation from Sencha. Documentation on how to create Javascript applications with Sencha Touch"
|
280
|
+
<meta name="description" content="Sencha Touch 2.0 API Documentation from Sencha. Documentation on how to create Javascript applications with Sencha Touch" />
|
266
281
|
EOHTML
|
267
282
|
|
268
283
|
@options += [
|
@@ -270,7 +285,7 @@ class JsDuckRunner
|
|
270
285
|
"--head-html", head_html,
|
271
286
|
"--footer", "Sencha Touch 2.0 Docs - Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> revison #{revision}",
|
272
287
|
"--categories", "#{@sdk_dir}/touch/docs/categories.json",
|
273
|
-
"--welcome", "
|
288
|
+
"--welcome", "opt/touch-welcome.html",
|
274
289
|
"--videos", "#{@sdk_dir}/touch/docs/videos.json",
|
275
290
|
"--guides", "#{@sdk_dir}/touch/docs/guides.json",
|
276
291
|
"--examples", "#{@sdk_dir}/touch/docs/examples.json",
|
@@ -280,7 +295,9 @@ class JsDuckRunner
|
|
280
295
|
"--external=google.maps.Map,google.maps.LatLng",
|
281
296
|
"--builtin-classes",
|
282
297
|
"--img", "<p class='screenshot'><img src='%u' alt='%a'><span>%a</span></p>",
|
283
|
-
"--eg-iframe", "
|
298
|
+
"--eg-iframe", "opt/touch-iframe.html",
|
299
|
+
"--warnings=-image",
|
300
|
+
# "--stats",
|
284
301
|
"#{@sdk_dir}/touch/resources/themes/stylesheets/sencha-touch/default",
|
285
302
|
]
|
286
303
|
|
@@ -307,9 +324,10 @@ class JsDuckRunner
|
|
307
324
|
|
308
325
|
def set_touch2_src
|
309
326
|
relative_touch_path = "../"
|
310
|
-
|
327
|
+
system("cp", "-r", "opt/touch-welcome.html", "template-min/touch-welcome.html")
|
328
|
+
system("cp", "-r", "opt/touch-iframe.html", "template-min/touch-iframe.html")
|
311
329
|
|
312
|
-
["template-min/
|
330
|
+
["template-min/touch-iframe.html", "template-min/touch-welcome.html"].each do |file|
|
313
331
|
html = IO.read(file);
|
314
332
|
|
315
333
|
touch_src_re = /((src|href)="touch)/m
|
@@ -327,21 +345,19 @@ class JsDuckRunner
|
|
327
345
|
Docs.exampleBaseUrl = "#{relative_touch_path}examples/";
|
328
346
|
if (Ext.is.Phone) { window.location = "#{relative_touch_path}examples/"; }
|
329
347
|
</script>
|
330
|
-
<div id="notice-text" style="display: none">
|
331
|
-
Use <a href="http://docs.sencha.com/touch/2-0">http://docs.sencha.com/touch/2-0</a> for up to date documentation and features
|
332
|
-
</div>
|
333
348
|
EOHTML
|
334
349
|
|
335
350
|
@options += [
|
351
|
+
"--body-html", head_html,
|
336
352
|
"--welcome", "template-min/touch-welcome.html",
|
337
|
-
"--
|
353
|
+
"--eg-iframe", "template-min/touch-iframe.html"
|
338
354
|
]
|
339
355
|
end
|
340
356
|
|
341
357
|
def add_touch_charts
|
342
358
|
head_html = <<-EOHTML
|
343
359
|
<link rel="canonical" href="http://docs.sencha.com/touch-charts/1-0/" />
|
344
|
-
<meta name="description" content="Sencha Touch Charts 1.0 API Documentation. Documentation on how to create Charts with Sencha Touch"
|
360
|
+
<meta name="description" content="Sencha Touch Charts 1.0 API Documentation. Documentation on how to create Charts with Sencha Touch" />
|
345
361
|
EOHTML
|
346
362
|
|
347
363
|
@options += [
|
@@ -381,7 +397,7 @@ class JsDuckRunner
|
|
381
397
|
def add_animator
|
382
398
|
head_html = <<-EOHTML
|
383
399
|
<link rel="canonical" href="http://docs.sencha.com/animator/1-0/" />
|
384
|
-
<meta name="description" content="Sencha Animator 1.0 API Documentation from Sencha. Documentation on how to create Javascript applications with Sencha Touch"
|
400
|
+
<meta name="description" content="Sencha Animator 1.0 API Documentation from Sencha. Documentation on how to create Javascript applications with Sencha Touch" />
|
385
401
|
EOHTML
|
386
402
|
|
387
403
|
@options += [
|
@@ -568,14 +584,29 @@ task :sdk, [:mode] => :sass do |t, args|
|
|
568
584
|
compress if mode == "export" || mode == "live"
|
569
585
|
|
570
586
|
runner = JsDuckRunner.new
|
571
|
-
runner.add_sdk
|
587
|
+
runner.add_sdk
|
572
588
|
runner.add_debug if mode == "debug"
|
573
589
|
runner.add_seo if mode == "debug" || mode == "live"
|
574
590
|
runner.add_sdk_export_notice if mode == "export"
|
575
591
|
runner.add_google_analytics if mode == "live"
|
592
|
+
runner.add_comments('comments-ext-js-4') if mode == "debug" || mode == "live"
|
576
593
|
runner.run
|
577
594
|
|
578
595
|
runner.copy_sdk_examples if mode == "export" || mode == "live"
|
596
|
+
runner.make_paths_relative if mode == "export"
|
597
|
+
end
|
598
|
+
|
599
|
+
desc "Run JSDuck on Docs app itself"
|
600
|
+
task :docs do
|
601
|
+
runner = JsDuckRunner.new
|
602
|
+
runner.add_ext4
|
603
|
+
runner.add_options([
|
604
|
+
"--builtin-classes",
|
605
|
+
"template/app"
|
606
|
+
])
|
607
|
+
runner.add_debug
|
608
|
+
runner.add_seo
|
609
|
+
runner.run
|
579
610
|
end
|
580
611
|
|
581
612
|
desc "Run JSDuck on official Ext JS 4.0.2a build\n" +
|
@@ -642,6 +673,7 @@ task :touch2, [:mode] => :sass do |t, args|
|
|
642
673
|
runner.set_touch2_src if mode == "export"
|
643
674
|
runner.add_seo if mode == "debug" || mode == "live"
|
644
675
|
runner.add_google_analytics if mode == "live"
|
676
|
+
runner.add_comments('comments-touch-2') if mode == "debug" || mode == "live"
|
645
677
|
runner.run
|
646
678
|
|
647
679
|
runner.copy_touch2_build if mode != "export"
|
data/js-classes/String.js
CHANGED
@@ -666,14 +666,16 @@
|
|
666
666
|
* return s.replace(test, convert);
|
667
667
|
* }
|
668
668
|
*
|
669
|
-
* @param {RegExp}
|
670
|
-
*
|
671
|
-
* @param {String}
|
672
|
-
*
|
673
|
-
*
|
674
|
-
*
|
675
|
-
*
|
676
|
-
* in the "Specifying a function as a parameter"
|
669
|
+
* @param {String/RegExp} pattern Either a string or regular expression pattern to search for.
|
670
|
+
*
|
671
|
+
* @param {String/Function} replacement Either string or function:
|
672
|
+
*
|
673
|
+
* - The String to replace the `pattern` with. Number of special replacement patterns are supported;
|
674
|
+
* see the "Specifying a string as a parameter" section above.
|
675
|
+
* - A function to be invoked to create the replacement.
|
676
|
+
* The arguments supplied to this function are described in the "Specifying a function as a parameter"
|
677
|
+
* section above.
|
678
|
+
*
|
677
679
|
* @return {String} String of matched replaced items.
|
678
680
|
*/
|
679
681
|
|
data/jsduck.gemspec
CHANGED
@@ -2,8 +2,8 @@ Gem::Specification.new do |s|
|
|
2
2
|
s.required_rubygems_version = ">= 1.3.5"
|
3
3
|
|
4
4
|
s.name = 'jsduck'
|
5
|
-
s.version = '3.0
|
6
|
-
s.date = '2011-
|
5
|
+
s.version = '3.1.0'
|
6
|
+
s.date = '2011-11-16'
|
7
7
|
s.summary = "Simple JavaScript Duckumentation generator"
|
8
8
|
s.description = "Documentation generator for Sencha JS frameworks"
|
9
9
|
s.homepage = "https://github.com/senchalabs/jsduck"
|
data/lib/jsduck/accessors.rb
CHANGED
@@ -58,6 +58,7 @@ module JsDuck
|
|
58
58
|
:files => cfg[:files],
|
59
59
|
:id => "method-" + name,
|
60
60
|
:deprecated => cfg[:deprecated],
|
61
|
+
:meta => cfg[:meta],
|
61
62
|
}
|
62
63
|
end
|
63
64
|
|
@@ -80,6 +81,7 @@ module JsDuck
|
|
80
81
|
:files => cfg[:files],
|
81
82
|
:id => "method-" + name,
|
82
83
|
:deprecated => cfg[:deprecated],
|
84
|
+
:meta => cfg[:meta]
|
83
85
|
}
|
84
86
|
end
|
85
87
|
|
@@ -116,6 +118,7 @@ module JsDuck
|
|
116
118
|
:files => cfg[:files],
|
117
119
|
:id => "event-" + name,
|
118
120
|
:deprecated => cfg[:deprecated],
|
121
|
+
:meta => cfg[:meta]
|
119
122
|
}
|
120
123
|
end
|
121
124
|
|
data/lib/jsduck/aggregator.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'jsduck/class'
|
2
2
|
require 'jsduck/accessors'
|
3
|
+
require 'jsduck/logger'
|
3
4
|
|
4
5
|
module JsDuck
|
5
6
|
|
@@ -9,6 +10,7 @@ module JsDuck
|
|
9
10
|
def initialize
|
10
11
|
@documentation = []
|
11
12
|
@classes = {}
|
13
|
+
@alt_names = {}
|
12
14
|
@orphans = []
|
13
15
|
@current_class = nil
|
14
16
|
end
|
@@ -38,6 +40,11 @@ module JsDuck
|
|
38
40
|
# Otherwise add as new class.
|
39
41
|
def add_class(cls)
|
40
42
|
old_cls = @classes[cls[:name]]
|
43
|
+
if !old_cls && @alt_names[cls[:name]]
|
44
|
+
old_cls = @alt_names[cls[:name]]
|
45
|
+
warn_alt_name(cls)
|
46
|
+
end
|
47
|
+
|
41
48
|
if old_cls
|
42
49
|
merge_classes(old_cls, cls)
|
43
50
|
@current_class = old_cls
|
@@ -45,10 +52,36 @@ module JsDuck
|
|
45
52
|
@current_class = cls
|
46
53
|
@documentation << cls
|
47
54
|
@classes[cls[:name]] = cls
|
55
|
+
|
56
|
+
# Register all alternate names of class for lookup too
|
57
|
+
cls[:alternateClassNames].each do |altname|
|
58
|
+
if cls[:name] == altname
|
59
|
+
# A buggy documentation, warn.
|
60
|
+
warn_alt_name(cls)
|
61
|
+
else
|
62
|
+
@alt_names[altname] = cls
|
63
|
+
# When an alternate name has been used as a class name before,
|
64
|
+
# then this is one crappy documentation, but attempt to handle
|
65
|
+
# it by merging the class with alt-name into this class.
|
66
|
+
if @classes[altname]
|
67
|
+
merge_classes(cls, @classes[altname])
|
68
|
+
@documentation.delete(@classes[altname])
|
69
|
+
@classes.delete(altname)
|
70
|
+
warn_alt_name(cls)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
48
75
|
insert_orphans(cls)
|
49
76
|
end
|
50
77
|
end
|
51
78
|
|
79
|
+
def warn_alt_name(cls)
|
80
|
+
file = cls[:files][0][:filename]
|
81
|
+
line = cls[:files][0][:linenr]
|
82
|
+
Logger.instance.warn(:alt_name, "Name #{cls[:name]} used as both classname and alternate classname", file, line)
|
83
|
+
end
|
84
|
+
|
52
85
|
# Merges new class-doc into old one.
|
53
86
|
def merge_classes(old, new)
|
54
87
|
# Merge booleans
|
@@ -60,7 +93,7 @@ module JsDuck
|
|
60
93
|
old[tag] = old[tag] + new[tag]
|
61
94
|
end
|
62
95
|
# Merge hashes of arrays
|
63
|
-
[:
|
96
|
+
[:aliases, :meta].each do |tag|
|
64
97
|
new[tag].each_pair do |key, contents|
|
65
98
|
old[tag][key] = (old[tag][key] || []) + contents
|
66
99
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'jsduck/json_duck'
|
2
|
+
require 'jsduck/class'
|
3
|
+
|
4
|
+
module JsDuck
|
5
|
+
|
6
|
+
# Exporter for simple JSON format listing only class name and names
|
7
|
+
# of all of its members.
|
8
|
+
#
|
9
|
+
# It produces the following structure:
|
10
|
+
#
|
11
|
+
# {
|
12
|
+
# :name => "Panel",
|
13
|
+
# :members => {
|
14
|
+
# :cfg => ["width", "height", "title"],
|
15
|
+
# :method => ["getWidth", "setWidth"],
|
16
|
+
# ...
|
17
|
+
# },
|
18
|
+
# :statics => { ... }
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
class ApiExporter
|
22
|
+
def initialize(relations, opts)
|
23
|
+
# All params ignored, they're present to be compatible with
|
24
|
+
# other exporters.
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns hash of class name and member names
|
28
|
+
def export(cls)
|
29
|
+
{
|
30
|
+
:name => cls[:name],
|
31
|
+
:members => export_members(cls, :members),
|
32
|
+
:statics => export_members(cls, :statics),
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def export_members(cls, context)
|
39
|
+
h = {}
|
40
|
+
Class.default_members_hash.each_key do |type|
|
41
|
+
h[type] = cls.members(type, context).map {|m| m[:name] }
|
42
|
+
end
|
43
|
+
h
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/lib/jsduck/app.rb
CHANGED
@@ -1,16 +1,11 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'jsduck/aggregator'
|
3
3
|
require 'jsduck/source_file'
|
4
|
-
require 'jsduck/source_writer'
|
5
4
|
require 'jsduck/doc_formatter'
|
6
5
|
require 'jsduck/class_formatter'
|
7
6
|
require 'jsduck/class'
|
8
|
-
require 'jsduck/icons'
|
9
|
-
require 'jsduck/search_data'
|
10
7
|
require 'jsduck/relations'
|
11
|
-
require 'jsduck/
|
12
|
-
require 'jsduck/exporter'
|
13
|
-
require 'jsduck/renderer'
|
8
|
+
require 'jsduck/inherit_doc'
|
14
9
|
require 'jsduck/parallel_wrap'
|
15
10
|
require 'jsduck/logger'
|
16
11
|
require 'jsduck/welcome'
|
@@ -21,6 +16,14 @@ require 'jsduck/categories'
|
|
21
16
|
require 'jsduck/images'
|
22
17
|
require 'jsduck/json_duck'
|
23
18
|
require 'jsduck/lint'
|
19
|
+
require 'jsduck/template_dir'
|
20
|
+
require 'jsduck/class_writer'
|
21
|
+
require 'jsduck/source_writer'
|
22
|
+
require 'jsduck/app_data'
|
23
|
+
require 'jsduck/index_html'
|
24
|
+
require 'jsduck/api_exporter'
|
25
|
+
require 'jsduck/full_exporter'
|
26
|
+
require 'jsduck/app_exporter'
|
24
27
|
require 'fileutils'
|
25
28
|
|
26
29
|
module JsDuck
|
@@ -33,9 +36,6 @@ module JsDuck
|
|
33
36
|
# Sets the nr of parallel processes to use.
|
34
37
|
# Set to 0 to disable parallelization completely.
|
35
38
|
@parallel = ParallelWrap.new(:in_processes => @opts.processes)
|
36
|
-
# Sets warnings and verbose mode on or off
|
37
|
-
Logger.instance.warnings = @opts.warnings
|
38
|
-
Logger.instance.verbose = @opts.verbose
|
39
39
|
# Turn JSON pretty-printing on/off
|
40
40
|
JsonDuck.pretty = @opts.pretty_json
|
41
41
|
end
|
@@ -45,70 +45,52 @@ module JsDuck
|
|
45
45
|
parsed_files = parallel_parse(@opts.input_files)
|
46
46
|
result = aggregate(parsed_files)
|
47
47
|
@relations = filter_classes(result)
|
48
|
-
|
48
|
+
InheritDoc.new(@relations).resolve_all
|
49
49
|
Lint.new(@relations).run
|
50
50
|
|
51
51
|
@images = Images.new(@opts.images)
|
52
|
+
@welcome = Welcome.create(@opts.welcome)
|
53
|
+
@guides = Guides.create(@opts.guides, DocFormatter.new(@relations, @opts))
|
54
|
+
@videos = Videos.create(@opts.videos)
|
55
|
+
@examples = Examples.create(@opts.examples)
|
56
|
+
@categories = Categories.create(@opts.categories_path, DocFormatter.new(@relations, @opts), @relations)
|
52
57
|
|
53
|
-
@
|
54
|
-
if @opts.welcome
|
55
|
-
@welcome.parse(@opts.welcome)
|
56
|
-
end
|
57
|
-
|
58
|
-
@guides = Guides.new(get_doc_formatter)
|
59
|
-
if @opts.guides
|
60
|
-
@guides.parse(@opts.guides)
|
61
|
-
end
|
62
|
-
|
63
|
-
@videos = Videos.new
|
64
|
-
if @opts.videos
|
65
|
-
@videos.parse(@opts.videos)
|
66
|
-
end
|
67
|
-
|
68
|
-
@examples = Examples.new
|
69
|
-
if @opts.examples
|
70
|
-
@examples.parse(@opts.examples)
|
71
|
-
end
|
72
|
-
|
73
|
-
@categories = Categories.new(get_doc_formatter, @relations)
|
74
|
-
if @opts.categories_path
|
75
|
-
@categories.parse(@opts.categories_path)
|
76
|
-
else
|
77
|
-
@categories.auto_generate
|
78
|
-
end
|
79
|
-
|
80
|
-
clear_output_dir unless @opts.export == :stdout
|
81
|
-
if @opts.export == :stdout
|
82
|
-
puts JsonDuck.generate(@relations.classes)
|
83
|
-
elsif @opts.export == :json
|
84
|
-
FileUtils.mkdir(@opts.output_dir)
|
58
|
+
if @opts.export
|
85
59
|
format_classes
|
86
|
-
|
60
|
+
FileUtils.rm_rf(@opts.output_dir) unless @opts.output_dir == :stdout
|
61
|
+
exporters = {:full => FullExporter, :api => ApiExporter}
|
62
|
+
cw = ClassWriter.new(exporters[@opts.export], @relations, @opts)
|
63
|
+
cw.write(@opts.output_dir, ".json")
|
87
64
|
else
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
65
|
+
FileUtils.rm_rf(@opts.output_dir)
|
66
|
+
TemplateDir.new(@opts).write
|
67
|
+
|
68
|
+
index = IndexHtml.new(@opts)
|
69
|
+
index.welcome = @welcome
|
70
|
+
index.categories = @categories
|
71
|
+
index.guides = @guides
|
72
|
+
index.write
|
73
|
+
|
74
|
+
app_data = AppData.new(@relations, @opts)
|
75
|
+
app_data.guides = @guides
|
76
|
+
app_data.videos = @videos
|
77
|
+
app_data.examples = @examples
|
78
|
+
app_data.write(@opts.output_dir+"/data.js")
|
79
|
+
|
80
|
+
# class-formatting is done in parallel which breaks the links
|
81
|
+
# between source files and classes. Therefore it MUST to be done
|
82
|
+
# after writing sources which needs the links to work.
|
83
|
+
SourceWriter.write_all(parsed_files, @opts.output_dir + "/source")
|
103
84
|
format_classes
|
104
|
-
|
105
|
-
|
85
|
+
|
86
|
+
cw = ClassWriter.new(AppExporter, @relations, @opts)
|
87
|
+
cw.write(@opts.output_dir+"/output", ".js")
|
88
|
+
|
106
89
|
@guides.write(@opts.output_dir+"/guides")
|
107
90
|
@videos.write(@opts.output_dir+"/videos")
|
108
91
|
@examples.write(@opts.output_dir+"/examples")
|
109
92
|
@images.copy(@opts.output_dir+"/images")
|
110
93
|
end
|
111
|
-
|
112
94
|
end
|
113
95
|
|
114
96
|
# Parses the files in parallel using as many processes as available CPU-s
|
@@ -144,7 +126,9 @@ module JsDuck
|
|
144
126
|
type = d[:tagname].to_s
|
145
127
|
name = d[:name]
|
146
128
|
file = d[:files][0]
|
147
|
-
|
129
|
+
# This warning is shown when there are orphaned members,
|
130
|
+
# but the creation of global class has been turned off.
|
131
|
+
Logger.instance.warn(:global, "Ignoring #{type}: #{name}", file[:filename], file[:linenr])
|
148
132
|
end
|
149
133
|
end
|
150
134
|
Relations.new(classes, @opts.external_classes)
|
@@ -152,7 +136,7 @@ module JsDuck
|
|
152
136
|
|
153
137
|
# Formats each class
|
154
138
|
def format_classes
|
155
|
-
doc_formatter =
|
139
|
+
doc_formatter = DocFormatter.new(@relations, @opts)
|
156
140
|
doc_formatter.img_path = "images"
|
157
141
|
class_formatter = ClassFormatter.new(@relations, doc_formatter)
|
158
142
|
# Don't format types when exporting
|
@@ -171,125 +155,6 @@ module JsDuck
|
|
171
155
|
end
|
172
156
|
end
|
173
157
|
|
174
|
-
# Writes classes, guides, videos, and search data to one big .js file
|
175
|
-
def write_app_data
|
176
|
-
js = "Docs.data = " + JsonDuck.generate({
|
177
|
-
:classes => Icons.new.create(@relations.classes),
|
178
|
-
:guides => @guides.to_array,
|
179
|
-
:videos => @videos.to_array,
|
180
|
-
:examples => @examples.to_array,
|
181
|
-
:search => SearchData.new.create(@relations.classes),
|
182
|
-
}) + ";\n"
|
183
|
-
File.open(@opts.output_dir+"/data.js", 'w') {|f| f.write(js) }
|
184
|
-
end
|
185
|
-
|
186
|
-
# Writes JSON export or JsonP file for each class
|
187
|
-
def write_classes
|
188
|
-
exporter = Exporter.new(@relations)
|
189
|
-
renderer = Renderer.new
|
190
|
-
# Inject formatter to all meta-tags.
|
191
|
-
doc_formatter = get_doc_formatter
|
192
|
-
@opts.meta_tags.each {|tag| tag.formatter = doc_formatter }
|
193
|
-
renderer.meta_tags = @opts.meta_tags
|
194
|
-
|
195
|
-
dir = @opts.output_dir + (@opts.export ? "" : "/output")
|
196
|
-
@parallel.each(@relations.classes) do |cls|
|
197
|
-
filename = dir + "/" + cls[:name] + (@opts.export ? ".json" : ".js")
|
198
|
-
Logger.instance.log("Writing docs", filename)
|
199
|
-
data = exporter.export(cls)
|
200
|
-
if @opts.export
|
201
|
-
JsonDuck.write_json(filename, data)
|
202
|
-
else
|
203
|
-
data[:html] = renderer.render(data)
|
204
|
-
data = exporter.compact(data)
|
205
|
-
JsonDuck.write_jsonp(filename, cls[:name].gsub(/\./, "_"), data)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
# Writes formatted HTML source code for each input file
|
211
|
-
def write_src(parsed_files)
|
212
|
-
src = SourceWriter.new(@opts.output_dir + "/source", @opts.export ? nil : :page)
|
213
|
-
# Can't be done in parallel, because file.html_filename= method
|
214
|
-
# updates all the doc-objects related to the file
|
215
|
-
parsed_files.each do |file|
|
216
|
-
html_filename = src.write(file.to_html, file.filename)
|
217
|
-
Logger.instance.log("Writing source", html_filename)
|
218
|
-
file.html_filename = File.basename(html_filename)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
# Creates and initializes DocFormatter
|
223
|
-
def get_doc_formatter
|
224
|
-
formatter = DocFormatter.new
|
225
|
-
formatter.link_tpl = @opts.link_tpl if @opts.link_tpl
|
226
|
-
formatter.img_tpl = @opts.img_tpl if @opts.img_tpl
|
227
|
-
formatter.relations = @relations
|
228
|
-
formatter
|
229
|
-
end
|
230
|
-
|
231
|
-
def copy_template
|
232
|
-
Logger.instance.log("Copying template files to", @opts.output_dir)
|
233
|
-
FileUtils.cp_r(@opts.template_dir, @opts.output_dir)
|
234
|
-
init_output_dirs
|
235
|
-
end
|
236
|
-
|
237
|
-
def link_template
|
238
|
-
Logger.instance.log("Linking template files to", @opts.output_dir)
|
239
|
-
FileUtils.mkdir(@opts.output_dir)
|
240
|
-
Dir.glob(@opts.template_dir + "/*").each do |file|
|
241
|
-
File.symlink(File.expand_path(file), @opts.output_dir+"/"+File.basename(file))
|
242
|
-
end
|
243
|
-
init_output_dirs
|
244
|
-
end
|
245
|
-
|
246
|
-
def clear_output_dir
|
247
|
-
if File.exists?(@opts.output_dir)
|
248
|
-
FileUtils.rm_r(@opts.output_dir)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def init_output_dirs
|
253
|
-
FileUtils.mkdir(@opts.output_dir + "/output")
|
254
|
-
FileUtils.mkdir(@opts.output_dir + "/source")
|
255
|
-
end
|
256
|
-
|
257
|
-
def create_template_html
|
258
|
-
write_template("template.html", {
|
259
|
-
"{title}" => @opts.title,
|
260
|
-
"{header}" => @opts.header,
|
261
|
-
"{footer}" => "<div id='footer-content' style='display: none'>#{@opts.footer}</div>",
|
262
|
-
"{extjs_path}" => @opts.extjs_path,
|
263
|
-
"{local_storage_db}" => @opts.local_storage_db,
|
264
|
-
"{show_print_button}" => @opts.seo ? "true" : "false",
|
265
|
-
"{touch_examples_ui}" => @opts.touch_examples_ui ? "true" : "false",
|
266
|
-
"{welcome}" => @welcome.to_html,
|
267
|
-
"{categories}" => @categories.to_html,
|
268
|
-
"{guides}" => @guides.to_html,
|
269
|
-
"{head_html}" => @opts.head_html,
|
270
|
-
"{body_html}" => @opts.body_html,
|
271
|
-
})
|
272
|
-
end
|
273
|
-
|
274
|
-
def create_print_template_html
|
275
|
-
write_template("print-template.html", {
|
276
|
-
"{title}" => @opts.title,
|
277
|
-
"{header}" => @opts.header,
|
278
|
-
})
|
279
|
-
end
|
280
|
-
|
281
|
-
# Opens file in template dir, replaces {keys} inside it, writes to output dir
|
282
|
-
def write_template(filename, replacements)
|
283
|
-
in_file = @opts.template_dir + '/' + filename
|
284
|
-
out_file = @opts.output_dir + '/' + filename
|
285
|
-
Logger.instance.log("Writing", out_file)
|
286
|
-
html = IO.read(in_file)
|
287
|
-
html.gsub!(/\{\w+\}/) do |key|
|
288
|
-
replacements[key] ? replacements[key] : key
|
289
|
-
end
|
290
|
-
FileUtils.rm(out_file)
|
291
|
-
File.open(out_file, 'w') {|f| f.write(html) }
|
292
|
-
end
|
293
158
|
end
|
294
159
|
|
295
160
|
end
|