jsduck 3.0.pre2 → 3.0.pre3
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 +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
|