jsduck 4.0.beta2 → 4.0.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/.gitignore +0 -1
- data/README.md +40 -20
- data/Rakefile +2 -11
- data/esprima/esprima.js +3581 -0
- data/js-classes/String.js +1 -1
- data/jsduck.gemspec +3 -5
- data/lib/jsduck/aggregator.rb +6 -3
- data/lib/jsduck/app.rb +9 -5
- data/lib/jsduck/ast.rb +4 -2
- data/lib/jsduck/class.rb +11 -3
- data/lib/jsduck/css_parser.rb +3 -2
- data/lib/jsduck/doc_ast.rb +1 -0
- data/lib/jsduck/doc_formatter.rb +3 -3
- data/lib/jsduck/doc_parser.rb +10 -0
- data/lib/jsduck/esprima.rb +7 -9
- data/lib/jsduck/examples.rb +1 -1
- data/lib/jsduck/file_categories.rb +3 -3
- data/lib/jsduck/grouped_asset.rb +2 -2
- data/lib/jsduck/guides.rb +4 -4
- data/lib/jsduck/importer.rb +25 -6
- data/lib/jsduck/inherit_doc.rb +3 -0
- data/lib/jsduck/inline_video.rb +4 -4
- data/lib/jsduck/js_parser.rb +2 -1
- data/lib/jsduck/json_duck.rb +2 -1
- data/lib/jsduck/logger.rb +42 -9
- data/lib/jsduck/option_parser.rb +109 -0
- data/lib/jsduck/options.rb +352 -176
- data/lib/jsduck/override.rb +87 -0
- data/lib/jsduck/tag/chainable.rb +14 -0
- data/lib/jsduck/videos.rb +1 -1
- metadata +10 -10
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -45
- data/lib/jsduck/markdown.rb +0 -46
data/lib/jsduck/js_parser.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'jsduck/esprima'
|
2
|
+
require 'jsduck/logger'
|
2
3
|
|
3
4
|
module JsDuck
|
4
5
|
|
@@ -155,7 +156,7 @@ module JsDuck
|
|
155
156
|
properties = NODE_TYPES[node["type"]]
|
156
157
|
|
157
158
|
unless properties
|
158
|
-
|
159
|
+
Logger.instance.fatal("Unknown node type: "+node["type"])
|
159
160
|
exit(1)
|
160
161
|
end
|
161
162
|
|
data/lib/jsduck/json_duck.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'jsduck/io'
|
2
|
+
require 'jsduck/logger'
|
2
3
|
require 'json'
|
3
4
|
|
4
5
|
module JsDuck
|
@@ -37,7 +38,7 @@ module JsDuck
|
|
37
38
|
begin
|
38
39
|
self.parse(JsDuck::IO.read(filename))
|
39
40
|
rescue
|
40
|
-
|
41
|
+
Logger.instance.fatal("#{filename} is not a valid JSON file")
|
41
42
|
exit(1)
|
42
43
|
end
|
43
44
|
end
|
data/lib/jsduck/logger.rb
CHANGED
@@ -57,7 +57,7 @@ module JsDuck
|
|
57
57
|
# Prints log message with optional filename appended
|
58
58
|
def log(msg, filename=nil)
|
59
59
|
if @verbose
|
60
|
-
puts msg + " " + format(filename) + "..."
|
60
|
+
$stderr.puts paint(:green, msg) + " " + format(filename) + " ..."
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -77,7 +77,7 @@ module JsDuck
|
|
77
77
|
|
78
78
|
# get documentation for all warnings
|
79
79
|
def doc_warnings
|
80
|
-
@warning_docs.map {|w| " #{@warnings[w[0]] ? '+' : '-'}#{w[0]} - #{w[1]}" }
|
80
|
+
@warning_docs.map {|w| " #{@warnings[w[0]] ? '+' : '-'}#{w[0]} - #{w[1]}" }
|
81
81
|
end
|
82
82
|
|
83
83
|
# Prints warning message.
|
@@ -92,7 +92,7 @@ module JsDuck
|
|
92
92
|
#
|
93
93
|
# Optionally filename and line number will be inserted to message.
|
94
94
|
def warn(type, msg, filename=nil, line=nil)
|
95
|
-
msg = "Warning: " + format(filename, line) + " " + msg
|
95
|
+
msg = paint(:yellow, "Warning: ") + format(filename, line) + " " + msg
|
96
96
|
|
97
97
|
if type == nil || @warnings[type]
|
98
98
|
if !@shown_warnings[msg]
|
@@ -115,16 +115,49 @@ module JsDuck
|
|
115
115
|
out += ":#{line}:"
|
116
116
|
end
|
117
117
|
end
|
118
|
-
out
|
118
|
+
paint(:magenta, out)
|
119
119
|
end
|
120
120
|
|
121
121
|
# Prints fatal error message with backtrace.
|
122
122
|
# The error param should be $! from resque block.
|
123
|
-
def fatal(msg
|
124
|
-
puts "
|
125
|
-
|
126
|
-
|
127
|
-
|
123
|
+
def fatal(msg)
|
124
|
+
$stderr.puts paint(:red, "Error: ") + msg
|
125
|
+
end
|
126
|
+
|
127
|
+
# Prints fatal error message with backtrace.
|
128
|
+
# The error param should be $! from resque block.
|
129
|
+
def fatal_backtrace(msg, error)
|
130
|
+
$stderr.puts paint(:red, "Error: ") + "#{msg}: #{error}"
|
131
|
+
$stderr.puts
|
132
|
+
$stderr.puts "Here's a full backtrace:"
|
133
|
+
$stderr.puts error.backtrace
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
COLORS = {
|
139
|
+
:black => "\e[30m",
|
140
|
+
:red => "\e[31m",
|
141
|
+
:green => "\e[32m",
|
142
|
+
:yellow => "\e[33m",
|
143
|
+
:blue => "\e[34m",
|
144
|
+
:magenta => "\e[35m",
|
145
|
+
:cyan => "\e[36m",
|
146
|
+
:white => "\e[37m",
|
147
|
+
}
|
148
|
+
|
149
|
+
CLEAR = "\e[0m"
|
150
|
+
|
151
|
+
# Helper for doing colored output in UNIX terminal
|
152
|
+
#
|
153
|
+
# Only does color output when STDERR is attached to TTY
|
154
|
+
# i.e. is not piped/redirected.
|
155
|
+
def paint(color_name, msg)
|
156
|
+
if OS.windows? || !$stderr.tty?
|
157
|
+
msg
|
158
|
+
else
|
159
|
+
COLORS[color_name] + msg + CLEAR
|
160
|
+
end
|
128
161
|
end
|
129
162
|
end
|
130
163
|
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module JsDuck
|
4
|
+
|
5
|
+
# JSDuck version of OptionParser
|
6
|
+
#
|
7
|
+
# Enhanced with ability to output options help in two ways:
|
8
|
+
#
|
9
|
+
# - short list of all options (with the built-in #help method)
|
10
|
+
# - long description of one option (with the added #help_single method)
|
11
|
+
#
|
12
|
+
class OptionParser < ::OptionParser
|
13
|
+
def initialize
|
14
|
+
@full_options_index = {}
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
# Override the #on method to do some pre-processing on its
|
19
|
+
# parameters before passing them to the original #on method.
|
20
|
+
#
|
21
|
+
# Options are defined as usual:
|
22
|
+
#
|
23
|
+
# opts.on("-v", "--version", Type, "First line of description.",
|
24
|
+
# "Second line of description.",
|
25
|
+
# "Third line of description.")
|
26
|
+
#
|
27
|
+
# But only the first line of description will be passed to
|
28
|
+
# original #on method - meaning that #help method will also only
|
29
|
+
# list this first line.
|
30
|
+
#
|
31
|
+
# The remaining lines are saved to a separate place and can be
|
32
|
+
# retrieved through asking for full docs for an option with
|
33
|
+
# #help_single method.
|
34
|
+
#
|
35
|
+
def on(*opts, &block)
|
36
|
+
core = []
|
37
|
+
keys = []
|
38
|
+
desc = []
|
39
|
+
|
40
|
+
desc_started = false
|
41
|
+
opts.each do |o|
|
42
|
+
if desc_started
|
43
|
+
desc << o
|
44
|
+
elsif String === o
|
45
|
+
if o =~ /^-/
|
46
|
+
core << o
|
47
|
+
keys << o
|
48
|
+
else
|
49
|
+
core << o
|
50
|
+
desc << o
|
51
|
+
desc_started = true
|
52
|
+
end
|
53
|
+
else
|
54
|
+
core << o
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
full = {:keys => keys, :desc => desc}
|
59
|
+
|
60
|
+
keys.each do |op|
|
61
|
+
each_index_key(op) {|k| @full_options_index[k] = full }
|
62
|
+
end
|
63
|
+
|
64
|
+
super(*core, &block)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Helper that turns option name like --images=PATH into list of
|
68
|
+
# keys by which we index the options:
|
69
|
+
#
|
70
|
+
# "--images=PATH" --> ["--images", "images"]
|
71
|
+
#
|
72
|
+
# For options containing "[no-]" all the alternative forms are expanded:
|
73
|
+
#
|
74
|
+
# "--[no-]seo" --> ["--[no-]seo", "[no-]seo", "--seo", "seo", "--no-seo", "no-seo"]
|
75
|
+
#
|
76
|
+
def each_index_key(option_name)
|
77
|
+
key = option_name.sub(/\[?=.*/, '')
|
78
|
+
plain_key = key.sub(/^-*/, '')
|
79
|
+
[key, plain_key].each do |k|
|
80
|
+
yield k
|
81
|
+
if k =~ /\[no-\]/
|
82
|
+
yield k.sub(/\[no-\]/, '')
|
83
|
+
yield k.sub(/\[no-\]/, 'no-')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns long help text for a single option.
|
89
|
+
def help_single(option_name)
|
90
|
+
o = @full_options_index[option_name] || {:keys => [option_name], :desc => ["No such option. See --help=help"]}
|
91
|
+
|
92
|
+
r = []
|
93
|
+
|
94
|
+
r << ""
|
95
|
+
r << " " + o[:keys].join(", ")
|
96
|
+
r << ""
|
97
|
+
|
98
|
+
o[:desc].each do |line|
|
99
|
+
r << " " + line
|
100
|
+
end
|
101
|
+
|
102
|
+
r << ""
|
103
|
+
r << ""
|
104
|
+
|
105
|
+
return r.join("\n")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
data/lib/jsduck/options.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'jsduck/option_parser'
|
2
2
|
require 'jsduck/meta_tag_registry'
|
3
3
|
require 'jsduck/logger'
|
4
4
|
require 'jsduck/json_duck'
|
@@ -12,6 +12,7 @@ module JsDuck
|
|
12
12
|
attr_accessor :output_dir
|
13
13
|
attr_accessor :ignore_global
|
14
14
|
attr_accessor :external_classes
|
15
|
+
attr_accessor :ext4_events
|
15
16
|
|
16
17
|
# Customizing output
|
17
18
|
attr_accessor :title
|
@@ -45,6 +46,7 @@ module JsDuck
|
|
45
46
|
attr_accessor :touch_examples_ui
|
46
47
|
attr_accessor :ext_namespaces
|
47
48
|
attr_accessor :imports
|
49
|
+
attr_accessor :new_since
|
48
50
|
|
49
51
|
def initialize
|
50
52
|
@input_files = []
|
@@ -74,13 +76,14 @@ module JsDuck
|
|
74
76
|
# Special anything-goes type
|
75
77
|
"Mixed",
|
76
78
|
]
|
79
|
+
@ext4_events = nil
|
77
80
|
@meta_tag_paths = []
|
78
81
|
|
79
|
-
@version = "4.0.
|
82
|
+
@version = "4.0.0"
|
80
83
|
|
81
84
|
# Customizing output
|
82
|
-
@title = "
|
83
|
-
@header = "<strong>
|
85
|
+
@title = "Documentation - JSDuck"
|
86
|
+
@header = "<strong>Documentation</strong> JSDuck"
|
84
87
|
@footer = "Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> #{@version}."
|
85
88
|
@head_html = ""
|
86
89
|
@body_html = ""
|
@@ -114,6 +117,7 @@ module JsDuck
|
|
114
117
|
@touch_examples_ui = false
|
115
118
|
@ext_namespaces = ["Ext"]
|
116
119
|
@imports = []
|
120
|
+
@new_since = nil
|
117
121
|
|
118
122
|
# enable all warnings except :link_auto
|
119
123
|
Logger.instance.set_warning(:all, true)
|
@@ -138,178 +142,386 @@ module JsDuck
|
|
138
142
|
end
|
139
143
|
|
140
144
|
def create_option_parser
|
141
|
-
optparser = OptionParser.new do | opts |
|
142
|
-
opts.banner = "Usage: jsduck [options] files/dirs
|
145
|
+
optparser = JsDuck::OptionParser.new do | opts |
|
146
|
+
opts.banner = "Usage: jsduck [options] files/dirs..."
|
147
|
+
opts.separator ""
|
148
|
+
opts.separator "For example:"
|
149
|
+
opts.separator ""
|
150
|
+
opts.separator " # Documentation for builtin JavaScript classes like Array and String"
|
151
|
+
opts.separator " jsduck --output output/dir --builtin-classes"
|
152
|
+
opts.separator ""
|
153
|
+
opts.separator " # Documentation for your own JavaScript"
|
154
|
+
opts.separator " jsduck --output output/dir input-file.js some/input/dir"
|
155
|
+
opts.separator ""
|
156
|
+
opts.separator "The main options:"
|
157
|
+
opts.separator ""
|
143
158
|
|
144
159
|
opts.on('-o', '--output=PATH',
|
145
|
-
"Directory to
|
146
|
-
"
|
147
|
-
"
|
160
|
+
"Directory to write all this documentation.",
|
161
|
+
"",
|
162
|
+
"This option is REQUIRED. When the directory exists,",
|
163
|
+
"it will be overwritten. Give dash '-' as argument",
|
164
|
+
"to write docs to STDOUT (works only with --export).") do |path|
|
148
165
|
@output_dir = path == "-" ? :stdout : canonical(path)
|
149
166
|
end
|
150
167
|
|
151
|
-
opts.on('--
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
"
|
157
|
-
"
|
158
|
-
"
|
159
|
-
@
|
168
|
+
opts.on('--export=TYPE',
|
169
|
+
"Exports docs in JSON.",
|
170
|
+
"",
|
171
|
+
"TYPE is one of:",
|
172
|
+
"",
|
173
|
+
"- full - full class docs.",
|
174
|
+
"- api - only class- and member names.",
|
175
|
+
"- examples - extracts inline examples from classes.") do |format|
|
176
|
+
@export = format.to_sym
|
160
177
|
end
|
161
178
|
|
162
179
|
opts.on('--builtin-classes',
|
163
|
-
"Includes docs for JavaScript
|
180
|
+
"Includes docs for JavaScript builtins.",
|
181
|
+
"",
|
182
|
+
"Docs for the following classes are included:",
|
183
|
+
"",
|
184
|
+
"- Array",
|
185
|
+
"- Boolean",
|
186
|
+
"- Date",
|
187
|
+
"- Function",
|
188
|
+
"- Number",
|
189
|
+
"- Object",
|
190
|
+
"- RegExp",
|
191
|
+
"- String") do
|
164
192
|
read_filenames(@root_dir + "/js-classes")
|
165
193
|
end
|
166
194
|
|
167
|
-
opts.on('--
|
168
|
-
"
|
169
|
-
"
|
170
|
-
|
195
|
+
opts.on('--seo', "Enables SEO-friendly print version.",
|
196
|
+
"",
|
197
|
+
"Instead of index.html creates index.php that will serve",
|
198
|
+
"the regular docs, print-friendly docs, and search-engine-",
|
199
|
+
"friendly docs (the latter two are pretty much the same).") do
|
200
|
+
@seo = true
|
171
201
|
end
|
172
202
|
|
173
|
-
opts.on('--
|
174
|
-
|
203
|
+
opts.on('--config=PATH',
|
204
|
+
"Loads config options from JSON file.",
|
205
|
+
"",
|
206
|
+
"An alternative to listing all options on command line.",
|
207
|
+
"",
|
208
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/Config-file") do |path|
|
209
|
+
path = canonical(path)
|
210
|
+
if File.exists?(path)
|
211
|
+
config = read_json_config(path)
|
212
|
+
else
|
213
|
+
Logger.instance.fatal("The config file #{path} doesn't exist")
|
214
|
+
exit(1)
|
215
|
+
end
|
216
|
+
# treat paths inside JSON config relative to the location of
|
217
|
+
# config file. When done, switch back to current working dir.
|
218
|
+
@working_dir = File.dirname(path)
|
219
|
+
optparser.parse!(config).each {|fname| read_filenames(canonical(fname)) }
|
220
|
+
@working_dir = nil
|
175
221
|
end
|
176
222
|
|
177
|
-
opts.on('
|
178
|
-
|
223
|
+
opts.on('--encoding=NAME', "Input encoding (defaults to UTF-8).") do |encoding|
|
224
|
+
JsDuck::IO.encoding = encoding
|
179
225
|
end
|
180
226
|
|
227
|
+
opts.separator ""
|
181
228
|
opts.separator "Customizing output:"
|
182
229
|
opts.separator ""
|
183
230
|
|
184
231
|
opts.on('--title=TEXT',
|
185
232
|
"Custom title text for the documentation.",
|
186
|
-
"
|
233
|
+
"",
|
234
|
+
"Defaults to 'Documentation - JSDuck'",
|
235
|
+
"",
|
236
|
+
"The title will be used both inside <title> and in",
|
237
|
+
"the header of the page. Inside page header the left",
|
238
|
+
"part (from ' - ' separator) will be shown in bold.") do |text|
|
187
239
|
@title = text
|
188
240
|
@header = text.sub(/^(.*?) +- +/, "<strong>\\1 </strong>")
|
189
241
|
end
|
190
242
|
|
191
243
|
opts.on('--footer=TEXT',
|
192
244
|
"Custom footer text for the documentation.",
|
193
|
-
"
|
245
|
+
"",
|
246
|
+
"Defaults to: 'Generated with JSDuck {VERSION}.'",
|
247
|
+
"",
|
248
|
+
"'{VERSION}' is a placeholder that will get substituted",
|
249
|
+
"with the current version of JSDuck. See --version.") do |text|
|
194
250
|
@footer = text.gsub(/\{VERSION\}/, @version)
|
195
251
|
end
|
196
252
|
|
197
|
-
opts.on('--head-html=HTML',
|
253
|
+
opts.on('--head-html=HTML',
|
254
|
+
"HTML for the <head> section of index.html.",
|
255
|
+
"",
|
256
|
+
"Useful for adding extra <style> and other tags.",
|
257
|
+
"",
|
258
|
+
"This option can be used repeatedly to append several",
|
259
|
+
"things to the header.") do |html|
|
198
260
|
@head_html += html
|
199
261
|
end
|
200
262
|
|
201
|
-
opts.on('--body-html=HTML',
|
263
|
+
opts.on('--body-html=HTML',
|
264
|
+
"HTML for the <body> section of index.html.",
|
265
|
+
"",
|
266
|
+
"Useful for adding extra markup to the page.",
|
267
|
+
"",
|
268
|
+
"This option can be used repeatedly to append several",
|
269
|
+
"things to the body.") do |html|
|
202
270
|
@body_html += html
|
203
271
|
end
|
204
272
|
|
205
273
|
opts.on('--welcome=PATH',
|
206
|
-
"
|
274
|
+
"HTML file with content for welcome page.",
|
275
|
+
"",
|
276
|
+
"It should only contain the <body> part of a HTML page.",
|
277
|
+
"",
|
278
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/Welcome-page") do |path|
|
207
279
|
@welcome = canonical(path)
|
208
280
|
end
|
209
281
|
|
210
282
|
opts.on('--guides=PATH',
|
211
|
-
"
|
212
|
-
"
|
213
|
-
"
|
214
|
-
"
|
283
|
+
"JSON file describing the guides.",
|
284
|
+
"",
|
285
|
+
"The file should be in a dir containing the actual guides.",
|
286
|
+
"A guide is a dir containing README.md, icon.png, and",
|
287
|
+
"other images referenced by the README.md file.",
|
288
|
+
"",
|
289
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/Guides") do |path|
|
215
290
|
@guides = canonical(path)
|
216
291
|
end
|
217
292
|
|
218
293
|
opts.on('--videos=PATH',
|
219
|
-
"
|
294
|
+
"JSON file describing the videos.",
|
295
|
+
"",
|
296
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/Videos") do |path|
|
220
297
|
@videos = canonical(path)
|
221
298
|
end
|
222
299
|
|
223
300
|
opts.on('--examples=PATH',
|
224
|
-
"
|
301
|
+
"JSON file describing the examples.",
|
302
|
+
"",
|
303
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/Examples") do |path|
|
225
304
|
@examples = canonical(path)
|
226
305
|
end
|
227
306
|
|
228
307
|
opts.on('--categories=PATH',
|
229
|
-
"
|
308
|
+
"JSON file defining categories for classes.",
|
309
|
+
"",
|
310
|
+
"Without this option the classes will be categorized",
|
311
|
+
"based on how they are namespaced.",
|
312
|
+
"",
|
313
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/Categories") do |path|
|
230
314
|
@categories_path = canonical(path)
|
231
315
|
end
|
232
316
|
|
233
317
|
opts.on('--no-source',
|
234
|
-
"Turns off the output of source files."
|
318
|
+
"Turns off the output of source files.") do
|
235
319
|
@source = false
|
236
320
|
end
|
237
321
|
|
238
|
-
opts.on('--pretty-json', "Turn on pretty-printing of JSON.", " ") do
|
239
|
-
@pretty_json = true
|
240
|
-
end
|
241
|
-
|
242
322
|
opts.on('--images=PATH',
|
243
|
-
"
|
244
|
-
"
|
245
|
-
"
|
323
|
+
"Path for images referenced by {@img} tag.",
|
324
|
+
"",
|
325
|
+
"Several paths can be specified by using the option",
|
326
|
+
"multiple times. This option only applies to {@img}",
|
327
|
+
"tags used in API (classes/members) documentation.",
|
328
|
+
"Images used in guides must be located inside the",
|
329
|
+
"directory of the specific guide.") do |path|
|
246
330
|
@images << canonical(path)
|
247
331
|
end
|
248
332
|
|
333
|
+
opts.on('--tests',
|
334
|
+
"Creates page for testing inline examples.") do
|
335
|
+
@tests = true
|
336
|
+
end
|
337
|
+
|
338
|
+
opts.on('--stats',
|
339
|
+
"Creates page with all kinds of statistics.") do
|
340
|
+
@stats = true
|
341
|
+
end
|
342
|
+
|
343
|
+
opts.on('--import=VERSION:PATH',
|
344
|
+
"Imports docs generating @since & @new.",
|
345
|
+
"",
|
346
|
+
"For example:",
|
347
|
+
"",
|
348
|
+
" --import='1.0:/path/to/first/version'",
|
349
|
+
" --import='2.0:/path/to/second/version'",
|
350
|
+
" --import='3.0",
|
351
|
+
"",
|
352
|
+
"Several versions can be imported using the option multiple",
|
353
|
+
"times. The last version must always be the current one",
|
354
|
+
"without the :PATH portion.",
|
355
|
+
"",
|
356
|
+
"JSDuck will then check in which version every class/member",
|
357
|
+
"first appears in and tag it with an appropriate @since tag.",
|
358
|
+
"Things appearing only in the latest version will also get",
|
359
|
+
"a @new tag (unless --new-since option is used).",
|
360
|
+
"",
|
361
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/@since") do |v|
|
362
|
+
if v =~ /\A(.*?):(.*)\Z/
|
363
|
+
@imports << {:version => $1, :path => canonical($2)}
|
364
|
+
else
|
365
|
+
@imports << {:version => v}
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
opts.on('--new-since=VERSION',
|
370
|
+
"Since when to label items with @new tag.",
|
371
|
+
"",
|
372
|
+
"The VERSION must be one of the version names defined",
|
373
|
+
"with --import option.",
|
374
|
+
"",
|
375
|
+
"Defaults to the last version listed by --import.") do |v|
|
376
|
+
@new_since = v
|
377
|
+
end
|
378
|
+
|
379
|
+
opts.separator ""
|
380
|
+
opts.separator "Tweaking:"
|
381
|
+
opts.separator ""
|
382
|
+
|
383
|
+
opts.on('--meta-tags=PATH',
|
384
|
+
"Path to custom meta-tag implementations.",
|
385
|
+
"",
|
386
|
+
"Can be a path to single Ruby file or a directory.",
|
387
|
+
"",
|
388
|
+
"This option can be used repeatedly to include multiple",
|
389
|
+
"meta tags from different places.",
|
390
|
+
"",
|
391
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/Custom-tags") do |path|
|
392
|
+
@meta_tag_paths << canonical(path)
|
393
|
+
end
|
394
|
+
|
395
|
+
opts.on('--ignore-global',
|
396
|
+
"Turns off the creation of 'global' class.",
|
397
|
+
"",
|
398
|
+
"The 'global' class gets created when members that",
|
399
|
+
"don't belong to any class are found - all these",
|
400
|
+
"members will be placed into the 'global' class.",
|
401
|
+
"",
|
402
|
+
"Using this option won't suppress the warning that's",
|
403
|
+
"given when global members are found. For that you",
|
404
|
+
"need to additionally use --warnings=-global") do
|
405
|
+
@ignore_global = true
|
406
|
+
end
|
407
|
+
|
408
|
+
opts.on('--external=Foo,Bar,Baz', Array,
|
409
|
+
"Declares list of external classes.",
|
410
|
+
"",
|
411
|
+
"These classes will then no more generate warnings",
|
412
|
+
"when used in type definitions or inherited from.",
|
413
|
+
"",
|
414
|
+
"Multiple classes can be given in comma-separated list,",
|
415
|
+
"or by using the option repeatedly.") do |classes|
|
416
|
+
@external_classes += classes
|
417
|
+
end
|
418
|
+
|
419
|
+
opts.on('--[no-]ext4-events',
|
420
|
+
"Forces Ext4 options param on events.",
|
421
|
+
"",
|
422
|
+
"In Ext JS 4 and Sencha Touch 2 all event handlers are",
|
423
|
+
"passed an additional options object at the end of the",
|
424
|
+
"parameters list. This options object is skipped in the",
|
425
|
+
"documentation of Ext4/Touch2 events, so it needs to be",
|
426
|
+
"appended by JSDuck.",
|
427
|
+
"",
|
428
|
+
"The default is to auto-detect if we're using Ext JS 4",
|
429
|
+
"or Sencha Touch 2 based on whether the code defines",
|
430
|
+
"classes using Ext.define(), and only then append the",
|
431
|
+
"options parameter. This should work most of the time.",
|
432
|
+
"",
|
433
|
+
"Use this option to override the auto-detection.") do |e|
|
434
|
+
@ext4_events = e
|
435
|
+
end
|
436
|
+
|
437
|
+
opts.on('--examples-base-url=URL',
|
438
|
+
"Base URL for examples with relative URL-s.",
|
439
|
+
" ",
|
440
|
+
"Defaults to: 'extjs-build/examples/'") do |path|
|
441
|
+
@examples_base_url = path
|
442
|
+
end
|
443
|
+
|
249
444
|
opts.on('--link=TPL',
|
250
445
|
"HTML template for replacing {@link}.",
|
446
|
+
"",
|
251
447
|
"Possible placeholders:",
|
448
|
+
"",
|
252
449
|
"%c - full class name (e.g. 'Ext.Panel')",
|
253
450
|
"%m - class member name prefixed with member type",
|
254
451
|
" (e.g. 'method-urlEncode')",
|
255
452
|
"%# - inserts '#' if member name present",
|
256
453
|
"%- - inserts '-' if member name present",
|
257
454
|
"%a - anchor text for link",
|
258
|
-
"
|
455
|
+
"",
|
456
|
+
"Defaults to: '<a href=\"#!/api/%c%-%m\" rel=\"%c%-%m\" class=\"docClass\">%a</a>'") do |tpl|
|
259
457
|
@link_tpl = tpl
|
260
458
|
end
|
261
459
|
|
262
460
|
opts.on('--img=TPL',
|
263
461
|
"HTML template for replacing {@img}.",
|
462
|
+
"",
|
264
463
|
"Possible placeholders:",
|
464
|
+
"",
|
265
465
|
"%u - URL from @img tag (e.g. 'some/path.png')",
|
266
466
|
"%a - alt text for image",
|
267
|
-
"
|
467
|
+
"",
|
468
|
+
"Defaults to: '<p><img src=\"%u\" alt=\"%a\"></p>'") do |tpl|
|
268
469
|
@img_tpl = tpl
|
269
470
|
end
|
270
471
|
|
271
|
-
opts.on('--export=TYPE',
|
272
|
-
"Exports docs in JSON. TYPE is one of:",
|
273
|
-
"* full - full class docs.",
|
274
|
-
"* api - only class- and member names.",
|
275
|
-
"* examples - extracts inline examples from classes.", " ") do |format|
|
276
|
-
@export = format.to_sym
|
277
|
-
end
|
278
|
-
|
279
|
-
opts.on('--seo', "Creates index.php that handles search engine traffic.", " ") do
|
280
|
-
@seo = true
|
281
|
-
end
|
282
|
-
|
283
472
|
opts.on('--eg-iframe=PATH',
|
284
|
-
"
|
285
|
-
"
|
473
|
+
"HTML file used to display inline examples.",
|
474
|
+
"",
|
475
|
+
"The file will be used inside <iframe> that renders the",
|
476
|
+
"example. Not just any HTML file will work - it needs to",
|
477
|
+
"define loadInlineExample function that will be called",
|
478
|
+
"with the example code.",
|
479
|
+
"",
|
480
|
+
"See also: https://github.com/senchalabs/jsduck/wiki/Inline-examples") do |path|
|
286
481
|
@eg_iframe = canonical(path)
|
287
482
|
end
|
288
483
|
|
289
|
-
opts.on('--
|
290
|
-
"
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
484
|
+
opts.on('--ext-namespaces=Ext,Foo', Array,
|
485
|
+
"Additional Ext JS namespaces to recognize.",
|
486
|
+
"",
|
487
|
+
"Defaults to 'Ext'",
|
488
|
+
"",
|
489
|
+
"Useful when using Ext JS in sandbox mode where instead",
|
490
|
+
"of Ext.define() your code contains YourNs.define().",
|
491
|
+
"In such case pass --ext-namespaces=Ext,YourNS option",
|
492
|
+
"and JSDuck will recognize both Ext.define() and",
|
493
|
+
"YourNs.define() plus few other things that depend on",
|
494
|
+
"Ext namespace like Ext.emptyFn.") do |ns|
|
495
|
+
@ext_namespaces = ns
|
296
496
|
end
|
297
497
|
|
298
|
-
opts.on('--
|
299
|
-
"
|
300
|
-
|
498
|
+
opts.on('--touch-examples-ui',
|
499
|
+
"Turns on phone/tablet UI for examples.",
|
500
|
+
"",
|
501
|
+
"This is a very Sencha Touch 2 docs specific option.",
|
502
|
+
"Effects both normal- and inline-examples.") do
|
503
|
+
@touch_examples_ui = true
|
301
504
|
end
|
302
505
|
|
506
|
+
opts.separator ""
|
303
507
|
opts.separator "Debugging:"
|
304
508
|
opts.separator ""
|
305
509
|
|
510
|
+
opts.on('-v', '--verbose',
|
511
|
+
"Turns on excessive logging.",
|
512
|
+
"",
|
513
|
+
"Log messages are writted to STDERR.") do
|
514
|
+
Logger.instance.verbose = true
|
515
|
+
end
|
516
|
+
|
306
517
|
opts.on('--warnings=+A,-B,+C', Array,
|
307
518
|
"Turns warnings selectively on/off.",
|
308
|
-
"
|
519
|
+
"",
|
309
520
|
" +all - to turn on all warnings",
|
310
|
-
"
|
311
|
-
"
|
312
|
-
" ",
|
521
|
+
"",
|
522
|
+
"List of all available warning types:",
|
523
|
+
"(Those with '+' in front of them default to on)",
|
524
|
+
"",
|
313
525
|
*Logger.instance.doc_warnings) do |warnings|
|
314
526
|
warnings.each do |op|
|
315
527
|
if op =~ /^([-+]?)(.*)$/
|
@@ -320,117 +532,81 @@ module JsDuck
|
|
320
532
|
end
|
321
533
|
end
|
322
534
|
|
323
|
-
# For debugging it's often useful to set --processes=0 to get deterministic results.
|
324
535
|
opts.on('-p', '--processes=COUNT',
|
325
536
|
"The number of parallel processes to use.",
|
326
|
-
|
327
|
-
"
|
537
|
+
"",
|
538
|
+
"Defaults to the number of processors/cores.",
|
539
|
+
"",
|
540
|
+
"Set to 0 to disable parallel processing completely.",
|
541
|
+
"This is often useful in debugging to get deterministic",
|
542
|
+
"results.",
|
543
|
+
"",
|
544
|
+
"In Windows this option is disabled.") do |count|
|
328
545
|
@processes = count.to_i
|
329
546
|
end
|
330
547
|
|
548
|
+
opts.on('--pretty-json',
|
549
|
+
"Turns on pretty-printing of JSON.",
|
550
|
+
"",
|
551
|
+
"This is useful when studying the JSON files generated",
|
552
|
+
"by --export option. But the option effects any JSON",
|
553
|
+
"that gets generated, so it's also useful when debugging",
|
554
|
+
"the resource files generated for the docs app.") do
|
555
|
+
@pretty_json = true
|
556
|
+
end
|
557
|
+
|
331
558
|
opts.on('--template=PATH',
|
332
|
-
"
|
559
|
+
"Dir containing the UI template files.",
|
560
|
+
"",
|
561
|
+
"Useful when developing the template files.") do |path|
|
333
562
|
@template_dir = canonical(path)
|
334
563
|
end
|
335
564
|
|
336
565
|
opts.on('--template-links',
|
337
|
-
"
|
338
|
-
"
|
339
|
-
"
|
566
|
+
"Creates symlinks to UI template files.",
|
567
|
+
"",
|
568
|
+
"Useful for template files development.",
|
569
|
+
"Only works on platforms supporting symbolic links.") do
|
340
570
|
@template_links = true
|
341
571
|
end
|
342
572
|
|
343
573
|
opts.on('--extjs-path=PATH',
|
344
|
-
"Path for main ExtJS JavaScript file.
|
345
|
-
"
|
574
|
+
"Path for main ExtJS JavaScript file.",
|
575
|
+
"",
|
576
|
+
"This is the ExtJS file that's used by the docs app UI.",
|
577
|
+
"",
|
578
|
+
"Defaults to extjs/ext-all.js",
|
579
|
+
"",
|
580
|
+
"Useful for switching to extjs/ext-all-debug.js in development.") do |path|
|
346
581
|
@extjs_path = path # NB! must be relative path
|
347
582
|
end
|
348
583
|
|
349
584
|
opts.on('--local-storage-db=NAME',
|
350
585
|
"Prefix for LocalStorage database names.",
|
351
|
-
"
|
586
|
+
"",
|
587
|
+
"Defaults to 'docs'") do |name|
|
352
588
|
@local_storage_db = name
|
353
589
|
end
|
354
590
|
|
355
|
-
opts.on('--
|
356
|
-
"Use
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
"
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
"Several versions can be imported using the option multiple times.",
|
368
|
-
"To specify the current version, leave the :PATH portion off.", " ") do |v|
|
369
|
-
if v =~ /\A(.*?):(.*)\Z/
|
370
|
-
@imports << {:version => $1, :path => canonical($2)}
|
371
|
-
else
|
372
|
-
@imports << {:version => v}
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
opts.on('--config=PATH',
|
377
|
-
"Loads config options from JSON file.", " ") do |path|
|
378
|
-
path = canonical(path)
|
379
|
-
if File.exists?(path)
|
380
|
-
config = read_json_config(path)
|
381
|
-
else
|
382
|
-
puts "Oh noes! The config file #{path} doesn't exist."
|
383
|
-
exit(1)
|
384
|
-
end
|
385
|
-
# treat paths inside JSON config relative to the location of
|
386
|
-
# config file. When done, switch back to current working dir.
|
387
|
-
@working_dir = File.dirname(path)
|
388
|
-
optparser.parse!(config).each {|fname| read_filenames(canonical(fname)) }
|
389
|
-
@working_dir = nil
|
390
|
-
end
|
391
|
-
|
392
|
-
opts.on('-h', '--help[=full]',
|
393
|
-
"Short help or --help=full for all available options.", " ") do |v|
|
394
|
-
if v == 'full'
|
395
|
-
puts opts
|
591
|
+
opts.on('-h', '--help[=--some-option]',
|
592
|
+
"Use --help=--option for help on option.",
|
593
|
+
"",
|
594
|
+
"For example To get help on --processes option any of the",
|
595
|
+
"following will work:",
|
596
|
+
"",
|
597
|
+
" --help=--processes",
|
598
|
+
" --help=processes",
|
599
|
+
" --help=-p",
|
600
|
+
" --help=p") do |v|
|
601
|
+
if v
|
602
|
+
puts opts.help_single(v)
|
396
603
|
else
|
397
|
-
puts opts.
|
398
|
-
puts "For example:"
|
399
|
-
puts
|
400
|
-
puts " # Documentation for builtin JavaScript classes like Array and String"
|
401
|
-
puts " jsduck --output output/dir --builtin-classes"
|
402
|
-
puts
|
403
|
-
puts " # Documentation for your own JavaScript"
|
404
|
-
puts " jsduck --output output/dir input-file.js some/input/dir"
|
405
|
-
puts
|
406
|
-
puts "The main options:"
|
407
|
-
puts
|
408
|
-
|
409
|
-
show_help = false
|
410
|
-
main_opts = [
|
411
|
-
/--output/,
|
412
|
-
/--builtin-classes/,
|
413
|
-
/--encoding/,
|
414
|
-
/--verbose/,
|
415
|
-
/--help/,
|
416
|
-
/--version/,
|
417
|
-
]
|
418
|
-
opts.summarize([], opts.summary_width) do |helpline|
|
419
|
-
if main_opts.any? {|re| helpline =~ re }
|
420
|
-
puts helpline
|
421
|
-
show_help = true
|
422
|
-
elsif helpline =~ /^\s*$/ && show_help == true
|
423
|
-
puts helpline
|
424
|
-
show_help = false
|
425
|
-
elsif show_help == true
|
426
|
-
puts helpline
|
427
|
-
end
|
428
|
-
end
|
604
|
+
puts opts.help
|
429
605
|
end
|
430
606
|
exit
|
431
607
|
end
|
432
608
|
|
433
|
-
opts.on('--version', "Prints JSDuck version"
|
609
|
+
opts.on('--version', "Prints JSDuck version") do
|
434
610
|
puts "JSDuck " + @version
|
435
611
|
exit
|
436
612
|
end
|
@@ -473,7 +649,7 @@ module JsDuck
|
|
473
649
|
@input_files << fname
|
474
650
|
end
|
475
651
|
else
|
476
|
-
Logger.instance.warn(nil, "File
|
652
|
+
Logger.instance.warn(nil, "File not found", fname)
|
477
653
|
end
|
478
654
|
end
|
479
655
|
|
@@ -502,35 +678,35 @@ module JsDuck
|
|
502
678
|
# Runs checks on the options
|
503
679
|
def validate
|
504
680
|
if @input_files.length == 0 && !@welcome && !@guides && !@videos && !@examples
|
505
|
-
|
681
|
+
Logger.instance.fatal("You should specify some input files, otherwise there's nothing I can do :(")
|
506
682
|
exit(1)
|
507
683
|
elsif @output_dir == :stdout && !@export
|
508
|
-
|
684
|
+
Logger.instance.fatal("Output to STDOUT only works when using --export option")
|
509
685
|
exit(1)
|
510
686
|
elsif ![nil, :full, :api, :examples].include?(@export)
|
511
|
-
|
687
|
+
Logger.instance.fatal("Unknown export format: #{@export}")
|
512
688
|
exit(1)
|
513
689
|
elsif @output_dir != :stdout
|
514
690
|
if !@output_dir
|
515
|
-
|
691
|
+
Logger.instance.fatal("You should also specify an output directory, where I could write all this amazing documentation")
|
516
692
|
exit(1)
|
517
693
|
elsif File.exists?(@output_dir) && !File.directory?(@output_dir)
|
518
|
-
|
694
|
+
Logger.instance.fatal("The output directory is not really a directory at all :(")
|
519
695
|
exit(1)
|
520
696
|
elsif !File.exists?(File.dirname(@output_dir))
|
521
|
-
|
697
|
+
Logger.instance.fatal("The parent directory for #{@output_dir} doesn't exist")
|
522
698
|
exit(1)
|
523
699
|
elsif !@export && !File.exists?(@template_dir + "/extjs")
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
700
|
+
Logger.instance.fatal("Oh noes! The template directory does not contain extjs/ directory :(")
|
701
|
+
Logger.instance.fatal("Please copy ExtJS over to template/extjs or create symlink.")
|
702
|
+
Logger.instance.fatal("For example:")
|
703
|
+
Logger.instance.fatal(" $ cp -r /path/to/ext-4.0.0 " + @template_dir + "/extjs")
|
528
704
|
exit(1)
|
529
705
|
elsif !@export && !File.exists?(@template_dir + "/resources/css")
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
706
|
+
Logger.instance.fatal("Oh noes! CSS files for custom ExtJS theme missing :(")
|
707
|
+
Logger.instance.fatal("Please compile SASS files in template/resources/sass with compass.")
|
708
|
+
Logger.instance.fatal("For example:")
|
709
|
+
Logger.instance.fatal(" $ compass compile " + @template_dir + "/resources/sass")
|
534
710
|
exit(1)
|
535
711
|
end
|
536
712
|
end
|