jsduck 4.5.1 → 4.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -1
- data/Rakefile +1 -3
- data/jsduck.gemspec +3 -3
- data/lib/jsduck/batch_parser.rb +2 -0
- data/lib/jsduck/circular_deps.rb +17 -0
- data/lib/jsduck/class_formatter.rb +2 -1
- data/lib/jsduck/doc_ast.rb +2 -1
- data/lib/jsduck/doc_formatter.rb +19 -17
- data/lib/jsduck/doc_parser.rb +23 -4
- data/lib/jsduck/guides.rb +1 -2
- data/lib/jsduck/html_stack.rb +91 -0
- data/lib/jsduck/lint.rb +0 -13
- data/lib/jsduck/logger.rb +1 -0
- data/lib/jsduck/options.rb +18 -1
- data/lib/jsduck/return_values.rb +1 -1
- metadata +409 -407
data/README.md
CHANGED
@@ -64,7 +64,7 @@ most sensible place to put it). Now you're ready to install JSDuck:
|
|
64
64
|
> gem install jsduck
|
65
65
|
|
66
66
|
[RVM]: https://rvm.io/
|
67
|
-
[download page]: https://
|
67
|
+
[download page]: https://sourceforge.net/projects/jsduck/files/
|
68
68
|
[libs download]: https://github.com/stereobooster/therubyracer/downloads
|
69
69
|
|
70
70
|
Usage
|
@@ -172,6 +172,7 @@ Katherine Chu,
|
|
172
172
|
[burnnat](https://github.com/burnnat),
|
173
173
|
[vjetteam](https://github.com/vjetteam),
|
174
174
|
[Chris Westbrook](https://github.com/cnstaging),
|
175
|
+
[Scott Whittaker](https://github.com/scottrobertwhittaker),
|
175
176
|
and many-many others who reported bugs, submitted patches, and
|
176
177
|
provided a lot of useful input.
|
177
178
|
|
data/Rakefile
CHANGED
@@ -104,7 +104,7 @@ def compress
|
|
104
104
|
dir = "template-min"
|
105
105
|
|
106
106
|
# Create JSB3 file for Docs app
|
107
|
-
system("sencha", "create", "jsb", "-a", "http://localhost
|
107
|
+
system("sencha", "create", "jsb", "-a", "http://localhost/docs/", "-p", "#{dir}/app.jsb3")
|
108
108
|
# Concatenate files listed in JSB3 file
|
109
109
|
system("sencha", "build", "-p", "#{dir}/app.jsb3", "-d", dir)
|
110
110
|
|
@@ -257,8 +257,6 @@ task :sdk => :sass do
|
|
257
257
|
"--output", OUT_DIR,
|
258
258
|
"--config", "#{SDK_DIR}/extjs/docs/config.json",
|
259
259
|
"--examples-base-url", "extjs-build/examples/",
|
260
|
-
"--import", "Ext 4.1.3:#{SDK_DIR}/../docs.sencha.com/exports/extjs-4.1.3",
|
261
|
-
"--import", "Ext 4.2.0",
|
262
260
|
"--seo"
|
263
261
|
)
|
264
262
|
runner.add_debug
|
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 = '4.
|
6
|
-
s.date = '
|
5
|
+
s.version = '4.6.0'
|
6
|
+
s.date = '2013-01-09'
|
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"
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency 'rdiscount'
|
23
23
|
s.add_dependency 'json'
|
24
24
|
s.add_dependency 'parallel'
|
25
|
-
s.add_dependency 'therubyracer', '
|
25
|
+
s.add_dependency 'therubyracer', '>= 0.10.0', '< 0.11.0'
|
26
26
|
|
27
27
|
s.add_development_dependency 'rspec'
|
28
28
|
s.add_development_dependency 'rake'
|
data/lib/jsduck/batch_parser.rb
CHANGED
@@ -9,6 +9,7 @@ require 'jsduck/inherit_doc'
|
|
9
9
|
require 'jsduck/importer'
|
10
10
|
require 'jsduck/return_values'
|
11
11
|
require 'jsduck/lint'
|
12
|
+
require 'jsduck/circular_deps'
|
12
13
|
|
13
14
|
module JsDuck
|
14
15
|
|
@@ -95,6 +96,7 @@ module JsDuck
|
|
95
96
|
|
96
97
|
# Do all kinds of post-processing on relations.
|
97
98
|
def apply_extra_processing
|
99
|
+
CircularDeps.new(@relations).check_all
|
98
100
|
InheritDoc.new(@relations).resolve_all
|
99
101
|
Importer.import(@opts.imports, @relations, @opts.new_since)
|
100
102
|
ReturnValues.auto_detect(@relations)
|
data/lib/jsduck/circular_deps.rb
CHANGED
@@ -1,7 +1,24 @@
|
|
1
|
+
require 'jsduck/logger'
|
2
|
+
|
1
3
|
module JsDuck
|
2
4
|
|
3
5
|
# Checks for circular dependencies
|
4
6
|
class CircularDeps
|
7
|
+
def initialize(classes)
|
8
|
+
@classes = classes
|
9
|
+
end
|
10
|
+
|
11
|
+
# Checks all classes for circular dependencies.
|
12
|
+
#
|
13
|
+
# When found, exits with a fatal error message.
|
14
|
+
def check_all
|
15
|
+
@classes.each do |cls|
|
16
|
+
if chain = check(cls)
|
17
|
+
Logger.fatal("Class #{cls[:name]} has a circular dependency: #{chain}")
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
5
22
|
|
6
23
|
# Checks class for circular dependencies.
|
7
24
|
#
|
@@ -2,6 +2,7 @@ require 'jsduck/type_parser'
|
|
2
2
|
require 'jsduck/logger'
|
3
3
|
require 'jsduck/meta_tag_registry'
|
4
4
|
require 'jsduck/shortener'
|
5
|
+
require 'jsduck/util/html'
|
5
6
|
|
6
7
|
module JsDuck
|
7
8
|
|
@@ -80,7 +81,7 @@ module JsDuck
|
|
80
81
|
else
|
81
82
|
Logger.warn(:type_name, "Unknown type #{type}", context[:filename], context[:linenr])
|
82
83
|
end
|
83
|
-
type
|
84
|
+
Util::HTML.escape(type)
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
data/lib/jsduck/doc_ast.rb
CHANGED
@@ -257,9 +257,10 @@ module JsDuck
|
|
257
257
|
end
|
258
258
|
|
259
259
|
def detect_return(doc_map)
|
260
|
+
has_return_tag = !!extract(doc_map, :return)
|
260
261
|
ret = extract(doc_map, :return) || {}
|
261
262
|
return {
|
262
|
-
:type => ret[:type] || "undefined",
|
263
|
+
:type => ret[:type] || (has_return_tag ? "Object" : "undefined"),
|
263
264
|
:name => ret[:name] || "return",
|
264
265
|
:doc => ret[:doc] || "",
|
265
266
|
:properties => doc_map[:return] ? detect_subproperties(:return, doc_map[:return]) : []
|
data/lib/jsduck/doc_formatter.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'strscan'
|
3
3
|
require 'rdiscount'
|
4
|
+
require 'jsduck/html_stack'
|
4
5
|
require 'jsduck/inline/link'
|
5
6
|
require 'jsduck/inline/img'
|
6
7
|
require 'jsduck/inline/video'
|
@@ -15,10 +16,12 @@ module JsDuck
|
|
15
16
|
# command line. For the actual effect of the options see
|
16
17
|
# Inline::* classes.
|
17
18
|
def initialize(opts={})
|
19
|
+
@opts = opts
|
18
20
|
@inline_link = Inline::Link.new(opts)
|
19
21
|
@inline_img = Inline::Img.new(opts)
|
20
22
|
@inline_video = Inline::Video.new(opts)
|
21
23
|
@inline_example = Inline::Example.new(opts)
|
24
|
+
@doc_context = {}
|
22
25
|
end
|
23
26
|
|
24
27
|
# Sets base path to prefix images from {@img} tags.
|
@@ -41,13 +44,14 @@ module JsDuck
|
|
41
44
|
# Sets up instance to work in context of particular doc object.
|
42
45
|
# Used for error reporting.
|
43
46
|
def doc_context=(doc)
|
47
|
+
@doc_context = doc
|
44
48
|
@inline_video.doc_context = doc
|
45
49
|
@inline_link.doc_context = doc
|
46
50
|
end
|
47
51
|
|
48
52
|
# Returns the current documentation context
|
49
53
|
def doc_context
|
50
|
-
@
|
54
|
+
@doc_context
|
51
55
|
end
|
52
56
|
|
53
57
|
# JsDuck::Relations for looking up class names.
|
@@ -94,10 +98,10 @@ module JsDuck
|
|
94
98
|
s = StringScanner.new(input)
|
95
99
|
out = ""
|
96
100
|
|
97
|
-
# Keep track of
|
98
|
-
#
|
99
|
-
#
|
100
|
-
|
101
|
+
# Keep track of open HTML tags. We're not auto-detecting class
|
102
|
+
# names when inside <a>. Also we want to close down the unclosed
|
103
|
+
# tags.
|
104
|
+
tags = HtmlStack.new(@opts[:ignore_html] || {}, @doc_context)
|
101
105
|
|
102
106
|
while !s.eos? do
|
103
107
|
if substitute = @inline_link.replace(s)
|
@@ -111,26 +115,24 @@ module JsDuck
|
|
111
115
|
out += s.scan(/[{]/)
|
112
116
|
elsif substitute = @inline_example.replace(s)
|
113
117
|
out += substitute
|
114
|
-
elsif s.check(
|
115
|
-
#
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
open_a_tags -= 1
|
121
|
-
out += s.scan(/<\/a>/)
|
118
|
+
elsif s.check(/<\w/)
|
119
|
+
# Open HTML tag
|
120
|
+
out += s.scan(/</) + tags.open(s.scan(/\w+/)) + s.scan_until(/>|\Z/)
|
121
|
+
elsif s.check(/<\/\w+>/)
|
122
|
+
# Close HTML tag
|
123
|
+
out += s.scan(/<\//) + tags.close(s.scan(/\w+/)) + s.scan(/>/)
|
122
124
|
elsif s.check(/</)
|
123
|
-
# Ignore
|
124
|
-
out += s.
|
125
|
+
# Ignore plain '<' char.
|
126
|
+
out += s.scan(/</)
|
125
127
|
else
|
126
128
|
# Replace class names in the following text up to next "<" or "{"
|
127
129
|
# but only when we're not inside <a>...</a>
|
128
130
|
text = s.scan(/[^{<]+/)
|
129
|
-
out +=
|
131
|
+
out += tags.open?("a") ? text : @inline_link.create_magic_links(text)
|
130
132
|
end
|
131
133
|
end
|
132
134
|
|
133
|
-
out
|
135
|
+
out + tags.close_unfinished
|
134
136
|
end
|
135
137
|
|
136
138
|
# Creates a link based on the link template.
|
data/lib/jsduck/doc_parser.rb
CHANGED
@@ -506,7 +506,7 @@ module JsDuck
|
|
506
506
|
# roll back to beginning and simply grab anything up to closing "]".
|
507
507
|
def default_value
|
508
508
|
start_pos = @input.pos
|
509
|
-
value = parse_balanced(/\[/, /\]/, /[^\[\]]*/)
|
509
|
+
value = parse_balanced(/\[/, /\]/, /[^\[\]'"]*/)
|
510
510
|
if look(/\]/)
|
511
511
|
value
|
512
512
|
else
|
@@ -519,7 +519,7 @@ module JsDuck
|
|
519
519
|
def typedef
|
520
520
|
match(/\{/)
|
521
521
|
|
522
|
-
name = parse_balanced(/\{/, /\}/, /[^{}]*/)
|
522
|
+
name = parse_balanced(/\{/, /\}/, /[^{}'"]*/)
|
523
523
|
|
524
524
|
if name =~ /=$/
|
525
525
|
name = name.chop
|
@@ -538,18 +538,37 @@ module JsDuck
|
|
538
538
|
#
|
539
539
|
# @param re_open The beginning brace regex
|
540
540
|
# @param re_close The closing brace regex
|
541
|
-
# @param re_rest Regex to match text without any braces
|
541
|
+
# @param re_rest Regex to match text without any braces and strings
|
542
542
|
def parse_balanced(re_open, re_close, re_rest)
|
543
|
-
result =
|
543
|
+
result = parse_with_strings(re_rest)
|
544
544
|
while look(re_open)
|
545
545
|
result += match(re_open)
|
546
546
|
result += parse_balanced(re_open, re_close, re_rest)
|
547
547
|
result += match(re_close)
|
548
|
+
result += parse_with_strings(re_rest)
|
549
|
+
end
|
550
|
+
result
|
551
|
+
end
|
552
|
+
|
553
|
+
# Helper for parse_balanced to parse rest of the text between
|
554
|
+
# braces, taking account the strings which might occur there.
|
555
|
+
def parse_with_strings(re_rest)
|
556
|
+
result = match(re_rest)
|
557
|
+
while look(/['"]/)
|
558
|
+
result += parse_string('"') if look(/"/)
|
559
|
+
result += parse_string("'") if look(/'/)
|
548
560
|
result += match(re_rest)
|
549
561
|
end
|
550
562
|
result
|
551
563
|
end
|
552
564
|
|
565
|
+
# Parses "..." or '...' including the escape sequence \' or '\"
|
566
|
+
def parse_string(quote)
|
567
|
+
re_quote = Regexp.new(quote)
|
568
|
+
re_rest = Regexp.new("(?:[^"+quote+"\\\\]|\\\\.)*")
|
569
|
+
match(re_quote) + match(re_rest) + (match(re_quote) || "")
|
570
|
+
end
|
571
|
+
|
553
572
|
# matches <ident_chain> <ident_chain> ... until line end
|
554
573
|
def class_list
|
555
574
|
skip_horiz_white
|
data/lib/jsduck/guides.rb
CHANGED
@@ -59,8 +59,7 @@ module JsDuck
|
|
59
59
|
|
60
60
|
begin
|
61
61
|
@formatter.doc_context = {:filename => guide_file, :linenr => 0}
|
62
|
-
|
63
|
-
@formatter.img_path = "guides/#{name}"
|
62
|
+
@formatter.img_path = "guides/#{guide["name"]}"
|
64
63
|
|
65
64
|
return add_toc(guide, @formatter.format(Util::IO.read(guide_file)))
|
66
65
|
rescue
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'jsduck/logger'
|
2
|
+
|
3
|
+
module JsDuck
|
4
|
+
|
5
|
+
# Tracks opening and closing of HTML tags, with the purpose of
|
6
|
+
# closing down the unfinished tags.
|
7
|
+
#
|
8
|
+
# Synopsis:
|
9
|
+
#
|
10
|
+
# tags = HtmlStack.new
|
11
|
+
# # open and close a bunch of tags
|
12
|
+
# tags.open("a")
|
13
|
+
# tags.open("b")
|
14
|
+
# tags.close("b")
|
15
|
+
#
|
16
|
+
# # ask which tags still need to be closed
|
17
|
+
# tags.close_unfinished --> "</a>"
|
18
|
+
#
|
19
|
+
class HtmlStack
|
20
|
+
|
21
|
+
# Initializes the stack with two optional parameters:
|
22
|
+
#
|
23
|
+
# @param ignore_html A hash of additional HTML tags that don't need closing.
|
24
|
+
# @param doc_context Filename and linenr of the current doc-comment.
|
25
|
+
def initialize(ignore_html={}, doc_context={})
|
26
|
+
@ignore_html = ignore_html
|
27
|
+
@doc_context = doc_context
|
28
|
+
@open_tags = []
|
29
|
+
end
|
30
|
+
|
31
|
+
# Registers opening of a tag. Returns the tag.
|
32
|
+
def open(tag)
|
33
|
+
@open_tags.unshift(tag) unless void?(tag)
|
34
|
+
tag
|
35
|
+
end
|
36
|
+
|
37
|
+
# Registers closing of a tag. Returns the tag.
|
38
|
+
def close(tag)
|
39
|
+
if @open_tags.include?(tag)
|
40
|
+
# delete the most recent unclosed tag in our tags stack
|
41
|
+
@open_tags.delete_at(@open_tags.index(tag))
|
42
|
+
end
|
43
|
+
tag
|
44
|
+
end
|
45
|
+
|
46
|
+
# True when the tag is currently open.
|
47
|
+
def open?(tag)
|
48
|
+
@open_tags.include?(tag)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns HTML for closing the still open tags.
|
52
|
+
# Also prints warnings for all the unclosed tags.
|
53
|
+
def close_unfinished
|
54
|
+
return "" if @open_tags.length == 0
|
55
|
+
|
56
|
+
warn_unfinished
|
57
|
+
|
58
|
+
@open_tags.map {|tag| "</#{tag}>" }.join
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def warn_unfinished
|
64
|
+
ctx = @doc_context
|
65
|
+
tag_list = @open_tags.map {|tag| "<#{tag}>" }.join(", ")
|
66
|
+
Logger.warn(:html, "Unclosed HTML tag: #{tag_list}", ctx[:filename], ctx[:linenr])
|
67
|
+
end
|
68
|
+
|
69
|
+
def void?(tag)
|
70
|
+
VOID_TAGS[tag] || @ignore_html[tag]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Tags that don't require closing
|
74
|
+
VOID_TAGS = {
|
75
|
+
"base" => true,
|
76
|
+
"link" => true,
|
77
|
+
"meta" => true,
|
78
|
+
"hr" => true,
|
79
|
+
"br" => true,
|
80
|
+
"wbr" => true,
|
81
|
+
"area" => true,
|
82
|
+
"img" => true,
|
83
|
+
"param" => true,
|
84
|
+
"input" => true,
|
85
|
+
"isindex" => true,
|
86
|
+
"option" => true,
|
87
|
+
}
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
data/lib/jsduck/lint.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'jsduck/logger'
|
2
2
|
require 'jsduck/class'
|
3
|
-
require 'jsduck/circular_deps'
|
4
3
|
|
5
4
|
module JsDuck
|
6
5
|
|
@@ -21,7 +20,6 @@ module JsDuck
|
|
21
20
|
warn_duplicate_members
|
22
21
|
warn_singleton_statics
|
23
22
|
warn_empty_enums
|
24
|
-
fail_on_circular_dependencies
|
25
23
|
end
|
26
24
|
|
27
25
|
# print warning for each member or parameter with no name
|
@@ -119,17 +117,6 @@ module JsDuck
|
|
119
117
|
end
|
120
118
|
end
|
121
119
|
|
122
|
-
# Print fatal error message for circular dependency.
|
123
|
-
def fail_on_circular_dependencies
|
124
|
-
circular_deps = CircularDeps.new
|
125
|
-
@relations.each do |cls|
|
126
|
-
if chain = circular_deps.check(cls)
|
127
|
-
Logger.fatal("Class #{cls[:name]} has a circular dependency: #{chain}")
|
128
|
-
exit 1
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
120
|
# Loops through all members of all classes
|
134
121
|
def each_member(&block)
|
135
122
|
@relations.each {|cls| cls.all_local_members.each(&block) }
|
data/lib/jsduck/logger.rb
CHANGED
@@ -20,6 +20,7 @@ module JsDuck
|
|
20
20
|
[:link, "{@link} to unknown class or member"],
|
21
21
|
[:link_ambiguous, "{@link} is ambiguous"],
|
22
22
|
[:link_auto, "Auto-detected link to unknown class or member"],
|
23
|
+
[:html, "Unclosed HTML tag."],
|
23
24
|
|
24
25
|
[:alt_name, "Name used as both classname and alternate classname"],
|
25
26
|
[:name_missing, "Member or parameter has no name"],
|
data/lib/jsduck/options.rb
CHANGED
@@ -39,6 +39,7 @@ module JsDuck
|
|
39
39
|
attr_accessor :tests
|
40
40
|
attr_accessor :comments_url
|
41
41
|
attr_accessor :comments_domain
|
42
|
+
attr_accessor :ignore_html
|
42
43
|
|
43
44
|
# Debugging
|
44
45
|
attr_accessor :template_dir
|
@@ -90,7 +91,7 @@ module JsDuck
|
|
90
91
|
@ext4_events = nil
|
91
92
|
@meta_tag_paths = []
|
92
93
|
|
93
|
-
@version = "4.
|
94
|
+
@version = "4.6.0"
|
94
95
|
|
95
96
|
# Customizing output
|
96
97
|
@title = "Documentation - JSDuck"
|
@@ -116,6 +117,7 @@ module JsDuck
|
|
116
117
|
@tests = false
|
117
118
|
@comments_url = nil
|
118
119
|
@comments_domain = nil
|
120
|
+
@ignore_html = {}
|
119
121
|
|
120
122
|
# Debugging
|
121
123
|
@root_dir = File.dirname(File.dirname(File.dirname(__FILE__)))
|
@@ -539,6 +541,21 @@ module JsDuck
|
|
539
541
|
@touch_examples_ui = true
|
540
542
|
end
|
541
543
|
|
544
|
+
opts.on('--ignore-html=TAG',
|
545
|
+
"Ignore a particular unclosed HTML tag.",
|
546
|
+
"",
|
547
|
+
"Normally all tags like <foo> that aren't followed at some",
|
548
|
+
"point with </foo> will get automatically closed by JSDuck",
|
549
|
+
"and a warning will be generated. Except standard void tags",
|
550
|
+
"like <img> and <br>. Use this option to specify additional",
|
551
|
+
"tags not requirering a closing tag.",
|
552
|
+
"",
|
553
|
+
"Useful for ignoring the ExtJS preprocessor directives",
|
554
|
+
"<locale> and <debug> which would otherwise be reported",
|
555
|
+
"as unclosed tags.") do |tag|
|
556
|
+
@ignore_html[tag] = true
|
557
|
+
end
|
558
|
+
|
542
559
|
opts.separator ""
|
543
560
|
opts.separator "Debugging:"
|
544
561
|
opts.separator ""
|