jsduck 0.5 → 0.6

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.
@@ -1,15 +1,10 @@
1
- require "jsduck/doc_formatter"
2
-
3
1
  module JsDuck
4
2
 
5
3
  # Renders method/event parameters list in long form
6
4
  # for use in documentation body.
7
5
  class LongParams
8
- def initialize(cls)
9
- @formatter = DocFormatter.new()
10
- @formatter.context = cls.full_name
11
- @formatter.css_class = 'docClass'
12
- @formatter.url_template = 'output/%cls%.html'
6
+ def initialize(formatter)
7
+ @formatter = formatter
13
8
  end
14
9
 
15
10
  def render(params)
@@ -22,9 +17,10 @@ module JsDuck
22
17
 
23
18
  def render_single(param)
24
19
  doc = @formatter.format(param[:doc])
20
+ type = @formatter.replace(param[:type])
25
21
  return [
26
22
  "<li>",
27
- "<code>#{param[:name]}</code> : #{param[:type]}",
23
+ "<code>#{param[:name]}</code> : #{type}",
28
24
  "<div class='sub-desc'>#{doc}</div>",
29
25
  "</li>",
30
26
  ].join("")
@@ -9,15 +9,29 @@ module JsDuck
9
9
  def create(docs)
10
10
  list = []
11
11
  docs.each do |cls|
12
+ list << class_node(cls)
12
13
  [:cfg, :property, :method, :event].each do |type|
13
14
  cls.members(type).each do |m|
14
- list << member_node(m, cls)
15
+ # skip inherited items and constructors
16
+ if m[:member] == cls.full_name && m[:name] != cls.short_name
17
+ list << member_node(m, cls)
18
+ end
15
19
  end
16
20
  end
17
21
  end
18
22
  list
19
23
  end
20
24
 
25
+ # Creates structure representing one class
26
+ def class_node(cls)
27
+ return {
28
+ :cls => cls.full_name,
29
+ :member => cls.short_name,
30
+ :type => :cls,
31
+ :doc => short_desc(cls[:doc])
32
+ }
33
+ end
34
+
21
35
  # Creates structure representing one member
22
36
  def member_node(member, cls)
23
37
  return {
data/lib/jsduck/merger.rb CHANGED
@@ -18,6 +18,10 @@ module JsDuck
18
18
  create_cfg(docs, code)
19
19
  when :property
20
20
  create_property(docs, code)
21
+ when :css_var
22
+ create_css_var(docs, code)
23
+ when :css_mixin
24
+ create_css_mixin(docs, code)
21
25
  end
22
26
  end
23
27
 
@@ -33,12 +37,16 @@ module JsDuck
33
37
  :method
34
38
  elsif doc_map[:property] || doc_map[:type]
35
39
  :property
40
+ elsif doc_map[:css_var]
41
+ :css_var
36
42
  elsif code[:type] == :ext_define
37
43
  :class
38
44
  elsif code[:type] == :assignment && class_name?(*code[:left])
39
45
  :class
40
46
  elsif code[:type] == :function && class_name?(code[:name])
41
47
  :class
48
+ elsif code[:type] == :css_mixin
49
+ :css_mixin
42
50
  elsif doc_map[:cfg]
43
51
  :cfg
44
52
  elsif code[:type] == :function
@@ -67,6 +75,8 @@ module JsDuck
67
75
  end
68
76
  result[:property] = []
69
77
  result[:event] = []
78
+ result[:css_var] = []
79
+ result[:css_mixin] = []
70
80
  result
71
81
  end
72
82
 
@@ -109,9 +119,11 @@ module JsDuck
109
119
  :name => detect_name(:class, doc_map, code, :full_name),
110
120
  :doc => detect_doc(docs),
111
121
  :extends => detect_extends(doc_map, code),
112
- :mixins => detect_mixins(doc_map, code),
122
+ :mixins => detect_list(:mixins, doc_map, code),
123
+ :alternateClassNames => detect_list(:alternateClassNames, doc_map, code),
113
124
  :xtype => detect_xtype(doc_map),
114
125
  :author => detect_author(doc_map),
126
+ :docauthor => detect_docauthor(doc_map),
115
127
  :singleton => !!doc_map[:singleton],
116
128
  :private => !!doc_map[:private],
117
129
  }
@@ -168,13 +180,39 @@ module JsDuck
168
180
  }
169
181
  end
170
182
 
183
+ def create_css_var(docs, code)
184
+ doc_map = build_doc_map(docs)
185
+ return {
186
+ :tagname => :css_var,
187
+ :name => detect_name(:css_var, doc_map, code),
188
+ :member => detect_member(doc_map),
189
+ :type => detect_type(:css_var, doc_map, code),
190
+ :doc => detect_doc(docs),
191
+ :private => !!doc_map[:private],
192
+ :static => !!doc_map[:static],
193
+ }
194
+ end
195
+
196
+ def create_css_mixin(docs, code)
197
+ doc_map = build_doc_map(docs)
198
+ return {
199
+ :tagname => :css_mixin,
200
+ :name => detect_name(:css_mixin, doc_map, code),
201
+ :member => detect_member(doc_map),
202
+ :doc => detect_doc(docs),
203
+ :params => detect_params(docs, code),
204
+ :private => !!doc_map[:private],
205
+ :static => !!doc_map[:static],
206
+ }
207
+ end
208
+
171
209
  def detect_name(tagname, doc_map, code, name_type = :last_name)
172
210
  main_tag = doc_map[tagname] ? doc_map[tagname].first : {}
173
211
  if main_tag[:name]
174
212
  main_tag[:name]
175
213
  elsif doc_map[:constructor]
176
214
  "constructor"
177
- elsif code[:type] == :function
215
+ elsif code[:type] == :function || code[:type] == :css_mixin
178
216
  code[:name]
179
217
  elsif code[:type] == :assignment
180
218
  name_type == :full_name ? code[:left].join(".") : code[:left].last
@@ -224,9 +262,12 @@ module JsDuck
224
262
  end
225
263
  end
226
264
 
227
- def detect_mixins(doc_map, code)
228
- if code[:type] == :ext_define && code[:mixins]
229
- code[:mixins]
265
+ # for detecting mixins and alternateClassNames
266
+ def detect_list(type, doc_map, code)
267
+ if doc_map[type]
268
+ doc_map[type].map {|d| d[type] }.flatten
269
+ elsif code[:type] == :ext_define && code[type]
270
+ code[type]
230
271
  else
231
272
  []
232
273
  end
@@ -240,6 +281,10 @@ module JsDuck
240
281
  doc_map[:author] ? doc_map[:author].first[:name] : nil
241
282
  end
242
283
 
284
+ def detect_docauthor(doc_map)
285
+ doc_map[:docauthor] ? doc_map[:docauthor].first[:name] : nil
286
+ end
287
+
243
288
  def detect_params(docs, code)
244
289
  implicit = detect_implicit_params(code)
245
290
  explicit = detect_explicit_params(docs)
@@ -5,19 +5,15 @@ require 'jsduck/long_params'
5
5
  module JsDuck
6
6
 
7
7
  class MethodTable < Table
8
- def initialize(cls, cache={})
9
- super(cls, cache)
8
+ def initialize(cls, formatter, cache={})
9
+ super(cls, formatter, cache)
10
10
  @type = :method
11
11
  @id = @cls.full_name + "-methods"
12
12
  @title = "Public Methods"
13
13
  @column_title = "Method"
14
14
  @row_class = "method-row"
15
15
  @short_params = ShortParams.new
16
- @long_params = LongParams.new(@cls)
17
- @formatter = DocFormatter.new()
18
- @formatter.context = @cls.full_name
19
- @formatter.css_class = 'docClass'
20
- @formatter.url_template = 'output/%cls%.html'
16
+ @long_params = LongParams.new(@formatter)
21
17
  end
22
18
 
23
19
  def signature_suffix(item)
@@ -36,7 +32,7 @@ module JsDuck
36
32
  end
37
33
 
38
34
  def render_return(item)
39
- type = item[:return][:type]
35
+ type = @formatter.replace(item[:return][:type])
40
36
  doc = @formatter.format(item[:return][:doc])
41
37
  if type == "void" && doc.length == 0
42
38
  "<ul><li>void</li></ul>"
data/lib/jsduck/page.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'cgi'
1
2
  require 'jsduck/doc_formatter'
2
3
  require 'jsduck/inheritance_tree'
3
4
  require 'jsduck/cfg_table'
@@ -21,8 +22,16 @@ module JsDuck
21
22
  @cache = cache
22
23
  @formatter = DocFormatter.new
23
24
  @formatter.context = cls.full_name
24
- @formatter.css_class = 'docClass'
25
- @formatter.url_template = 'output/%cls%.html'
25
+ @formatter.link_tpl = '<a href="output/%c.html%M" rel="%c%M" class="docClass">%a</a>'
26
+ @formatter.relations = relations
27
+ end
28
+
29
+ # Setters to override link and image templates
30
+ def link_tpl=(tpl)
31
+ @formatter.link_tpl = tpl
32
+ end
33
+ def img_tpl=(tpl)
34
+ @formatter.img_tpl = tpl
26
35
  end
27
36
 
28
37
  def to_html
@@ -33,17 +42,17 @@ module JsDuck
33
42
  abstract,
34
43
  description,
35
44
  "<div class='hr'></div>",
36
- CfgTable.new(@cls, @cache).to_html,
37
- PropertyTable.new(@cls, @cache).to_html,
38
- MethodTable.new(@cls, @cache).to_html,
39
- EventTable.new(@cls, @cache).to_html,
45
+ CfgTable.new(@cls, @formatter, @cache).to_html,
46
+ PropertyTable.new(@cls, @formatter, @cache).to_html,
47
+ MethodTable.new(@cls, @formatter, @cache).to_html,
48
+ EventTable.new(@cls, @formatter, @cache).to_html,
40
49
  "</div>",
41
50
  ].join("\n")
42
51
  end
43
52
 
44
53
  # only render the tree if class has at least one ancestor
45
54
  def inheritance_tree
46
- @cls.parent ? InheritanceTree.new(@cls).to_html : ""
55
+ @cls.parent ? InheritanceTree.new(@cls, @formatter).to_html : ""
47
56
  end
48
57
 
49
58
  def heading
@@ -53,13 +62,15 @@ module JsDuck
53
62
  def abstract
54
63
  [
55
64
  "<table cellspacing='0'>",
65
+ boolean_row("Alternate names:", @cls[:alternateClassNames].join(", ")),
56
66
  row("Extends:", extends_link),
57
67
  classes_row("Mixins:", @cls.mixins),
58
- row("Defind In:", file_link),
68
+ row("Defined In:", file_link),
59
69
  classes_row("Subclasses:", @relations.subclasses(@cls)),
60
70
  classes_row("Mixed into:", @relations.mixed_into(@cls)),
61
71
  boolean_row("xtype:", @cls[:xtype]),
62
72
  boolean_row("Author:", @cls[:author]),
73
+ boolean_row("Author of docs:", @cls[:docauthor]),
63
74
  "</table>",
64
75
  ].join("\n")
65
76
  end
@@ -92,7 +103,7 @@ module JsDuck
92
103
  end
93
104
 
94
105
  def boolean_row(label, item)
95
- item ? row(label, item) : ""
106
+ (item && item != "") ? row(label, CGI.escapeHTML(item)) : ""
96
107
  end
97
108
 
98
109
  def row(label, info)
@@ -3,8 +3,8 @@ require 'jsduck/table'
3
3
  module JsDuck
4
4
 
5
5
  class PropertyTable < Table
6
- def initialize(cls, cache={})
7
- super(cls, cache)
6
+ def initialize(cls, formatter, cache={})
7
+ super(cls, formatter, cache)
8
8
  @type = :property
9
9
  @id = @cls.full_name + "-props"
10
10
  @title = "Public Properties"
@@ -34,6 +34,10 @@ module JsDuck
34
34
  @lookup[classname]
35
35
  end
36
36
 
37
+ def each(&block)
38
+ @classes.each(&block)
39
+ end
40
+
37
41
  def reg_subclasses(cls)
38
42
  if !cls.parent
39
43
  # do nothing
@@ -0,0 +1,101 @@
1
+ require 'jsduck/js_parser'
2
+ require 'jsduck/css_parser'
3
+ require 'jsduck/merger'
4
+ require "cgi"
5
+
6
+ module JsDuck
7
+
8
+ # Represents one JavaScript or CSS source file.
9
+ #
10
+ # The filename parameter determines whether it's parsed as
11
+ # JavaScript (the default) or CSS.
12
+ class SourceFile
13
+ attr_reader :filename
14
+ attr_reader :contents
15
+ attr_reader :docs
16
+ attr_reader :html_filename
17
+
18
+ def initialize(contents, filename="")
19
+ @contents = contents
20
+ @filename = filename
21
+ @html_filename = ""
22
+ @links = {}
23
+
24
+ merger = Merger.new
25
+ @docs = parse.map do |docset|
26
+ link(docset[:linenr], merger.merge(docset[:comment], docset[:code]))
27
+ end
28
+ end
29
+
30
+ # loops through each doc-object in file
31
+ def each(&block)
32
+ @docs.each(&block)
33
+ end
34
+
35
+ # Sets the html filename of this file,
36
+ # updating also all doc-objects linking this file
37
+ def html_filename=(html_filename)
38
+ @html_filename = html_filename
39
+ @links.each_value do |line|
40
+ line.each do |doc|
41
+ doc[:html_filename] = @html_filename
42
+ doc[:href] = @html_filename + "#" + id(doc)
43
+ end
44
+ end
45
+ end
46
+
47
+ # Returns source code as HTML with lines starting doc-comments specially marked.
48
+ def to_html
49
+ linenr = 0
50
+ return @contents.lines.map do |line|
51
+ linenr += 1;
52
+ line = CGI.escapeHTML(line)
53
+ # wrap the line in as many spans as there are links to this line number.
54
+ if @links[linenr]
55
+ @links[linenr].each do |doc|
56
+ line = "<span id='#{id(doc)}'>#{line}</span>"
57
+ end
58
+ end
59
+ line
60
+ end.join()
61
+ end
62
+
63
+ def id(doc)
64
+ if doc[:tagname] == :class
65
+ doc[:name].gsub(/\./, '-')
66
+ else
67
+ # when creation of global class is skipped,
68
+ # this member property can be nil.
69
+ (doc[:member] || "global").gsub(/\./, '-') + "-" + doc[:tagname].to_s + "-" + doc[:name]
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ # Parses the file depending on filename as JS or CSS
76
+ def parse
77
+ if @filename =~ /\.s?css$/
78
+ CssParser.new(@contents).parse
79
+ else
80
+ JsParser.new(@contents).parse
81
+ end
82
+ end
83
+
84
+ # Creates two-way link between sourcefile and doc-object.
85
+ # If doc-object is class, links also the contained cfgs and constructor.
86
+ # Returns the modified doc-object after done.
87
+ def link(linenr, doc)
88
+ @links[linenr] = [] unless @links[linenr]
89
+ @links[linenr] << doc
90
+ doc[:filename] = @filename
91
+ doc[:linenr] = linenr
92
+ if doc[:tagname] == :class
93
+ doc[:cfg].each {|cfg| link(linenr, cfg) }
94
+ doc[:method].each {|method| link(linenr, method) }
95
+ end
96
+ doc
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -1,28 +1,25 @@
1
- require "cgi"
2
-
3
1
  module JsDuck
4
2
 
5
- # Formats JavaScript source into HTML page. Inside the HTML every
6
- # source code line will be marked with ID, so that it can be linked
7
- # from documentation.
8
- class SourceFormatter
3
+ # Writes HTML JavaScript/CSS source into HTML file.
4
+ class SourceWriter
9
5
 
10
6
  # Initializes SourceFormatter to the directory where
11
7
  # HTML-formatted source files will be placed.
12
8
  #
13
- # formatter can be either :format_page or :format_pre; with the
14
- # first one the whole HTML page is created, otherwise just a
15
- # contents of <pre> element.
16
- def initialize(output_dir, formatter = :format_page)
9
+ # Wrapper can be either :page or nil; with the first one the whole
10
+ # HTML page is created, otherwise source is left as is.
11
+ def initialize(output_dir, wrapper = :page)
17
12
  @output_dir = output_dir
18
- @formatter = formatter
13
+ @wrapper = wrapper
19
14
  end
20
15
 
21
- # Converts source to HTML and writes into file in output
22
- # directory. It returns the name of the file that it wrote.
16
+ # Writes HTML into file in output directory. It returns the name
17
+ # of the file that it wrote.
23
18
  def write(source, filename)
24
19
  fname = uniq_html_filename(filename)
25
- File.open(fname, 'w') {|f| f.write(self.send(@formatter, source)) }
20
+ File.open(fname, 'w') do |f|
21
+ f.write(@wrapper ? wrap_page(source) : source)
22
+ end
26
23
  fname
27
24
  end
28
25
 
@@ -40,8 +37,8 @@ module JsDuck
40
37
  @output_dir + "/" + File.basename(filename, ".js") + (nr > 0 ? nr.to_s : "") + ".html"
41
38
  end
42
39
 
43
- # Returns full source for HTML page
44
- def format_page(source)
40
+ # Returns source wrapped inside HTML page
41
+ def wrap_page(source)
45
42
  return <<-EOHTML
46
43
  <!DOCTYPE html>
47
44
  <html>
@@ -60,22 +57,12 @@ module JsDuck
60
57
  </script>
61
58
  </head>
62
59
  <body onload="prettyPrint(); highlight();">
63
- <pre class="prettyprint lang-js">#{format_pre(source)}</pre>
60
+ <pre class="prettyprint lang-js">#{source}</pre>
64
61
  </body>
65
62
  </html>
66
63
  EOHTML
67
64
  end
68
65
 
69
- # Formats the contents of <pre>, wrapping each source code line
70
- # inside <span>.
71
- def format_pre(source)
72
- i = 0
73
- return source.lines.collect do |line|
74
- i += 1
75
- "<span id='line-#{i}'>#{CGI.escapeHTML(line)}</span>"
76
- end.join()
77
- end
78
-
79
66
  end
80
67
 
81
68
  end