jsduck 3.0.pre2 → 3.0.pre3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +14 -7
- data/Rakefile +277 -24
- data/bin/compare +163 -0
- data/bin/stats +92 -0
- data/jsduck.gemspec +3 -3
- data/lib/jsduck/accessors.rb +64 -8
- data/lib/jsduck/aggregator.rb +10 -6
- data/lib/jsduck/aliases.rb +3 -2
- data/lib/jsduck/app.rb +51 -44
- data/lib/jsduck/author_tag.rb +11 -0
- data/lib/jsduck/categories.rb +14 -8
- data/lib/jsduck/class.rb +2 -1
- data/lib/jsduck/class_formatter.rb +5 -4
- data/lib/jsduck/doc_author_tag.rb +11 -0
- data/lib/jsduck/doc_formatter.rb +17 -37
- data/lib/jsduck/doc_parser.rb +39 -11
- data/lib/jsduck/exporter.rb +11 -0
- data/lib/jsduck/guides.rb +3 -3
- data/lib/jsduck/images.rb +72 -0
- data/lib/jsduck/js_parser.rb +20 -4
- data/lib/jsduck/lexer.rb +2 -8
- data/lib/jsduck/lint.rb +3 -2
- data/lib/jsduck/logger.rb +24 -5
- data/lib/jsduck/merger.rb +38 -8
- data/lib/jsduck/meta_tag.rb +49 -0
- data/lib/jsduck/meta_tag_loader.rb +48 -0
- data/lib/jsduck/options.rb +37 -25
- data/lib/jsduck/os.rb +11 -0
- data/lib/jsduck/renderer.rb +37 -34
- data/lib/jsduck/search_data.rb +1 -1
- data/lib/jsduck/source_file.rb +13 -8
- data/template-min/app.js +1 -1
- data/template-min/{egIframe.html → extIframe.html} +3 -4
- data/template-min/extjs/ext-all-debug.js +3107 -2026
- data/template-min/extjs/ext-all.js +1 -1
- data/template-min/extjs/resources/css/ext-all.css +1 -1
- data/template-min/resources/css/app.css +1 -1
- data/template-min/resources/images/down-arr.png +0 -0
- data/template-min/resources/images/gettingstarted.jpg +0 -0
- data/template-min/resources/images/ipad-l.jpg +0 -0
- data/template-min/resources/images/ipad-p.jpg +0 -0
- data/template-min/resources/images/iphone-l.jpg +0 -0
- data/template-min/resources/images/iphone-p.jpg +0 -0
- data/template-min/resources/images/iphone-small-l.jpg +0 -0
- data/template-min/resources/images/iphone-small-p.jpg +0 -0
- data/template-min/resources/images/link-arrow-next.png +0 -0
- data/template-min/template.html +5 -1
- data/template-min/touch-welcome.html +122 -0
- data/template-min/touchIframe.html +85 -0
- data/template-min/welcome.html +2 -0
- metadata +25 -8
- data/lib/jsduck/page.rb +0 -118
- data/lib/jsduck/timer.rb +0 -44
data/bin/stats
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Print stats for JSON export
|
3
|
+
|
4
|
+
# For running when gem not installed
|
5
|
+
$:.unshift File.dirname(File.dirname(__FILE__)) + "/lib"
|
6
|
+
|
7
|
+
require "rubygems"
|
8
|
+
require "jsduck/json_duck"
|
9
|
+
|
10
|
+
def read_all_classes(dir)
|
11
|
+
classes = []
|
12
|
+
Dir[dir+"/*.json"].each do |filename|
|
13
|
+
print "."
|
14
|
+
STDOUT.flush
|
15
|
+
classes << JsDuck::JsonDuck.read(filename)
|
16
|
+
end
|
17
|
+
puts "OK"
|
18
|
+
classes
|
19
|
+
end
|
20
|
+
|
21
|
+
def count_members(classes, group, type)
|
22
|
+
classes.map do |c|
|
23
|
+
c[group][type].find_all {|m| m["owner"] == c["name"] }
|
24
|
+
end.flatten.length
|
25
|
+
end
|
26
|
+
|
27
|
+
# Strips HTML and counts words in text
|
28
|
+
def wc(string)
|
29
|
+
string.gsub(/<\/?[^>]*>/, "").scan(/\w+/).size
|
30
|
+
end
|
31
|
+
|
32
|
+
def property_wc(property)
|
33
|
+
cnt = wc(property["doc"])
|
34
|
+
(property["properties"] || []).each {|p| cnt += property_wc(p) }
|
35
|
+
cnt
|
36
|
+
end
|
37
|
+
|
38
|
+
def class_wc(cls)
|
39
|
+
cnt = wc(cls["doc"])
|
40
|
+
["members", "statics"].each do |group|
|
41
|
+
cls[group].each_value do |members|
|
42
|
+
members.find_all {|m| m["owner"] == cls["name"] }.each do |m|
|
43
|
+
cnt += wc(m["doc"])
|
44
|
+
(m["params"] || []).each {|p| cnt += property_wc(p) }
|
45
|
+
(m["properties"] || []).each {|p| cnt += property_wc(p) }
|
46
|
+
cnt += wc(m["return"]["doc"]) if m["return"]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
cnt
|
51
|
+
end
|
52
|
+
|
53
|
+
classes = read_all_classes(ARGV[0])
|
54
|
+
|
55
|
+
puts "%d classes in total" % classes.length
|
56
|
+
puts "%d public classes" % classes.find_all {|c| !c["private"] }.length
|
57
|
+
puts "%d private classes" % classes.find_all {|c| c["private"] }.length
|
58
|
+
puts
|
59
|
+
|
60
|
+
mem = count_members(classes, "members", "cfg")
|
61
|
+
sta = count_members(classes, "statics", "cfg")
|
62
|
+
puts "%d public cfgs" % (mem+sta)
|
63
|
+
puts " %d instance" % mem
|
64
|
+
puts " %d static" % sta
|
65
|
+
|
66
|
+
mem = count_members(classes, "members", "property")
|
67
|
+
sta = count_members(classes, "statics", "property")
|
68
|
+
puts "%d public properties" % (mem+sta)
|
69
|
+
puts " %d instance" % mem
|
70
|
+
puts " %d static" % sta
|
71
|
+
|
72
|
+
mem = count_members(classes, "members", "method")
|
73
|
+
sta = count_members(classes, "statics", "method")
|
74
|
+
puts "%d public methods" % (mem+sta)
|
75
|
+
puts " %d instance" % mem
|
76
|
+
puts " %d static" % sta
|
77
|
+
|
78
|
+
mem = count_members(classes, "members", "event")
|
79
|
+
sta = count_members(classes, "statics", "event")
|
80
|
+
puts "%d public events" % (mem+sta)
|
81
|
+
puts " %d instance" % mem
|
82
|
+
puts " %d static" % sta
|
83
|
+
|
84
|
+
puts
|
85
|
+
puts "Word counts"
|
86
|
+
puts "-----------"
|
87
|
+
classes.map {|cls| [cls, class_wc(cls)] }.sort {|a,b| a[1] <=> b[1] }.each do |pair|
|
88
|
+
puts "%d %s" % [pair[1], pair[0]["name"]]
|
89
|
+
end
|
90
|
+
|
91
|
+
puts
|
92
|
+
puts "%d total words in documentation" % classes.map {|cls| class_wc(cls) }.inject(0) {|a,b| a+b }
|
data/jsduck.gemspec
CHANGED
@@ -2,10 +2,10 @@ Gem::Specification.new do |s|
|
|
2
2
|
s.required_rubygems_version = ">= 1.3.7"
|
3
3
|
|
4
4
|
s.name = 'jsduck'
|
5
|
-
s.version = '3.0.
|
6
|
-
s.date = '2011-
|
5
|
+
s.version = '3.0.pre3'
|
6
|
+
s.date = '2011-10-17'
|
7
7
|
s.summary = "Simple JavaScript Duckumentation generator"
|
8
|
-
s.description = "Documentation generator for
|
8
|
+
s.description = "Documentation generator for Sencha JS frameworks"
|
9
9
|
s.homepage = "https://github.com/senchalabs/jsduck"
|
10
10
|
s.authors = ["Rene Saarsoo", "Nick Poulden"]
|
11
11
|
s.email = "rene.saarsoo@sencha.com"
|
data/lib/jsduck/accessors.rb
CHANGED
@@ -9,13 +9,11 @@ module JsDuck
|
|
9
9
|
# not added.
|
10
10
|
def create(cls)
|
11
11
|
# Grab all configs tagged as @accessor
|
12
|
-
accessors = cls[:members][:cfg].find_all {|cfg| cfg[:accessor] }
|
12
|
+
accessors = cls[:members][:cfg].find_all {|cfg| cfg[:accessor] && !cfg[:private] }
|
13
13
|
|
14
|
-
# Build lookup
|
15
|
-
methods =
|
16
|
-
cls[:members][:
|
17
|
-
methods[m[:name]] = m;
|
18
|
-
end
|
14
|
+
# Build lookup tables of method and event names
|
15
|
+
methods = build_lookup_table(cls[:members][:method])
|
16
|
+
events = build_lookup_table(cls[:members][:event])
|
19
17
|
|
20
18
|
accessors.each do |cfg|
|
21
19
|
# add getter if no method with same name exists
|
@@ -28,13 +26,28 @@ module JsDuck
|
|
28
26
|
if !methods[set[:name]]
|
29
27
|
cls[:members][:method] << set
|
30
28
|
end
|
29
|
+
# for evented accessors
|
30
|
+
if cfg[:evented]
|
31
|
+
# add event if no event with same name exists
|
32
|
+
ev = create_event(cfg)
|
33
|
+
if !events[ev[:name]]
|
34
|
+
cls[:members][:event] << ev
|
35
|
+
end
|
36
|
+
end
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
40
|
+
def build_lookup_table(members)
|
41
|
+
map = {}
|
42
|
+
members.each {|m| map[m[:name]] = m }
|
43
|
+
map
|
44
|
+
end
|
45
|
+
|
34
46
|
def create_getter(cfg)
|
47
|
+
name = "get" + upcase_first(cfg[:name])
|
35
48
|
return {
|
36
49
|
:tagname => :method,
|
37
|
-
:name =>
|
50
|
+
:name => name,
|
38
51
|
:doc => "Returns the value of {@link #cfg-#{cfg[:name]}}.",
|
39
52
|
:params => [],
|
40
53
|
:return => {
|
@@ -42,13 +55,17 @@ module JsDuck
|
|
42
55
|
:doc => "",
|
43
56
|
},
|
44
57
|
:owner => cfg[:owner],
|
58
|
+
:files => cfg[:files],
|
59
|
+
:id => "method-" + name,
|
60
|
+
:deprecated => cfg[:deprecated],
|
45
61
|
}
|
46
62
|
end
|
47
63
|
|
48
64
|
def create_setter(cfg)
|
65
|
+
name = "set" + upcase_first(cfg[:name]);
|
49
66
|
return {
|
50
67
|
:tagname => :method,
|
51
|
-
:name =>
|
68
|
+
:name => name,
|
52
69
|
:doc => "Sets the value of {@link #cfg-#{cfg[:name]}}.",
|
53
70
|
:params => [{
|
54
71
|
:type => cfg[:type],
|
@@ -60,6 +77,45 @@ module JsDuck
|
|
60
77
|
:doc => "",
|
61
78
|
},
|
62
79
|
:owner => cfg[:owner],
|
80
|
+
:files => cfg[:files],
|
81
|
+
:id => "method-" + name,
|
82
|
+
:deprecated => cfg[:deprecated],
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_event(cfg)
|
87
|
+
name = cfg[:name].downcase + "change"
|
88
|
+
setter_name = "set" + upcase_first(cfg[:name]);
|
89
|
+
return {
|
90
|
+
:tagname => :event,
|
91
|
+
:name => name,
|
92
|
+
:doc =>
|
93
|
+
"Fires when the {@link ##{cfg[:id]}} configuration is changed by {@link #method-#{setter_name}}." +
|
94
|
+
"\n\n" +
|
95
|
+
"Note that this event is fired *before* the value of {@link ##{cfg[:id]}} has been updated, " +
|
96
|
+
"and that you can return false from any listener to the #{name} event " +
|
97
|
+
"to cancel the change.",
|
98
|
+
:params => [
|
99
|
+
{
|
100
|
+
:name => "this",
|
101
|
+
:type => cfg[:owner],
|
102
|
+
:doc => "The #{cfg[:owner]} instance."
|
103
|
+
},
|
104
|
+
{
|
105
|
+
:name => "value",
|
106
|
+
:type => cfg[:type],
|
107
|
+
:doc => "The new value being set."
|
108
|
+
},
|
109
|
+
{
|
110
|
+
:name => "oldValue",
|
111
|
+
:type => cfg[:type],
|
112
|
+
:doc => "The existing value."
|
113
|
+
},
|
114
|
+
],
|
115
|
+
:owner => cfg[:owner],
|
116
|
+
:files => cfg[:files],
|
117
|
+
:id => "event-" + name,
|
118
|
+
:deprecated => cfg[:deprecated],
|
63
119
|
}
|
64
120
|
end
|
65
121
|
|
data/lib/jsduck/aggregator.rb
CHANGED
@@ -51,14 +51,19 @@ module JsDuck
|
|
51
51
|
|
52
52
|
# Merges new class-doc into old one.
|
53
53
|
def merge_classes(old, new)
|
54
|
+
# Merge booleans
|
54
55
|
[:extends, :singleton, :private, :protected].each do |tag|
|
55
56
|
old[tag] = old[tag] || new[tag]
|
56
57
|
end
|
57
|
-
|
58
|
+
# Merge arrays
|
59
|
+
[:mixins, :alternateClassNames, :files].each do |tag|
|
58
60
|
old[tag] = old[tag] + new[tag]
|
59
61
|
end
|
60
|
-
|
61
|
-
|
62
|
+
# Merge hashes of arrays
|
63
|
+
[:xtypes, :meta].each do |tag|
|
64
|
+
new[tag].each_pair do |key, contents|
|
65
|
+
old[tag][key] = (old[tag][key] || []) + contents
|
66
|
+
end
|
62
67
|
end
|
63
68
|
old[:doc] = old[:doc].length > 0 ? old[:doc] : new[:doc]
|
64
69
|
# Additionally the doc-comment can contain configs and constructor
|
@@ -144,9 +149,8 @@ module JsDuck
|
|
144
149
|
:alternateClassNames => [],
|
145
150
|
:members => Class.default_members_hash,
|
146
151
|
:statics => Class.default_members_hash,
|
147
|
-
:
|
148
|
-
:
|
149
|
-
:linenr => 0,
|
152
|
+
:meta => {},
|
153
|
+
:files => [{:filename => "", :linenr => 0}],
|
150
154
|
})
|
151
155
|
end
|
152
156
|
|
data/lib/jsduck/aliases.rb
CHANGED
@@ -28,16 +28,17 @@ module JsDuck
|
|
28
28
|
# Given aliased member, finds the original member.
|
29
29
|
# If the original also happens to be an alias, continue recursively.
|
30
30
|
def find_original(al)
|
31
|
+
context = al[:files][0]
|
31
32
|
al_def = al[:alias]
|
32
33
|
|
33
34
|
orig = @relations[al_def[:cls]]
|
34
35
|
unless orig
|
35
|
-
Logger.instance.warn("Class #{al_def[:cls]} not found
|
36
|
+
Logger.instance.warn("Class #{al_def[:cls]} not found", context[:filename], context[:linenr])
|
36
37
|
return al
|
37
38
|
end
|
38
39
|
orig = orig.get_member(al_def[:member], al_def[:type] || al[:tagname])
|
39
40
|
unless orig
|
40
|
-
Logger.instance.warn("Member #{al_def[:cls]}##{al_def[:member]} not found
|
41
|
+
Logger.instance.warn("Member #{al_def[:cls]}##{al_def[:member]} not found", context[:filename], context[:linenr])
|
41
42
|
return al
|
42
43
|
end
|
43
44
|
|
data/lib/jsduck/app.rb
CHANGED
@@ -11,7 +11,6 @@ require 'jsduck/relations'
|
|
11
11
|
require 'jsduck/aliases'
|
12
12
|
require 'jsduck/exporter'
|
13
13
|
require 'jsduck/renderer'
|
14
|
-
require 'jsduck/timer'
|
15
14
|
require 'jsduck/parallel_wrap'
|
16
15
|
require 'jsduck/logger'
|
17
16
|
require 'jsduck/welcome'
|
@@ -19,6 +18,7 @@ require 'jsduck/guides'
|
|
19
18
|
require 'jsduck/videos'
|
20
19
|
require 'jsduck/examples'
|
21
20
|
require 'jsduck/categories'
|
21
|
+
require 'jsduck/images'
|
22
22
|
require 'jsduck/json_duck'
|
23
23
|
require 'jsduck/lint'
|
24
24
|
require 'fileutils'
|
@@ -30,7 +30,6 @@ module JsDuck
|
|
30
30
|
# Initializes app with JsDuck::Options object
|
31
31
|
def initialize(opts)
|
32
32
|
@opts = opts
|
33
|
-
@timer = Timer.new
|
34
33
|
# Sets the nr of parallel processes to use.
|
35
34
|
# Set to 0 to disable parallelization completely.
|
36
35
|
@parallel = ParallelWrap.new(:in_processes => @opts.processes)
|
@@ -43,47 +42,47 @@ module JsDuck
|
|
43
42
|
|
44
43
|
# Call this after input parameters set
|
45
44
|
def run
|
46
|
-
parsed_files =
|
47
|
-
result =
|
48
|
-
@relations =
|
45
|
+
parsed_files = parallel_parse(@opts.input_files)
|
46
|
+
result = aggregate(parsed_files)
|
47
|
+
@relations = filter_classes(result)
|
49
48
|
Aliases.new(@relations).resolve_all
|
50
49
|
Lint.new(@relations).run
|
51
50
|
|
51
|
+
@images = Images.new(@opts.images)
|
52
|
+
|
52
53
|
@welcome = Welcome.new
|
53
54
|
if @opts.welcome
|
54
|
-
@
|
55
|
+
@welcome.parse(@opts.welcome)
|
55
56
|
end
|
56
57
|
|
57
58
|
@guides = Guides.new(get_doc_formatter)
|
58
59
|
if @opts.guides
|
59
|
-
@
|
60
|
+
@guides.parse(@opts.guides)
|
60
61
|
end
|
61
62
|
|
62
63
|
@videos = Videos.new
|
63
64
|
if @opts.videos
|
64
|
-
@
|
65
|
+
@videos.parse(@opts.videos)
|
65
66
|
end
|
66
67
|
|
67
68
|
@examples = Examples.new
|
68
69
|
if @opts.examples
|
69
|
-
@
|
70
|
+
@examples.parse(@opts.examples)
|
70
71
|
end
|
71
72
|
|
72
73
|
@categories = Categories.new(get_doc_formatter, @relations)
|
73
74
|
if @opts.categories_path
|
74
|
-
@
|
75
|
-
|
76
|
-
@categories.validate
|
77
|
-
end
|
75
|
+
@categories.parse(@opts.categories_path)
|
76
|
+
@categories.validate
|
78
77
|
end
|
79
78
|
|
80
79
|
clear_output_dir unless @opts.export == :stdout
|
81
80
|
if @opts.export == :stdout
|
82
|
-
|
81
|
+
puts JsonDuck.generate(@relations.classes)
|
83
82
|
elsif @opts.export == :json
|
84
83
|
FileUtils.mkdir(@opts.output_dir)
|
85
|
-
|
86
|
-
|
84
|
+
format_classes
|
85
|
+
write_classes
|
87
86
|
else
|
88
87
|
if @opts.template_links
|
89
88
|
link_template
|
@@ -96,22 +95,22 @@ module JsDuck
|
|
96
95
|
FileUtils.rm(@opts.output_dir+"/index.php")
|
97
96
|
FileUtils.cp(@opts.output_dir+"/template.html", @opts.output_dir+"/index.html")
|
98
97
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
@
|
104
|
-
@
|
105
|
-
@
|
98
|
+
write_src(parsed_files)
|
99
|
+
format_classes
|
100
|
+
write_app_data
|
101
|
+
write_classes
|
102
|
+
@guides.write(@opts.output_dir+"/guides")
|
103
|
+
@videos.write(@opts.output_dir+"/videos")
|
104
|
+
@examples.write(@opts.output_dir+"/examples")
|
105
|
+
@images.copy(@opts.output_dir+"/images")
|
106
106
|
end
|
107
107
|
|
108
|
-
@timer.report
|
109
108
|
end
|
110
109
|
|
111
110
|
# Parses the files in parallel using as many processes as available CPU-s
|
112
111
|
def parallel_parse(filenames)
|
113
112
|
@parallel.map(filenames) do |fname|
|
114
|
-
Logger.instance.log("Parsing
|
113
|
+
Logger.instance.log("Parsing", fname)
|
115
114
|
SourceFile.new(IO.read(fname), fname, @opts)
|
116
115
|
end
|
117
116
|
end
|
@@ -120,7 +119,7 @@ module JsDuck
|
|
120
119
|
def aggregate(parsed_files)
|
121
120
|
agr = Aggregator.new
|
122
121
|
parsed_files.each do |file|
|
123
|
-
Logger.instance.log("Aggregating
|
122
|
+
Logger.instance.log("Aggregating", file.filename)
|
124
123
|
agr.aggregate(file)
|
125
124
|
end
|
126
125
|
agr.classify_orphans
|
@@ -140,9 +139,8 @@ module JsDuck
|
|
140
139
|
else
|
141
140
|
type = d[:tagname].to_s
|
142
141
|
name = d[:name]
|
143
|
-
file = d[:
|
144
|
-
|
145
|
-
Logger.instance.warn("Ignoring #{type}: #{name} in #{file} line #{line}")
|
142
|
+
file = d[:files][0]
|
143
|
+
Logger.instance.warn("Ignoring #{type}: #{name}", file[:filename], file[:linenr])
|
146
144
|
end
|
147
145
|
end
|
148
146
|
Relations.new(classes, @opts.external_classes)
|
@@ -150,16 +148,22 @@ module JsDuck
|
|
150
148
|
|
151
149
|
# Formats each class
|
152
150
|
def format_classes
|
153
|
-
|
151
|
+
doc_formatter = get_doc_formatter
|
152
|
+
doc_formatter.img_path = "images"
|
153
|
+
class_formatter = ClassFormatter.new(@relations, doc_formatter)
|
154
154
|
# Don't format types when exporting
|
155
|
-
|
155
|
+
class_formatter.include_types = !@opts.export
|
156
156
|
# Format all doc-objects in parallel
|
157
|
-
|
158
|
-
|
157
|
+
formatted_classes = @parallel.map(@relations.classes) do |cls|
|
158
|
+
{
|
159
|
+
:doc => class_formatter.format(cls.internal_doc),
|
160
|
+
:images => doc_formatter.images
|
161
|
+
}
|
159
162
|
end
|
160
163
|
# Then merge the data back to classes sequentially
|
161
|
-
|
162
|
-
@relations[doc[:name]].internal_doc = doc
|
164
|
+
formatted_classes.each do |cls|
|
165
|
+
@relations[cls[:doc][:name]].internal_doc = cls[:doc]
|
166
|
+
cls[:images].each {|img| @images.add(img) }
|
163
167
|
end
|
164
168
|
end
|
165
169
|
|
@@ -178,11 +182,16 @@ module JsDuck
|
|
178
182
|
# Writes JSON export or JsonP file for each class
|
179
183
|
def write_classes
|
180
184
|
exporter = Exporter.new(@relations)
|
181
|
-
renderer = Renderer.new
|
185
|
+
renderer = Renderer.new
|
186
|
+
# Inject formatter to all meta-tags.
|
187
|
+
doc_formatter = get_doc_formatter
|
188
|
+
@opts.meta_tags.each {|tag| tag.formatter = doc_formatter }
|
189
|
+
renderer.meta_tags = @opts.meta_tags
|
190
|
+
|
182
191
|
dir = @opts.output_dir + (@opts.export ? "" : "/output")
|
183
192
|
@parallel.each(@relations.classes) do |cls|
|
184
193
|
filename = dir + "/" + cls[:name] + (@opts.export ? ".json" : ".js")
|
185
|
-
Logger.instance.log("Writing
|
194
|
+
Logger.instance.log("Writing docs", filename)
|
186
195
|
data = exporter.export(cls)
|
187
196
|
if @opts.export
|
188
197
|
JsonDuck.write_json(filename, data)
|
@@ -201,7 +210,7 @@ module JsDuck
|
|
201
210
|
# updates all the doc-objects related to the file
|
202
211
|
parsed_files.each do |file|
|
203
212
|
html_filename = src.write(file.to_html, file.filename)
|
204
|
-
Logger.instance.log("Writing
|
213
|
+
Logger.instance.log("Writing source", html_filename)
|
205
214
|
file.html_filename = File.basename(html_filename)
|
206
215
|
end
|
207
216
|
end
|
@@ -212,20 +221,17 @@ module JsDuck
|
|
212
221
|
formatter.link_tpl = @opts.link_tpl if @opts.link_tpl
|
213
222
|
formatter.img_tpl = @opts.img_tpl if @opts.img_tpl
|
214
223
|
formatter.relations = @relations
|
215
|
-
if @opts.inline_examples_dir
|
216
|
-
formatter.get_example = lambda {|path| IO.read(@opts.inline_examples_dir + "/" + path) }
|
217
|
-
end
|
218
224
|
formatter
|
219
225
|
end
|
220
226
|
|
221
227
|
def copy_template
|
222
|
-
Logger.instance.log("Copying template files to
|
228
|
+
Logger.instance.log("Copying template files to", @opts.output_dir)
|
223
229
|
FileUtils.cp_r(@opts.template_dir, @opts.output_dir)
|
224
230
|
init_output_dirs
|
225
231
|
end
|
226
232
|
|
227
233
|
def link_template
|
228
|
-
Logger.instance.log("Linking template files to
|
234
|
+
Logger.instance.log("Linking template files to", @opts.output_dir)
|
229
235
|
FileUtils.mkdir(@opts.output_dir)
|
230
236
|
Dir.glob(@opts.template_dir + "/*").each do |file|
|
231
237
|
File.symlink(File.expand_path(file), @opts.output_dir+"/"+File.basename(file))
|
@@ -252,6 +258,7 @@ module JsDuck
|
|
252
258
|
"{extjs_path}" => @opts.extjs_path,
|
253
259
|
"{local_storage_db}" => @opts.local_storage_db,
|
254
260
|
"{show_print_button}" => @opts.seo ? "true" : "false",
|
261
|
+
"{touch_examples_ui}" => @opts.touch_examples_ui ? "true" : "false",
|
255
262
|
"{welcome}" => @welcome.to_html,
|
256
263
|
"{categories}" => @categories.to_html,
|
257
264
|
"{guides}" => @guides.to_html,
|
@@ -271,7 +278,7 @@ module JsDuck
|
|
271
278
|
def write_template(filename, replacements)
|
272
279
|
in_file = @opts.template_dir + '/' + filename
|
273
280
|
out_file = @opts.output_dir + '/' + filename
|
274
|
-
Logger.instance.log("
|
281
|
+
Logger.instance.log("Writing", out_file)
|
275
282
|
html = IO.read(in_file)
|
276
283
|
html.gsub!(/\{\w+\}/) do |key|
|
277
284
|
replacements[key] ? replacements[key] : key
|
data/lib/jsduck/categories.rb
CHANGED
@@ -13,7 +13,13 @@ module JsDuck
|
|
13
13
|
|
14
14
|
# Parses categories in JSON file
|
15
15
|
def parse(path)
|
16
|
-
@categories = JsonDuck.read(path)
|
16
|
+
@categories = JsonDuck.read(path)
|
17
|
+
|
18
|
+
# Don't crash if old syntax is used.
|
19
|
+
if @categories.is_a?(Hash) && @categories["categories"]
|
20
|
+
Logger.instance.warn('Update categories file to contain just the array inside {"categories": [...]}')
|
21
|
+
@categories = @categories["categories"]
|
22
|
+
end
|
17
23
|
|
18
24
|
# Perform expansion on all class names containing * wildcard
|
19
25
|
@categories.each do |cat|
|
@@ -28,26 +34,26 @@ module JsDuck
|
|
28
34
|
# Expands class name like 'Foo.*' into multiple class names.
|
29
35
|
def expand(name)
|
30
36
|
re = Regexp.new("^" + name.split(/\*/, -1).map {|part| Regexp.escape(part) }.join('.*') + "$")
|
31
|
-
@relations.to_a.find_all {|cls| re =~ cls[:name] && !cls[:private] }.map {|cls| cls[:name] }.sort
|
37
|
+
classes = @relations.to_a.find_all {|cls| re =~ cls[:name] && !cls[:private] }.map {|cls| cls[:name] }.sort
|
38
|
+
if classes.length == 0
|
39
|
+
Logger.instance.warn("No class found matching a pattern '#{name}' in categories file.")
|
40
|
+
end
|
41
|
+
classes
|
32
42
|
end
|
33
43
|
|
34
44
|
# Prints warnings for missing classes in categories file
|
35
45
|
def validate
|
46
|
+
# Build a map of all classes listed in categories
|
36
47
|
listed_classes = {}
|
37
|
-
|
38
|
-
# Check that each class listed in overview file exists
|
39
48
|
@categories.each do |cat|
|
40
49
|
cat["groups"].each do |group|
|
41
50
|
group["classes"].each do |cls_name|
|
42
|
-
unless @relations[cls_name]
|
43
|
-
Logger.instance.warn("Class '#{cls_name}' in category '#{cat['name']}/#{group['name']}' not found")
|
44
|
-
end
|
45
51
|
listed_classes[cls_name] = true
|
46
52
|
end
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
50
|
-
# Check that each existing non-private class is listed
|
56
|
+
# Check that each existing non-private class is listed
|
51
57
|
@relations.each do |cls|
|
52
58
|
unless listed_classes[cls[:name]] || cls[:private]
|
53
59
|
Logger.instance.warn("Class '#{cls[:name]}' not found in categories file")
|
data/lib/jsduck/class.rb
CHANGED
@@ -61,7 +61,8 @@ module JsDuck
|
|
61
61
|
if @relations[classname]
|
62
62
|
@relations[classname]
|
63
63
|
elsif !@relations.ignore?(classname)
|
64
|
-
|
64
|
+
context = @doc[:files][0]
|
65
|
+
Logger.instance.warn("Class #{classname} not found", context[:filename], context[:linenr])
|
65
66
|
nil
|
66
67
|
end
|
67
68
|
end
|
@@ -14,6 +14,7 @@ module JsDuck
|
|
14
14
|
@relations = relations
|
15
15
|
@formatter = formatter
|
16
16
|
@include_types = true
|
17
|
+
@meta_tags = []
|
17
18
|
end
|
18
19
|
|
19
20
|
# Runs the formatter on doc object of a class.
|
@@ -21,7 +22,7 @@ module JsDuck
|
|
21
22
|
def format(cls)
|
22
23
|
@cls = cls
|
23
24
|
@formatter.class_context = cls[:name]
|
24
|
-
@formatter.doc_context = cls
|
25
|
+
@formatter.doc_context = cls[:files][0]
|
25
26
|
cls[:doc] = @formatter.format(cls[:doc]) if cls[:doc]
|
26
27
|
cls[:members].each_pair do |type, members|
|
27
28
|
cls[:members][type] = members.reject {|m| m[:private] }.map {|m| format_member(m) }
|
@@ -33,7 +34,7 @@ module JsDuck
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def format_member(m)
|
36
|
-
@formatter.doc_context = m
|
37
|
+
@formatter.doc_context = m[:files][0]
|
37
38
|
m[:doc] = @formatter.format(m[:doc]) if m[:doc]
|
38
39
|
m[:deprecated][:text] = @formatter.format(m[:deprecated][:text]) if m[:deprecated]
|
39
40
|
if expandable?(m) || @formatter.too_long?(m[:doc])
|
@@ -68,9 +69,9 @@ module JsDuck
|
|
68
69
|
else
|
69
70
|
context = @formatter.doc_context
|
70
71
|
if tp.error == :syntax
|
71
|
-
Logger.instance.warn("Incorrect type syntax #{type}
|
72
|
+
Logger.instance.warn("Incorrect type syntax #{type}", context[:filename], context[:linenr])
|
72
73
|
else
|
73
|
-
Logger.instance.warn("Unknown type #{type}
|
74
|
+
Logger.instance.warn("Unknown type #{type}", context[:filename], context[:linenr])
|
74
75
|
end
|
75
76
|
type
|
76
77
|
end
|