jazzy 0.0.13 → 0.0.14

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -3
  3. data/Gemfile.lock +5 -3
  4. data/Rakefile +4 -2
  5. data/bin/sourcekitten +0 -0
  6. data/jazzy.gemspec +1 -0
  7. data/lib/jazzy/assets/css/{jazzy.css → jazzy.css.scss} +199 -231
  8. data/lib/jazzy/config.rb +27 -13
  9. data/lib/jazzy/doc.mustache +2 -2
  10. data/lib/jazzy/doc.rb +2 -1
  11. data/lib/jazzy/doc_builder.rb +124 -70
  12. data/lib/jazzy/gem_version.rb +1 -1
  13. data/lib/jazzy/source_module.rb +28 -0
  14. data/lib/jazzy/sourcekitten.rb +95 -70
  15. data/lib/jazzy/xml_helper.rb +2 -1
  16. data/spec/integration_specs/document_alamofire/after/docs/Classes.html +2 -2
  17. data/spec/integration_specs/document_alamofire/after/docs/Classes/Manager.html +2 -2
  18. data/spec/integration_specs/document_alamofire/after/docs/Classes/Manager/init(configuration:).html +2 -2
  19. data/spec/integration_specs/document_alamofire/after/docs/Classes/Request.html +2 -2
  20. data/spec/integration_specs/document_alamofire/after/docs/Enums.html +2 -2
  21. data/spec/integration_specs/document_alamofire/after/docs/Enums/ParameterEncoding.html +2 -2
  22. data/spec/integration_specs/document_alamofire/after/docs/Extensions.html +2 -2
  23. data/spec/integration_specs/document_alamofire/after/docs/Extensions/Manager.html +2 -2
  24. data/spec/integration_specs/document_alamofire/after/docs/Extensions/Request.html +2 -2
  25. data/spec/integration_specs/document_alamofire/after/docs/Functions.html +2 -2
  26. data/spec/integration_specs/document_alamofire/after/docs/Global Variables.html +2 -2
  27. data/spec/integration_specs/document_alamofire/after/docs/Protocols.html +2 -2
  28. data/spec/integration_specs/document_alamofire/after/docs/Protocols/URLRequestConvertible.html +2 -2
  29. data/spec/integration_specs/document_alamofire/after/docs/Protocols/URLStringConvertible.html +2 -2
  30. data/spec/integration_specs/document_alamofire/after/docs/css/jazzy.css +140 -257
  31. data/spec/integration_specs/document_alamofire/after/docs/index.html +2 -2
  32. data/spec/integration_specs/document_alamofire/after/execution_output.txt +2 -1
  33. data/spec/integration_specs/misc_jazzy_features/after/docs/Classes.html +2 -2
  34. data/spec/integration_specs/misc_jazzy_features/after/docs/Classes/ImplicitlyInternalTopLevelClass.html +2 -2
  35. data/spec/integration_specs/misc_jazzy_features/after/docs/Enums.html +2 -2
  36. data/spec/integration_specs/misc_jazzy_features/after/docs/Enums/DocumentedEnum.html +2 -2
  37. data/spec/integration_specs/misc_jazzy_features/after/docs/Global Variables.html +2 -2
  38. data/spec/integration_specs/misc_jazzy_features/after/docs/css/jazzy.css +140 -257
  39. data/spec/integration_specs/misc_jazzy_features/after/docs/index.html +2 -2
  40. data/spec/integration_specs/misc_jazzy_features/after/execution_output.txt +2 -1
  41. metadata +18 -4
  42. data/.rubocop_todo.yml +0 -24
data/lib/jazzy/config.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'optparse'
2
+ require 'pathname'
2
3
 
3
4
  module Jazzy
4
5
  class Config
@@ -14,7 +15,7 @@ module Jazzy
14
15
  attr_accessor :clean
15
16
 
16
17
  def initialize
17
- self.output = File.expand_path('docs')
18
+ self.output = Pathname('docs')
18
19
  self.xcodebuild_arguments = []
19
20
  self.author_name = ''
20
21
  self.module_name = ''
@@ -26,6 +27,7 @@ module Jazzy
26
27
  self.clean = false
27
28
  end
28
29
 
30
+ # rubocop:disable Metrics/MethodLength
29
31
  def self.parse!
30
32
  config = new
31
33
  OptionParser.new do |opt|
@@ -33,46 +35,58 @@ module Jazzy
33
35
  opt.separator ''
34
36
  opt.separator 'Options'
35
37
 
36
- opt.on('-o', '--output FOLDER', 'Folder to output the HTML docs to') do |output|
37
- config.output = File.expand_path(output)
38
+ opt.on('-o', '--output FOLDER',
39
+ 'Folder to output the HTML docs to') do |output|
40
+ config.output = Pathname(output)
38
41
  end
39
42
 
40
43
  opt.on('-c', '--[no-]clean',
41
44
  'Delete contents of output directory before running.',
42
- 'WARNING: If --output is set to ~/Desktop, this will delete the ~/Desktop directory.') do |clean|
45
+ 'WARNING: If --output is set to ~/Desktop, this will delete the \
46
+ ~/Desktop directory.') do |clean|
43
47
  config.clean = clean
44
48
  end
45
49
 
46
- opt.on('-x', '--xcodebuild-arguments arg1,arg2,…argN', Array, 'Arguments to forward to xcodebuild') do |args|
50
+ opt.on('-x', '--xcodebuild-arguments arg1,arg2,…argN', Array,
51
+ 'Arguments to forward to xcodebuild') do |args|
47
52
  config.xcodebuild_arguments = args
48
53
  end
49
54
 
50
- opt.on('-a', '--author AUTHOR_NAME', 'Name of author to attribute in docs (i.e. Realm)') do |a|
55
+ opt.on('-a', '--author AUTHOR_NAME',
56
+ 'Name of author to attribute in docs (i.e. Realm)') do |a|
51
57
  config.author_name = a
52
58
  end
53
59
 
54
- opt.on('-u', '--author_url URL', 'Author URL of this project (i.e. http://realm.io)') do |u|
60
+ opt.on('-u', '--author_url URL',
61
+ 'Author URL of this project (i.e. http://realm.io)') do |u|
55
62
  config.author_url = u
56
63
  end
57
64
 
58
- opt.on('-m', '--module MODULE_NAME', 'Name of module being documented. (i.e. RealmSwift)') do |m|
65
+ opt.on('-m', '--module MODULE_NAME',
66
+ 'Name of module being documented. (i.e. RealmSwift)') do |m|
59
67
  config.module_name = m
60
68
  end
61
69
 
62
- opt.on('-d', '--dash_url URL', 'URL to install docs in Dash (i.e. dash-feed://http%3A%2F%2Fcocoadocs.org%2Fdocsets%2FRealm%2FRealm.xml') do |d|
70
+ opt.on('-d', '--dash_url URL',
71
+ 'URL to install docs in Dash (i.e. dash-feed://...') do |d|
63
72
  config.dash_url = d
64
73
  end
65
74
 
66
- opt.on('-g', '--github_url URL', 'GitHub URL of this project (i.e. https://github.com/realm/realm-cocoa)') do |g|
75
+ opt.on('-g', '--github_url URL',
76
+ 'GitHub URL of this project (i.e. \
77
+ https://github.com/realm/realm-cocoa)') do |g|
67
78
  config.github_url = g
68
79
  end
69
80
 
70
- opt.on('--github-file-prefix PREFIX', 'GitHub URL file prefix of this project (i.e. https://github.com/realm/realm-cocoa/tree/v0.87.1)') do |g|
81
+ opt.on('--github-file-prefix PREFIX',
82
+ 'GitHub URL file prefix of this project (i.e. \
83
+ https://github.com/realm/realm-cocoa/tree/v0.87.1)') do |g|
71
84
  config.github_file_prefix = g
72
85
  end
73
86
 
74
- opt.on('-s', '--sourcekitten-sourcefile FILEPATH', 'XML doc file generated from sourcekitten to parse') do |s|
75
- config.sourcekitten_sourcefile = s
87
+ opt.on('-s', '--sourcekitten-sourcefile FILEPATH',
88
+ 'XML doc file generated from sourcekitten to parse') do |s|
89
+ config.sourcekitten_sourcefile = Pathname(s)
76
90
  end
77
91
 
78
92
  opt.on('-v', '--version', 'Print version number') do
@@ -11,7 +11,7 @@
11
11
  <a title="{{name}} {{kind}} Reference"></a>
12
12
  <header>
13
13
  <div class="content-wrapper">
14
- <p class="header-text"><a href="#">{{module_name}} Docs</a></p>
14
+ <p class="header-text"><a href="{{path_to_root}}index.html">{{module_name}} Docs</a> ({{doc_coverage}}% documented)</p>
15
15
  {{#github_url}}
16
16
  <p id="header-links"><a href="{{github_url}}"><img id="header-icon" src="{{path_to_root}}img/gh.png" height="16px" width="16px" />View on GitHub</a></p>
17
17
  {{/github_url}}
@@ -23,7 +23,7 @@
23
23
  <section id="valence">
24
24
  <div class="content-wrapper">
25
25
  <p id="hierarchial_navigation">
26
- <a href="#" id="design_resources_link">{{module_name}} Reference</a>
26
+ <a href="{{path_to_root}}index.html" id="design_resources_link">{{module_name}} Reference</a>
27
27
  <img id="carat" src="{{path_to_root}}img/carat.png" height="10px" width="6px" />
28
28
  {{name}} {{kind}} Reference
29
29
  </p>
data/lib/jazzy/doc.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require 'date'
2
+ require 'pathname'
2
3
 
3
4
  require 'jazzy/gem_version'
4
5
 
5
6
  module Jazzy
6
7
  class Doc < Mustache
7
- self.template_path = File.dirname(__FILE__) + '/..'
8
+ self.template_path = Pathname(__FILE__).parent.parent
8
9
 
9
10
  def date
10
11
  # Fake date is used to keep integration tests consistent
@@ -1,11 +1,14 @@
1
1
  require 'fileutils'
2
2
  require 'mustache'
3
3
  require 'uri'
4
+ require 'pathname'
5
+ require 'sass'
4
6
 
5
7
  require 'jazzy/config'
6
8
  require 'jazzy/doc'
7
9
  require 'jazzy/jazzy_markdown'
8
10
  require 'jazzy/source_declaration'
11
+ require 'jazzy/source_module'
9
12
  require 'jazzy/sourcekitten'
10
13
 
11
14
  module Jazzy
@@ -14,18 +17,21 @@ module Jazzy
14
17
  module DocBuilder
15
18
  # mkdir -p output directory and clean if option is set
16
19
  def self.prepare_output_dir(output_dir, clean)
17
- FileUtils.rm_r output_dir if clean && File.directory?(output_dir)
20
+ FileUtils.rm_r output_dir if clean && output_dir.directory?
18
21
  FileUtils.mkdir_p output_dir
19
22
  end
20
23
 
21
24
  # Generate doc structure to be used in sidebar navigation
22
- # @return [Array] doc structure comprised of section names and child names and URLs
25
+ # @return [Array] doc structure comprised of
26
+ # section names & child names & URLs
23
27
  def self.doc_structure_for_docs(docs)
24
28
  structure = []
25
29
  docs.each do |doc|
26
30
  structure << {
27
31
  section: doc.name,
28
- children: doc.children.map { |child| { name: child.name, url: child.url } },
32
+ children: doc.children.map do |child|
33
+ { name: child.name, url: child.url }
34
+ end,
29
35
  }
30
36
  end
31
37
  structure
@@ -35,9 +41,7 @@ module Jazzy
35
41
  # @param [Config] options
36
42
  def self.build(options)
37
43
  if options.sourcekitten_sourcefile
38
- file = File.open(options.sourcekitten_sourcefile)
39
- file_contents = file.read
40
- file.close
44
+ file_contents = options.sourcekitten_sourcefile.read
41
45
  build_docs_for_sourcekitten_output(file_contents, options)
42
46
  else
43
47
  stdout = SourceKitten.run_sourcekitten(options.xcodebuild_arguments)
@@ -61,16 +65,22 @@ module Jazzy
61
65
  # @param [Integer] depth Number of parents. Used to calculate path_to_root
62
66
  # for web.
63
67
  # @param [Array] doc_structure @see #doc_structure_for_docs
64
- def self.build_docs(output_dir, docs, options, depth, doc_structure)
68
+ def self.build_docs(output_dir, docs, source_module, depth)
65
69
  docs.each do |doc|
66
70
  next if doc.name != 'index' && doc.children.count == 0
67
71
  prepare_output_dir(output_dir, false)
68
- path = File.join(output_dir, "#{doc.name}.html")
72
+ path = output_dir + "#{doc.name}.html"
69
73
  path_to_root = ['../'].cycle(depth).to_a.join('')
70
- File.open(path, 'w') { |file| file.write(DocBuilder.document(options, doc, path_to_root, doc_structure)) }
71
- if doc.name != 'index'
72
- DocBuilder.build_docs(File.join(output_dir, doc.name), doc.children, options, depth + 1, doc_structure)
74
+ path.open('w') do |file|
75
+ file.write(document(source_module, doc, path_to_root))
73
76
  end
77
+ next if doc.name == 'index'
78
+ build_docs(
79
+ output_dir + doc.name,
80
+ doc.children,
81
+ source_module,
82
+ depth + 1,
83
+ )
74
84
  end
75
85
  end
76
86
 
@@ -80,88 +90,132 @@ module Jazzy
80
90
  def self.build_docs_for_sourcekitten_output(sourcekitten_output, options)
81
91
  output_dir = options.output
82
92
  prepare_output_dir(output_dir, options.clean)
83
- docs = SourceKitten.parse(sourcekitten_output)
84
- doc_structure = doc_structure_for_docs(docs)
93
+
94
+ (docs, coverage) = SourceKitten.parse(sourcekitten_output)
95
+
96
+ structure = doc_structure_for_docs(docs)
97
+
85
98
  docs << SourceDeclaration.new.tap { |sd| sd.name = 'index' }
86
- DocBuilder.build_docs(output_dir, docs, options, 0, doc_structure)
87
99
 
88
- # Copy assets into output directory
89
- assets_dir = File.expand_path(File.dirname(__FILE__) + '/../../lib/jazzy/assets/') + '/.'
90
- FileUtils.cp_r(assets_dir, output_dir)
100
+ source_module = SourceModule.new(options, docs, structure, coverage)
101
+ build_docs(output_dir, source_module.docs, source_module, 0)
102
+
103
+ copy_assets(output_dir)
91
104
 
92
- puts 'jam out ♪♫ to your fresh new docs at ' + output_dir
105
+ puts "jam out ♪♫ to your fresh new docs in `#{output_dir}`"
93
106
  end
94
107
 
95
- # Build Mustache document from single parsed doc
108
+ def self.copy_assets(destination)
109
+ origin = Pathname(__FILE__).parent + '../../lib/jazzy/assets/.'
110
+ FileUtils.cp_r(origin, destination)
111
+ Pathname.glob(destination + 'css/**/*.scss').each do |scss|
112
+ contents = scss.read
113
+ css = Sass::Engine.new(contents, syntax: :scss).render
114
+ css_filename = scss.sub(/\.scss$/, '')
115
+ css_filename.open('w') { |f| f.write(css) }
116
+ FileUtils.rm scss
117
+ end
118
+ end
119
+
120
+ # Build index Mustache document
96
121
  # @param [Config] options Build options
97
- # @param [Hash] doc_model Parsed doc. @see SourceKitten.parse
98
122
  # @param [String] path_to_root
99
123
  # @param [Array] doc_structure doc structure comprised of section names and
100
124
  # child names and URLs. @see doc_structure_for_docs
101
- def self.document(options, doc_model, path_to_root, doc_structure)
125
+ def self.document_index(source_module, path_to_root)
102
126
  doc = Doc.new # Mustache model instance
103
- # Do something special for index.
104
- # @todo render README here
105
- if doc_model.name == 'index'
106
- doc[:name] = options.module_name
107
- doc[:overview] = Jazzy.markdown.render(
108
- "This is the index page for #{options.module_name} docs. " \
109
- 'Navigate using the links on the left.',
110
- )
111
- doc[:structure] = doc_structure
112
- doc[:module_name] = options.module_name
113
- doc[:author_name] = options.author_name
114
- doc[:author_website] = options.author_url
115
- doc[:github_url] = options.github_url
116
- doc[:dash_url] = options.dash_url
117
- doc[:path_to_root] = path_to_root
118
- return doc.render
127
+ doc[:name] = source_module.name
128
+ doc[:overview] = Jazzy.markdown.render(
129
+ "This is the index page for #{source_module.name} docs. " \
130
+ 'Navigate using the links on the left.',
131
+ )
132
+ doc[:doc_coverage] = source_module.doc_coverage
133
+ doc[:structure] = source_module.doc_structure
134
+ doc[:module_name] = source_module.name
135
+ doc[:author_name] = source_module.author_name
136
+ doc[:author_website] = source_module.author_url
137
+ doc[:github_url] = source_module.github_url
138
+ doc[:dash_url] = source_module.dash_url
139
+ doc[:path_to_root] = path_to_root
140
+ doc.render
141
+ end
142
+
143
+ # Construct Github token URL
144
+ # @param [Hash] item Parsed doc child item
145
+ # @param [Config] options Build options
146
+ def self.gh_token_url(item, source_module)
147
+ if source_module.github_file_prefix && item.file
148
+ gh_prefix = source_module.github_file_prefix
149
+ relative_file_path = item.file.gsub(`pwd`.strip, '')
150
+ gh_line = "#L#{item.line}"
151
+ gh_prefix + relative_file_path + gh_line
119
152
  end
153
+ end
120
154
 
121
- ########################################################
122
- # Map doc_model values to mustache model values
123
- ########################################################
155
+ # Build mustache item for a top-level doc
156
+ # @param [Hash] item Parsed doc child item
157
+ # @param [Config] options Build options
158
+ def self.render_item(item, source_module)
159
+ # Combine abstract and discussion into abstract
160
+ abstract = (item.abstract || '') + (item.discussion || '')
161
+ item_render = {
162
+ name: item.name,
163
+ abstract: Jazzy.markdown.render(abstract),
164
+ declaration: item.declaration,
165
+ usr: item.usr,
166
+ }
167
+ gh_token_url = gh_token_url(item, source_module)
168
+ item_render[:github_token_url] = gh_token_url if gh_token_url
169
+ item_render[:return] = Jazzy.markdown.render(item.return) if item.return
170
+ item_render[:parameters] = item.parameters if item.parameters.length > 0
171
+ item_render
172
+ end
124
173
 
125
- doc[:name] = doc_model.name
126
- doc[:kind] = doc_model.kindName
127
- doc[:overview] = Jazzy.markdown.render(doc_model.abstract || '')
128
- doc[:tasks] = []
129
- doc[:structure] = doc_structure
174
+ # Render tasks for Mustache document
175
+ # @param [Config] options Build options
176
+ # @param [Hash] doc_model Parsed doc. @see SourceKitten.parse
177
+ def self.render_tasks(source_module, doc_model)
178
+ tasks = []
130
179
  # @todo parse mark-style comments and use as task names
131
180
  tasknames = ['Children']
132
181
  tasknames.each do |taskname|
133
182
  items = []
134
- doc_model.children.each do |sub_item|
135
- # Combine abstract and discussion into abstract
136
- abstract = (sub_item.abstract || '') + (sub_item.discussion || '')
137
- item = {
138
- name: sub_item.name,
139
- abstract: Jazzy.markdown.render(abstract),
140
- declaration: sub_item.declaration,
141
- usr: sub_item.usr,
142
- }
143
- if options.github_file_prefix && sub_item.file
144
- gh_prefix = options.github_file_prefix
145
- relative_file_path = sub_item.file.gsub(`pwd`.strip, '')
146
- gh_line = "#L#{sub_item.line}"
147
- item[:github_token_url] = gh_prefix + relative_file_path + gh_line
148
- end
149
- item[:return] = Jazzy.markdown.render(sub_item.return) if sub_item.return
150
- parameters = sub_item.parameters
151
- item[:parameters] = parameters if parameters.length > 0
152
- items << item
183
+ doc_model.children.each do |item|
184
+ items << render_item(item, source_module)
153
185
  end
154
- doc[:tasks] << {
186
+ tasks << {
155
187
  name: '',
156
188
  uid: URI.encode(taskname),
157
189
  items: items,
158
190
  }
159
191
  end
160
- doc[:module_name] = options.module_name
161
- doc[:author_name] = options.author_name
162
- doc[:author_website] = options.author_url
163
- doc[:github_url] = options.github_url
164
- doc[:dash_url] = options.dash_url
192
+ tasks
193
+ end
194
+
195
+ # Build Mustache document from single parsed doc
196
+ # @param [Config] options Build options
197
+ # @param [Hash] doc_model Parsed doc. @see SourceKitten.parse
198
+ # @param [String] path_to_root
199
+ # @param [Array] doc_structure doc structure comprised of section names and
200
+ # child names and URLs. @see doc_structure_for_docs
201
+ def self.document(source_module, doc_model, path_to_root)
202
+ # @todo render README here
203
+ if doc_model.name == 'index'
204
+ return document_index(source_module, path_to_root)
205
+ end
206
+
207
+ doc = Doc.new # Mustache model instance
208
+ doc[:doc_coverage] = source_module.doc_coverage
209
+ doc[:name] = doc_model.name
210
+ doc[:kind] = doc_model.kindName
211
+ doc[:overview] = Jazzy.markdown.render(doc_model.abstract || '')
212
+ doc[:structure] = source_module.doc_structure
213
+ doc[:tasks] = render_tasks(source_module, doc_model)
214
+ doc[:module_name] = source_module.name
215
+ doc[:author_name] = source_module.author_name
216
+ doc[:author_website] = source_module.author_url
217
+ doc[:github_url] = source_module.github_url
218
+ doc[:dash_url] = source_module.dash_url
165
219
  doc[:path_to_root] = path_to_root
166
220
  doc.render
167
221
  end
@@ -1,3 +1,3 @@
1
1
  module Jazzy
2
- VERSION = '0.0.13' unless defined? Jazzy::VERSION
2
+ VERSION = '0.0.14' unless defined? Jazzy::VERSION
3
3
  end
@@ -0,0 +1,28 @@
1
+ require 'jazzy/config'
2
+ require 'jazzy/source_declaration'
3
+
4
+ module Jazzy
5
+ class SourceModule
6
+ attr_accessor :name
7
+ attr_accessor :docs
8
+ attr_accessor :doc_coverage
9
+ attr_accessor :doc_structure
10
+ attr_accessor :author_name
11
+ attr_accessor :github_url
12
+ attr_accessor :github_file_prefix
13
+ attr_accessor :author_url
14
+ attr_accessor :dash_url
15
+
16
+ def initialize(options, docs, doc_structure, doc_coverage)
17
+ self.docs = docs
18
+ self.doc_structure = doc_structure
19
+ self.doc_coverage = doc_coverage
20
+ self.name = options.module_name
21
+ self.author_name = options.author_name
22
+ self.github_url = options.github_url
23
+ self.github_file_prefix = options.github_file_prefix
24
+ self.author_url = options.author_url
25
+ self.dash_url = options.dash_url
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,6 @@
1
1
  require 'active_support/inflector'
2
2
  require 'json'
3
+ require 'pathname'
3
4
 
4
5
  require 'jazzy/config'
5
6
  require 'jazzy/source_declaration'
@@ -8,42 +9,40 @@ require 'jazzy/xml_helper'
8
9
  module Jazzy
9
10
  # This module interacts with the sourcekitten command-line executable
10
11
  module SourceKitten
11
- # SourceKit-provided token kinds along with their human-readable descriptions
12
+ # SourceKit-provided token kinds along with their names
12
13
  # @todo Make sure this list is exhaustive for source.lang.swift.decl.*
13
- def self.kinds
14
- {
15
- 'source.lang.swift.decl.function.method.class' => 'Class Method',
16
- 'source.lang.swift.decl.var.class' => 'Class Variable',
17
- 'source.lang.swift.decl.class' => 'Class',
18
- 'source.lang.swift.decl.function.constructor' => 'Constructor',
19
- 'source.lang.swift.decl.function.destructor' => 'Destructor',
20
- 'source.lang.swift.decl.var.global' => 'Global Variable',
21
- 'source.lang.swift.decl.enumelement' => 'Enum Element',
22
- 'source.lang.swift.decl.enum' => 'Enum',
23
- 'source.lang.swift.decl.extension' => 'Extension',
24
- 'source.lang.swift.decl.function.free' => 'Function',
25
- 'source.lang.swift.decl.function.method.instance' => 'Instance Method',
26
- 'source.lang.swift.decl.var.instance' => 'Instance Variable',
27
- 'source.lang.swift.decl.var.local' => 'Local Variable',
28
- 'source.lang.swift.decl.var.parameter' => 'Parameter',
29
- 'source.lang.swift.decl.protocol' => 'Protocol',
30
- 'source.lang.swift.decl.function.method.static' => 'Static Method',
31
- 'source.lang.swift.decl.var.static' => 'Static Variable',
32
- 'source.lang.swift.decl.struct' => 'Struct',
33
- 'source.lang.swift.decl.function.subscript' => 'Subscript',
34
- 'source.lang.swift.decl.typealias' => 'Typealias',
35
- }
36
- end
14
+ @kinds = {
15
+ 'source.lang.swift.decl.function.method.class' => 'Class Method',
16
+ 'source.lang.swift.decl.var.class' => 'Class Variable',
17
+ 'source.lang.swift.decl.class' => 'Class',
18
+ 'source.lang.swift.decl.function.constructor' => 'Constructor',
19
+ 'source.lang.swift.decl.function.destructor' => 'Destructor',
20
+ 'source.lang.swift.decl.var.global' => 'Global Variable',
21
+ 'source.lang.swift.decl.enumelement' => 'Enum Element',
22
+ 'source.lang.swift.decl.enum' => 'Enum',
23
+ 'source.lang.swift.decl.extension' => 'Extension',
24
+ 'source.lang.swift.decl.function.free' => 'Function',
25
+ 'source.lang.swift.decl.function.method.instance' => 'Instance Method',
26
+ 'source.lang.swift.decl.var.instance' => 'Instance Variable',
27
+ 'source.lang.swift.decl.var.local' => 'Local Variable',
28
+ 'source.lang.swift.decl.var.parameter' => 'Parameter',
29
+ 'source.lang.swift.decl.protocol' => 'Protocol',
30
+ 'source.lang.swift.decl.function.method.static' => 'Static Method',
31
+ 'source.lang.swift.decl.var.static' => 'Static Variable',
32
+ 'source.lang.swift.decl.struct' => 'Struct',
33
+ 'source.lang.swift.decl.function.subscript' => 'Subscript',
34
+ 'source.lang.swift.decl.typealias' => 'Typealias',
35
+ }.freeze
37
36
 
38
37
  # Group root-level docs by kind and add as children to a group doc element
39
38
  def self.group_docs(docs, kind)
40
- kind_name_plural = kinds[kind].pluralize
39
+ kind_name_plural = @kinds[kind].pluralize
41
40
  group, docs = docs.partition { |doc| doc.kind == kind }
42
41
  docs << SourceDeclaration.new.tap do |sd|
43
42
  sd.name = kind_name_plural
44
43
  sd.kind = 'Overview'
45
- sd.abstract = "The following #{kind_name_plural.downcase} are available " \
46
- 'globally.'
44
+ sd.abstract = "The following #{kind_name_plural.downcase} are " \
45
+ 'available globally.'
47
46
  sd.children = group
48
47
  end if group.count > 0
49
48
  docs
@@ -69,10 +68,53 @@ module Jazzy
69
68
 
70
69
  # Run sourcekitten with given arguments and return STDOUT
71
70
  def self.run_sourcekitten(arguments)
72
- bin_path = File.expand_path(File.join(File.dirname(__FILE__), '../../bin'))
71
+ bin_path = Pathname(__FILE__).parent + '../../bin'
73
72
  `#{bin_path}/sourcekitten #{(arguments).join(' ')}`
74
73
  end
75
74
 
75
+ def self.make_default_doc_info(declaration)
76
+ # @todo: Fix these
77
+ declaration.line = 0
78
+ declaration.column = 0
79
+ declaration.abstract = 'Undocumented'
80
+ declaration.parameters = []
81
+ end
82
+
83
+ def self.make_doc_info(doc, declaration)
84
+ if doc['key.doc.full_as_xml']
85
+ xml = Nokogiri::XML(doc['key.doc.full_as_xml']).root
86
+ declaration.line = XMLHelper.attribute(xml, 'line').to_i
87
+ declaration.column = XMLHelper.attribute(xml, 'column').to_i
88
+ declaration.declaration = XMLHelper.xpath(xml, 'Declaration')
89
+ declaration.abstract = XMLHelper.xpath(xml, 'Abstract')
90
+ declaration.discussion = XMLHelper.xpath(xml, 'Discussion')
91
+ declaration.return = XMLHelper.xpath(xml, 'ResultDiscussion')
92
+
93
+ declaration.parameters = []
94
+ xml.xpath('Parameters/Parameter').each do |parameter_el|
95
+ declaration.parameters << {
96
+ name: XMLHelper.xpath(parameter_el, 'Name'),
97
+ discussion: Jazzy.markdown.render(
98
+ XMLHelper.xpath(parameter_el, 'Discussion'),
99
+ ),
100
+ }
101
+ end
102
+ else
103
+ make_default_doc_info(declaration)
104
+ end
105
+ end
106
+
107
+ def self.make_substructure(doc, declaration)
108
+ if doc['key.substructure']
109
+ declaration.children = make_source_declarations(
110
+ doc['key.substructure'],
111
+ )
112
+ else
113
+ declaration.children = []
114
+ end
115
+ end
116
+
117
+ # rubocop:disable Metrics/MethodLength
76
118
  def self.make_source_declarations(docs)
77
119
  declarations = []
78
120
  docs.each do |doc|
@@ -83,63 +125,46 @@ module Jazzy
83
125
  declaration = SourceDeclaration.new
84
126
  declaration.kind = doc['key.kind']
85
127
  next unless declaration.kind =~ /^source\.lang\.swift\.decl\..*/
86
- next if declaration.kind == 'source.lang.swift.decl.var.parameter'
87
128
 
88
- declaration.kindName = kinds[declaration.kind]
89
-
90
- raise 'Please file an issue on https://github.com/realm/jazzy/issues ' \
91
- "about adding support for `#{declaration.kind}`" unless declaration.kindName
129
+ unless declaration.kindName = @kinds[declaration.kind]
130
+ raise 'Please file an issue on ' \
131
+ 'https://github.com/realm/jazzy/issues about adding support for ' \
132
+ "`#{declaration.kind}`"
133
+ end
92
134
 
93
135
  declaration.kindNamePlural = declaration.kindName.pluralize
94
136
  declaration.file = doc['key.filepath']
95
137
  declaration.usr = doc['key.usr']
96
138
  declaration.name = doc['key.name']
97
139
 
98
- if doc['key.doc.full_as_xml']
99
- xml = Nokogiri::XML(doc['key.doc.full_as_xml']).root
100
- declaration.line = XMLHelper.attribute(xml, 'line').to_i
101
- declaration.column = XMLHelper.attribute(xml, 'column').to_i
102
- declaration.declaration = XMLHelper.xpath(xml, 'Declaration')
103
- declaration.abstract = XMLHelper.xpath(xml, 'Abstract')
104
- declaration.discussion = XMLHelper.xpath(xml, 'Discussion')
105
- declaration.return = XMLHelper.xpath(xml, 'ResultDiscussion')
106
-
107
- parameters = []
108
- xml.xpath('Parameters/Parameter').each do |parameter_el|
109
- parameters << {
110
- name: XMLHelper.xpath(parameter_el, 'Name'),
111
- discussion: Jazzy.markdown.render(
112
- XMLHelper.xpath(parameter_el, 'Discussion'),
113
- ),
114
- }
115
- end
116
- declaration.parameters = parameters
117
- else
118
- # @todo: Fix these
119
- declaration.line = 0
120
- declaration.column = 0
121
- declaration.abstract = 'Undocumented'
122
- declaration.parameters = []
123
- end
124
-
125
- if doc['key.substructure']
126
- declaration.children = make_source_declarations(doc['key.substructure'])
127
- else
128
- declaration.children = []
129
- end
140
+ make_doc_info(doc, declaration)
141
+ make_substructure(doc, declaration)
130
142
  declarations << declaration
131
143
  end
132
144
  declarations
133
145
  end
146
+ # rubocop:enable Metrics/MethodLength
147
+
148
+ def self.doc_coverage(sourcekitten_json)
149
+ documented = sourcekitten_json
150
+ .map { |el| el['key.doc.documented'] }
151
+ .inject(:+)
152
+ undocumented = sourcekitten_json
153
+ .map { |el| el['key.doc.undocumented'] }
154
+ .inject(:+)
155
+ return 0 if documented == 0 && undocumented == 0
156
+ (100 * documented) / (undocumented + documented)
157
+ end
134
158
 
135
- # Parse sourcekitten STDOUT+STDERR output as JSON
159
+ # Parse sourcekitten STDOUT output as JSON
136
160
  # @return [Hash] structured docs
137
161
  def self.parse(sourcekitten_output)
138
- docs = make_source_declarations(JSON.parse(sourcekitten_output))
139
- kinds.keys.each do |kind|
162
+ sourcekitten_json = JSON.parse(sourcekitten_output)
163
+ docs = make_source_declarations(sourcekitten_json)
164
+ @kinds.keys.each do |kind|
140
165
  docs = group_docs(docs, kind)
141
166
  end
142
- make_doc_urls(docs, [])
167
+ [make_doc_urls(docs, []), doc_coverage(sourcekitten_json)]
143
168
  end
144
169
  end
145
170
  end