jsduck 3.9.1 → 3.10.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 CHANGED
@@ -126,8 +126,10 @@ Thanks to [Ondřej Jirman](https://github.com/megous),
126
126
  [Ed Spencer](https://github.com/edspencer),
127
127
  [atian25](https://github.com/atian25),
128
128
  Katherine Chu,
129
- [Rob Dougan](https://github.com/rdougan) and many-many others who
130
- reported bugs, submitted patches, and provided a lot of useful input.
129
+ [Rob Dougan](https://github.com/rdougan),
130
+ [Dave Thompson](https://github.com/limscoder),
131
+ and many-many others who reported bugs, submitted patches, and
132
+ provided a lot of useful input.
131
133
 
132
134
 
133
135
  Changelog
data/Rakefile CHANGED
@@ -19,20 +19,14 @@ def load_sdk_vars
19
19
  puts
20
20
  puts "Please create file sdk-vars.rb and define in it:"
21
21
  puts
22
- puts " # path to Ext JS 4 build"
23
- puts " EXT_BUILD='/path/to/ext-4.0.7'"
24
- puts " # path to Touch 2 build"
25
- puts " TOUCH_BUILD='/path/to/touch-2.0.0'"
26
22
  puts " # where to output the docs"
27
23
  puts " OUT_DIR='/path/to/ouput/dir'"
24
+ puts " # path to Ext JS 4 build"
25
+ puts " EXT_BUILD='/path/to/ext-4'"
26
+ puts " # path to Touch 2 build"
27
+ puts " TOUCH_BUILD='/path/to/touch-2'"
28
28
  puts " # path to SDK (for developers at Sencha)"
29
29
  puts " SDK_DIR='/path/to/SDK'"
30
- puts " # paths to other projects (for developers at Sencha)"
31
- puts " ANIMATOR_DIR='/path/to/Animator'"
32
- puts " ARCHITECT_DIR='/path/to/Architect'"
33
- puts " SENCHAIO_DIR='/path/to/IO'"
34
- puts " EXT3_DIR='/path/to/ext3'"
35
- puts " EXT2_DIR='/path/to/ext2'"
36
30
  exit 1
37
31
  end
38
32
  end
@@ -147,7 +141,7 @@ class JsDuckRunner
147
141
  load_sdk_vars
148
142
  end
149
143
 
150
- def add_options(options)
144
+ def add_options(*options)
151
145
  @options += options
152
146
  end
153
147
 
@@ -167,25 +161,13 @@ class JsDuckRunner
167
161
  EOHTML
168
162
  end
169
163
 
170
- # For export of ExtJS, reference extjs from the parent dir
171
- def make_extjs_path_relative
172
- ["#{OUT_DIR}/index.html"].each do |file|
173
- out = []
174
- IO.read(file).each_line do |line|
175
- out << line.sub(/(src|href)="extjs\//, '\1="../')
176
- end
177
- File.open(file, 'w') {|f| f.write(out) }
178
- end
179
- system "rm -rf #{OUT_DIR}/extjs"
180
- end
181
-
182
164
  def add_ext4
183
165
  @options += [
184
166
  "--title", "Sencha Docs - Ext JS 4.0",
185
167
  "--footer", "Ext JS 4.0 Docs - Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> {VERSION}." +
186
168
  " <a href='http://www.sencha.com/legal/terms-of-use/'>Terms of Use</a>",
187
169
  "--ignore-global",
188
- "--no-warnings",
170
+ "--warnings", "-all",
189
171
  "--images", "#{EXT_BUILD}/docs/doc-resources",
190
172
  "--local-storage-db", "ext-4",
191
173
  "--output", "#{OUT_DIR}",
@@ -193,14 +175,6 @@ class JsDuckRunner
193
175
  ]
194
176
  end
195
177
 
196
- def add_phone_redirect
197
- @options += ["--body-html", <<-EOHTML]
198
- <script type="text/javascript">
199
- if (Ext.is.Phone) { window.location = "../examples/"; }
200
- </script>
201
- EOHTML
202
- end
203
-
204
178
  def add_debug
205
179
  @options += [
206
180
  "--extjs-path", "extjs/ext-all-debug.js",
@@ -209,121 +183,6 @@ class JsDuckRunner
209
183
  ]
210
184
  end
211
185
 
212
- def add_seo
213
- @options += [
214
- "--seo",
215
- ]
216
- end
217
-
218
- def add_export_notice path
219
- @options += [
220
- "--body-html", <<-EOHTML
221
- <div id="notice-text" style="display: none">
222
- Use <a href="http://docs.sencha.com/#{path}">http://docs.sencha.com/#{path}</a> for up to date documentation and features
223
- </div>
224
- EOHTML
225
- ]
226
- end
227
-
228
- def add_google_analytics
229
- @options += [
230
- "--body-html", <<-EOHTML
231
- <script type="text/javascript">
232
- var _gaq = _gaq || [];
233
- _gaq.push(['_setAccount', 'UA-1396058-10']);
234
- _gaq.push(['_trackPageview']);
235
- (function() {
236
- var ga = document.createElement('script');
237
- ga.type = 'text/javascript';
238
- ga.async = true;
239
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
240
- var s = document.getElementsByTagName('script')[0];
241
- s.parentNode.insertBefore(ga, s);
242
- })();
243
-
244
- Docs.initEventTracking = function() {
245
- Docs.App.getController('Classes').addListener({
246
- showClass: function(cls) {
247
- _gaq.push(['_trackEvent', 'Classes', 'Show', cls]);
248
- },
249
- showMember: function(cls, anchor) {
250
- _gaq.push(['_trackEvent', 'Classes', 'Member', cls + ' - ' + anchor]);
251
- }
252
- });
253
- Docs.App.getController('Guides').addListener({
254
- showGuide: function(guide) {
255
- _gaq.push(['_trackEvent', 'Guides', 'Show', guide]);
256
- }
257
- });
258
- Docs.App.getController('Videos').addListener({
259
- showVideo: function(video) {
260
- _gaq.push(['_trackEvent', 'Video', 'Show', video]);
261
- }
262
- });
263
- Docs.App.getController('Examples').addListener({
264
- showExample: function(example) {
265
- _gaq.push(['_trackEvent', 'Example', 'Show', example]);
266
- }
267
- });
268
- }
269
-
270
- Docs.otherProducts = [
271
- {
272
- text: 'Ext JS 4.1',
273
- href: 'http://docs.sencha.com/ext-js/4-1'
274
- },
275
- {
276
- text: 'Ext JS 4.0',
277
- href: 'http://docs.sencha.com/ext-js/4-0'
278
- },
279
- {
280
- text: 'Ext JS 3',
281
- href: 'http://docs.sencha.com/ext-js/3-4'
282
- },
283
- {
284
- text: 'Ext JS 2',
285
- href: 'http://docs.sencha.com/ext-js/2-3'
286
- },
287
- {
288
- text: 'Sencha Touch 2',
289
- href: 'http://docs.sencha.com/touch/2-0'
290
- },
291
- {
292
- text: 'Sencha Touch 1',
293
- href: 'http://docs.sencha.com/touch/1-1'
294
- },
295
- {
296
- text: 'Touch Charts',
297
- href: 'http://docs.sencha.com/touch-charts/1-0'
298
- },
299
- {
300
- text: 'Sencha Animator',
301
- href: 'http://docs.sencha.com/animator/1-0'
302
- },
303
- {
304
- text: 'Sencha Architect',
305
- href: 'http://docs.sencha.com/arhitect/2-0'
306
- },
307
- {
308
- text: 'Sencha.io',
309
- href: 'http://docs.sencha.com/io/1-0'
310
- }
311
- ];
312
- </script>
313
- EOHTML
314
- ]
315
-
316
- end
317
-
318
- def copy_extjs_build
319
- system "cp -r #{EXT_BUILD} #{OUT_DIR}/extjs-build"
320
- end
321
-
322
- # Copy over Sencha Touch
323
- def copy_touch2_build
324
- system "cp -r #{TOUCH_BUILD} #{OUT_DIR}/touch"
325
- end
326
-
327
186
  def run
328
187
  # Pass multiple arguments to system, so we'll take advantage of the built-in escaping
329
188
  system(*["ruby", "bin/jsduck"].concat(@options))
@@ -335,226 +194,68 @@ task :sass do
335
194
  system "compass compile --quiet template/resources/sass"
336
195
  end
337
196
 
338
- desc "Run JSDuck on Ext JS SDK (for internal use at Sencha)\n" +
339
- "sdk - creates debug/development version\n" +
340
- "sdk[export] - creates export version\n" +
341
- "sdk[live] - create live version for deployment\n"
342
- task :sdk, [:mode] => :sass do |t, args|
343
- mode = args[:mode] || "debug"
344
- throw "Unknown mode #{mode}" unless ["debug", "export", "live"].include?(mode)
345
- compress if mode == "export" || mode == "live"
346
-
347
- runner = JsDuckRunner.new
348
- runner.add_options ["--output", OUT_DIR, "--config", "#{SDK_DIR}/extjs/docs/config.json"]
349
- runner.add_debug if mode == "debug"
350
- runner.add_seo if mode == "debug" || mode == "live"
351
- runner.add_export_notice("ext-js/4-0") if mode == "export"
352
- runner.add_google_analytics if mode == "live"
353
- runner.add_comments('ext-js', '4') if mode == "debug" || mode == "live"
354
- if mode == "export"
355
- runner.add_options ["--eg-iframe", "#{SDK_DIR}/extjs/docs/eg-iframe-build.html"]
356
- runner.add_options ["--examples-base-url", "../examples/"]
357
- else
358
- runner.add_options ["--examples-base-url", "extjs-build/examples/"]
359
- end
360
- runner.run
361
-
362
- if mode == "export"
363
- runner.make_extjs_path_relative
364
- else
365
- runner.copy_extjs_build
366
- end
197
+ desc "Build JSDuck gem"
198
+ task :gem => :sass do
199
+ compress
200
+ system "gem build jsduck.gemspec"
367
201
  end
368
202
 
369
203
  desc "Run JSDuck on Docs app itself"
370
204
  task :docs do
371
205
  runner = JsDuckRunner.new
372
206
  runner.add_ext4
373
- runner.add_options([
207
+ runner.add_options(
374
208
  "--builtin-classes",
375
209
  "template/app"
376
- ])
210
+ )
377
211
  runner.add_debug
378
- runner.add_seo
379
212
  runner.run
380
213
  end
381
214
 
382
- desc "Run JSDuck on official Ext JS 4.0.2a build\n" +
383
- "ext4 - creates debug/development version\n" +
384
- "ext4[export] - creates export/deployable version\n"
385
- task :ext4, [:mode] => :sass do |t, args|
386
- mode = args[:mode] || "debug"
387
- throw "Unknown mode #{mode}" unless ["debug", "export"].include?(mode)
388
- compress if mode == "export"
389
-
215
+ desc "Run JSDuck on official Ext JS 4 build"
216
+ task :ext4 => :sass do
390
217
  runner = JsDuckRunner.new
391
218
  runner.add_ext4
392
- runner.add_debug if mode == "debug"
393
- runner.add_seo
394
- runner.run
395
- end
396
-
397
- desc "Run JSDuck on official Ext JS 3.4 build\n" +
398
- "ext3 - creates debug/development version\n" +
399
- "ext3[export] - creates export/deployable version\n"
400
- "ext3[live] - creates live version for deployment\n"
401
- task :ext3, [:mode] => :sass do |t, args|
402
- mode = args[:mode] || "debug"
403
- throw "Unknown mode #{mode}" unless ["debug", "export", "live"].include?(mode)
404
- compress if mode == "export"
405
-
406
- runner = JsDuckRunner.new
407
- runner.add_options ["--output", OUT_DIR, "--config", "#{EXT3_DIR}/src/doc-config.json"]
408
- runner.add_debug if mode == "debug"
409
- runner.add_seo if mode == "live"
410
- runner.add_google_analytics if mode == "live"
411
- runner.run
412
- end
413
-
414
- desc "Run JSDuck on official Ext JS 2.3 build\n" +
415
- "ext2 - creates debug/development version\n" +
416
- "ext2[export] - creates export/deployable version\n"
417
- "ext2[live] - creates live version for deployment\n"
418
- task :ext2, [:mode] => :sass do |t, args|
419
- mode = args[:mode] || "debug"
420
- throw "Unknown mode #{mode}" unless ["debug", "export", "live"].include?(mode)
421
- compress if mode == "export"
422
-
423
- runner = JsDuckRunner.new
424
- runner.add_options ["--output", OUT_DIR, "--config", "#{EXT2_DIR}/doc-config.json"]
425
- runner.add_debug if mode == "debug"
426
- runner.add_seo if mode == "live"
427
- runner.add_google_analytics if mode == "live"
219
+ runner.add_debug
220
+ runner.add_options("--tests")
428
221
  runner.run
429
- end
430
-
431
- desc "Run JSDuck on Sencha Touch (for internal use at Sencha)\n" +
432
- "touch - creates debug/development version\n" +
433
- "touch[live] - create live version for deployment\n"
434
- task :touch, [:mode] => :sass do |t, args|
435
- mode = args[:mode] || "debug"
436
- throw "Unknown mode #{mode}" unless ["debug", "live"].include?(mode)
437
- compress if mode == "live"
438
222
 
439
- runner = JsDuckRunner.new
440
- runner.add_options ["--output", OUT_DIR, "--config", "#{SDK_DIR}/touch/doc-resources/config.json"]
441
- runner.add_debug if mode == "debug"
442
- runner.add_seo if mode == "debug" || mode == "live"
443
- runner.add_google_analytics if mode == "live"
444
- runner.run
223
+ system("cp -r #{EXT_BUILD} #{OUT_DIR}/extjs-build")
445
224
  end
446
225
 
447
- desc "Run JSDuck on Sencha Touch 2 (for internal use at Sencha)\n" +
448
- "touch2 - creates debug/development version\n" +
449
- "touch2[export] - creates export version\n" +
450
- "touch2[live] - create live version for deployment\n"
451
- task :touch2, [:mode] => :sass do |t, args|
452
- mode = args[:mode] || "debug"
453
- throw "Unknown mode #{mode}" unless ["debug", "export", "live"].include?(mode)
454
- compress if mode == "live" || mode == "export"
455
-
226
+ desc "Run JSDuck on Ext JS from SDK repo (for internal use at Sencha)"
227
+ task :sdk => :sass do
456
228
  runner = JsDuckRunner.new
457
- runner.add_options [
229
+ runner.add_options(
458
230
  "--output", OUT_DIR,
459
- "--config", "#{SDK_DIR}/touch/docs/config.json"
460
- ]
461
-
462
- if mode == "export"
463
- runner.add_export_notice("touch/2-0")
464
- runner.add_phone_redirect
465
- # override settings in config.json
466
- runner.add_options [
467
- "--welcome", "#{SDK_DIR}/touch/docs/build-welcome.html",
468
- "--eg-iframe", "#{SDK_DIR}/touch/docs/build-eg-iframe.html",
469
- "--examples-base-url", "../examples/",
470
- ]
471
- else
472
- runner.add_options ["--examples-base-url", "touch/examples/production/"]
473
- end
474
-
475
- runner.add_debug if mode == "debug"
476
- runner.add_seo if mode == "debug" || mode == "live"
477
- runner.add_google_analytics if mode == "live"
478
- runner.add_comments('touch', '2') if mode == "debug" || mode == "live"
479
- runner.run
480
-
481
- runner.copy_touch2_build if mode != "export"
482
- end
483
-
484
- desc "Run JSDuck on Sencha Touch Charts (for internal use at Sencha)\n" +
485
- "charts - creates debug/development version\n" +
486
- "charts[export] - create live version for deployment\n"
487
- "charts[live] - create live version for deployment\n"
488
- task :charts, [:mode] => :sass do |t, args|
489
- mode = args[:mode] || "debug"
490
- throw "Unknown mode #{mode}" unless ["debug", "export", "live"].include?(mode)
491
- compress if mode == "live"
492
-
493
- runner = JsDuckRunner.new
494
- runner.add_options ["--output", OUT_DIR, "--config", "#{SDK_DIR}/charts/docs/config.json"]
495
- runner.add_debug if mode == "debug"
496
- runner.add_seo if mode == "debug" || mode == "live"
497
- runner.add_google_analytics if mode == "live"
231
+ "--config", "#{SDK_DIR}/extjs/docs/config.json",
232
+ "--examples-base-url", "extjs-build/examples/",
233
+ "--seo",
234
+ "--tests"
235
+ )
236
+ runner.add_debug
237
+ runner.add_comments('ext-js', '4')
498
238
  runner.run
499
- end
500
-
501
- desc "Run JSDuck on Sencha.IO Sync (for internal use at Sencha)\n" +
502
- "senchaio - creates debug/development version\n" +
503
- "senchaio[export] - create live version for deployment\n"
504
- "senchaio[live] - create live version for deployment\n"
505
- task :senchaio, [:mode] => :sass do |t, args|
506
- mode = args[:mode] || "debug"
507
- throw "Unknown mode #{mode}" unless ["debug", "export", "live"].include?(mode)
508
- compress if mode == "live"
509
239
 
510
- runner = JsDuckRunner.new
511
- runner.add_options ["--output", OUT_DIR, "--config", "#{SENCHAIO_DIR}/docs/config.json"]
512
- runner.add_debug if mode == "debug"
513
- runner.add_seo if mode == "debug" || mode == "live"
514
- runner.add_google_analytics if mode == "live"
515
- runner.run
240
+ system("cp -r #{EXT_BUILD} #{OUT_DIR}/extjs-build")
516
241
  end
517
242
 
518
- desc "Run JSDuck on Sencha Animator (for internal use at Sencha)\n" +
519
- "animator - creates debug/development version\n" +
520
- "animator[export] - create live version for deployment\n"
521
- "animator[live] - create live version for deployment\n"
522
- task :animator, [:mode] => :sass do |t, args|
523
- mode = args[:mode] || "debug"
524
- throw "Unknown mode #{mode}" unless ["debug", "live", "export"].include?(mode)
525
- compress if mode == "live"
526
-
243
+ desc "Run JSDuck on Sencha Touch 2 repo (for internal use at Sencha)"
244
+ task :touch2 => :sass do
527
245
  runner = JsDuckRunner.new
528
- runner.add_options ["--output", OUT_DIR, "--config", "#{ANIMATOR_DIR}/docs/config.json"]
529
- runner.add_debug if mode == "debug"
530
- runner.add_seo if mode == "debug" || mode == "live"
531
- runner.add_google_analytics if mode == "live"
532
- runner.add_comments('animator', '1') if mode == "debug" || mode == "live"
533
- runner.run
534
- end
535
-
536
- desc "Run JSDuck on Sencha Architect (for internal use at Sencha)\n" +
537
- "architect - creates debug/development version\n" +
538
- "architect[export] - create live version for deployment\n"
539
- "architect[live] - create live version for deployment\n"
540
- task :architect, [:mode] => :sass do |t, args|
541
- mode = args[:mode] || "debug"
542
- throw "Unknown mode #{mode}" unless ["debug", "live", "export"].include?(mode)
543
- compress if mode == "live"
246
+ runner.add_options(
247
+ "--output", OUT_DIR,
248
+ "--config", "#{SDK_DIR}/touch/docs/config.json",
249
+ "--examples-base-url", "touch/examples/production/",
250
+ "--seo",
251
+ "--tests"
252
+ )
544
253
 
545
- runner = JsDuckRunner.new
546
- runner.add_options ["--output", OUT_DIR, "--config", "#{ARCHITECT_DIR}/docs/config.json"]
547
- runner.add_debug if mode == "debug"
548
- runner.add_seo if mode == "debug" || mode == "live"
549
- runner.add_google_analytics if mode == "live"
550
- runner.add_comments('architect', '2') if mode == "debug" || mode == "live"
254
+ runner.add_debug
255
+ runner.add_comments('touch', '2')
551
256
  runner.run
552
- end
553
257
 
554
- desc "Build JSDuck gem"
555
- task :gem => :sass do
556
- compress
557
- system "gem build jsduck.gemspec"
258
+ system("cp -r #{TOUCH_BUILD} #{OUT_DIR}/touch")
558
259
  end
559
260
 
560
261
  task :default => :spec
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.9.1'
6
- s.date = '2012-04-25'
5
+ s.version = '3.10.0'
6
+ s.date = '2012-05-04'
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"
@@ -19,7 +19,7 @@ module JsDuck
19
19
  # }
20
20
  #
21
21
  class ApiExporter
22
- def initialize(relations)
22
+ def initialize(relations, opts)
23
23
  # All params ignored, they're present to be compatible with
24
24
  # other exporters.
25
25
  end
data/lib/jsduck/app.rb CHANGED
@@ -20,6 +20,10 @@ require 'jsduck/index_html'
20
20
  require 'jsduck/api_exporter'
21
21
  require 'jsduck/full_exporter'
22
22
  require 'jsduck/app_exporter'
23
+ require 'jsduck/examples_exporter'
24
+ require 'jsduck/inline_examples'
25
+ require 'jsduck/guide_writer'
26
+ require 'jsduck/stdout'
23
27
  require 'fileutils'
24
28
 
25
29
  module JsDuck
@@ -53,9 +57,18 @@ module JsDuck
53
57
  if @opts.export
54
58
  format_classes
55
59
  FileUtils.rm_rf(@opts.output_dir) unless @opts.output_dir == :stdout
56
- exporters = {:full => FullExporter, :api => ApiExporter}
60
+ exporters = {
61
+ :full => FullExporter,
62
+ :api => ApiExporter,
63
+ :examples => ExamplesExporter,
64
+ }
57
65
  cw = ClassWriter.new(exporters[@opts.export], @relations, @opts)
58
66
  cw.write(@opts.output_dir, ".json")
67
+ if @opts.export == :examples
68
+ gw = GuideWriter.new(exporters[@opts.export], @assets.guides, @opts)
69
+ gw.write(@opts.output_dir, ".json")
70
+ end
71
+ Stdout.instance.flush
59
72
  else
60
73
  FileUtils.rm_rf(@opts.output_dir)
61
74
  TemplateDir.new(@opts).write
@@ -67,10 +80,19 @@ module JsDuck
67
80
  # class-formatting is done in parallel which breaks the links
68
81
  # between source files and classes. Therefore it MUST to be done
69
82
  # after writing sources which needs the links to work.
70
- source_writer = SourceWriter.new(parsed_files, @parallel)
71
- source_writer.write(@opts.output_dir + "/source")
83
+ if @opts.source
84
+ source_writer = SourceWriter.new(parsed_files, @parallel)
85
+ source_writer.write(@opts.output_dir + "/source")
86
+ end
72
87
  format_classes
73
88
 
89
+ if @opts.tests
90
+ examples = InlineExamples.new
91
+ examples.add_classes(@relations)
92
+ examples.add_guides(@assets.guides)
93
+ examples.write(@opts.output_dir+"/inline-examples.js")
94
+ end
95
+
74
96
  cw = ClassWriter.new(AppExporter, @relations, @opts)
75
97
  cw.write(@opts.output_dir+"/output", ".js")
76
98
 
@@ -24,10 +24,12 @@ module JsDuck
24
24
  :examples => @assets.examples.to_array,
25
25
  :search => SearchData.new.create(@relations.classes, @assets),
26
26
  :stats => @opts.stats ? Stats.new.create(@relations.classes) : [],
27
+ :tests => @opts.tests,
27
28
  :signatures => MetaTagRegistry.instance.signatures,
28
29
  :localStorageDb => @opts.local_storage_db,
29
30
  :showPrintButton => @opts.seo,
30
31
  :touchExamplesUi => @opts.touch_examples_ui,
32
+ :source => @opts.source,
31
33
  }
32
34
  }) + ";\n"
33
35
  File.open(filename, 'w') {|f| f.write(js) }
@@ -6,9 +6,9 @@ module JsDuck
6
6
 
7
7
  # Exports data for Docs app.
8
8
  class AppExporter < FullExporter
9
- def initialize(relations)
10
- super(relations)
11
- @renderer = Renderer.new
9
+ def initialize(relations, opts)
10
+ super(relations, opts)
11
+ @renderer = Renderer.new(opts)
12
12
  end
13
13
 
14
14
  # Returns compacted class data hash which contains an additional
@@ -1,6 +1,6 @@
1
1
  require 'jsduck/parallel_wrap'
2
2
  require 'jsduck/logger'
3
- require 'jsduck/json_duck'
3
+ require 'jsduck/stdout'
4
4
  require 'fileutils'
5
5
 
6
6
  module JsDuck
@@ -9,7 +9,7 @@ module JsDuck
9
9
  class ClassWriter
10
10
  def initialize(exporter_class, relations, opts)
11
11
  @relations = relations
12
- @exporter = exporter_class.new(relations)
12
+ @exporter = exporter_class.new(relations, opts)
13
13
  @parallel = ParallelWrap.new(:in_processes => opts.processes)
14
14
  end
15
15
 
@@ -24,8 +24,8 @@ module JsDuck
24
24
  private
25
25
 
26
26
  def write_stdout
27
- json = @parallel.map(@relations.classes) {|cls| @exporter.export(cls) }
28
- puts JsonDuck.generate(json)
27
+ json = @parallel.map(@relations.classes) {|cls| @exporter.export(cls) }.compact
28
+ Stdout.instance.add(json)
29
29
  end
30
30
 
31
31
  def write_dir(dir, extension)
@@ -34,12 +34,15 @@ module JsDuck
34
34
  filename = dir + "/" + cls[:name] + extension
35
35
  Logger.instance.log("Writing docs", filename)
36
36
  json = @exporter.export(cls)
37
- if extension == ".json"
38
- JsonDuck.write_json(filename, json)
39
- elsif extension == ".js"
40
- JsonDuck.write_jsonp(filename, cls[:name].gsub(/\./, "_"), json)
41
- else
42
- throw "Unexpected file extension: #{extension}"
37
+ # skip file if exporter returned nil
38
+ if json
39
+ if extension == ".json"
40
+ JsonDuck.write_json(filename, json)
41
+ elsif extension == ".js"
42
+ JsonDuck.write_jsonp(filename, cls[:name].gsub(/\./, "_"), json)
43
+ else
44
+ throw "Unexpected file extension: #{extension}"
45
+ end
43
46
  end
44
47
  end
45
48
  end
@@ -0,0 +1,56 @@
1
+ require 'jsduck/inline_examples'
2
+
3
+ module JsDuck
4
+
5
+ # Exporter for inline examples.
6
+ #
7
+ # It produces the following structure:
8
+ #
9
+ # {
10
+ # :type => :class, # can also be :guide
11
+ # :name => "Panel",
12
+ # :examples => [
13
+ # {:code => "bla bla", :options => {}},
14
+ # {:code => "bla bla", :options => {"raw" => true}},
15
+ # ...
16
+ # ]
17
+ # }
18
+ #
19
+ class ExamplesExporter
20
+ def initialize(relations, opts)
21
+ # All params ignored, they're present to be compatible with
22
+ # other exporters.
23
+ @inline_examples = InlineExamples.new
24
+ end
25
+
26
+ # Returns hash of class name and inline examples
27
+ def export(cls)
28
+ examples = @inline_examples.extract(cls[:doc])
29
+ if examples.length > 0
30
+ {
31
+ :type => :class,
32
+ :name => cls[:name],
33
+ :examples => examples,
34
+ }
35
+ else
36
+ nil
37
+ end
38
+ end
39
+
40
+ # Returns hash of guide name and inline examples
41
+ def export_guide(guide)
42
+ examples = @inline_examples.extract(guide[:html] || "")
43
+ if examples.length > 0
44
+ {
45
+ :type => :guide,
46
+ :name => guide["name"],
47
+ :examples => examples,
48
+ }
49
+ else
50
+ nil
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -4,8 +4,9 @@ module JsDuck
4
4
 
5
5
  # Exporter for all the class docs.
6
6
  class FullExporter
7
- def initialize(relations)
7
+ def initialize(relations, opts)
8
8
  @relations = relations
9
+ # opts parameter is here just for compatibility with other exporters
9
10
  end
10
11
 
11
12
  # Returns all data in Class object as hash.
@@ -0,0 +1,58 @@
1
+ require 'jsduck/parallel_wrap'
2
+ require 'jsduck/logger'
3
+ require 'jsduck/stdout'
4
+ require 'fileutils'
5
+
6
+ module JsDuck
7
+
8
+ # Writes guide data into files in JSON or JSONP format or to STDOUT.
9
+ class GuideWriter
10
+ def initialize(exporter_class, guides, opts)
11
+ @guides = guides
12
+ @exporter = exporter_class.new(guides, opts)
13
+ @parallel = ParallelWrap.new(:in_processes => opts.processes)
14
+ end
15
+
16
+ # Writes guide data into given directory or STDOUT when dir == :stdout.
17
+ #
18
+ # Extension is either ".json" for normal JSON output
19
+ # or ".js" for JsonP output.
20
+ def write(dir, extension)
21
+ dir == :stdout ? write_stdout : write_dir(dir, extension)
22
+ end
23
+
24
+ private
25
+
26
+ def write_stdout
27
+ json = @parallel.map(all_guides) {|guide| @exporter.export_guide(guide) }.compact
28
+ Stdout.instance.add(json)
29
+ end
30
+
31
+ def write_dir(dir, extension)
32
+ FileUtils.mkdir(dir) unless File.exists?(dir)
33
+ @parallel.each(all_guides) do |guide|
34
+ filename = dir + "/" + guide["name"] + extension
35
+ Logger.instance.log("Writing guide", filename)
36
+ json = @exporter.export_guide(guide)
37
+ # skip file if exporter returned nil
38
+ if json
39
+ if extension == ".json"
40
+ JsonDuck.write_json(filename, json)
41
+ elsif extension == ".js"
42
+ JsonDuck.write_jsonp(filename, guide["name"], json)
43
+ else
44
+ throw "Unexpected file extension: #{extension}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def all_guides
51
+ arr = []
52
+ @guides.each_item {|g| arr << g }
53
+ arr
54
+ end
55
+
56
+ end
57
+
58
+ end
data/lib/jsduck/guides.rb CHANGED
@@ -34,14 +34,48 @@ module JsDuck
34
34
  each_item {|guide| write_guide(guide, dir) }
35
35
  end
36
36
 
37
- def write_guide(guide, dir)
37
+ # Modified each_item that also loads HTML for each guide
38
+ def each_item(&block)
39
+ unless @loaded
40
+ super do |guide|
41
+ guide[:html] = load_guide(guide)
42
+ end
43
+ @loaded = true
44
+ end
45
+
46
+ super(&block)
47
+ end
48
+
49
+ # Modified to_array that excludes the :html from guide nodes
50
+ def to_array
51
+ @groups.map do |group|
52
+ {
53
+ "title" => group["title"],
54
+ "items" => group["items"].map {|g| g.select {|k, v| k != :html } }
55
+ }
56
+ end
57
+ end
58
+
59
+ def load_guide(guide)
38
60
  in_dir = @path + "/guides/" + guide["name"]
39
- out_dir = dir + "/" + guide["name"]
40
61
  return Logger.instance.warn(:guide, "Guide #{in_dir} not found") unless File.exists?(in_dir)
41
62
 
42
63
  guide_file = in_dir + "/README.md"
43
64
  return Logger.instance.warn(:guide, "README.md not found in #{in_dir}") unless File.exists?(guide_file)
44
65
 
66
+ @formatter.doc_context = {:filename => guide_file, :linenr => 0}
67
+ name = File.basename(in_dir)
68
+ @formatter.img_path = "guides/#{name}"
69
+
70
+ return add_toc(guide, @formatter.format(JsDuck::IO.read(guide_file)))
71
+ end
72
+
73
+ def write_guide(guide, dir)
74
+ return unless guide[:html]
75
+
76
+ in_dir = @path + "/guides/" + guide["name"]
77
+ out_dir = dir + "/" + guide["name"]
78
+
45
79
  Logger.instance.log("Writing guide", out_dir)
46
80
  # Copy the whole guide dir over
47
81
  FileUtils.cp_r(in_dir, out_dir)
@@ -49,12 +83,7 @@ module JsDuck
49
83
  # Ensure the guide has an icon
50
84
  fix_icon(out_dir)
51
85
 
52
- @formatter.doc_context = {:filename => guide_file, :linenr => 0}
53
- name = File.basename(in_dir)
54
- @formatter.img_path = "guides/#{name}"
55
- html = add_toc(guide, @formatter.format(JsDuck::IO.read(guide_file)))
56
-
57
- JsonDuck.write_jsonp(out_dir+"/README.js", name, {:guide => html, :title => guide["title"]})
86
+ JsonDuck.write_jsonp(out_dir+"/README.js", guide["name"], {:guide => guide[:html], :title => guide["title"]})
58
87
  end
59
88
 
60
89
  # Ensures the guide dir contains icon.png.
@@ -0,0 +1,97 @@
1
+ require 'jsduck/json_duck'
2
+ require 'cgi'
3
+
4
+ module JsDuck
5
+
6
+ # Extracts inline examples from formatted docs and writes to file
7
+ class InlineExamples
8
+ def initialize
9
+ @begin_example_re = /<pre class='inline-example ([^']*)'><code>/
10
+ @end_example_re = /<\/code><\/pre>/
11
+ @examples = []
12
+ end
13
+
14
+ # Extracts inline examples from classes
15
+ def add_classes(relations)
16
+ relations.each do |cls|
17
+ extract(cls[:doc]).each_with_index do |ex, i|
18
+ @examples << {
19
+ :id => cls.full_name + "-" + i.to_s,
20
+ :name => cls.full_name + " example #" + (i+1).to_s,
21
+ :href => '#!/api/' + cls.full_name,
22
+ :code => ex[:code],
23
+ :options => ex[:options],
24
+ }
25
+ end
26
+ end
27
+
28
+ self
29
+ end
30
+
31
+ # Extracts inline examples from guides
32
+ def add_guides(guides)
33
+ guides.each_item do |guide|
34
+ extract(guide[:html]).each_with_index do |ex, i|
35
+ @examples << {
36
+ :id => guide["name"] + "-" + i.to_s,
37
+ :name => guide["title"] + " example #" + (i+1).to_s,
38
+ :href => '#!/guide/' + guide["name"],
39
+ :code => ex[:code],
40
+ :options => ex[:options],
41
+ }
42
+ end
43
+ end
44
+
45
+ self
46
+ end
47
+
48
+ # Writes all found examples to .js file
49
+ def write(filename)
50
+ JsonDuck.write_jsonp(filename, "__inline_examples__", @examples)
51
+ end
52
+
53
+ # Extracts inline examples from HTML
54
+ def extract(html)
55
+ examples = []
56
+
57
+ s = StringScanner.new(html)
58
+ while !s.eos? do
59
+ if s.check(/</)
60
+ if s.check(@begin_example_re)
61
+
62
+ s.scan(@begin_example_re) =~ @begin_example_re
63
+ options = build_options_hash($1)
64
+
65
+ ex = s.scan_until(@end_example_re).sub(@end_example_re, '')
66
+
67
+ examples << {
68
+ :code => CGI.unescapeHTML(strip_tags(ex)),
69
+ :options => options,
70
+ }
71
+ else
72
+ s.skip(/</)
73
+ end
74
+ else
75
+ s.skip(/[^<]+/)
76
+ end
77
+ end
78
+
79
+ examples
80
+ end
81
+
82
+ private
83
+
84
+ def build_options_hash(css_classes)
85
+ hash = {}
86
+ css_classes.split(/ +/).each do |k|
87
+ hash[k] = true
88
+ end
89
+ hash
90
+ end
91
+
92
+ def strip_tags(str)
93
+ str.gsub(/<.*?>/, "")
94
+ end
95
+ end
96
+
97
+ end
@@ -25,6 +25,7 @@ module JsDuck
25
25
  attr_accessor :examples
26
26
  attr_accessor :stats
27
27
  attr_accessor :categories_path
28
+ attr_accessor :source
28
29
  attr_accessor :pretty_json
29
30
  attr_accessor :images
30
31
  attr_accessor :link_tpl
@@ -33,6 +34,7 @@ module JsDuck
33
34
  attr_accessor :seo
34
35
  attr_accessor :eg_iframe
35
36
  attr_accessor :examples_base_url
37
+ attr_accessor :tests
36
38
 
37
39
  # Debugging
38
40
  attr_accessor :processes
@@ -73,7 +75,7 @@ module JsDuck
73
75
  ]
74
76
  @meta_tag_paths = []
75
77
 
76
- @version = "3.9.1"
78
+ @version = "3.10.0"
77
79
 
78
80
  # Customizing output
79
81
  @title = "Sencha Docs - Ext JS"
@@ -87,6 +89,7 @@ module JsDuck
87
89
  @examples = nil
88
90
  @stats = false
89
91
  @categories_path = nil
92
+ @source = true
90
93
  @pretty_json = false
91
94
  @images = []
92
95
  @link_tpl = '<a href="#!/api/%c%-%m" rel="%c%-%m" class="docClass">%a</a>'
@@ -97,6 +100,7 @@ module JsDuck
97
100
  @seo = false
98
101
  @eg_iframe = nil
99
102
  @examples_base_url = "extjs-build/examples/"
103
+ @tests = false
100
104
 
101
105
  # Debugging
102
106
  # Turn multiprocessing off by default in Windows
@@ -219,16 +223,16 @@ module JsDuck
219
223
  @examples = canonical(path)
220
224
  end
221
225
 
222
- opts.on('--stats',
223
- "Creates page with all kinds of statistics. Experimental!", " ") do
224
- @stats = true
225
- end
226
-
227
226
  opts.on('--categories=PATH',
228
227
  "Path to JSON file which defines categories for classes.", " ") do |path|
229
228
  @categories_path = canonical(path)
230
229
  end
231
230
 
231
+ opts.on('--no-source',
232
+ "Turns off the output of source files.", " ") do
233
+ @source = false
234
+ end
235
+
232
236
  opts.on('--pretty-json', "Turn on pretty-printing of JSON.", " ") do
233
237
  @pretty_json = true
234
238
  end
@@ -264,8 +268,9 @@ module JsDuck
264
268
 
265
269
  opts.on('--export=TYPE',
266
270
  "Exports docs in JSON. TYPE is one of:",
267
- "* full - full class docs.",
268
- "* api - only class- and member names.", " ") do |format|
271
+ "* full - full class docs.",
272
+ "* api - only class- and member names.",
273
+ "* examples - extracts inline examples from classes.", " ") do |format|
269
274
  @export = format.to_sym
270
275
  end
271
276
 
@@ -284,6 +289,15 @@ module JsDuck
284
289
  @examples_base_url = path
285
290
  end
286
291
 
292
+ opts.on('--tests', "Creates page for testing inline examples.", " ") do
293
+ @tests = true
294
+ end
295
+
296
+ opts.on('--stats',
297
+ "Creates page with all kinds of statistics. Experimental!", " ") do
298
+ @stats = true
299
+ end
300
+
287
301
  opts.separator "Debugging:"
288
302
  opts.separator ""
289
303
 
@@ -480,7 +494,7 @@ module JsDuck
480
494
  elsif @output_dir == :stdout && !@export
481
495
  puts "Output to STDOUT only works when using --export option."
482
496
  exit(1)
483
- elsif ![nil, :full, :api].include?(@export)
497
+ elsif ![nil, :full, :api, :examples].include?(@export)
484
498
  puts "Unknown export format: #{@export}"
485
499
  exit(1)
486
500
  elsif @output_dir != :stdout
@@ -6,6 +6,10 @@ module JsDuck
6
6
  # Ruby-side implementation of class docs Renderer.
7
7
  # Uses PhantomJS to run Docs.Renderer JavaScript.
8
8
  class Renderer
9
+ def initialize(opts)
10
+ @opts = opts
11
+ end
12
+
9
13
  def render(cls)
10
14
  @cls = cls
11
15
 
@@ -50,7 +54,7 @@ module JsDuck
50
54
  render_dependencies(:subclasses, "Subclasses"),
51
55
  render_dependencies(:mixedInto, "Mixed into"),
52
56
  render_dependencies(:uses, "Uses"),
53
- render_files,
57
+ @opts.source ? render_files : nil,
54
58
  ]
55
59
  if items.compact.length > 0
56
60
  return ['<pre class="hierarchy">', items, '</pre>']
@@ -197,7 +201,7 @@ module JsDuck
197
201
  inherited ? "<a href='#!/api/#{owner}' rel='#{owner}' class='defined-in docClass'>#{owner}</a>" :
198
202
  "<span class='defined-in' rel='#{owner}'>#{owner}</span>",
199
203
  "<br/>",
200
- "<a href='source/#{m[:files][0][:href]}' target='_blank' class='view-source'>view source</a>",
204
+ @opts.source ? "<a href='source/#{m[:files][0][:href]}' target='_blank' class='view-source'>view source</a>" : "",
201
205
  "</div>",
202
206
  # method params signature or property type signature
203
207
  render_signature(m),
@@ -0,0 +1,31 @@
1
+ require 'jsduck/json_duck'
2
+ require 'singleton'
3
+
4
+ module JsDuck
5
+
6
+ # Central place for buffering JSON data that's meant to be written to STDOUT
7
+ class Stdout
8
+ include Singleton
9
+
10
+ def initialize
11
+ @data = nil
12
+ end
13
+
14
+ # Adds array of new data
15
+ def add(data)
16
+ if @data
17
+ @data += data
18
+ else
19
+ @data = data
20
+ end
21
+ end
22
+
23
+ # Writes data to STDOUT in JSON format,
24
+ # but only if some data was added.
25
+ def flush
26
+ puts JsonDuck.generate(@data) if @data
27
+ end
28
+
29
+ end
30
+
31
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsduck
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.1
4
+ version: 3.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-04-25 00:00:00.000000000 Z
13
+ date: 2012-05-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rdiscount
17
- requirement: &20844700 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,15 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *20844700
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
26
31
  - !ruby/object:Gem::Dependency
27
32
  name: json
28
- requirement: &20842780 !ruby/object:Gem::Requirement
33
+ requirement: !ruby/object:Gem::Requirement
29
34
  none: false
30
35
  requirements:
31
36
  - - ! '>='
@@ -33,10 +38,15 @@ dependencies:
33
38
  version: '0'
34
39
  type: :runtime
35
40
  prerelease: false
36
- version_requirements: *20842780
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: parallel
39
- requirement: &20841760 !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
40
50
  none: false
41
51
  requirements:
42
52
  - - ! '>='
@@ -44,7 +54,12 @@ dependencies:
44
54
  version: '0'
45
55
  type: :runtime
46
56
  prerelease: false
47
- version_requirements: *20841760
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
48
63
  description: Documentation generator for Sencha JS frameworks
49
64
  email: rene.saarsoo@sencha.com
50
65
  executables:
@@ -83,14 +98,17 @@ files:
83
98
  - lib/jsduck/doc_formatter.rb
84
99
  - lib/jsduck/doc_parser.rb
85
100
  - lib/jsduck/examples.rb
101
+ - lib/jsduck/examples_exporter.rb
86
102
  - lib/jsduck/file_categories.rb
87
103
  - lib/jsduck/full_exporter.rb
88
104
  - lib/jsduck/grouped_asset.rb
105
+ - lib/jsduck/guide_writer.rb
89
106
  - lib/jsduck/guides.rb
90
107
  - lib/jsduck/icons.rb
91
108
  - lib/jsduck/images.rb
92
109
  - lib/jsduck/index_html.rb
93
110
  - lib/jsduck/inherit_doc.rb
111
+ - lib/jsduck/inline_examples.rb
94
112
  - lib/jsduck/inline_img.rb
95
113
  - lib/jsduck/inline_video.rb
96
114
  - lib/jsduck/io.rb
@@ -115,6 +133,7 @@ files:
115
133
  - lib/jsduck/source_file.rb
116
134
  - lib/jsduck/source_writer.rb
117
135
  - lib/jsduck/stats.rb
136
+ - lib/jsduck/stdout.rb
118
137
  - lib/jsduck/tag/abstract.rb
119
138
  - lib/jsduck/tag/aside.rb
120
139
  - lib/jsduck/tag/author.rb
@@ -597,7 +616,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
597
616
  version: 1.3.5
598
617
  requirements: []
599
618
  rubyforge_project: jsduck
600
- rubygems_version: 1.8.17
619
+ rubygems_version: 1.8.23
601
620
  signing_key:
602
621
  specification_version: 3
603
622
  summary: Simple JavaScript Duckumentation generator