jsduck 4.10.4 → 5.0.0.beta01

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,80 +0,0 @@
1
- module JsDuck
2
-
3
- # Automatically divides all available classes into categories
4
- class AutoCategories
5
- def initialize(relations)
6
- @relations = relations
7
- end
8
-
9
- # Performs the generation
10
- def generate
11
- # list names of all public classes
12
- class_names = @relations.to_a.find_all {|cls| !cls[:private] }.map {|cls| cls[:name] }
13
-
14
- # divide classes into top-level categories by namespace
15
- categories = categorize(class_names)
16
-
17
- # in each category, create sub-categories
18
- categories.each_pair do |ns, classes|
19
- categories[ns] = categorize(classes, 1)
20
- end
21
-
22
- # Turn categories hash into array, sort everything
23
- categories_array = []
24
- categories.each_pair do |ns, groups|
25
- groups_array = []
26
- groups.each_pair do |gns, classes|
27
- groups_array << {
28
- "name" => gns,
29
- "classes" => classes.sort
30
- }
31
- end
32
- groups_array.sort! {|a, b| cat_compare(a, b) }
33
- categories_array << {
34
- "name" => ns,
35
- "groups" => groups_array
36
- }
37
- end
38
- categories_array.sort! {|a, b| cat_compare(a, b) }
39
-
40
- return categories_array
41
- end
42
-
43
- # Divides classes into categories by namespace. Collapses
44
- # categories having only one class into a category "Others..."
45
- def categorize(class_names, level=0)
46
- categories = {}
47
- class_names.each do |name|
48
- ns = name.split(/\./)[level] || name.split(/\./)[0]
49
- categories[ns] = [] unless categories[ns]
50
- categories[ns] << name
51
- end
52
-
53
- globals = []
54
- categories.each_pair do |ns, classes|
55
- if classes.length == 1
56
- globals << classes[0]
57
- categories.delete(ns)
58
- end
59
- end
60
- if globals.length > 0
61
- categories["Others..."] = globals
62
- end
63
-
64
- categories
65
- end
66
-
67
- # Comparison function for sorting categories that always places
68
- # "Others..." category at the end.
69
- def cat_compare(a, b)
70
- if a["name"] == "Others..."
71
- 1
72
- elsif b["name"] == "Others..."
73
- -1
74
- else
75
- a["name"] <=> b["name"]
76
- end
77
- end
78
- end
79
-
80
- end
@@ -1,60 +0,0 @@
1
- require 'jsduck/util/parallel'
2
- require 'jsduck/class_formatter'
3
- require 'jsduck/doc_formatter'
4
- require 'jsduck/img/dir_set'
5
- require 'jsduck/logger'
6
-
7
- module JsDuck
8
-
9
- # Performs the formatting of the doc-object of all classes.
10
- class BatchFormatter
11
-
12
- # Formats all classes.
13
- # Also registers found images in assets.
14
- def self.format_all!(relations, assets, opts)
15
- # Format all doc-objects in parallel
16
- formatted_classes = Util::Parallel.map(relations.classes) do |cls|
17
-
18
- files = cls[:files].map {|f| f[:filename] }.join(" ")
19
- Logger.log("Markdown formatting #{cls[:name]}", files)
20
-
21
- formatter = create_class_formatter(relations, opts)
22
- begin
23
- {
24
- :doc => formatter.format(cls.internal_doc),
25
- :images => formatter.images.all_used
26
- }
27
- rescue
28
- Logger.fatal_backtrace("Error while formatting #{cls[:name]} #{files}", $!)
29
- exit(1)
30
- end
31
- end
32
-
33
- # Then merge the data back to classes sequentially
34
- formatted_classes.each do |cls|
35
- relations[cls[:doc][:name]].internal_doc = cls[:doc]
36
- # Perform lookup of all the images again. We're really doing
37
- # this work twice now, but as we usually don't have excessive
38
- # amounts of images, the performance penalty should be minimal.
39
- cls[:images].each {|img| assets.images.get(img[:filename]) }
40
- end
41
-
42
- # Print warnings for unused images
43
- assets.images.report_unused
44
- end
45
-
46
- # Factory method to create new ClassFormatter instances.
47
- def self.create_class_formatter(relations, opts)
48
- doc_formatter = DocFormatter.new(relations, opts)
49
- doc_formatter.images = Img::DirSet.new(opts.images, "images")
50
-
51
- class_formatter = ClassFormatter.new(relations, doc_formatter)
52
- # Don't format types when exporting
53
- class_formatter.include_types = !opts.export
54
-
55
- class_formatter
56
- end
57
-
58
- end
59
-
60
- end
@@ -1,73 +0,0 @@
1
- require 'jsduck/logger'
2
- require 'jsduck/file_categories'
3
- require 'jsduck/auto_categories'
4
- require 'jsduck/categories_class_name'
5
- require 'jsduck/columns'
6
-
7
- module JsDuck
8
-
9
- # Reads in categories and outputs them as HTML div
10
- class Categories
11
- def self.create(filename, doc_formatter, relations)
12
- if filename
13
- categories = FileCategories.new(filename, relations)
14
- else
15
- categories = AutoCategories.new(relations)
16
- end
17
- Categories.new(categories.generate, doc_formatter, relations)
18
- end
19
-
20
- def initialize(categories, doc_formatter, relations={})
21
- @categories = categories
22
- @class_name = CategoriesClassName.new(doc_formatter, relations)
23
- @columns = Columns.new("classes")
24
- end
25
-
26
- # Returns HTML listing of classes divided into categories
27
- def to_html(style="")
28
- html = @categories.map do |category|
29
- [
30
- "<div class='section'>",
31
- "<h1>#{category['name']}</h1>",
32
- render_columns(category['groups']),
33
- "<div style='clear:both'></div>",
34
- "</div>",
35
- ]
36
- end.flatten.join("\n")
37
-
38
- return <<-EOHTML
39
- <div id='categories-content' style='#{style}'>
40
- #{html}
41
- </div>
42
- EOHTML
43
- end
44
-
45
- private
46
-
47
- def render_columns(groups)
48
- align = ["left-column", "middle-column", "right-column"]
49
- i = -1
50
- return @columns.split(groups, 3).map do |col|
51
- i += 1
52
- [
53
- "<div class='#{align[i]}'>",
54
- render_groups(col),
55
- "</div>",
56
- ]
57
- end
58
- end
59
-
60
- def render_groups(groups)
61
- return groups.map do |g|
62
- [
63
- "<h3>#{g['name']}</h3>",
64
- "<ul class='links'>",
65
- g["classes"].map {|cls| "<li>" + @class_name.render(cls) + "</li>" },
66
- "</ul>",
67
- ]
68
- end
69
- end
70
-
71
- end
72
-
73
- end
@@ -1,37 +0,0 @@
1
- module JsDuck
2
-
3
- # Renders class names for class categories page.
4
- class CategoriesClassName
5
- def initialize(doc_formatter, relations={})
6
- @doc_formatter = doc_formatter
7
- @relations = relations
8
- end
9
-
10
- # Renders the class name as a link or plain text.
11
- #
12
- # For new classes appends a star behind class name. For classes
13
- # with new members appends list n small stars behind class name
14
- # (reflecting the number of new members).
15
- def render(name)
16
- cls = @relations[name]
17
- if cls
18
- @doc_formatter.link(name, nil, name) + render_new_label(cls)
19
- else
20
- name
21
- end
22
- end
23
-
24
- private
25
-
26
- # Adds small star to new classes in the current version.
27
- def render_new_label(cls)
28
- if cls[:meta][:new]
29
- "&nbsp;<span class='new-class' title='New class'>&#9733;</span>"
30
- else
31
- ""
32
- end
33
- end
34
-
35
- end
36
-
37
- end
@@ -1,56 +0,0 @@
1
- require 'jsduck/logger'
2
-
3
- module JsDuck
4
-
5
- # Checks for circular dependencies
6
- class CircularDeps
7
- def initialize(classes)
8
- @classes = classes
9
- end
10
-
11
- # Checks all classes for circular dependencies.
12
- #
13
- # When found, exits with a fatal error message.
14
- def check_all
15
- @classes.each do |cls|
16
- if chain = check(cls)
17
- Logger.fatal("Class #{cls[:name]} has a circular dependency: #{chain}")
18
- exit 1
19
- end
20
- end
21
- end
22
-
23
- # Checks class for circular dependencies.
24
- #
25
- # When all OK, returns false.
26
- #
27
- # When circular dependencies found returns a string describing the
28
- # problematic dependency chain e.g. "Foo extends Bar mixins Foo".
29
- def check(cls, names = [])
30
- names += [cls[:name]]
31
-
32
- if cls.parent && chain = track_circular(" extends ", cls.parent, names)
33
- return chain
34
- end
35
-
36
- cls.mixins.each do |mixin|
37
- if chain = track_circular(" mixins ", mixin, names)
38
- return chain
39
- end
40
- end
41
-
42
- false
43
- end
44
-
45
- def track_circular(type, cls, names)
46
- names += [type]
47
- if names.include?(cls[:name])
48
- (names + [cls[:name]]).join("")
49
- else
50
- check(cls, names)
51
- end
52
- end
53
-
54
- end
55
-
56
- end
@@ -1,102 +0,0 @@
1
- require 'jsduck/type_parser'
2
- require 'jsduck/logger'
3
- require 'jsduck/meta_tag_registry'
4
- require 'jsduck/shortener'
5
- require 'jsduck/util/html'
6
-
7
- module JsDuck
8
-
9
- # Converts :doc properties of class from markdown to HTML, resolves
10
- # @links, and converts type definitions to HTML.
11
- class ClassFormatter
12
- # Set to false to disable HTML-formatting of type definitions.
13
- attr_accessor :include_types
14
-
15
- def initialize(relations, formatter)
16
- @relations = relations
17
- @formatter = formatter
18
- # inject formatter to all meta-tags
19
- MetaTagRegistry.instance.formatter = formatter
20
- @include_types = true
21
- end
22
-
23
- # Runs the formatter on doc object of a class.
24
- # Accessed using Class#internal_doc
25
- def format(cls)
26
- @cls = cls
27
- @formatter.class_context = cls[:name]
28
- @formatter.doc_context = cls[:files][0]
29
- cls[:doc] = @formatter.format(cls[:doc]) if cls[:doc]
30
- # format all members (except hidden ones)
31
- cls[:members] = cls[:members].map {|m| m[:meta][:hide] ? m : format_member(m) }
32
- cls[:html_meta] = format_meta_data(cls)
33
- cls
34
- end
35
-
36
- # Access to the Img::DirSet object inside doc-formatter
37
- def images
38
- @formatter.images
39
- end
40
-
41
- private
42
-
43
- def format_member(m)
44
- @formatter.doc_context = m[:files][0]
45
- m[:doc] = @formatter.format(m[:doc]) if m[:doc]
46
- if expandable?(m) || Shortener.too_long?(m[:doc])
47
- m[:shortDoc] = Shortener.shorten(m[:doc])
48
- end
49
-
50
- # We don't validate and format CSS var and mixin type definitions
51
- is_css_tag = m[:tagname] == :css_var || m[:tagname] == :css_mixin
52
-
53
- m[:html_type] = (@include_types && !is_css_tag) ? format_type(m[:type]) : m[:type] if m[:type]
54
- m[:params] = m[:params].map {|p| format_item(p, is_css_tag) } if m[:params]
55
- m[:return] = format_item(m[:return], is_css_tag) if m[:return]
56
- m[:throws] = m[:throws].map {|t| format_item(t, is_css_tag) } if m[:throws]
57
- m[:properties] = m[:properties].map {|b| format_item(b, is_css_tag) } if m[:properties]
58
- m[:html_meta] = format_meta_data(m)
59
- m
60
- end
61
-
62
- def expandable?(m)
63
- m[:params] || (m[:properties] && m[:properties].length > 0) || m[:default] || m[:meta][:deprecated] || m[:meta][:template]
64
- end
65
-
66
- def format_item(it, is_css_tag)
67
- it[:doc] = @formatter.format(it[:doc]) if it[:doc]
68
- it[:html_type] = (@include_types && !is_css_tag) ? format_type(it[:type]) : it[:type] if it[:type]
69
- it[:properties] = it[:properties].map {|s| format_item(s, is_css_tag) } if it[:properties]
70
- it
71
- end
72
-
73
- def format_type(type)
74
- tp = TypeParser.new(@relations, @formatter)
75
- if tp.parse(type)
76
- tp.out
77
- else
78
- context = @formatter.doc_context
79
- if tp.error == :syntax
80
- Logger.warn(:type_syntax, "Incorrect type syntax #{type}", context[:filename], context[:linenr])
81
- else
82
- Logger.warn(:type_name, "Unknown type #{type}", context[:filename], context[:linenr])
83
- end
84
- Util::HTML.escape(type)
85
- end
86
- end
87
-
88
- def format_meta_data(context)
89
- result = {}
90
- context[:meta].each_pair do |key, value|
91
- if value
92
- tag = MetaTagRegistry.instance[key]
93
- tag.context = context
94
- result[key] = tag.to_html(value)
95
- end
96
- end
97
- result
98
- end
99
-
100
- end
101
-
102
- end
@@ -1,56 +0,0 @@
1
- module JsDuck
2
-
3
- # Splits array of items with subitems into roughly equal size groups.
4
- class Columns
5
- # Initialized with the name of subitems field.
6
- def initialize(subitems_field)
7
- @header_size = 3
8
- @subitems_field = subitems_field
9
- end
10
-
11
- # Splits the array of items into n chunks so that the sum of
12
- # largest chunk is as small as possible.
13
- #
14
- # This is a brute-force implementation - we just try all the
15
- # combinations and choose the best one.
16
- def split(items, n)
17
- if n == 1
18
- [items]
19
- elsif items.length <= n
20
- Array.new(n) {|i| items[i] ? [items[i]] : [] }
21
- else
22
- min_max = nil
23
- min_arr = nil
24
- i = 0
25
- while i <= items.length-n
26
- i += 1
27
- # Try placing 1, 2, 3, ... items to first chunk.
28
- # Calculate the remaining chunks recursively.
29
- cols = [items[0,i]] + split(items[i, items.length], n-1)
30
- max = max_sum(cols)
31
- # Is this the optimal solution so far? Remember it.
32
- if !min_max || max < min_max
33
- min_max = max
34
- min_arr = cols
35
- end
36
- end
37
- min_arr
38
- end
39
- end
40
-
41
- private
42
-
43
- def max_sum(cols)
44
- cols.map {|col| sum(col) }.max
45
- end
46
-
47
- # Finds the total size of items in array
48
- #
49
- # The size of one item is it's number of classes + the space for header
50
- def sum(arr)
51
- arr.reduce(0) {|sum, item| sum + item[@subitems_field].length + @header_size }
52
- end
53
-
54
- end
55
-
56
- end