jsduck 4.10.4 → 5.0.0.beta01

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.
Files changed (183) hide show
  1. data/.travis.yml +0 -1
  2. data/README.md +32 -6
  3. data/Rakefile +10 -18
  4. data/bin/compare +5 -5
  5. data/bin/jsduck +2 -3
  6. data/jsduck.gemspec +3 -4
  7. data/lib/jsduck/aggregator.rb +21 -80
  8. data/lib/jsduck/app.rb +7 -14
  9. data/lib/jsduck/app_data.rb +4 -5
  10. data/lib/jsduck/assets.rb +4 -7
  11. data/lib/jsduck/base_type.rb +53 -0
  12. data/lib/jsduck/batch_parser.rb +8 -87
  13. data/lib/jsduck/batch_processor.rb +77 -0
  14. data/lib/jsduck/categories/auto.rb +83 -0
  15. data/lib/jsduck/categories/class_name.rb +63 -0
  16. data/lib/jsduck/categories/factory.rb +113 -0
  17. data/lib/jsduck/categories/file.rb +75 -0
  18. data/lib/jsduck/class.rb +3 -9
  19. data/lib/jsduck/class_doc_expander.rb +1 -1
  20. data/lib/jsduck/css/lexer.rb +203 -0
  21. data/lib/jsduck/css/parser.rb +121 -0
  22. data/lib/jsduck/doc/comment.rb +40 -0
  23. data/lib/jsduck/doc/map.rb +23 -0
  24. data/lib/jsduck/doc/parser.rb +128 -0
  25. data/lib/jsduck/doc/processor.rb +52 -0
  26. data/lib/jsduck/doc/scanner.rb +76 -0
  27. data/lib/jsduck/doc/standard_tag_parser.rb +154 -0
  28. data/lib/jsduck/doc/subproperties.rb +64 -0
  29. data/lib/jsduck/docs_code_comparer.rb +31 -0
  30. data/lib/jsduck/export_writer.rb +2 -2
  31. data/lib/jsduck/exporter/app.rb +16 -4
  32. data/lib/jsduck/exporter/full.rb +2 -2
  33. data/lib/jsduck/format/batch.rb +58 -0
  34. data/lib/jsduck/format/class.rb +62 -0
  35. data/lib/jsduck/format/doc.rb +172 -0
  36. data/lib/jsduck/format/html_stack.rb +109 -0
  37. data/lib/jsduck/format/shortener.rb +55 -0
  38. data/lib/jsduck/format/subproperties.rb +64 -0
  39. data/lib/jsduck/guides.rb +32 -14
  40. data/lib/jsduck/index_html.rb +3 -1
  41. data/lib/jsduck/inline/auto_link.rb +2 -2
  42. data/lib/jsduck/inline/link.rb +4 -3
  43. data/lib/jsduck/inline/link_renderer.rb +2 -2
  44. data/lib/jsduck/inline/video.rb +8 -2
  45. data/lib/jsduck/js/ast.rb +361 -0
  46. data/lib/jsduck/js/esprima.rb +39 -0
  47. data/lib/jsduck/{esprima → js/esprima}/esprima.js +0 -0
  48. data/lib/jsduck/js/evaluator.rb +70 -0
  49. data/lib/jsduck/js/ext_patterns.rb +70 -0
  50. data/lib/jsduck/js/function.rb +206 -0
  51. data/lib/jsduck/js/node.rb +194 -0
  52. data/lib/jsduck/js/node_array.rb +36 -0
  53. data/lib/jsduck/js/parser.rb +223 -0
  54. data/lib/jsduck/js/serializer.rb +263 -0
  55. data/lib/jsduck/js/utils.rb +21 -0
  56. data/lib/jsduck/logger.rb +3 -13
  57. data/lib/jsduck/members_index.rb +3 -4
  58. data/lib/jsduck/merger.rb +25 -145
  59. data/lib/jsduck/options.rb +29 -132
  60. data/lib/jsduck/parser.rb +76 -0
  61. data/lib/jsduck/process/accessors.rb +133 -0
  62. data/lib/jsduck/process/circular_deps.rb +58 -0
  63. data/lib/jsduck/process/enums.rb +91 -0
  64. data/lib/jsduck/process/ext4_events.rb +43 -0
  65. data/lib/jsduck/process/global_members.rb +36 -0
  66. data/lib/jsduck/process/ignored_classes.rb +16 -0
  67. data/lib/jsduck/process/importer.rb +58 -0
  68. data/lib/jsduck/process/inherit_doc.rb +197 -0
  69. data/lib/jsduck/process/lint.rb +135 -0
  70. data/lib/jsduck/process/overrides.rb +99 -0
  71. data/lib/jsduck/process/return_values.rb +72 -0
  72. data/lib/jsduck/process/versions.rb +102 -0
  73. data/lib/jsduck/relations.rb +5 -0
  74. data/lib/jsduck/render/class.rb +144 -0
  75. data/lib/jsduck/render/sidebar.rb +97 -0
  76. data/lib/jsduck/render/signature.rb +94 -0
  77. data/lib/jsduck/render/subproperties.rb +99 -0
  78. data/lib/jsduck/render/tags.rb +38 -0
  79. data/lib/jsduck/search_data.rb +19 -13
  80. data/lib/jsduck/source/file.rb +8 -17
  81. data/lib/jsduck/tag/abstract.rb +4 -7
  82. data/lib/jsduck/tag/accessor.rb +10 -0
  83. data/lib/jsduck/tag/alias.rb +61 -0
  84. data/lib/jsduck/tag/alternate_class_names.rb +17 -0
  85. data/lib/jsduck/tag/aside.rb +28 -31
  86. data/lib/jsduck/tag/author.rb +9 -5
  87. data/lib/jsduck/tag/boolean_tag.rb +24 -0
  88. data/lib/jsduck/tag/cfg.rb +45 -0
  89. data/lib/jsduck/tag/chainable.rb +5 -7
  90. data/lib/jsduck/tag/class.rb +28 -0
  91. data/lib/jsduck/tag/class_list_tag.rb +40 -0
  92. data/lib/jsduck/tag/constructor.rb +24 -0
  93. data/lib/jsduck/tag/css_mixin.rb +17 -0
  94. data/lib/jsduck/tag/css_var.rb +29 -0
  95. data/lib/jsduck/tag/default.rb +31 -0
  96. data/lib/jsduck/tag/deprecated.rb +13 -27
  97. data/lib/jsduck/tag/deprecated_tag.rb +58 -0
  98. data/lib/jsduck/tag/doc.rb +32 -0
  99. data/lib/jsduck/tag/docauthor.rb +4 -5
  100. data/lib/jsduck/tag/enum.rb +70 -0
  101. data/lib/jsduck/tag/event.rb +28 -0
  102. data/lib/jsduck/tag/evented.rb +10 -0
  103. data/lib/jsduck/tag/extends.rb +45 -0
  104. data/lib/jsduck/tag/ftype.rb +18 -0
  105. data/lib/jsduck/tag/hide.rb +4 -11
  106. data/lib/jsduck/tag/ignore.rb +6 -7
  107. data/lib/jsduck/tag/inheritable.rb +10 -0
  108. data/lib/jsduck/tag/inheritdoc.rb +48 -0
  109. data/lib/jsduck/tag/markdown.rb +8 -6
  110. data/lib/jsduck/tag/member.rb +24 -0
  111. data/lib/jsduck/tag/method.rb +35 -0
  112. data/lib/jsduck/tag/mixins.rb +26 -0
  113. data/lib/jsduck/tag/name.rb +36 -0
  114. data/lib/jsduck/tag/new.rb +13 -27
  115. data/lib/jsduck/tag/override.rb +37 -0
  116. data/lib/jsduck/tag/overrides.rb +29 -0
  117. data/lib/jsduck/tag/param.rb +87 -0
  118. data/lib/jsduck/tag/preventable.rb +19 -10
  119. data/lib/jsduck/tag/private.rb +28 -13
  120. data/lib/jsduck/tag/property.rb +39 -0
  121. data/lib/jsduck/tag/protected.rb +5 -7
  122. data/lib/jsduck/tag/ptype.rb +18 -0
  123. data/lib/jsduck/tag/readonly.rb +4 -7
  124. data/lib/jsduck/tag/removed.rb +21 -29
  125. data/lib/jsduck/tag/required.rb +11 -9
  126. data/lib/jsduck/tag/requires.rb +12 -0
  127. data/lib/jsduck/tag/return.rb +47 -0
  128. data/lib/jsduck/tag/since.rb +19 -11
  129. data/lib/jsduck/tag/singleton.rb +15 -0
  130. data/lib/jsduck/tag/static.rb +5 -7
  131. data/lib/jsduck/tag/subproperties.rb +23 -0
  132. data/lib/jsduck/tag/tag.rb +208 -0
  133. data/lib/jsduck/tag/template.rb +14 -9
  134. data/lib/jsduck/tag/throws.rb +38 -0
  135. data/lib/jsduck/tag/type.rb +48 -0
  136. data/lib/jsduck/tag/uses.rb +12 -0
  137. data/lib/jsduck/tag/xtype.rb +30 -0
  138. data/lib/jsduck/tag_loader.rb +39 -0
  139. data/lib/jsduck/tag_registry.rb +189 -0
  140. data/lib/jsduck/type_parser.rb +3 -3
  141. data/lib/jsduck/web_writer.rb +2 -2
  142. data/lib/jsduck/welcome.rb +1 -1
  143. metadata +578 -538
  144. data/lib/jsduck/accessors.rb +0 -136
  145. data/lib/jsduck/ast.rb +0 -524
  146. data/lib/jsduck/auto_categories.rb +0 -80
  147. data/lib/jsduck/batch_formatter.rb +0 -60
  148. data/lib/jsduck/categories.rb +0 -73
  149. data/lib/jsduck/categories_class_name.rb +0 -37
  150. data/lib/jsduck/circular_deps.rb +0 -56
  151. data/lib/jsduck/class_formatter.rb +0 -102
  152. data/lib/jsduck/columns.rb +0 -56
  153. data/lib/jsduck/css_lexer.rb +0 -201
  154. data/lib/jsduck/css_parser.rb +0 -119
  155. data/lib/jsduck/doc_ast.rb +0 -319
  156. data/lib/jsduck/doc_formatter.rb +0 -142
  157. data/lib/jsduck/doc_parser.rb +0 -611
  158. data/lib/jsduck/doc_type.rb +0 -59
  159. data/lib/jsduck/enum.rb +0 -73
  160. data/lib/jsduck/esprima.rb +0 -51
  161. data/lib/jsduck/evaluator.rb +0 -69
  162. data/lib/jsduck/ext_patterns.rb +0 -58
  163. data/lib/jsduck/file_categories.rb +0 -76
  164. data/lib/jsduck/function_ast.rb +0 -206
  165. data/lib/jsduck/guide_anchors.rb +0 -32
  166. data/lib/jsduck/guide_toc.rb +0 -49
  167. data/lib/jsduck/html_stack.rb +0 -105
  168. data/lib/jsduck/importer.rb +0 -121
  169. data/lib/jsduck/inherit_doc.rb +0 -193
  170. data/lib/jsduck/js_parser.rb +0 -221
  171. data/lib/jsduck/lint.rb +0 -133
  172. data/lib/jsduck/meta_tag.rb +0 -88
  173. data/lib/jsduck/meta_tag_loader.rb +0 -67
  174. data/lib/jsduck/meta_tag_registry.rb +0 -111
  175. data/lib/jsduck/meta_tag_renderer.rb +0 -34
  176. data/lib/jsduck/news.rb +0 -128
  177. data/lib/jsduck/override.rb +0 -87
  178. data/lib/jsduck/renderer.rb +0 -361
  179. data/lib/jsduck/return_values.rb +0 -72
  180. data/lib/jsduck/serializer.rb +0 -262
  181. data/lib/jsduck/shortener.rb +0 -58
  182. data/lib/jsduck/signature_renderer.rb +0 -91
  183. data/lib/jsduck/source/file_parser.rb +0 -72
@@ -0,0 +1,75 @@
1
+ require 'jsduck/logger'
2
+ require 'jsduck/util/json'
3
+
4
+ module JsDuck
5
+ module Categories
6
+
7
+ # Reads categories info from config file
8
+ class File
9
+ def initialize(filename, relations)
10
+ @filename = filename
11
+ @relations = relations
12
+ end
13
+
14
+ # Parses categories in JSON file
15
+ def generate
16
+ @categories = Util::Json.read(@filename)
17
+
18
+ # Don't crash if old syntax is used.
19
+ if @categories.is_a?(Hash) && @categories["categories"]
20
+ Logger.warn(nil, 'Update categories file to contain just the array inside {"categories": [...]}', @filename)
21
+ @categories = @categories["categories"]
22
+ end
23
+
24
+ # Perform expansion on all class names containing * wildcard
25
+ @categories.each do |cat|
26
+ cat["groups"].each do |group|
27
+ group["classes"] = group["classes"].map do |name|
28
+ expand(name)
29
+ end.flatten
30
+ end
31
+ end
32
+
33
+ validate
34
+
35
+ @categories
36
+ end
37
+
38
+ # Expands class name like 'Foo.*' into multiple class names.
39
+ def expand(name)
40
+ re = Regexp.new("^" + name.split(/\*/, -1).map {|part| Regexp.escape(part) }.join('.*') + "$")
41
+
42
+ classes = @relations.to_a.find_all do |cls|
43
+ re =~ cls[:name] && !cls[:private] && !cls[:deprecated]
44
+ end.map {|cls| cls[:name] }.sort
45
+
46
+ if classes.length == 0
47
+ Logger.warn(:cat_no_match, "No class found matching a pattern '#{name}' in categories file", @filename)
48
+ end
49
+ classes
50
+ end
51
+
52
+ # Prints warnings for missing classes in categories file
53
+ def validate
54
+ # Build a map of all classes listed in categories
55
+ listed_classes = {}
56
+ @categories.each do |cat|
57
+ cat["groups"].each do |group|
58
+ group["classes"].each do |cls_name|
59
+ listed_classes[cls_name] = true
60
+ end
61
+ end
62
+ end
63
+
64
+ # Check that each existing non-private & non-deprecated class is listed
65
+ @relations.each do |cls|
66
+ unless listed_classes[cls[:name]] || cls[:private] || cls[:deprecated]
67
+ Logger.warn(:cat_class_missing, "Class '#{cls[:name]}' not found in categories file", @filename)
68
+ end
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+ end
data/lib/jsduck/class.rb CHANGED
@@ -162,9 +162,9 @@ module JsDuck
162
162
  end
163
163
 
164
164
  if query[:static] == true
165
- ms = ms.find_all {|m| m[:meta] && m[:meta][:static] }
165
+ ms = ms.find_all {|m| m[:static] }
166
166
  elsif query[:static] == false
167
- ms = ms.reject {|m| m[:meta] && m[:meta][:static] }
167
+ ms = ms.reject {|m| m[:static] }
168
168
  end
169
169
 
170
170
  ms
@@ -190,13 +190,7 @@ module JsDuck
190
190
  def self.member_id(m)
191
191
  # Sanitize $ in member names with something safer
192
192
  name = m[:name].gsub(/\$/, 'S-')
193
- "#{m[:meta][:static] ? 'static-' : ''}#{m[:tagname]}-#{name}"
194
- end
195
-
196
- # Loops through all available member types,
197
- # passing the tagname of the member to the block.
198
- def self.each_member_type(&block)
199
- [:cfg, :property, :method, :event, :css_var, :css_mixin].each(&block)
193
+ "#{m[:static] ? 'static-' : ''}#{m[:tagname]}-#{name}"
200
194
  end
201
195
 
202
196
  # True if the given member is a constructor method
@@ -55,7 +55,7 @@ module JsDuck
55
55
  end
56
56
  end
57
57
 
58
- if tagname == :alias
58
+ if tagname == :aliases
59
59
  # For backwards compatibility allow @xtype after @constructor
60
60
  groups[:class] << tag
61
61
  elsif group_name == :cfg
@@ -0,0 +1,203 @@
1
+ require 'strscan'
2
+
3
+ module JsDuck
4
+ module Css
5
+
6
+ # Tokenizes CSS or SCSS code into lexical tokens.
7
+ #
8
+ # Each token has a type and value.
9
+ # Types and possible values for them are as follows:
10
+ #
11
+ # - :number -- "25.8"
12
+ # - :percentage -- "25%"
13
+ # - :dimension -- "2em"
14
+ # - :string -- '"Hello world"'
15
+ # - :ident -- "foo-bar"
16
+ # - :at_keyword -- "@mixin"
17
+ # - :hash -- "#00FF66"
18
+ # - :delim -- "{"
19
+ # - :doc_comment -- "/** My comment */"
20
+ #
21
+ # Notice that doc-comments are recognized as tokens while normal
22
+ # comments are ignored just as whitespace.
23
+ #
24
+ class Lexer
25
+ # Initializes lexer with input string.
26
+ def initialize(input)
27
+ @input = StringScanner.new(input)
28
+ @buffer = []
29
+ end
30
+
31
+ # Tests if given pattern matches the tokens that follow at current
32
+ # position.
33
+ #
34
+ # Takes list of strings and symbols. Symbols are compared to
35
+ # token type, while strings to token value. For example:
36
+ #
37
+ # look(:ident, ":", :dimension)
38
+ #
39
+ def look(*tokens)
40
+ buffer_tokens(tokens.length)
41
+ i = 0
42
+ tokens.all? do |t|
43
+ tok = @buffer[i]
44
+ i += 1
45
+ if !tok
46
+ false
47
+ elsif t.instance_of?(Symbol)
48
+ tok[:type] == t
49
+ else
50
+ tok[:value] == t
51
+ end
52
+ end
53
+ end
54
+
55
+ # Returns the value of next token, moving the current token cursor
56
+ # also to next token.
57
+ #
58
+ # When full=true, returns full token as hash like so:
59
+ #
60
+ # {:type => :ident, :value => "foo"}
61
+ #
62
+ # For doc-comments the full token also contains the field :linenr,
63
+ # pointing to the line where the doc-comment began.
64
+ #
65
+ def next(full=false)
66
+ buffer_tokens(1)
67
+ tok = @buffer.shift
68
+ # advance the scanpointer to the position after this token
69
+ @input.pos = tok[:pos]
70
+ full ? tok : tok[:value]
71
+ end
72
+
73
+ # True when no more tokens.
74
+ def empty?
75
+ buffer_tokens(1)
76
+ return !@buffer.first
77
+ end
78
+
79
+ # Ensures next n tokens are read in buffer
80
+ #
81
+ # At the end of buffering the initial position scanpointer is
82
+ # restored. Only the #next method will advance the scanpointer in
83
+ # a way that's visible outside this class.
84
+ def buffer_tokens(n)
85
+ prev_pos = @input.pos
86
+ @input.pos = @buffer.last[:pos] if @buffer.last
87
+ (n - @buffer.length).times do
88
+ @previous_token = tok = next_token
89
+ if tok
90
+ # remember scanpointer position after each token
91
+ tok[:pos] = @input.pos
92
+ @buffer << tok
93
+ end
94
+ end
95
+ @input.pos = prev_pos
96
+ end
97
+
98
+ # Parses out next token from input stream.
99
+ def next_token
100
+ while !@input.eos? do
101
+ skip_white
102
+ if @input.check(IDENT)
103
+ return {
104
+ :type => :ident,
105
+ :value => @input.scan(IDENT)
106
+ }
107
+ elsif @input.check(/'/)
108
+ return {
109
+ :type => :string,
110
+ :value => @input.scan(/'([^'\\]|\\.)*('|\z)/m)
111
+ }
112
+ elsif @input.check(/"/)
113
+ return {
114
+ :type => :string,
115
+ :value => @input.scan(/"([^"\\]|\\.)*("|\z)/m)
116
+ }
117
+ elsif @input.check(/\//)
118
+ # Several things begin with dash:
119
+ # - comments, regexes, division-operators
120
+ if @input.check(/\/\*\*[^\/]/)
121
+ return {
122
+ :type => :doc_comment,
123
+ # Calculate current line number, starting with 1
124
+ :linenr => @input.string[0...@input.pos].count("\n") + 1,
125
+ :value => @input.scan_until(/\*\/|\z/).sub(/\A\/\*\*/, "").sub(/\*\/\z/, "")
126
+ }
127
+ elsif @input.check(/\/\*/)
128
+ # skip multiline comment
129
+ @input.scan_until(/\*\/|\z/)
130
+ elsif @input.check(/\/\//)
131
+ # skip line comment
132
+ @input.scan_until(/\n|\z/)
133
+ else
134
+ return {
135
+ :type => :operator,
136
+ :value => @input.scan(/\//)
137
+ }
138
+ end
139
+ elsif @input.check(NUM)
140
+ nr = @input.scan(NUM)
141
+ if @input.check(/%/)
142
+ return {
143
+ :type => :percentage,
144
+ :value => nr + @input.scan(/%/)
145
+ }
146
+ elsif @input.check(IDENT)
147
+ return {
148
+ :type => :dimension,
149
+ :value => nr + @input.scan(IDENT)
150
+ }
151
+ else
152
+ return {
153
+ :type => :number,
154
+ :value => nr
155
+ }
156
+ end
157
+ elsif @input.check(/@/)
158
+ return maybe(:at_keyword, /@/, IDENT)
159
+ elsif @input.check(/#/)
160
+ return maybe(:hash, /#/, NAME)
161
+ elsif @input.check(/\$/)
162
+ return maybe(:var, /\$/, IDENT)
163
+ elsif @input.check(/./)
164
+ return {
165
+ :type => :delim,
166
+ :value => @input.scan(/./)
167
+ }
168
+ end
169
+ end
170
+ end
171
+
172
+ # Returns token of given type when both regexes match.
173
+ # Otherwise returns :delim token with value of first regex match.
174
+ # First regex must always match.
175
+ def maybe(token_type, before_re, after_re)
176
+ before = @input.scan(before_re)
177
+ if @input.check(after_re)
178
+ return {
179
+ :type => token_type,
180
+ :value => before + @input.scan(after_re)
181
+ }
182
+ else
183
+ return {
184
+ :type => :delim,
185
+ :value => before
186
+ }
187
+ end
188
+ end
189
+
190
+ def skip_white
191
+ @input.scan(/\s+/)
192
+ end
193
+
194
+ # Simplified token syntax based on:
195
+ # http://www.w3.org/TR/CSS21/syndata.html
196
+ IDENT = /-?[_a-z][_a-z0-9-]*/i
197
+ NAME = /[_a-z0-9-]+/i
198
+ NUM = /[0-9]*\.[0-9]+|[0-9]+/
199
+
200
+ end
201
+
202
+ end
203
+ end
@@ -0,0 +1,121 @@
1
+ require 'jsduck/css/lexer'
2
+
3
+ module JsDuck
4
+ module Css
5
+
6
+ class Parser
7
+ def initialize(input, options = {})
8
+ @lex = Css::Lexer.new(input)
9
+ @docs = []
10
+ end
11
+
12
+ # Parses the whole CSS block and returns same kind of structure
13
+ # that JavaScript parser does.
14
+ def parse
15
+ while !@lex.empty? do
16
+ if look(:doc_comment)
17
+ comment = @lex.next(true)
18
+ @docs << {
19
+ :comment => comment[:value],
20
+ :linenr => comment[:linenr],
21
+ :code => code_block,
22
+ :type => :doc_comment,
23
+ }
24
+ else
25
+ @lex.next
26
+ end
27
+ end
28
+ @docs
29
+ end
30
+
31
+ # <code-block> := <mixin-declaration> | <var-declaration> | <property>
32
+ def code_block
33
+ if look("@mixin")
34
+ mixin_declaration
35
+ elsif look(:var, ":")
36
+ var_declaration
37
+ else
38
+ # Default to property like in Js::Parser.
39
+ {:tagname => :property}
40
+ end
41
+ end
42
+
43
+ # <mixin-declaration> := "@mixin" <ident>
44
+ def mixin_declaration
45
+ match("@mixin")
46
+ return {
47
+ :tagname => :css_mixin,
48
+ :name => look(:ident) ? match(:ident) : nil,
49
+ }
50
+ end
51
+
52
+ # <var-declaration> := <var> ":" <css-value>
53
+ def var_declaration
54
+ name = match(:var)
55
+ match(":")
56
+ value_list = css_value
57
+ return {
58
+ :tagname => :css_var,
59
+ :name => name,
60
+ :default => value_list.map {|v| v[:value] }.join(" "),
61
+ :type => value_type(value_list),
62
+ }
63
+ end
64
+
65
+ # <css-value> := ...anything up to... [ ";" | "}" | "!default" ]
66
+ def css_value
67
+ val = []
68
+ while !look(";") && !look("}") && !look("!", "default")
69
+ val << @lex.next(true)
70
+ end
71
+ val
72
+ end
73
+
74
+ # Determines type of CSS value
75
+ def value_type(val)
76
+ case val[0][:type]
77
+ when :number
78
+ "number"
79
+ when :dimension
80
+ "length"
81
+ when :percentage
82
+ "percentage"
83
+ when :string
84
+ "string"
85
+ when :hash
86
+ "color"
87
+ when :ident
88
+ case val[0][:value]
89
+ when "true", "false"
90
+ return "boolean"
91
+ when "rgb", "rgba", "hsl", "hsla"
92
+ return "color"
93
+ when "black", "silver", "gray", "white", "maroon",
94
+ "red", "purple", "fuchsia", "green", "lime", "olive",
95
+ "yellow", "navy", "blue", "teal", "aqua", "orange"
96
+ return "color"
97
+ when "transparent"
98
+ return "color"
99
+ end
100
+ end
101
+ end
102
+
103
+ # Matches all arguments, returns the value of last match
104
+ # When the whole sequence doesn't match, throws exception
105
+ def match(*args)
106
+ if look(*args)
107
+ last = nil
108
+ args.length.times { last = @lex.next }
109
+ last
110
+ else
111
+ throw "Expected: " + args.join(", ")
112
+ end
113
+ end
114
+
115
+ def look(*args)
116
+ @lex.look(*args)
117
+ end
118
+ end
119
+
120
+ end
121
+ end
@@ -0,0 +1,40 @@
1
+ module JsDuck
2
+ module Doc
3
+
4
+ # A simple helper to extract doc comment contents.
5
+ class Comment
6
+
7
+ # Extracts content inside /** ... */
8
+ def self.purify(input)
9
+ result = []
10
+
11
+ # We can have two types of lines:
12
+ # - those beginning with *
13
+ # - and those without it
14
+ indent = nil
15
+ input.each_line do |line|
16
+ line.chomp!
17
+ if line =~ /\A\s*\*\s?(.*)\z/
18
+ # When comment contains *-lines, switch indent-trimming off
19
+ indent = 0
20
+ result << $1
21
+ elsif line =~ /\A\s*\z/
22
+ # pass-through empty lines
23
+ result << line
24
+ elsif indent == nil && line =~ /\A(\s*)(.*?\z)/
25
+ # When indent not measured, measure it and remember
26
+ indent = $1.length
27
+ result << $2
28
+ else
29
+ # Trim away indent if available
30
+ result << line.sub(/\A\s{0,#{indent||0}}/, "")
31
+ end
32
+ end
33
+
34
+ result.join("\n")
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end