jazzy 0.10.0 → 0.13.0

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.
data/bin/sourcekitten CHANGED
Binary file
data/jazzy.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_runtime_dependency 'open4'
23
23
  spec.add_runtime_dependency 'redcarpet', '~> 3.4'
24
24
  spec.add_runtime_dependency 'rouge', ['>= 2.0.6', '< 4.0']
25
- spec.add_runtime_dependency 'sass', '~> 3.6'
25
+ spec.add_runtime_dependency 'sassc', '~> 2.1'
26
26
  spec.add_runtime_dependency 'sqlite3', '~> 1.3'
27
27
  spec.add_runtime_dependency 'xcinvoke', '~> 0.3.0'
28
28
 
data/lib/jazzy/config.rb CHANGED
@@ -79,6 +79,14 @@ module Jazzy
79
79
  @all_config_attrs << Attribute.new(name, **opts)
80
80
  end
81
81
 
82
+ def self.alias_config_attr(name, forward, **opts)
83
+ alias_method name.to_s, forward.to_s
84
+ alias_method "#{name}=", "#{forward}="
85
+ alias_method "#{name}_configured", "#{forward}_configured"
86
+ alias_method "#{name}_configured=", "#{forward}_configured="
87
+ @all_config_attrs << Attribute.new(name, **opts)
88
+ end
89
+
82
90
  class << self
83
91
  attr_reader :all_config_attrs
84
92
  end
@@ -94,6 +102,14 @@ module Jazzy
94
102
  Pathname(Dir[abs_path][0] || abs_path) # Use existing filesystem spelling
95
103
  end
96
104
 
105
+ def hide_swift?
106
+ hide_declarations == 'swift'
107
+ end
108
+
109
+ def hide_objc?
110
+ hide_declarations == 'objc'
111
+ end
112
+
97
113
  # ──────── Build ────────
98
114
 
99
115
  # rubocop:disable Layout/AlignParameters
@@ -135,9 +151,9 @@ module Jazzy
135
151
  command_line: '--hide-declarations [objc|swift] ',
136
152
  description: 'Hide declarations in the specified language. Given that ' \
137
153
  'generating Swift docs only generates Swift declarations, ' \
138
- 'this is only really useful to display just the Swift ' \
139
- 'declarations & names when generating docs for an ' \
140
- 'Objective-C framework.',
154
+ 'this is useful for hiding a specific interface for ' \
155
+ 'either Objective-C or mixed Objective-C and Swift ' \
156
+ 'projects.',
141
157
  default: ''
142
158
 
143
159
  config_attr :config_file,
@@ -146,15 +162,21 @@ module Jazzy
146
162
  'Default: .jazzy.yaml in source directory or ancestor'],
147
163
  parse: ->(cf) { expand_path(cf) }
148
164
 
149
- config_attr :xcodebuild_arguments,
150
- command_line: ['-x', '--xcodebuild-arguments arg1,arg2,…argN', Array],
151
- description: 'Arguments to forward to xcodebuild',
165
+ config_attr :build_tool_arguments,
166
+ command_line: ['-b', '--build-tool-arguments arg1,arg2,…argN', Array],
167
+ description: 'Arguments to forward to xcodebuild, swift build, or ' \
168
+ 'sourcekitten.',
152
169
  default: []
153
170
 
171
+ alias_config_attr :xcodebuild_arguments, :build_tool_arguments,
172
+ command_line: ['-x', '--xcodebuild-arguments arg1,arg2,…argN', Array],
173
+ description: 'Back-compatibility alias for build_tool_arguments.'
174
+
154
175
  config_attr :sourcekitten_sourcefile,
155
- command_line: ['-s', '--sourcekitten-sourcefile FILEPATH'],
156
- description: 'File generated from sourcekitten output to parse',
157
- parse: ->(s) { expand_path(s) }
176
+ command_line: ['-s', '--sourcekitten-sourcefile filepath1,…filepathN',
177
+ Array],
178
+ description: 'File(s) generated from sourcekitten output to parse',
179
+ parse: ->(paths) { [paths].flatten.map { |path| expand_path(path) } }
158
180
 
159
181
  config_attr :source_directory,
160
182
  command_line: '--source-directory DIRPATH',
@@ -192,6 +214,20 @@ module Jazzy
192
214
  end
193
215
  end
194
216
 
217
+ SWIFT_BUILD_TOOLS = %w[spm xcodebuild].freeze
218
+
219
+ config_attr :swift_build_tool,
220
+ command_line: "--swift-build-tool #{SWIFT_BUILD_TOOLS.join(' | ')}",
221
+ description: 'Control whether Jazzy uses Swift Package Manager or '\
222
+ 'xcodebuild to build the module to be documented. By '\
223
+ 'default it uses xcodebuild if there is a .xcodeproj '\
224
+ 'file in the source directory.',
225
+ parse: ->(tool) do
226
+ return tool.to_sym if SWIFT_BUILD_TOOLS.include?(tool)
227
+ raise "Unsupported swift_build_tool #{tool}, "\
228
+ "supported values: #{SWIFT_BUILD_TOOLS.join(', ')}"
229
+ end
230
+
195
231
  # ──────── Metadata ────────
196
232
 
197
233
  config_attr :author_name,
data/lib/jazzy/doc.rb CHANGED
@@ -32,10 +32,6 @@ module Jazzy
32
32
  config.objc_mode && config.hide_declarations != 'objc'
33
33
  end
34
34
 
35
- def language
36
- objc_first? ? 'Objective-C' : 'Swift'
37
- end
38
-
39
35
  def language_stub
40
36
  objc_first? ? 'objc' : 'swift'
41
37
  end
@@ -1,7 +1,7 @@
1
1
  require 'fileutils'
2
2
  require 'mustache'
3
3
  require 'pathname'
4
- require 'sass'
4
+ require 'sassc'
5
5
 
6
6
  require 'jazzy/config'
7
7
  require 'jazzy/doc'
@@ -53,23 +53,16 @@ module Jazzy
53
53
  # @param [Config] options
54
54
  # @return [SourceModule] the documented source module
55
55
  def self.build(options)
56
- if options.sourcekitten_sourcefile
57
- stdout = options.sourcekitten_sourcefile.read
56
+ if options.sourcekitten_sourcefile_configured
57
+ stdout = '[' + options.sourcekitten_sourcefile.map(&:read)
58
+ .join(',') + ']'
59
+ elsif options.podspec_configured
60
+ pod_documenter = PodspecDocumenter.new(options.podspec)
61
+ stdout = pod_documenter.sourcekitten_output(options)
58
62
  else
59
- if options.podspec_configured
60
- pod_documenter = PodspecDocumenter.new(options.podspec)
61
- stdout = pod_documenter.sourcekitten_output(options)
62
- else
63
- stdout = Dir.chdir(options.source_directory) do
64
- arguments = SourceKitten.arguments_from_options(options)
65
- SourceKitten.run_sourcekitten(arguments)
66
- end
67
- end
68
- unless $?.success?
69
- warn 'Please pass in xcodebuild arguments using -x'
70
- warn 'If build arguments are correct, please file an issue on ' \
71
- 'https://github.com/realm/jazzy/issues'
72
- exit $?.exitstatus || 1
63
+ stdout = Dir.chdir(options.source_directory) do
64
+ arguments = SourceKitten.arguments_from_options(options)
65
+ SourceKitten.run_sourcekitten(arguments)
73
66
  end
74
67
  end
75
68
 
@@ -95,10 +88,9 @@ module Jazzy
95
88
  def self.each_doc(output_dir, docs, &block)
96
89
  docs.each do |doc|
97
90
  next unless doc.render_as_page?
98
- # Assuming URL is relative to documentation root:
99
- path = output_dir + (doc.url || "#{doc.name}.html")
91
+ # Filepath is relative to documentation root:
92
+ path = output_dir + doc.filepath
100
93
  block.call(doc, path)
101
- next if doc.name == 'index'
102
94
  each_doc(
103
95
  output_dir,
104
96
  doc.children,
@@ -198,8 +190,7 @@ module Jazzy
198
190
  assets_directory = Config.instance.theme_directory + 'assets'
199
191
  FileUtils.cp_r(assets_directory.children, destination)
200
192
  Pathname.glob(destination + 'css/**/*.scss').each do |scss|
201
- contents = scss.read
202
- css = Sass::Engine.new(contents, syntax: :scss).render
193
+ css = SassC::Engine.new(scss.read).render
203
194
  css_filename = scss.sub(/\.scss$/, '')
204
195
  css_filename.open('w') { |f| f.write(css) }
205
196
  FileUtils.rm scss
@@ -339,6 +330,7 @@ module Jazzy
339
330
  name: item.name,
340
331
  abstract: abstract,
341
332
  declaration: item.display_declaration,
333
+ language: item.display_language,
342
334
  other_language_declaration: item.display_other_language_declaration,
343
335
  usr: item.usr,
344
336
  dash_type: item.type.dash_type,
@@ -358,9 +350,10 @@ module Jazzy
358
350
  end
359
351
  # rubocop:enable Metrics/MethodLength
360
352
 
361
- def self.make_task(mark, uid, items)
353
+ def self.make_task(mark, uid, items, doc_model)
362
354
  {
363
355
  name: mark.name,
356
+ name_html: (render(doc_model, mark.name) if mark.name),
364
357
  uid: URI.encode(uid),
365
358
  items: items,
366
359
  pre_separator: mark.has_start_dash,
@@ -384,7 +377,7 @@ module Jazzy
384
377
  else
385
378
  mark_names_counts[uid] = 1
386
379
  end
387
- make_task(mark, uid, items)
380
+ make_task(mark, uid, items, mark_children.first)
388
381
  end
389
382
  end
390
383
 
@@ -78,7 +78,7 @@ module Jazzy
78
78
  'searchIndex (name, type, path);')
79
79
  source_module.all_declarations.select(&:type).each do |doc|
80
80
  db.execute('INSERT OR IGNORE INTO searchIndex(name, type, path) ' \
81
- 'VALUES (?, ?, ?);', [doc.name, doc.type.dash_type, doc.url])
81
+ 'VALUES (?, ?, ?);', [doc.name, doc.type.dash_type, doc.filepath])
82
82
  end
83
83
  end
84
84
  end
@@ -1,3 +1,3 @@
1
1
  module Jazzy
2
- VERSION = '0.10.0'.freeze unless defined? Jazzy::VERSION
2
+ VERSION = '0.13.0'.freeze unless defined? Jazzy::VERSION
3
3
  end
@@ -3,6 +3,9 @@ require 'rouge'
3
3
  module Jazzy
4
4
  # This module helps highlight code
5
5
  module Highlighter
6
+ SWIFT = 'swift'.freeze
7
+ OBJC = 'objective_c'.freeze
8
+
6
9
  class Formatter < Rouge::Formatters::HTML
7
10
  def initialize(language)
8
11
  @language = language
@@ -16,16 +19,15 @@ module Jazzy
16
19
  end
17
20
  end
18
21
 
19
- # What Rouge calls the language
20
- def self.default_language
21
- if Config.instance.objc_mode
22
- 'objective_c'
23
- else
24
- 'swift'
25
- end
22
+ def self.highlight_swift(source)
23
+ highlight(source, SWIFT)
24
+ end
25
+
26
+ def self.highlight_objc(source)
27
+ highlight(source, OBJC)
26
28
  end
27
29
 
28
- def self.highlight(source, language = default_language)
30
+ def self.highlight(source, language)
29
31
  source && Rouge.highlight(source, language, Formatter.new(language))
30
32
  end
31
33
  end
@@ -11,7 +11,7 @@ module Jazzy
11
11
  attr_accessor :default_language
12
12
 
13
13
  def header(text, header_level)
14
- text_slug = text.gsub(/[^\w]+/, '-')
14
+ text_slug = text.gsub(/[^[[:word:]]]+/, '-')
15
15
  .downcase
16
16
  .sub(/^-/, '')
17
17
  .sub(/-$/, '')
@@ -82,21 +82,21 @@ module Jazzy
82
82
 
83
83
  def render_aside(type, text)
84
84
  <<-HTML
85
- <div class="aside aside-#{type.underscore.tr('_', '-')}">
85
+ </ul><div class="aside aside-#{type.underscore.tr('_', '-')}">
86
86
  <p class="aside-title">#{type.underscore.humanize}</p>
87
87
  #{text}
88
- </div>
88
+ </div><ul>
89
89
  HTML
90
90
  end
91
91
 
92
92
  def list(text, list_type)
93
93
  elided = text.gsub!(ELIDED_LI_TOKEN, '')
94
94
  return if text =~ /\A\s*\Z/ && elided
95
- return text if text =~ /class="aside-title"/
96
95
  str = "\n"
97
96
  str << (list_type == :ordered ? "<ol>\n" : "<ul>\n")
98
97
  str << text
99
98
  str << (list_type == :ordered ? "</ol>\n" : "</ul>\n")
99
+ str.gsub(%r{\n?<ul>\n<\/ul>}, '')
100
100
  end
101
101
 
102
102
  def block_code(code, language)
@@ -112,7 +112,6 @@ module Jazzy
112
112
  autolink: true,
113
113
  fenced_code_blocks: true,
114
114
  no_intra_emphasis: true,
115
- quote: true,
116
115
  strikethrough: true,
117
116
  space_after_headers: false,
118
117
  tables: true,
@@ -1,6 +1,7 @@
1
1
  require 'jazzy/source_declaration/access_control_level'
2
2
  require 'jazzy/source_declaration/type'
3
3
 
4
+ # rubocop:disable Metrics/ClassLength
4
5
  module Jazzy
5
6
  class SourceDeclaration
6
7
  # kind of declaration (e.g. class, variable, function)
@@ -13,6 +14,14 @@ module Jazzy
13
14
  children.any?
14
15
  end
15
16
 
17
+ def swift?
18
+ type.swift_type?
19
+ end
20
+
21
+ def highlight_language
22
+ swift? ? Highlighter::SWIFT : Highlighter::OBJC
23
+ end
24
+
16
25
  # When referencing this item from its parent category,
17
26
  # include the content or just link to it directly?
18
27
  def omit_content_from_parent?
@@ -67,17 +76,32 @@ module Jazzy
67
76
  name.split(/[\(\)]/) if type.objc_category?
68
77
  end
69
78
 
79
+ def swift_objc_extension?
80
+ type.swift_extension? && usr && usr.start_with?('c:objc')
81
+ end
82
+
83
+ def swift_extension_objc_name
84
+ return unless type.swift_extension? && usr
85
+
86
+ usr.split('(cs)').last
87
+ end
88
+
89
+ # The language in the templates for display
90
+ def display_language
91
+ return 'Swift' if swift?
92
+
93
+ Config.instance.hide_objc? ? 'Swift' : 'Objective-C'
94
+ end
95
+
70
96
  def display_declaration
71
- if Config.instance.hide_declarations == 'objc'
72
- other_language_declaration
73
- else
74
- declaration
75
- end
97
+ return declaration if swift?
98
+
99
+ Config.instance.hide_objc? ? other_language_declaration : declaration
76
100
  end
77
101
 
78
102
  def display_other_language_declaration
79
103
  other_language_declaration unless
80
- %w[swift objc].include? Config.instance.hide_declarations
104
+ Config.instance.hide_objc? || Config.instance.hide_swift?
81
105
  end
82
106
 
83
107
  attr_accessor :file
@@ -106,11 +130,47 @@ module Jazzy
106
130
  attr_accessor :deprecation_message
107
131
  attr_accessor :unavailable
108
132
  attr_accessor :unavailable_message
133
+ attr_accessor :generic_requirements
134
+ attr_accessor :inherited_types
109
135
 
110
136
  def usage_discouraged?
111
137
  unavailable || deprecated
112
138
  end
113
139
 
140
+ def filepath
141
+ CGI.unescape(url)
142
+ end
143
+
144
+ def constrained_extension?
145
+ type.swift_extension? &&
146
+ generic_requirements
147
+ end
148
+
149
+ def mark_for_children
150
+ if constrained_extension?
151
+ SourceMark.new_generic_requirements(generic_requirements)
152
+ else
153
+ SourceMark.new
154
+ end
155
+ end
156
+
157
+ def inherited_types?
158
+ inherited_types &&
159
+ !inherited_types.empty?
160
+ end
161
+
162
+ # Is there at least one inherited type that is not in the given list?
163
+ def other_inherited_types?(unwanted)
164
+ return false unless inherited_types?
165
+ inherited_types.any? { |t| !unwanted.include?(t) }
166
+ end
167
+
168
+ # SourceKit only sets modulename for imported modules
169
+ def type_from_doc_module?
170
+ !type.extension? ||
171
+ (swift? && usr && modulename.nil?)
172
+ end
173
+
114
174
  def alternative_abstract
115
175
  if file = alternative_abstract_file
116
176
  Pathname(file).read
@@ -77,6 +77,10 @@ module Jazzy
77
77
  kind == 'sourcekitten.source.lang.objc.decl.class'
78
78
  end
79
79
 
80
+ def swift_type?
81
+ kind.include? 'swift'
82
+ end
83
+
80
84
  def swift_enum_case?
81
85
  kind == 'source.lang.swift.decl.enumcase'
82
86
  end
@@ -110,6 +114,10 @@ module Jazzy
110
114
  kind == 'source.lang.swift.decl.protocol'
111
115
  end
112
116
 
117
+ def swift_typealias?
118
+ kind == 'source.lang.swift.decl.typealias'
119
+ end
120
+
113
121
  def param?
114
122
  # SourceKit strangely categorizes initializer parameters as local
115
123
  # variables, so both kinds represent a parameter in jazzy.
@@ -20,6 +20,7 @@ module Jazzy
20
20
  def self.make_index(readme_path)
21
21
  SourceDocument.new.tap do |sd|
22
22
  sd.name = 'index'
23
+ sd.url = sd.name + '.html'
23
24
  sd.readme_path = readme_path
24
25
  end
25
26
  end
@@ -36,8 +37,8 @@ module Jazzy
36
37
  Config.instance
37
38
  end
38
39
 
39
- def url
40
- name.downcase.strip.tr(' ', '-').gsub(/[^\w-]/, '') + '.html'
40
+ def url_name
41
+ name.downcase.strip.tr(' ', '-').gsub(/[^[[:word:]]-]/, '')
41
42
  end
42
43
 
43
44
  def content(source_module)