jsduck 3.7.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -1
- data/Rakefile +1 -1
- data/jsduck.gemspec +2 -2
- data/lib/jsduck/app.rb +2 -1
- data/lib/jsduck/app_data.rb +1 -1
- data/lib/jsduck/class.rb +13 -2
- data/lib/jsduck/doc_formatter.rb +30 -43
- data/lib/jsduck/doc_parser.rb +26 -5
- data/lib/jsduck/guides.rb +2 -1
- data/lib/jsduck/index_html.rb +2 -1
- data/lib/jsduck/inline_img.rb +53 -0
- data/lib/jsduck/inline_video.rb +58 -0
- data/lib/jsduck/io.rb +30 -0
- data/lib/jsduck/json_duck.rb +2 -1
- data/lib/jsduck/options.rb +6 -8
- data/lib/jsduck/search_data.rb +61 -25
- data/lib/jsduck/tag/aside.rb +0 -3
- data/lib/jsduck/type_parser.rb +305 -30
- data/lib/jsduck/welcome.rb +2 -1
- data/opt/comments-server-side/app.js +60 -45
- data/opt/comments-server-side/package.json +1 -1
- data/opt/comments-server-side/util.js +129 -54
- metadata +398 -404
data/README.md
CHANGED
@@ -120,7 +120,9 @@ Thanks to [Ondřej Jirman](https://github.com/megous),
|
|
120
120
|
[ligaard](https://github.com/ligaard),
|
121
121
|
[Bill Hubbard](http://www.sencha.com/forum/member.php?272458-BillHubbard),
|
122
122
|
[Ed Spencer](https://github.com/edspencer),
|
123
|
-
[atian25](https://github.com/atian25)
|
123
|
+
[atian25](https://github.com/atian25),
|
124
|
+
Katherine Chu,
|
125
|
+
[Rob Dougan](https://github.com/rdougan) and many-many others who
|
124
126
|
reported bugs, submitted patches, and provided a lot of useful input.
|
125
127
|
|
126
128
|
|
data/Rakefile
CHANGED
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.
|
6
|
-
s.date = '2012-
|
5
|
+
s.version = '3.8.0'
|
6
|
+
s.date = '2012-03-15'
|
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/app.rb
CHANGED
@@ -10,6 +10,7 @@ require 'jsduck/parallel_wrap'
|
|
10
10
|
require 'jsduck/logger'
|
11
11
|
require 'jsduck/assets'
|
12
12
|
require 'jsduck/json_duck'
|
13
|
+
require 'jsduck/io'
|
13
14
|
require 'jsduck/lint'
|
14
15
|
require 'jsduck/template_dir'
|
15
16
|
require 'jsduck/class_writer'
|
@@ -81,7 +82,7 @@ module JsDuck
|
|
81
82
|
def parallel_parse(filenames)
|
82
83
|
@parallel.map(filenames) do |fname|
|
83
84
|
Logger.instance.log("Parsing", fname)
|
84
|
-
SourceFile.new(IO.read(fname), fname, @opts)
|
85
|
+
SourceFile.new(JsDuck::IO.read(fname), fname, @opts)
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
data/lib/jsduck/app_data.rb
CHANGED
@@ -22,7 +22,7 @@ module JsDuck
|
|
22
22
|
:guides => @assets.guides.to_array,
|
23
23
|
:videos => @assets.videos.to_array,
|
24
24
|
:examples => @assets.examples.to_array,
|
25
|
-
:search => SearchData.new.create(@relations.classes),
|
25
|
+
:search => SearchData.new.create(@relations.classes, @assets),
|
26
26
|
:stats => @opts.stats ? Stats.new.create(@relations.classes) : [],
|
27
27
|
:signatures => MetaTagRegistry.instance.signatures,
|
28
28
|
:localStorageDb => @opts.local_storage_db,
|
data/lib/jsduck/class.rb
CHANGED
@@ -178,7 +178,7 @@ module JsDuck
|
|
178
178
|
end
|
179
179
|
|
180
180
|
# merges second members hash into first one
|
181
|
-
def merge!(hash1, hash2)
|
181
|
+
def merge!(hash1, hash2, skip_overrides=false)
|
182
182
|
hash2.each_pair do |name, m|
|
183
183
|
if m[:meta] && m[:meta][:hide]
|
184
184
|
if hash1[name]
|
@@ -210,7 +210,18 @@ module JsDuck
|
|
210
210
|
# this, ignore overriding itself.
|
211
211
|
if new[:owner] != old[:owner]
|
212
212
|
new[:overrides] = [] unless new[:overrides]
|
213
|
-
|
213
|
+
unless new[:overrides].any? {|m| m[:owner] == old[:owner] }
|
214
|
+
# Make a copy of the important properties for us. We can't
|
215
|
+
# just push the actual `old` member itself, because there
|
216
|
+
# can be circular overrides (notably with Ext.Base), which
|
217
|
+
# will result in infinite loop when we try to convert our
|
218
|
+
# class into JSON.
|
219
|
+
new[:overrides] << {
|
220
|
+
:name => old[:name],
|
221
|
+
:owner => old[:owner],
|
222
|
+
:id => old[:id],
|
223
|
+
}
|
224
|
+
end
|
214
225
|
end
|
215
226
|
end
|
216
227
|
|
data/lib/jsduck/doc_formatter.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require 'rubygems'
|
2
3
|
require 'rdiscount'
|
3
4
|
require 'strscan'
|
4
5
|
require 'cgi'
|
5
6
|
require 'jsduck/logger'
|
7
|
+
require 'jsduck/inline_img'
|
8
|
+
require 'jsduck/inline_video'
|
6
9
|
|
7
10
|
module JsDuck
|
8
11
|
|
@@ -20,22 +23,6 @@ module JsDuck
|
|
20
23
|
# Default value: '<a href="%c%M">%a</a>'
|
21
24
|
attr_accessor :link_tpl
|
22
25
|
|
23
|
-
# Template HTML that replaces {@img URL alt text}
|
24
|
-
# Can contain placeholders:
|
25
|
-
#
|
26
|
-
# %u - URL from @img tag (e.g. "some/path.png")
|
27
|
-
# %a - alt text for image
|
28
|
-
#
|
29
|
-
# Default value: '<img src="%u" alt="%a"/>'
|
30
|
-
attr_accessor :img_tpl
|
31
|
-
|
32
|
-
# This will hold list of all image paths gathered from {@img} tags.
|
33
|
-
attr_accessor :images
|
34
|
-
|
35
|
-
# Base path to prefix images from {@img} tags.
|
36
|
-
# Defaults to no prefix.
|
37
|
-
attr_accessor :img_path
|
38
|
-
|
39
26
|
# Sets up instance to work in context of particular class, so
|
40
27
|
# that when {@link #blah} is encountered it knows that
|
41
28
|
# Context#blah is meant.
|
@@ -61,13 +48,26 @@ module JsDuck
|
|
61
48
|
@max_length = 120
|
62
49
|
@relations = relations
|
63
50
|
@images = []
|
51
|
+
|
52
|
+
@inline_img = InlineImg.new(opts)
|
53
|
+
@inline_video = InlineVideo.new(opts)
|
54
|
+
|
64
55
|
@link_tpl = opts[:link_tpl] || '<a href="%c%#%m">%a</a>'
|
65
|
-
@img_tpl = opts[:img_tpl] || '<img src="%u" alt="%a"/>'
|
66
56
|
@link_re = /\{@link\s+(\S*?)(?:\s+(.+?))?\}/m
|
67
|
-
|
57
|
+
|
68
58
|
@example_annotation_re = /<pre><code>\s*@example( +[^\n]*)?\s+/m
|
69
59
|
end
|
70
60
|
|
61
|
+
# Sets base path to prefix images from {@img} tags.
|
62
|
+
def img_path=(path)
|
63
|
+
@inline_img.base_path = path
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns list of all image paths gathered from {@img} tags.
|
67
|
+
def images
|
68
|
+
@inline_img.images
|
69
|
+
end
|
70
|
+
|
71
71
|
# Replaces {@link} and {@img} tags, auto-generates links for
|
72
72
|
# recognized classnames.
|
73
73
|
#
|
@@ -93,8 +93,10 @@ module JsDuck
|
|
93
93
|
while !s.eos? do
|
94
94
|
if s.check(@link_re)
|
95
95
|
out += replace_link_tag(s.scan(@link_re))
|
96
|
-
elsif
|
97
|
-
out +=
|
96
|
+
elsif substitute = @inline_img.replace(s)
|
97
|
+
out += substitute
|
98
|
+
elsif substitute = @inline_video.replace(s)
|
99
|
+
out += substitute
|
98
100
|
elsif s.check(/[{]/)
|
99
101
|
# There might still be "{" that doesn't begin {@link} or {@img} - ignore it
|
100
102
|
out += s.scan(/[{]/)
|
@@ -185,10 +187,6 @@ module JsDuck
|
|
185
187
|
end
|
186
188
|
end
|
187
189
|
|
188
|
-
def replace_img_tag(input)
|
189
|
-
input.sub(@img_re) { img($1, $2) }
|
190
|
-
end
|
191
|
-
|
192
190
|
# Looks input text for patterns like:
|
193
191
|
#
|
194
192
|
# My.ClassName
|
@@ -258,21 +256,6 @@ module JsDuck
|
|
258
256
|
Logger.instance.warn(:link_auto, msg, @doc_context[:filename], @doc_context[:linenr])
|
259
257
|
end
|
260
258
|
|
261
|
-
# applies the image template
|
262
|
-
def img(url, alt_text)
|
263
|
-
@images << url
|
264
|
-
@img_tpl.gsub(/(%\w)/) do
|
265
|
-
case $1
|
266
|
-
when '%u'
|
267
|
-
@img_path ? (@img_path + "/" + url) : url
|
268
|
-
when '%a'
|
269
|
-
CGI.escapeHTML(alt_text||"")
|
270
|
-
else
|
271
|
-
$1
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
259
|
# applies the link template
|
277
260
|
def link(cls, member, anchor_text, type=nil, static=false)
|
278
261
|
# Use the canonical class name for link (not some alternateClassName)
|
@@ -345,21 +328,25 @@ module JsDuck
|
|
345
328
|
#
|
346
329
|
def shorten(input)
|
347
330
|
sent = first_sentence(strip_tags(input))
|
348
|
-
|
349
|
-
|
331
|
+
# Use u-modifier to correctly count multi-byte characters
|
332
|
+
chars = sent.scan(/./mu)
|
333
|
+
if chars.length > @max_length
|
334
|
+
chars[0..(@max_length-4)].join + "..."
|
350
335
|
else
|
351
336
|
sent + " ..."
|
352
337
|
end
|
353
338
|
end
|
354
339
|
|
355
340
|
def first_sentence(str)
|
356
|
-
str.sub(/\A(
|
341
|
+
str.sub(/\A(.+?(\.|。))\s.*\Z/mu, "\\1")
|
357
342
|
end
|
358
343
|
|
359
344
|
# Returns true when input should get shortened.
|
360
345
|
def too_long?(input)
|
361
346
|
stripped = strip_tags(input)
|
362
|
-
|
347
|
+
# for sentence v/s full - compare byte length
|
348
|
+
# for full v/s max - compare char length
|
349
|
+
first_sentence(stripped).length < stripped.length || stripped.scan(/./mu).length > @max_length
|
363
350
|
end
|
364
351
|
|
365
352
|
def strip_tags(str)
|
data/lib/jsduck/doc_parser.rb
CHANGED
@@ -286,7 +286,9 @@ module JsDuck
|
|
286
286
|
add_tag(:type)
|
287
287
|
skip_horiz_white
|
288
288
|
if look(/\{/)
|
289
|
-
|
289
|
+
tdf = typedef
|
290
|
+
@current_tag[:type] = tdf[:type]
|
291
|
+
@current_tag[:optional] = true if tdf[:optional]
|
290
292
|
elsif look(/\S/)
|
291
293
|
@current_tag[:type] = @input.scan(/\S+/)
|
292
294
|
end
|
@@ -354,10 +356,13 @@ module JsDuck
|
|
354
356
|
end
|
355
357
|
|
356
358
|
# matches {type} if possible and sets it on @current_tag
|
359
|
+
# Also checks for {optionality=} in type definition.
|
357
360
|
def maybe_type
|
358
361
|
skip_horiz_white
|
359
362
|
if look(/\{/)
|
360
|
-
|
363
|
+
tdf = typedef
|
364
|
+
@current_tag[:type] = tdf[:type]
|
365
|
+
@current_tag[:optional] = true if tdf[:optional]
|
361
366
|
end
|
362
367
|
end
|
363
368
|
|
@@ -431,12 +436,28 @@ module JsDuck
|
|
431
436
|
end
|
432
437
|
end
|
433
438
|
|
434
|
-
# matches {
|
439
|
+
# matches {...=} and returns text inside brackets
|
435
440
|
def typedef
|
436
441
|
match(/\{/)
|
437
|
-
name = @input.scan(/[^}]
|
442
|
+
name = @input.scan(/[^{}]*/)
|
443
|
+
|
444
|
+
# Type definition can contain nested braces: {{foo:Number}}
|
445
|
+
# In such case we parse the definition so that the braces are balanced.
|
446
|
+
while @input.check(/[{]/)
|
447
|
+
name += "{" + typedef[:type] +"}"
|
448
|
+
name += @input.scan(/[^{}]*/)
|
449
|
+
end
|
450
|
+
|
451
|
+
if name =~ /=$/
|
452
|
+
name = name.chop
|
453
|
+
optional = true
|
454
|
+
else
|
455
|
+
optional = nil
|
456
|
+
end
|
457
|
+
|
438
458
|
match(/\}/)
|
439
|
-
|
459
|
+
|
460
|
+
return {:type => name, :optional => optional}
|
440
461
|
end
|
441
462
|
|
442
463
|
# matches <ident_chain> <ident_chain> ... until line end
|
data/lib/jsduck/guides.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'jsduck/logger'
|
2
2
|
require 'jsduck/json_duck'
|
3
|
+
require 'jsduck/io'
|
3
4
|
require 'jsduck/null_object'
|
4
5
|
require 'jsduck/logger'
|
5
6
|
require 'jsduck/grouped_asset'
|
@@ -51,7 +52,7 @@ module JsDuck
|
|
51
52
|
@formatter.doc_context = {:filename => guide_file, :linenr => 0}
|
52
53
|
name = File.basename(in_dir)
|
53
54
|
@formatter.img_path = "guides/#{name}"
|
54
|
-
html = add_toc(guide, @formatter.format(IO.read(guide_file)))
|
55
|
+
html = add_toc(guide, @formatter.format(JsDuck::IO.read(guide_file)))
|
55
56
|
|
56
57
|
JsonDuck.write_jsonp(out_dir+"/README.js", name, {:guide => html, :title => guide["title"]})
|
57
58
|
end
|
data/lib/jsduck/index_html.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'jsduck/logger'
|
2
|
+
require 'jsduck/io'
|
2
3
|
require 'fileutils'
|
3
4
|
|
4
5
|
module JsDuck
|
@@ -49,7 +50,7 @@ module JsDuck
|
|
49
50
|
# Opens in_file, replaces {keys} inside it, writes to out_file
|
50
51
|
def write_template(in_file, out_file, replacements)
|
51
52
|
Logger.instance.log("Writing", out_file)
|
52
|
-
html = IO.read(in_file)
|
53
|
+
html = JsDuck::IO.read(in_file)
|
53
54
|
html.gsub!(/\{\w+\}/) do |key|
|
54
55
|
replacements[key] ? replacements[key] : key
|
55
56
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'jsduck/logger'
|
3
|
+
|
4
|
+
module JsDuck
|
5
|
+
|
6
|
+
# Implementation of inline tag {@img}
|
7
|
+
class InlineImg
|
8
|
+
# Base path to prefix images from {@img} tags.
|
9
|
+
# Defaults to no prefix.
|
10
|
+
attr_accessor :base_path
|
11
|
+
|
12
|
+
# This will hold list of all image paths gathered from {@img} tags.
|
13
|
+
attr_accessor :images
|
14
|
+
|
15
|
+
def initialize(opts={})
|
16
|
+
@tpl = opts[:img_tpl] || '<img src="%u" alt="%a"/>'
|
17
|
+
|
18
|
+
@re = /\{@img\s+(\S*?)(?:\s+(.+?))?\}/m
|
19
|
+
|
20
|
+
@base_path = nil
|
21
|
+
@images = []
|
22
|
+
end
|
23
|
+
|
24
|
+
# Takes StringScanner instance.
|
25
|
+
#
|
26
|
+
# Looks for inline tag at the current scan pointer position, when
|
27
|
+
# found, moves scan pointer forward and performs the apporpriate
|
28
|
+
# replacement.
|
29
|
+
def replace(input)
|
30
|
+
if input.check(@re)
|
31
|
+
input.scan(@re).sub(@re) { apply_tpl($1, $2) }
|
32
|
+
else
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# applies the image template
|
38
|
+
def apply_tpl(url, alt_text)
|
39
|
+
@images << url
|
40
|
+
@tpl.gsub(/(%\w)/) do
|
41
|
+
case $1
|
42
|
+
when '%u'
|
43
|
+
@base_path ? (@base_path + "/" + url) : url
|
44
|
+
when '%a'
|
45
|
+
CGI.escapeHTML(alt_text||"")
|
46
|
+
else
|
47
|
+
$1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'jsduck/logger'
|
3
|
+
|
4
|
+
module JsDuck
|
5
|
+
|
6
|
+
# Implementation of inline tag {@video}
|
7
|
+
class InlineVideo
|
8
|
+
def initialize(opts={})
|
9
|
+
@templates = {
|
10
|
+
"html5" => '<video src="%u">%a</video>',
|
11
|
+
"vimeo" => [
|
12
|
+
'<p><object width="640" height="360">',
|
13
|
+
'<param name="allowfullscreen" value="true" />',
|
14
|
+
'<param name="allowscriptaccess" value="always" />',
|
15
|
+
'<param name="flashvars" value="api=1" />',
|
16
|
+
'<param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=%u&server=vimeo.com&color=4CC208&fullscreen=1" />',
|
17
|
+
'<embed src="http://vimeo.com/moogaloop.swf?clip_id=%u&server=vimeo.com&color=4CC208&fullscreen=1" ',
|
18
|
+
'type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="360"></embed>',
|
19
|
+
'</object></p>',
|
20
|
+
].join
|
21
|
+
}
|
22
|
+
|
23
|
+
@re = /\{@video\s+(\w+)\s+(\S*?)(?:\s+(.+?))?\}/m
|
24
|
+
end
|
25
|
+
|
26
|
+
# Takes StringScanner instance.
|
27
|
+
#
|
28
|
+
# Looks for inline tag at the current scan pointer position, when
|
29
|
+
# found, moves scan pointer forward and performs the apporpriate
|
30
|
+
# replacement.
|
31
|
+
def replace(input)
|
32
|
+
if input.check(@re)
|
33
|
+
input.scan(@re).sub(@re) { apply_tpl($1, $2, $3) }
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# applies the video template of the specified type
|
40
|
+
def apply_tpl(type, url, alt_text)
|
41
|
+
unless @templates.has_key?(type)
|
42
|
+
Logger.instance.warn(nil, "Unknown video type #{type}")
|
43
|
+
end
|
44
|
+
|
45
|
+
@templates[type].gsub(/(%\w)/) do
|
46
|
+
case $1
|
47
|
+
when '%u'
|
48
|
+
url
|
49
|
+
when '%a'
|
50
|
+
CGI.escapeHTML(alt_text||"")
|
51
|
+
else
|
52
|
+
$1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/jsduck/io.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module JsDuck
|
2
|
+
|
3
|
+
# A helper to use instead the builtin IO class to read files in
|
4
|
+
# correct encoding.
|
5
|
+
#
|
6
|
+
# By default in Ruby 1.9 the encoding is auto-detected, which can
|
7
|
+
# have surprising results. So in here we read in all files in UTF-8
|
8
|
+
# (the default) or in some other encoding specified through --encoding
|
9
|
+
# option and convert it to UTF-8 internally.
|
10
|
+
class IO
|
11
|
+
@@encoding = "UTF-8"
|
12
|
+
|
13
|
+
# Sets the external encoding to be used for reading files.
|
14
|
+
# When it's different from UTF-8, the input will be converted to UTF-8.
|
15
|
+
def self.encoding=(e)
|
16
|
+
if e =~ /^UTF-8$/i
|
17
|
+
@@encoding = e
|
18
|
+
else
|
19
|
+
@@encoding = e+":UTF-8"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Reads given filename into string
|
24
|
+
def self.read(filename)
|
25
|
+
File.open(filename, "r:"+@@encoding) {|f| f.read }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|