jsduck 5.0.0.beta01 → 5.0.0.beta2

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 (95) hide show
  1. data/.travis.yml +1 -0
  2. data/README.md +6 -32
  3. data/Rakefile +5 -5
  4. data/bin/jsduck +0 -1
  5. data/js-classes/String.js +3 -5
  6. data/jsduck.gemspec +3 -2
  7. data/lib/jsduck/aggregator.rb +1 -3
  8. data/lib/jsduck/app.rb +2 -2
  9. data/lib/jsduck/categories/file.rb +0 -6
  10. data/lib/jsduck/class.rb +1 -2
  11. data/lib/jsduck/doc/parser.rb +12 -5
  12. data/lib/jsduck/doc/scanner.rb +6 -0
  13. data/lib/jsduck/doc/standard_tag_parser.rb +10 -5
  14. data/lib/jsduck/doc/subproperties.rb +9 -2
  15. data/lib/jsduck/docs_code_comparer.rb +20 -7
  16. data/lib/jsduck/exporter/app.rb +18 -13
  17. data/lib/jsduck/exporter/full.rb +18 -21
  18. data/lib/jsduck/format/doc.rb +0 -1
  19. data/lib/jsduck/format/html_stack.rb +1 -2
  20. data/lib/jsduck/format/subproperties.rb +2 -2
  21. data/lib/jsduck/inline/auto_link.rb +1 -1
  22. data/lib/jsduck/inline/img.rb +1 -1
  23. data/lib/jsduck/inline/link.rb +4 -6
  24. data/lib/jsduck/inline/video.rb +1 -2
  25. data/lib/jsduck/js/ast.rb +1 -1
  26. data/lib/jsduck/js/esprima.rb +24 -9
  27. data/lib/jsduck/logger.rb +50 -12
  28. data/lib/jsduck/members_index.rb +1 -2
  29. data/lib/jsduck/merger.rb +20 -2
  30. data/lib/jsduck/options.rb +125 -24
  31. data/lib/jsduck/process/accessors.rb +21 -8
  32. data/lib/jsduck/process/enums.rb +2 -3
  33. data/lib/jsduck/process/ext4_events.rb +2 -1
  34. data/lib/jsduck/process/global_members.rb +1 -2
  35. data/lib/jsduck/process/importer.rb +2 -6
  36. data/lib/jsduck/process/inherit_class.rb +58 -0
  37. data/lib/jsduck/process/inherit_doc.rb +6 -175
  38. data/lib/jsduck/process/inherit_members.rb +257 -0
  39. data/lib/jsduck/process/lint.rb +18 -7
  40. data/lib/jsduck/process/overrides.rb +1 -2
  41. data/lib/jsduck/render/class.rb +1 -1
  42. data/lib/jsduck/tag/alias.rb +2 -1
  43. data/lib/jsduck/tag/alternate_class_names.rb +1 -0
  44. data/lib/jsduck/tag/aside.rb +3 -3
  45. data/lib/jsduck/tag/author.rb +18 -3
  46. data/lib/jsduck/tag/autodetected.rb +21 -0
  47. data/lib/jsduck/tag/boolean_tag.rb +1 -1
  48. data/lib/jsduck/tag/cfg.rb +7 -3
  49. data/lib/jsduck/tag/class.rb +1 -1
  50. data/lib/jsduck/tag/class_list_tag.rb +1 -1
  51. data/lib/jsduck/tag/constructor.rb +1 -1
  52. data/lib/jsduck/tag/css_var.rb +1 -1
  53. data/lib/jsduck/tag/default.rb +1 -1
  54. data/lib/jsduck/tag/deprecated_tag.rb +1 -1
  55. data/lib/jsduck/tag/docauthor.rb +2 -0
  56. data/lib/jsduck/tag/enum.rb +2 -2
  57. data/lib/jsduck/tag/event.rb +1 -1
  58. data/lib/jsduck/tag/extends.rb +1 -1
  59. data/lib/jsduck/tag/ftype.rb +2 -1
  60. data/lib/jsduck/tag/inheritdoc.rb +1 -1
  61. data/lib/jsduck/tag/localdoc.rb +33 -0
  62. data/lib/jsduck/tag/markdown.rb +1 -1
  63. data/lib/jsduck/tag/member.rb +1 -1
  64. data/lib/jsduck/tag/method.rb +1 -1
  65. data/lib/jsduck/tag/mixins.rb +1 -0
  66. data/lib/jsduck/tag/override.rb +1 -1
  67. data/lib/jsduck/tag/param.rb +16 -5
  68. data/lib/jsduck/tag/preventable.rb +1 -1
  69. data/lib/jsduck/tag/property.rb +7 -3
  70. data/lib/jsduck/tag/ptype.rb +2 -1
  71. data/lib/jsduck/tag/requires.rb +1 -0
  72. data/lib/jsduck/tag/return.rb +2 -1
  73. data/lib/jsduck/tag/since.rb +1 -5
  74. data/lib/jsduck/tag/tag.rb +21 -12
  75. data/lib/jsduck/tag/throws.rb +2 -1
  76. data/lib/jsduck/tag/type.rb +2 -2
  77. data/lib/jsduck/tag/uses.rb +1 -0
  78. data/lib/jsduck/tag/xtype.rb +2 -1
  79. data/lib/jsduck/tag_loader.rb +26 -15
  80. data/lib/jsduck/tag_registry.rb +20 -11
  81. data/lib/jsduck/web/css.rb +22 -0
  82. data/lib/jsduck/web/data.rb +50 -0
  83. data/lib/jsduck/web/icons.rb +31 -0
  84. data/lib/jsduck/web/index_html.rb +88 -0
  85. data/lib/jsduck/web/search.rb +148 -0
  86. data/lib/jsduck/{source/writer.rb → web/source.rb} +2 -2
  87. data/lib/jsduck/web/template.rb +52 -0
  88. data/lib/jsduck/web/writer.rb +84 -0
  89. metadata +513 -488
  90. data/lib/jsduck/app_data.rb +0 -41
  91. data/lib/jsduck/icons.rb +0 -29
  92. data/lib/jsduck/index_html.rb +0 -84
  93. data/lib/jsduck/search_data.rb +0 -146
  94. data/lib/jsduck/template_dir.rb +0 -50
  95. data/lib/jsduck/web_writer.rb +0 -87
data/.travis.yml CHANGED
@@ -6,6 +6,7 @@ install:
6
6
  - gem install rdiscount
7
7
  - gem install json
8
8
  - gem install parallel
9
+ - gem install execjs
9
10
  - gem install therubyracer -v 0.10.1
10
11
  - gem install rspec
11
12
  - gem install rake
data/README.md CHANGED
@@ -34,38 +34,12 @@ Standard rubygems install should do:
34
34
 
35
35
  $ [sudo] gem install jsduck
36
36
 
37
- If you encounter errors during gem installation, you may need to
38
- install the header files for compiling extension modules for Ruby 1.9.
39
- For Debian systems you'll need the `ruby1.9-dev` package. For Red Hat
40
- / CentOS / Fedora use the `ruby-devel` package.
41
-
42
- In **OSX Mountain Lion** the compilation of `therubyracer` dependency
43
- often fails for so far unknown reasons. Most users have found a
44
- solution in upgrading to Ruby 1.9 using [RVM][].
45
-
46
- For **Windows** users out there, you can download the binary version,
47
- which includes Ruby interpreter and all dependencies bundled in a
48
- single .exe file. Grab it from the [download page][].
49
-
50
- Alternatively you can install through rubygems, but you need to do
51
- some additional tweaks. First go and [download][libs download]
52
- therubyracer gem and v8 lib that stereobooster has built for
53
- windows. You need to install this special rubyracer version instead of
54
- the one from rubygems:
55
-
56
- > gem install therubyracer-0.11.0beta1-x86-mingw32.gem
57
-
58
- To make it actually work you need `v8.dll` somewhere in your
59
- system. Extract the `lib_v8.3.11.9.zip` take the `v8.dll` inside it
60
- and place into the `bin` directory of your Ruby installation (other
61
- dirs that are on your PATH can work too, but I've found this to be the
62
- most sensible place to put it). Now you're ready to install JSDuck:
63
-
64
- > gem install jsduck
65
-
66
- [RVM]: https://rvm.io/
67
- [download page]: https://sourceforge.net/projects/jsduck/files/
68
- [libs download]: https://github.com/stereobooster/therubyracer/downloads
37
+ Windows users probably want to [download a binary release][winbin].
38
+
39
+ See the [installation guide][] for help when you run into problems.
40
+
41
+ [winbin]: https://sourceforge.net/projects/jsduck/files/
42
+ [installation guide]: https://github.com/senchalabs/jsduck/wiki/Installation
69
43
 
70
44
  Usage
71
45
  -----
data/Rakefile CHANGED
@@ -104,7 +104,7 @@ def compress
104
104
  dir = "template-min"
105
105
 
106
106
  # Create JSB3 file for Docs app
107
- system("sencha", "create", "jsb", "-a", "http://localhost/~renesaarsoo/docs/", "-p", "#{dir}/app.jsb3")
107
+ system("sencha", "create", "jsb", "-a", "http://localhost/docs/", "-p", "#{dir}/app.jsb3")
108
108
  # Concatenate files listed in JSB3 file
109
109
  system("sencha", "build", "-p", "#{dir}/app.jsb3", "-d", dir)
110
110
 
@@ -247,7 +247,7 @@ task :ext4 => :sass do
247
247
  runner.add_debug
248
248
  runner.run
249
249
 
250
- system("cp -r #{EXT_BUILD} #{OUT_DIR}/extjs-build")
250
+ system("ln -s #{EXT_BUILD} #{OUT_DIR}/extjs-build")
251
251
  end
252
252
 
253
253
  desc "Run JSDuck on Ext JS from SDK repo (for internal use at Sencha)"
@@ -257,7 +257,7 @@ task :sdk => :sass do
257
257
  "--output", OUT_DIR,
258
258
  "--config", "#{SDK_DIR}/extjs/docs/config.json",
259
259
  "--examples-base-url", "extjs-build/examples/",
260
- # "--import", "4.1:../docs.sencha.com/exports/extjs-4.1.1",
260
+ # "--import", "4.1.3:../docs.sencha.com/exports/extjs-4.1.3",
261
261
  # "--import", "4.2",
262
262
  "--seo"
263
263
  )
@@ -265,7 +265,7 @@ task :sdk => :sass do
265
265
  runner.add_comments('ext-js', '4')
266
266
  runner.run
267
267
 
268
- system("cp -r #{EXT_BUILD} #{OUT_DIR}/extjs-build")
268
+ system("ln -s #{EXT_BUILD} #{OUT_DIR}/extjs-build")
269
269
  end
270
270
 
271
271
  desc "Run JSDuck on Sencha Touch 2 repo (for internal use at Sencha)"
@@ -286,7 +286,7 @@ task :touch2 => :sass do
286
286
  runner.add_comments('touch', '2')
287
287
  runner.run
288
288
 
289
- system("cp -r #{TOUCH_BUILD} #{OUT_DIR}/touch-build")
289
+ system("ln -s #{TOUCH_BUILD} #{OUT_DIR}/touch-build")
290
290
  end
291
291
 
292
292
  task :default => :spec
data/bin/jsduck CHANGED
@@ -17,7 +17,6 @@
17
17
  # For running when gem not installed
18
18
  $:.unshift File.dirname(File.dirname(__FILE__)) + "/lib"
19
19
 
20
- require 'rubygems'
21
20
  require 'jsduck/app'
22
21
  require 'jsduck/options'
23
22
 
data/js-classes/String.js CHANGED
@@ -125,7 +125,7 @@
125
125
  *
126
126
  * String.fromCharCode(65,66,67)
127
127
  *
128
- * @param {Number} num1, ..., numN A sequence of numbers that are Unicode values.
128
+ * @param {Number...} numbers A sequence of numbers that are Unicode values.
129
129
  * @return {String} String containing characters from encoding.
130
130
  */
131
131
 
@@ -359,9 +359,7 @@
359
359
 
360
360
  /**
361
361
  * @method concat
362
- * Combines the text of two strings and returns a new string.
363
- *
364
- * `concat` combines the text from one or more strings and returns a new string. Changes to the text in
362
+ * Combines combines the text from one or more strings and returns a new string. Changes to the text in
365
363
  * one string do not affect the other string.
366
364
  *
367
365
  * The following example combines strings into a new string.
@@ -369,7 +367,7 @@
369
367
  * var hello = "Hello, ";
370
368
  * console.log(hello.concat("Kevin", " have a nice day.")); // Hello, Kevin have a nice day.
371
369
  *
372
- * @param {String} string2...stringN
370
+ * @param {String...} strings The strings to concatenate.
373
371
  * @return {String} Result of both strings.
374
372
  */
375
373
 
data/jsduck.gemspec CHANGED
@@ -2,8 +2,8 @@ Gem::Specification.new do |s|
2
2
  s.required_rubygems_version = ">= 1.3.5"
3
3
 
4
4
  s.name = 'jsduck'
5
- s.version = '5.0.0.beta01'
6
- s.date = '2013-02-25'
5
+ s.version = '5.0.0.beta2'
6
+ s.date = Time.new.strftime('%Y-%m-%d')
7
7
  s.summary = "Simple JavaScript Duckumentation generator"
8
8
  s.description = "Documentation generator for Sencha JS frameworks"
9
9
  s.homepage = "https://github.com/senchalabs/jsduck"
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_dependency 'rdiscount'
23
23
  s.add_dependency 'json'
24
24
  s.add_dependency 'parallel'
25
+ s.add_dependency 'execjs'
25
26
  s.add_dependency 'therubyracer', '>= 0.10.0', '< 0.11.0'
26
27
  s.add_dependency 'dimensions'
27
28
 
@@ -87,9 +87,7 @@ module JsDuck
87
87
  end
88
88
 
89
89
  def warn_alt_name(cls)
90
- file = cls[:files][0][:filename]
91
- line = cls[:files][0][:linenr]
92
- Logger.warn(:alt_name, "Name #{cls[:name]} used as both classname and alternate classname", file, line)
90
+ Logger.warn(:alt_name, "Name #{cls[:name]} used as both classname and alternate classname", cls[:files][0])
93
91
  end
94
92
 
95
93
  # Merges new class-doc into old one.
data/lib/jsduck/app.rb CHANGED
@@ -3,7 +3,7 @@ require 'jsduck/batch_processor'
3
3
  require 'jsduck/assets'
4
4
  require 'jsduck/tag_registry'
5
5
  require 'jsduck/export_writer'
6
- require 'jsduck/web_writer'
6
+ require 'jsduck/web/writer'
7
7
 
8
8
  module JsDuck
9
9
 
@@ -47,7 +47,7 @@ module JsDuck
47
47
  end
48
48
 
49
49
  def generate_web_page
50
- WebWriter.new(@relations, @assets, @parsed_files, @opts).write
50
+ Web::Writer.new(@relations, @assets, @parsed_files, @opts).write
51
51
  end
52
52
 
53
53
  end
@@ -15,12 +15,6 @@ module JsDuck
15
15
  def generate
16
16
  @categories = Util::Json.read(@filename)
17
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
18
  # Perform expansion on all class names containing * wildcard
25
19
  @categories.each do |cat|
26
20
  cat["groups"].each do |group|
data/lib/jsduck/class.rb CHANGED
@@ -115,8 +115,7 @@ module JsDuck
115
115
  # simplest thing and ignore it.
116
116
  Class.new({:name => classname}, false)
117
117
  else
118
- context = @doc[:files][0]
119
- Logger.warn(:extend, "Class #{classname} not found", context[:filename], context[:linenr])
118
+ Logger.warn(:extend, "Class #{classname} not found", @doc[:files][0])
120
119
  # Create placeholder class
121
120
  Class.new({:name => classname}, false)
122
121
  end
@@ -27,10 +27,10 @@ module JsDuck
27
27
  # JsDuck::DocFormatter.
28
28
  #
29
29
  class Parser < Doc::Scanner
30
- def parse(input, filename="", linenr=0)
31
- @filename = filename
32
- @linenr = linenr
30
+ def parse(input, filename="", linenr = 0)
31
+ @position = {:filename => filename, :linenr => linenr}
33
32
  @tags = []
33
+ @non_repeatable_tags = {}
34
34
  @input = StringScanner.new(Doc::Comment.purify(input))
35
35
 
36
36
  parse_loop
@@ -86,16 +86,23 @@ module JsDuck
86
86
  match(/\w+/)
87
87
  hw # Skip the whitespace right after the tag.
88
88
 
89
- tags = tag.parse_doc(self)
89
+ tags = tag.parse_doc(self, @position)
90
90
  if tags.is_a?(Hash)
91
91
  add_tag(tags)
92
92
  elsif tags.is_a?(Array)
93
93
  tags.each {|t| add_tag(t) }
94
94
  end
95
95
 
96
+ if !tag.repeatable
97
+ if @non_repeatable_tags[name]
98
+ warn(:tag_repeated, "@#{name} tag can occur only once per doc-comment")
99
+ end
100
+ @non_repeatable_tags[name] = true
101
+ end
102
+
96
103
  skip_white
97
104
  else
98
- Logger.warn(:tag, "Unsupported tag: @#{name}", @filename, @linenr)
105
+ warn(:tag, "Unsupported tag: @#{name}")
99
106
  @multiline_tag[:doc] += "@"
100
107
  end
101
108
  end
@@ -16,6 +16,7 @@ module JsDuck
16
16
  @ident_chain_pattern = /[$\w-]+(\.[$\w-]+)*/
17
17
 
18
18
  @input = nil # set to StringScanner in subclass
19
+ @position = {} # set in subclass
19
20
  end
20
21
 
21
22
  # Provides access to StringScanner
@@ -70,6 +71,11 @@ module JsDuck
70
71
  self
71
72
  end
72
73
 
74
+ # Prints a warning message
75
+ def warn(type, msg)
76
+ Logger.warn(type, msg, @position)
77
+ end
78
+
73
79
  end
74
80
 
75
81
  end
@@ -30,6 +30,7 @@ module JsDuck
30
30
  # were specified and how their matching succeeded.
31
31
  #
32
32
  def parse(cfg)
33
+ @tagname = cfg[:tagname]
33
34
  tag = {:tagname => cfg[:tagname]}
34
35
  add_type(tag) if cfg[:type]
35
36
  add_name_with_default(tag) if cfg[:name]
@@ -61,7 +62,7 @@ module JsDuck
61
62
  optional = nil
62
63
  end
63
64
 
64
- match(/\}/)
65
+ match(/\}/) or warn("@#{@tagname} tag syntax: '}' expected")
65
66
 
66
67
  return {:type => name, :optional => optional}
67
68
  end
@@ -71,10 +72,10 @@ module JsDuck
71
72
  if hw.match(/\[/)
72
73
  tag[:name] = hw.ident_chain
73
74
  if hw.match(/=/)
74
- hw
75
- tag[:default] = default_value
76
- end
77
- hw.match(/\]/)
75
+ hw
76
+ tag[:default] = default_value
77
+ end
78
+ hw.match(/\]/) or warn("@#{@tagname} tag syntax: ']' expected")
78
79
  tag[:optional] = true
79
80
  else
80
81
  tag[:name] = hw.ident_chain
@@ -148,6 +149,10 @@ module JsDuck
148
149
  def hw
149
150
  @ds.hw
150
151
  end
152
+
153
+ def warn(msg)
154
+ @ds.warn(:tag_syntax, msg)
155
+ end
151
156
  end
152
157
 
153
158
  end
@@ -28,6 +28,8 @@ module JsDuck
28
28
  def nest(raw_items, pos)
29
29
  # First item can't be namespaced, if it is ignore the rest.
30
30
  if raw_items[0] && raw_items[0][:name] =~ /\./
31
+ warn(raw_items[0][:name], pos)
32
+ raw_items[0][:name].sub!(/\..*$/, '')
31
33
  return [raw_items[0]]
32
34
  end
33
35
 
@@ -47,8 +49,7 @@ module JsDuck
47
49
  parent[:properties] = [] unless parent[:properties]
48
50
  parent[:properties] << it
49
51
  else
50
- msg = "Ignoring subproperty #{$1}.#{$2}, no parent found with name '#{$1}'."
51
- Logger.warn(:subproperty, msg, pos[:filename], pos[:linenr])
52
+ warn("#{$1}.#{$2}", pos)
52
53
  end
53
54
  else
54
55
  items << it
@@ -58,6 +59,12 @@ module JsDuck
58
59
  return items
59
60
  end
60
61
 
62
+ def warn(name, pos)
63
+ parent = name.sub(/\.[^.]*$/, '')
64
+ msg = "Ignoring subproperty '#{name}' not parent found with name '#{parent}'."
65
+ Logger.warn(:subproperty, msg, pos)
66
+ end
67
+
61
68
  end
62
69
 
63
70
  end
@@ -7,16 +7,23 @@ module JsDuck
7
7
  class DocsCodeComparer
8
8
  include Util::Singleton
9
9
 
10
- # When docs has the key, returns value from there.
11
- # When code has the key and matches with docs, gets value from there.
12
- # Otherwise returns nil.
13
- def merge_if_matches(key, docs, code)
10
+ # Sets the value of a field in result hash based on its value in
11
+ # docs and code hashes.
12
+ #
13
+ # - When docs has the key, gets value from there.
14
+ #
15
+ # - When code has the key and matches with docs, gets value from
16
+ # there, and also remembers the fact that we're using
17
+ # auto-detected value by recording it in :autodetected field.
18
+ #
19
+ def merge_if_matches(h, key, docs, code)
14
20
  if docs[key]
15
- docs[key]
21
+ h[key] = docs[key]
16
22
  elsif code[key] && matches?(docs, code)
17
- code[key]
23
+ h[key] = code[key]
24
+ mark_autodetected(h, key)
18
25
  else
19
- nil
26
+ # nothing
20
27
  end
21
28
  end
22
29
 
@@ -26,6 +33,12 @@ module JsDuck
26
33
  return docs[:name] == nil || docs[:name] == code[:name]
27
34
  end
28
35
 
36
+ # Stores the key as flag into h[:autodetcted]
37
+ def mark_autodetected(h, key)
38
+ h[:autodetected] = {} unless h[:autodetected]
39
+ h[:autodetected][key] = true
40
+ end
41
+
29
42
  end
30
43
 
31
44
  end
@@ -6,17 +6,31 @@ module JsDuck
6
6
  module Exporter
7
7
 
8
8
  # Exports data for Docs app.
9
- class App < Full
9
+ class App
10
10
  def initialize(relations, opts)
11
- super(relations, opts)
11
+ @full_exporter = Exporter::Full.new(relations, opts)
12
+ @relations = relations
12
13
  @renderer = Render::Class.new(opts)
13
14
  end
14
15
 
15
16
  # Returns compacted class data hash which contains an additional
16
17
  # :html field with full HTML to show on class overview page.
17
18
  def export(cls)
18
- data = super(cls)
19
+ data = @full_exporter.export(cls)
20
+
21
+ data[:component] = cls.inherits_from?("Ext.Component")
22
+ data[:superclasses] = cls.superclasses.collect {|c| c[:name] }
23
+ data[:subclasses] = @relations.subclasses(cls).collect {|c| c[:name] }.sort
24
+ data[:mixedInto] = @relations.mixed_into(cls).collect {|c| c[:name] }.sort
25
+ data[:alternateClassNames] = cls[:alternateClassNames].sort if cls[:alternateClassNames]
26
+
27
+ data[:mixins] = cls.deps(:mixins).collect {|c| c[:name] }.sort
28
+ data[:parentMixins] = cls.parent_deps(:mixins).collect {|c| c[:name] }.sort
29
+ data[:requires] = cls.deps(:requires).collect {|c| c[:name] }.sort
30
+ data[:uses] = cls.deps(:uses).collect {|c| c[:name] }.sort
31
+
19
32
  data[:html] = @renderer.render(data)
33
+
20
34
  return compact(data)
21
35
  end
22
36
 
@@ -25,21 +39,12 @@ module JsDuck
25
39
  # removes extra data from export
26
40
  def compact(cls)
27
41
  cls.delete(:doc)
28
- cls[:members] = compact_members_group(cls[:members])
29
- cls[:statics] = compact_members_group(cls[:statics])
42
+ cls[:members] = cls[:members].map {|m| compact_member(m) }
30
43
  cls[:files] = compact_files(cls[:files])
31
44
  cls[:meta] = combine_meta(cls)
32
45
  cls
33
46
  end
34
47
 
35
- def compact_members_group(group)
36
- c_group = {}
37
- group.each_pair do |type, members|
38
- c_group[type] = members.map {|m| compact_member(m) }
39
- end
40
- c_group
41
- end
42
-
43
48
  def compact_member(m)
44
49
  m_copy = {}
45
50
  [:name, :tagname, :owner, :id].each do |key|