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/lib/jsduck/doc_formatter.rb
CHANGED
@@ -29,9 +29,12 @@ module JsDuck
|
|
29
29
|
# Default value: '<img src="%u" alt="%a"/>'
|
30
30
|
attr_accessor :img_tpl
|
31
31
|
|
32
|
-
#
|
33
|
-
|
34
|
-
|
32
|
+
# This will hold list of all image paths gathered from {@img} tags.
|
33
|
+
attr_accessor :images
|
34
|
+
|
35
|
+
# Base path to prefix images from {@img} tags.
|
36
|
+
# Defaults to no prefix.
|
37
|
+
attr_accessor :img_path
|
35
38
|
|
36
39
|
# Sets up instance to work in context of particular class, so
|
37
40
|
# that when {@link #blah} is encountered it knows that
|
@@ -57,13 +60,12 @@ module JsDuck
|
|
57
60
|
@doc_context = {}
|
58
61
|
@max_length = 120
|
59
62
|
@relations = {}
|
63
|
+
@images = []
|
60
64
|
@link_tpl = '<a href="%c%#%m">%a</a>'
|
61
65
|
@img_tpl = '<img src="%u" alt="%a"/>'
|
62
|
-
@example_tpl = '<pre class="inline-example"><code>%a</code></pre>'
|
63
66
|
@link_re = /\{@link\s+(\S*?)(?:\s+(.+?))?\}/m
|
64
67
|
@img_re = /\{@img\s+(\S*?)(?:\s+(.+?))?\}/m
|
65
|
-
@
|
66
|
-
@example_annotation_re = /<pre><code>@example( +[^\n]*)?\s+/m
|
68
|
+
@example_annotation_re = /<pre><code>\s*@example( +[^\n]*)?\s+/m
|
67
69
|
end
|
68
70
|
|
69
71
|
# Replaces {@link} and {@img} tags, auto-generates links for
|
@@ -74,8 +76,6 @@ module JsDuck
|
|
74
76
|
#
|
75
77
|
# Replaces {@img path/to/image.jpg Alt text} with HTML from @img_tpl.
|
76
78
|
#
|
77
|
-
# Replaces {@example path/to/example.js} with source from that file.
|
78
|
-
#
|
79
79
|
# Adds 'inline-example' class to code examples beginning with @example.
|
80
80
|
#
|
81
81
|
# Additionally replaces strings recognized as ClassNames with
|
@@ -89,11 +89,12 @@ module JsDuck
|
|
89
89
|
out += replace_link_tag(s.scan(@link_re))
|
90
90
|
elsif s.check(@img_re)
|
91
91
|
out += replace_img_tag(s.scan(@img_re))
|
92
|
-
elsif s.check(@example_re)
|
93
|
-
out += replace_example_tag(s.scan(@example_re))
|
94
92
|
elsif s.check(@example_annotation_re)
|
95
|
-
|
96
|
-
|
93
|
+
# Match possible classnames following @example and add them
|
94
|
+
# as CSS classes inside <pre> element.
|
95
|
+
s.scan(@example_annotation_re) =~ @example_annotation_re
|
96
|
+
css_classes = ($1 || "").strip
|
97
|
+
out += "<pre class='inline-example #{css_classes}'><code>"
|
97
98
|
elsif s.check(/[{<]/)
|
98
99
|
out += s.scan(/[{<]/)
|
99
100
|
else
|
@@ -129,10 +130,10 @@ module JsDuck
|
|
129
130
|
file = @doc_context[:filename]
|
130
131
|
line = @doc_context[:linenr]
|
131
132
|
if !@relations[cls]
|
132
|
-
Logger.instance.warn("#{
|
133
|
+
Logger.instance.warn("#{input} links to non-existing class", file, line)
|
133
134
|
text
|
134
135
|
elsif member && !get_member(cls, member, type)
|
135
|
-
Logger.instance.warn("#{
|
136
|
+
Logger.instance.warn("#{input} links to non-existing member", file, line)
|
136
137
|
text
|
137
138
|
else
|
138
139
|
link(cls, member, text, type)
|
@@ -144,10 +145,6 @@ module JsDuck
|
|
144
145
|
input.sub(@img_re) { img($1, $2) }
|
145
146
|
end
|
146
147
|
|
147
|
-
def replace_example_tag(input)
|
148
|
-
input.sub(@example_re) { example($1) }
|
149
|
-
end
|
150
|
-
|
151
148
|
def replace_class_names(input)
|
152
149
|
input.gsub(/(\A|\s)([A-Z][A-Za-z0-9.]*[A-Za-z0-9])(?:(#)([A-Za-z0-9]+))?([.,]?(?:\s|\Z))/m) do
|
153
150
|
before = $1
|
@@ -167,10 +164,11 @@ module JsDuck
|
|
167
164
|
|
168
165
|
# applies the image template
|
169
166
|
def img(url, alt_text)
|
167
|
+
@images << url
|
170
168
|
@img_tpl.gsub(/(%\w)/) do
|
171
169
|
case $1
|
172
170
|
when '%u'
|
173
|
-
url
|
171
|
+
@img_path ? (@img_path + "/" + url) : url
|
174
172
|
when '%a'
|
175
173
|
CGI.escapeHTML(alt_text||"")
|
176
174
|
else
|
@@ -179,24 +177,6 @@ module JsDuck
|
|
179
177
|
end
|
180
178
|
end
|
181
179
|
|
182
|
-
# Replaces example template with example read from file
|
183
|
-
def example(path)
|
184
|
-
@example_tpl.gsub(/(%\w)/) do
|
185
|
-
case $1
|
186
|
-
when '%a'
|
187
|
-
if @get_example
|
188
|
-
CGI.escapeHTML(@get_example.call(path))
|
189
|
-
else
|
190
|
-
file = @doc_context[:filename]
|
191
|
-
line = @doc_context[:linenr]
|
192
|
-
Logger.instance.warn("--examples not specified, but {@example} found in #{file} line #{line}.")
|
193
|
-
end
|
194
|
-
else
|
195
|
-
$1
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
180
|
# applies the link template
|
201
181
|
def link(cls, member, anchor_text, type=nil)
|
202
182
|
# Use the canonical class name for link (not some alternateClassName)
|
data/lib/jsduck/doc_parser.rb
CHANGED
@@ -30,7 +30,7 @@ module JsDuck
|
|
30
30
|
|
31
31
|
@meta_tags_map = {}
|
32
32
|
(meta_tags || []).each do |tag|
|
33
|
-
@meta_tags_map[tag
|
33
|
+
@meta_tags_map[tag.name] = tag
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -136,6 +136,8 @@ module JsDuck
|
|
136
136
|
boolean_at_tag(/@protected/, :protected)
|
137
137
|
elsif look(/@accessor\b/)
|
138
138
|
boolean_at_tag(/@accessor/, :accessor)
|
139
|
+
elsif look(/@evented\b/)
|
140
|
+
boolean_at_tag(/@evented/, :evented)
|
139
141
|
elsif look(/@template\b/)
|
140
142
|
boolean_at_tag(/@template/, :template)
|
141
143
|
elsif look(/@markdown\b/)
|
@@ -146,12 +148,9 @@ module JsDuck
|
|
146
148
|
boolean_at_tag(/@abstract/, :abstract)
|
147
149
|
elsif look(/@/)
|
148
150
|
@input.scan(/@/)
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
skip_horiz_white
|
153
|
-
@current_tag[:content] = @input.scan(/.*$/)
|
154
|
-
skip_white
|
151
|
+
tag = @meta_tags_map[look(/\w+/)]
|
152
|
+
if tag
|
153
|
+
meta_at_tag(tag)
|
155
154
|
else
|
156
155
|
@current_tag[:doc] += "@"
|
157
156
|
end
|
@@ -161,6 +160,24 @@ module JsDuck
|
|
161
160
|
end
|
162
161
|
end
|
163
162
|
|
163
|
+
# Matches the given meta-tag
|
164
|
+
def meta_at_tag(tag)
|
165
|
+
prev_tag = @current_tag
|
166
|
+
|
167
|
+
add_tag(:meta)
|
168
|
+
@current_tag[:name] = match(/\w+/)
|
169
|
+
skip_horiz_white
|
170
|
+
|
171
|
+
# Fors singleline tags, scan to the end of line and finish the
|
172
|
+
# tag. For multiline tags we leave the tag open for :doc
|
173
|
+
# addition just like with built-in multiline tags.
|
174
|
+
unless tag.multiline
|
175
|
+
@current_tag[:doc] = @input.scan(/.*$/).strip
|
176
|
+
skip_white
|
177
|
+
@current_tag = prev_tag
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
164
181
|
# matches @class name ...
|
165
182
|
def at_class
|
166
183
|
match(/@class/)
|
@@ -354,7 +371,7 @@ module JsDuck
|
|
354
371
|
end
|
355
372
|
end
|
356
373
|
|
357
|
-
# matches: <ident-chain> | "[" <ident-chain> [ "=" <
|
374
|
+
# matches: <ident-chain> | "[" <ident-chain> [ "=" <default-value> ] "]"
|
358
375
|
def maybe_name_with_default
|
359
376
|
skip_horiz_white
|
360
377
|
if look(/\[/)
|
@@ -364,7 +381,7 @@ module JsDuck
|
|
364
381
|
if look(/=/)
|
365
382
|
match(/=/)
|
366
383
|
skip_horiz_white
|
367
|
-
@current_tag[:default] =
|
384
|
+
@current_tag[:default] = default_value
|
368
385
|
end
|
369
386
|
skip_horiz_white
|
370
387
|
match(/\]/)
|
@@ -408,9 +425,20 @@ module JsDuck
|
|
408
425
|
end
|
409
426
|
end
|
410
427
|
|
411
|
-
|
428
|
+
# attempts to match javascript literal,
|
429
|
+
# when it fails grabs anything up to closing "]"
|
430
|
+
def default_value
|
431
|
+
start_pos = @input.pos
|
412
432
|
lit = JsLiteralParser.new(@input).literal
|
413
|
-
lit
|
433
|
+
if lit && look(/ *\]/)
|
434
|
+
# When lital matched and there's nothing after it up to the closing "]"
|
435
|
+
JsLiteralBuilder.new.to_s(lit)
|
436
|
+
else
|
437
|
+
# Otherwise reset parsing position to where we started
|
438
|
+
# and rescan up to "]" using simple regex.
|
439
|
+
@input.pos = start_pos
|
440
|
+
match(/[^\]]*/)
|
441
|
+
end
|
414
442
|
end
|
415
443
|
|
416
444
|
# matches {...} and returns text inside brackets
|
data/lib/jsduck/exporter.rb
CHANGED
@@ -29,6 +29,7 @@ module JsDuck
|
|
29
29
|
cls.delete(:doc)
|
30
30
|
cls[:members] = compact_members_group(cls[:members])
|
31
31
|
cls[:statics] = compact_members_group(cls[:statics])
|
32
|
+
cls[:files] = compact_files(cls[:files])
|
32
33
|
cls
|
33
34
|
end
|
34
35
|
|
@@ -47,6 +48,16 @@ module JsDuck
|
|
47
48
|
end
|
48
49
|
m_copy
|
49
50
|
end
|
51
|
+
|
52
|
+
# Remove full path from filename for privacy considerations as the
|
53
|
+
# path can reveal information about the system where JSDuck was
|
54
|
+
# run. The docs app doesn't need to have this information.
|
55
|
+
def compact_files(files)
|
56
|
+
files.map do |f|
|
57
|
+
{:filename => File.basename(f[:filename]), :href => f[:href]}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
50
61
|
end
|
51
62
|
|
52
63
|
end
|
data/lib/jsduck/guides.rb
CHANGED
@@ -44,14 +44,14 @@ module JsDuck
|
|
44
44
|
guide_file = in_dir + "/README.md"
|
45
45
|
return Logger.instance.warn("README.md not found in #{in_dir}") unless File.exists?(guide_file)
|
46
46
|
|
47
|
-
Logger.instance.log("Writing guide
|
47
|
+
Logger.instance.log("Writing guide", out_dir)
|
48
48
|
# Copy the whole guide dir over
|
49
49
|
FileUtils.cp_r(in_dir, out_dir)
|
50
50
|
|
51
51
|
@formatter.doc_context = {:filename => guide_file, :linenr => 0}
|
52
|
-
html = @formatter.format(IO.read(guide_file))
|
53
52
|
name = File.basename(in_dir)
|
54
|
-
|
53
|
+
@formatter.img_path = "guides/#{name}"
|
54
|
+
html = @formatter.format(IO.read(guide_file))
|
55
55
|
|
56
56
|
JsonDuck.write_jsonp(out_dir+"/README.js", name, {:guide => html, :title => guide["title"]})
|
57
57
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "jsduck/logger"
|
2
|
+
require "fileutils"
|
3
|
+
|
4
|
+
module JsDuck
|
5
|
+
|
6
|
+
# Looks up images from directories specified through --images option.
|
7
|
+
class Images
|
8
|
+
def initialize(paths)
|
9
|
+
@paths = scan_for_images(paths)
|
10
|
+
@images = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Scans each path for image files, building a hash of paths where
|
14
|
+
# each path points to a hash of image files found in that path.
|
15
|
+
def scan_for_images(paths)
|
16
|
+
map = {}
|
17
|
+
paths.each do |path|
|
18
|
+
# Scans directory for image files
|
19
|
+
map[path] = {}
|
20
|
+
Dir[path+"/**/*.{png,jpg,jpeg,gif}"].each do |img|
|
21
|
+
map[path][img] = false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
map
|
25
|
+
end
|
26
|
+
|
27
|
+
# Adds relative image path of an image
|
28
|
+
def add(filename)
|
29
|
+
unless @images[filename]
|
30
|
+
@images[filename] = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Copys over images to given output dir
|
35
|
+
def copy(output_dir)
|
36
|
+
@images.each_key do |img|
|
37
|
+
unless copy_img(img, output_dir)
|
38
|
+
Logger.instance.warn("Image not found.", img)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
report_unused
|
42
|
+
end
|
43
|
+
|
44
|
+
# Attempts to copy one image, returns true on success
|
45
|
+
def copy_img(img, output_dir)
|
46
|
+
@paths.each_pair do |path, map|
|
47
|
+
filename = path + "/" + img
|
48
|
+
if map.has_key?(filename)
|
49
|
+
dest = output_dir + "/" + img
|
50
|
+
Logger.instance.log("Copying image", dest)
|
51
|
+
FileUtils.makedirs(File.dirname(dest))
|
52
|
+
FileUtils.cp(filename, dest)
|
53
|
+
# mark file as used.
|
54
|
+
map[filename] = true
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
|
61
|
+
# Report unused images
|
62
|
+
def report_unused
|
63
|
+
@paths.each_pair do |path, map|
|
64
|
+
map.each_pair do |img, used|
|
65
|
+
Logger.instance.warn("Image not used.", img) unless used
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/lib/jsduck/js_parser.rb
CHANGED
@@ -234,7 +234,7 @@ module JsDuck
|
|
234
234
|
end
|
235
235
|
|
236
236
|
# <ext-define-cfg> := "{" ( <extend> | <mixins> | <alternate-class-name> | <alias> |
|
237
|
-
# <requires> | <uses> | <singleton> | <?> )*
|
237
|
+
# <xtype> | <requires> | <uses> | <singleton> | <?> )*
|
238
238
|
def ext_define_cfg
|
239
239
|
match("{")
|
240
240
|
cfg = {}
|
@@ -249,6 +249,8 @@ module JsDuck
|
|
249
249
|
cfg[:alternateClassNames] = found
|
250
250
|
elsif found = ext_define_alias
|
251
251
|
cfg[:alias] = found
|
252
|
+
elsif found = ext_define_xtype
|
253
|
+
cfg[:xtype] = found
|
252
254
|
elsif found = ext_define_requires
|
253
255
|
cfg[:requires] = found
|
254
256
|
elsif found = ext_define_uses
|
@@ -270,12 +272,18 @@ module JsDuck
|
|
270
272
|
end
|
271
273
|
end
|
272
274
|
|
273
|
-
# <mixins> := "mixins" ":" <object-literal>
|
275
|
+
# <mixins> := "mixins" ":" [ <object-literal> | <array-literal> ]
|
274
276
|
def ext_define_mixins
|
275
|
-
if look("mixins", ":"
|
277
|
+
if look("mixins", ":")
|
276
278
|
match("mixins", ":")
|
277
279
|
lit = literal
|
278
|
-
lit && lit[:
|
280
|
+
if lit && lit[:type] == :object
|
281
|
+
lit[:value].map {|x| x[:value][:value] }
|
282
|
+
elsif lit && lit[:type] == :array
|
283
|
+
lit[:value].map {|x| x[:value] }
|
284
|
+
else
|
285
|
+
nil
|
286
|
+
end
|
279
287
|
end
|
280
288
|
end
|
281
289
|
|
@@ -295,6 +303,14 @@ module JsDuck
|
|
295
303
|
end
|
296
304
|
end
|
297
305
|
|
306
|
+
# <xtype> := "xtype" ":" <string-or-list>
|
307
|
+
def ext_define_xtype
|
308
|
+
if look("xtype", ":")
|
309
|
+
match("xtype", ":")
|
310
|
+
string_or_list
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
298
314
|
# <requires> := "requires" ":" <string-or-list>
|
299
315
|
def ext_define_requires
|
300
316
|
if look("requires", ":")
|
data/lib/jsduck/lexer.rb
CHANGED
@@ -118,8 +118,8 @@ module JsDuck
|
|
118
118
|
:type => :operator,
|
119
119
|
:value => @input.scan(/./)
|
120
120
|
}
|
121
|
-
elsif @input.check(/[a-zA-Z_]/)
|
122
|
-
value = @input.scan(
|
121
|
+
elsif @input.check(/[a-zA-Z_$]/)
|
122
|
+
value = @input.scan(/[$\w]+/)
|
123
123
|
return {
|
124
124
|
:type => KEYWORDS[value] ? :keyword : :ident,
|
125
125
|
:value => value
|
@@ -167,12 +167,6 @@ module JsDuck
|
|
167
167
|
:type => :number,
|
168
168
|
:value => nr
|
169
169
|
}
|
170
|
-
elsif @input.check(/\$/)
|
171
|
-
value = @input.scan(/\$\w*/)
|
172
|
-
return {
|
173
|
-
:type => :ident,
|
174
|
-
:value => value
|
175
|
-
}
|
176
170
|
elsif @input.check(/./)
|
177
171
|
return {
|
178
172
|
:type => :operator,
|
data/lib/jsduck/lint.rb
CHANGED
@@ -75,8 +75,9 @@ module JsDuck
|
|
75
75
|
end
|
76
76
|
|
77
77
|
# Prints warning + filename and linenumber from doc-context
|
78
|
-
def warn(msg,
|
79
|
-
|
78
|
+
def warn(msg, member)
|
79
|
+
context = member[:files][0]
|
80
|
+
Logger.instance.warn(msg, context[:filename], context[:linenr])
|
80
81
|
end
|
81
82
|
|
82
83
|
end
|
data/lib/jsduck/logger.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'singleton'
|
2
|
+
require 'jsduck/os'
|
2
3
|
|
3
4
|
module JsDuck
|
4
5
|
|
@@ -15,9 +16,11 @@ module JsDuck
|
|
15
16
|
@shown_warnings = {}
|
16
17
|
end
|
17
18
|
|
18
|
-
# Prints log message
|
19
|
-
def log(msg)
|
20
|
-
|
19
|
+
# Prints log message with optional filename appended
|
20
|
+
def log(msg, filename=nil)
|
21
|
+
if @verbose
|
22
|
+
puts msg + " " + format(filename) + "..."
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
23
26
|
# Prints warning message.
|
@@ -25,12 +28,28 @@ module JsDuck
|
|
25
28
|
# Ignores duplicate warnings - only prints the first one.
|
26
29
|
# Works best when --processes=0, but it reduces the amount of
|
27
30
|
# warnings greatly also when run multiple processes.
|
28
|
-
|
31
|
+
#
|
32
|
+
# Optionally filename and line number will be inserted to message.
|
33
|
+
def warn(msg, filename=nil, line=nil)
|
34
|
+
msg = "Warning: " + format(filename, line) + " " + msg
|
35
|
+
|
29
36
|
if @warnings && !@shown_warnings[msg]
|
30
|
-
$stderr.puts
|
37
|
+
$stderr.puts msg
|
31
38
|
@shown_warnings[msg] = true
|
32
39
|
end
|
33
40
|
end
|
41
|
+
|
42
|
+
# Formats filename and line number for output
|
43
|
+
def format(filename=nil, line=nil)
|
44
|
+
out = ""
|
45
|
+
if filename
|
46
|
+
out = OS::windows? ? filename.gsub('/', '\\') : filename
|
47
|
+
if line
|
48
|
+
out += ":#{line}:"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
out
|
52
|
+
end
|
34
53
|
end
|
35
54
|
|
36
55
|
end
|
data/lib/jsduck/merger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'jsduck/logger'
|
2
|
+
|
1
3
|
module JsDuck
|
2
4
|
|
3
5
|
# Takes data from doc-comment and code that follows it and combines
|
@@ -6,6 +8,15 @@ module JsDuck
|
|
6
8
|
#
|
7
9
|
# The main method merge() produces a hash as a result.
|
8
10
|
class Merger
|
11
|
+
# Allow passing in filename and line for error reporting
|
12
|
+
attr_accessor :filename
|
13
|
+
attr_accessor :linenr
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@filename = ""
|
17
|
+
@linenr = 0
|
18
|
+
end
|
19
|
+
|
9
20
|
def merge(docs, code)
|
10
21
|
case detect_doc_type(docs, code)
|
11
22
|
when :class
|
@@ -170,6 +181,7 @@ module JsDuck
|
|
170
181
|
:default => detect_default(:cfg, doc_map, code),
|
171
182
|
:properties => detect_subproperties(docs, :cfg),
|
172
183
|
:accessor => !!doc_map[:accessor],
|
184
|
+
:evented => !!doc_map[:evented],
|
173
185
|
}, doc_map)
|
174
186
|
end
|
175
187
|
|
@@ -222,7 +234,9 @@ module JsDuck
|
|
222
234
|
end
|
223
235
|
|
224
236
|
def create_member_id(m)
|
225
|
-
|
237
|
+
# Sanitize $ in member names with something safer
|
238
|
+
name = m[:name].gsub(/\$/, 'S-')
|
239
|
+
"#{m[:static] ? 'static-' : ''}#{m[:tagname]}-#{name}"
|
226
240
|
end
|
227
241
|
|
228
242
|
def detect_name(tagname, doc_map, code, name_type = :last_name)
|
@@ -319,10 +333,17 @@ module JsDuck
|
|
319
333
|
def detect_xtypes(doc_map, code)
|
320
334
|
if doc_map[:xtype]
|
321
335
|
{"widget" => doc_map[:xtype].map {|tag| tag[:name] } }
|
322
|
-
elsif code[:alias]
|
336
|
+
elsif code[:xtype] || code[:alias]
|
323
337
|
xtypes = {}
|
324
|
-
code[:
|
325
|
-
if
|
338
|
+
(code[:xtype] || []).each do |a|
|
339
|
+
if xtypes["widget"]
|
340
|
+
xtypes["widget"] << a
|
341
|
+
else
|
342
|
+
xtypes["widget"] = [a]
|
343
|
+
end
|
344
|
+
end
|
345
|
+
(code[:alias] || []).each do |a|
|
346
|
+
if a =~ /^([\w.]+)\.(\w+)$/
|
326
347
|
if xtypes[$1]
|
327
348
|
xtypes[$1] << $2
|
328
349
|
else
|
@@ -337,7 +358,12 @@ module JsDuck
|
|
337
358
|
end
|
338
359
|
|
339
360
|
def detect_meta(doc_map)
|
340
|
-
|
361
|
+
meta = {}
|
362
|
+
(doc_map[:meta] || []).map do |tag|
|
363
|
+
meta[tag[:name]] = [] unless meta[tag[:name]]
|
364
|
+
meta[tag[:name]] << tag[:doc]
|
365
|
+
end
|
366
|
+
meta
|
341
367
|
end
|
342
368
|
|
343
369
|
def detect_deprecated(doc_map)
|
@@ -407,8 +433,12 @@ module JsDuck
|
|
407
433
|
if it[:name] =~ /^(.+)\.([^.]+)$/
|
408
434
|
it[:name] = $2
|
409
435
|
parent = index[$1]
|
410
|
-
|
411
|
-
|
436
|
+
if parent
|
437
|
+
parent[:properties] = [] unless parent[:properties]
|
438
|
+
parent[:properties] << it
|
439
|
+
else
|
440
|
+
Logger.instance.warn("Ignoring subproperty #{$1}.#{$2}, no parent found with name '#{$1}'.", @filename, @linenr)
|
441
|
+
end
|
412
442
|
else
|
413
443
|
items << it
|
414
444
|
end
|
@@ -429,7 +459,7 @@ module JsDuck
|
|
429
459
|
# Combines :doc-s of most tags
|
430
460
|
# Ignores tags that have doc comment themselves and subproperty tags
|
431
461
|
def detect_doc(docs)
|
432
|
-
ignore_tags = [:param, :return]
|
462
|
+
ignore_tags = [:param, :return, :meta]
|
433
463
|
doc_tags = docs.find_all { |tag| !ignore_tags.include?(tag[:tagname]) && !subproperty?(tag) }
|
434
464
|
doc_tags.map { |tag| tag[:doc] }.compact.join(" ")
|
435
465
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module JsDuck
|
2
|
+
|
3
|
+
# Abstract base class for all meta tag implementations.
|
4
|
+
#
|
5
|
+
# Child classes must define value for @name attribute. They can
|
6
|
+
# also provide @multiline, and override #to_html method.
|
7
|
+
class MetaTag
|
8
|
+
# Name of the tag (required)
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
# True to include all lines up to next @tag as part of this meta-tag
|
12
|
+
attr_reader :multiline
|
13
|
+
|
14
|
+
# Override this to transform the content of meta-tag to HTML to be
|
15
|
+
# included into documentation.
|
16
|
+
#
|
17
|
+
# It gets passed an array of contents gathered from all meta-tags
|
18
|
+
# of given type. It should return an HTML string to inject into
|
19
|
+
# document. For help in that it can use the #format method to
|
20
|
+
# easily support Markdown and {@link/img} tags inside the contents
|
21
|
+
# of meta-tag.
|
22
|
+
#
|
23
|
+
# By default the method returns nil, which means the tag will not
|
24
|
+
# be rendered at all.
|
25
|
+
def to_html(contents)
|
26
|
+
end
|
27
|
+
|
28
|
+
# This is used to inject the formatter object for #markdown method
|
29
|
+
attr_accessor :formatter
|
30
|
+
|
31
|
+
# Helper method to format the text in standard JsDuck way.
|
32
|
+
# This means running it through Markdown engine and expanding
|
33
|
+
# {@link} and {@img} tags.
|
34
|
+
def format(text)
|
35
|
+
@formatter.format(text)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns all descendants of MetaTag class.
|
39
|
+
def self.descendants
|
40
|
+
result = []
|
41
|
+
ObjectSpace.each_object(::Class) do |cls|
|
42
|
+
result << cls if cls < self
|
43
|
+
end
|
44
|
+
result
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "jsduck/meta_tag"
|
2
|
+
require 'jsduck/author_tag'
|
3
|
+
require 'jsduck/doc_author_tag'
|
4
|
+
|
5
|
+
module JsDuck
|
6
|
+
|
7
|
+
# Loads user-defined meta-tags
|
8
|
+
class MetaTagLoader
|
9
|
+
# instatiates builtin meta tags
|
10
|
+
def initialize
|
11
|
+
@classes = MetaTag.descendants
|
12
|
+
@meta_tags = @classes.map {|cls| cls.new }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Loads user-defined meta-tags from given paths.
|
16
|
+
# Returns list of meta-tag instances.
|
17
|
+
def load(paths)
|
18
|
+
paths.each do |path|
|
19
|
+
if File.directory?(path)
|
20
|
+
Dir[path+"/**/*.rb"].each do |file|
|
21
|
+
require(file)
|
22
|
+
init_remaining
|
23
|
+
end
|
24
|
+
else
|
25
|
+
require(path)
|
26
|
+
init_remaining
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@meta_tags
|
30
|
+
end
|
31
|
+
|
32
|
+
# Instantiates meta tag classes that haven't been instantiated
|
33
|
+
# already. This is called after each meta-tags file is loaded so
|
34
|
+
# that the list of meta-tags will be in order specified from
|
35
|
+
# command line.
|
36
|
+
def init_remaining
|
37
|
+
MetaTag.descendants.each do |cls|
|
38
|
+
if !@classes.include?(cls)
|
39
|
+
@classes << cls
|
40
|
+
newtag = cls.new
|
41
|
+
@meta_tags = @meta_tags.find_all {|t| t.name != newtag.name }
|
42
|
+
@meta_tags << newtag
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|