jsduck 3.0.1 → 3.1.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/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
|