jazzy 0.14.4 → 0.15.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.
- checksums.yaml +4 -4
- data/.github/workflows/Tests.yml +6 -5
- data/.rubocop.yml +13 -0
- data/CHANGELOG.md +40 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile.lock +62 -47
- data/README.md +115 -5
- data/bin/sourcekitten +0 -0
- data/js/package-lock.json +6 -6
- data/lib/jazzy/config.rb +156 -24
- data/lib/jazzy/doc.rb +2 -2
- data/lib/jazzy/doc_builder.rb +55 -29
- data/lib/jazzy/doc_index.rb +185 -0
- data/lib/jazzy/docset_builder/info_plist.mustache +1 -1
- data/lib/jazzy/docset_builder.rb +44 -13
- data/lib/jazzy/extensions/katex/css/katex.min.css +1 -1
- data/lib/jazzy/extensions/katex/js/katex.min.js +1 -1
- data/lib/jazzy/gem_version.rb +1 -1
- data/lib/jazzy/grouper.rb +130 -0
- data/lib/jazzy/podspec_documenter.rb +1 -1
- data/lib/jazzy/source_declaration/type.rb +10 -2
- data/lib/jazzy/source_declaration.rb +69 -8
- data/lib/jazzy/source_document.rb +5 -1
- data/lib/jazzy/source_module.rb +13 -11
- data/lib/jazzy/sourcekitten.rb +231 -237
- data/lib/jazzy/symbol_graph/ext_key.rb +37 -0
- data/lib/jazzy/symbol_graph/ext_node.rb +23 -6
- data/lib/jazzy/symbol_graph/graph.rb +31 -19
- data/lib/jazzy/symbol_graph/relationship.rb +21 -3
- data/lib/jazzy/symbol_graph/sym_node.rb +10 -22
- data/lib/jazzy/symbol_graph/symbol.rb +28 -0
- data/lib/jazzy/symbol_graph.rb +19 -16
- data/lib/jazzy/themes/apple/assets/css/jazzy.css.scss +10 -7
- data/lib/jazzy/themes/apple/assets/js/typeahead.jquery.js +3 -2
- data/lib/jazzy/themes/apple/templates/doc.mustache +8 -1
- data/lib/jazzy/themes/fullwidth/assets/css/jazzy.css.scss +5 -5
- data/lib/jazzy/themes/fullwidth/assets/js/typeahead.jquery.js +3 -2
- data/lib/jazzy/themes/fullwidth/templates/doc.mustache +8 -1
- data/lib/jazzy/themes/jony/assets/css/jazzy.css.scss +6 -5
- data/lib/jazzy/themes/jony/templates/doc.mustache +9 -2
- data/spec/integration_spec.rb +8 -1
- metadata +5 -2
data/lib/jazzy/gem_version.rb
CHANGED
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jazzy
|
4
|
+
# This module deals with arranging top-level declarations and guides into
|
5
|
+
# groups automatically and/or using a custom list.
|
6
|
+
module Grouper
|
7
|
+
extend Config::Mixin
|
8
|
+
|
9
|
+
# Group root-level docs by custom categories (if any) and type or module
|
10
|
+
def self.group_docs(docs, doc_index)
|
11
|
+
custom_categories, docs = group_custom_categories(docs, doc_index)
|
12
|
+
unlisted_prefix = config.custom_categories_unlisted_prefix
|
13
|
+
type_category_prefix = custom_categories.any? ? unlisted_prefix : ''
|
14
|
+
all_categories =
|
15
|
+
custom_categories +
|
16
|
+
if config.merge_modules == :all
|
17
|
+
group_docs_by_type(docs, type_category_prefix)
|
18
|
+
else
|
19
|
+
group_docs_by_module(docs, type_category_prefix)
|
20
|
+
end
|
21
|
+
merge_consecutive_marks(all_categories)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Group root-level docs by type
|
25
|
+
def self.group_docs_by_type(docs, type_category_prefix)
|
26
|
+
type_groups = SourceDeclaration::Type.all.map do |type|
|
27
|
+
children, docs = docs.partition { _1.type == type }
|
28
|
+
make_type_group(children, type, type_category_prefix)
|
29
|
+
end
|
30
|
+
merge_categories(type_groups.compact) + docs
|
31
|
+
end
|
32
|
+
|
33
|
+
# Group root-level docs by module name
|
34
|
+
def self.group_docs_by_module(docs, type_category_prefix)
|
35
|
+
guide_categories, docs = group_guides(docs, type_category_prefix)
|
36
|
+
|
37
|
+
module_categories = docs
|
38
|
+
.group_by(&:doc_module_name)
|
39
|
+
.map do |name, module_docs|
|
40
|
+
make_group(
|
41
|
+
module_docs,
|
42
|
+
name,
|
43
|
+
"The following declarations are provided by module #{name}.",
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
guide_categories + module_categories
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.group_custom_categories(docs, doc_index)
|
51
|
+
group = config.custom_categories.map do |category|
|
52
|
+
children = category['children'].filter_map do |name|
|
53
|
+
unless doc = doc_index.lookup(name)
|
54
|
+
warn 'WARNING: No documented top-level declarations match ' \
|
55
|
+
"name \"#{name}\" specified in categories file"
|
56
|
+
next nil
|
57
|
+
end
|
58
|
+
|
59
|
+
unless doc.parent_in_code.nil?
|
60
|
+
warn "WARNING: Declaration \"#{doc.fully_qualified_module_name}\" " \
|
61
|
+
'specified in categories file exists but is not top-level and ' \
|
62
|
+
'cannot be included here'
|
63
|
+
next nil
|
64
|
+
end
|
65
|
+
|
66
|
+
docs.delete(doc)
|
67
|
+
end
|
68
|
+
# Category config overrides alphabetization
|
69
|
+
children.each.with_index { |child, i| child.nav_order = i }
|
70
|
+
make_group(children, category['name'], '')
|
71
|
+
end
|
72
|
+
[group.compact, docs]
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.group_guides(docs, prefix)
|
76
|
+
guides, others = docs.partition { _1.type.markdown? }
|
77
|
+
return [[], others] unless guides.any?
|
78
|
+
|
79
|
+
[[make_type_group(guides, guides.first.type, prefix)], others]
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.make_type_group(docs, type, type_category_prefix)
|
83
|
+
make_group(
|
84
|
+
docs,
|
85
|
+
type_category_prefix + type.plural_name,
|
86
|
+
"The following #{type.plural_name.downcase} are available globally.",
|
87
|
+
type_category_prefix + type.plural_url_name,
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Join categories with the same name (eg. ObjC and Swift classes)
|
92
|
+
def self.merge_categories(categories)
|
93
|
+
merged = []
|
94
|
+
categories.each do |new_category|
|
95
|
+
if existing = merged.find { _1.name == new_category.name }
|
96
|
+
existing.children += new_category.children
|
97
|
+
else
|
98
|
+
merged.append(new_category)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
merged
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.make_group(group, name, abstract, url_name = nil)
|
105
|
+
group.reject! { _1.name.empty? }
|
106
|
+
unless group.empty?
|
107
|
+
SourceDeclaration.new.tap do |sd|
|
108
|
+
sd.type = SourceDeclaration::Type.overview
|
109
|
+
sd.name = name
|
110
|
+
sd.url_name = url_name
|
111
|
+
sd.abstract = Markdown.render(abstract)
|
112
|
+
sd.children = group
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Merge consecutive sections with the same mark into one section
|
118
|
+
# Needed because of pulling various decls into groups
|
119
|
+
def self.merge_consecutive_marks(docs)
|
120
|
+
prev_mark = nil
|
121
|
+
docs.each do |doc|
|
122
|
+
if prev_mark&.can_merge?(doc.mark)
|
123
|
+
doc.mark = prev_mark
|
124
|
+
end
|
125
|
+
prev_mark = doc.mark
|
126
|
+
merge_consecutive_marks(doc.children)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -52,7 +52,7 @@ module Jazzy
|
|
52
52
|
config.author_name = author_name(podspec)
|
53
53
|
config.author_name_configured = true
|
54
54
|
end
|
55
|
-
unless config.
|
55
|
+
unless config.module_name_known?
|
56
56
|
config.module_name = podspec.module_name
|
57
57
|
config.module_name_configured = true
|
58
58
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'active_support'
|
3
4
|
require 'active_support/inflector'
|
4
5
|
|
5
6
|
module Jazzy
|
@@ -163,8 +164,14 @@ module Jazzy
|
|
163
164
|
kind == 'sourcekitten.source.lang.objc.decl.unexposed'
|
164
165
|
end
|
165
166
|
|
167
|
+
OVERVIEW_KIND = 'Overview'
|
168
|
+
|
166
169
|
def self.overview
|
167
|
-
Type.new(
|
170
|
+
Type.new(OVERVIEW_KIND)
|
171
|
+
end
|
172
|
+
|
173
|
+
def overview?
|
174
|
+
kind == OVERVIEW_KIND
|
168
175
|
end
|
169
176
|
|
170
177
|
MARKDOWN_KIND = 'document.markdown'
|
@@ -193,7 +200,8 @@ module Jazzy
|
|
193
200
|
dash: 'Guide',
|
194
201
|
}.freeze,
|
195
202
|
|
196
|
-
|
203
|
+
# Group/Overview
|
204
|
+
OVERVIEW_KIND => {
|
197
205
|
jazzy: nil,
|
198
206
|
dash: 'Section',
|
199
207
|
}.freeze,
|
@@ -62,6 +62,7 @@ module Jazzy
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
# 'OuterType.NestedType.method(arg:)'
|
65
66
|
def fully_qualified_name
|
66
67
|
namespace_path.map(&:name).join('.')
|
67
68
|
end
|
@@ -74,6 +75,21 @@ module Jazzy
|
|
74
75
|
.join('(?:<.*?>)?\.'))
|
75
76
|
end
|
76
77
|
|
78
|
+
def fully_qualified_module_name_parts
|
79
|
+
path = namespace_path
|
80
|
+
path.map(&:name).prepend(path.first.module_name).compact
|
81
|
+
end
|
82
|
+
|
83
|
+
# 'MyModule.OuterType.NestedType.method(arg:)'
|
84
|
+
def fully_qualified_module_name
|
85
|
+
fully_qualified_module_name_parts.join('.')
|
86
|
+
end
|
87
|
+
|
88
|
+
# List of doc_parent decls, .last is self
|
89
|
+
def docs_path
|
90
|
+
(parent_in_docs&.docs_path || []) + [self]
|
91
|
+
end
|
92
|
+
|
77
93
|
# If this declaration is an objc category, returns an array with the name
|
78
94
|
# of the extended objc class and the category name itself, i.e.
|
79
95
|
# ["NSString", "MyMethods"], nil otherwise.
|
@@ -114,7 +130,7 @@ module Jazzy
|
|
114
130
|
attr_accessor :column
|
115
131
|
attr_accessor :usr
|
116
132
|
attr_accessor :type_usr
|
117
|
-
attr_accessor :
|
133
|
+
attr_accessor :module_name
|
118
134
|
attr_accessor :name
|
119
135
|
attr_accessor :objc_name
|
120
136
|
attr_accessor :declaration
|
@@ -140,6 +156,11 @@ module Jazzy
|
|
140
156
|
attr_accessor :inherited_types
|
141
157
|
attr_accessor :async
|
142
158
|
|
159
|
+
# The name of the module being documented that contains this
|
160
|
+
# declaration. Only different from module_name when this is
|
161
|
+
# an extension of a type from another module. Nil for guides.
|
162
|
+
attr_accessor :doc_module_name
|
163
|
+
|
143
164
|
def usage_discouraged?
|
144
165
|
unavailable || deprecated
|
145
166
|
end
|
@@ -183,20 +204,60 @@ module Jazzy
|
|
183
204
|
inherited_types.any? { |t| !unwanted.include?(t) }
|
184
205
|
end
|
185
206
|
|
186
|
-
# Pre-Swift 5.6: SourceKit only sets
|
187
|
-
# Swift 5.6+:
|
207
|
+
# Pre-Swift 5.6: SourceKit only sets module_name for imported modules
|
208
|
+
# Swift 5.6+: module_name is always set
|
188
209
|
def type_from_doc_module?
|
189
210
|
!type.extension? ||
|
190
211
|
(swift? && usr &&
|
191
|
-
(
|
212
|
+
(module_name.nil? || module_name == doc_module_name))
|
213
|
+
end
|
214
|
+
|
215
|
+
# Don't ask the user to write documentation for types being extended
|
216
|
+
# from other modules. Compile errors leave no docs and a `nil` USR.
|
217
|
+
def mark_undocumented?
|
218
|
+
!swift? || (usr && !extension_of_external_type?)
|
219
|
+
end
|
220
|
+
|
221
|
+
def extension_of_external_type?
|
222
|
+
!module_name.nil? &&
|
223
|
+
!Config.instance.module_name?(module_name)
|
224
|
+
end
|
225
|
+
|
226
|
+
# Is it unclear from context what module the (top-level) decl is from?
|
227
|
+
def ambiguous_module_name?(group_name)
|
228
|
+
extension_of_external_type? ||
|
229
|
+
(Config.instance.multiple_modules? &&
|
230
|
+
!module_name.nil? &&
|
231
|
+
group_name != module_name)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Does the user need help understanding how to get this declaration?
|
235
|
+
def need_doc_module_note?
|
236
|
+
return false unless Config.instance.multiple_modules?
|
237
|
+
return false if docs_path.first.name == doc_module_name
|
238
|
+
|
239
|
+
if parent_in_code.nil?
|
240
|
+
# Top-level decls with no page of their own
|
241
|
+
!render_as_page?
|
242
|
+
else
|
243
|
+
# Members added by extension
|
244
|
+
parent_in_code.module_name != doc_module_name
|
245
|
+
end
|
192
246
|
end
|
193
247
|
|
194
248
|
# Info text for contents page by collapsed item name
|
195
249
|
def declaration_note
|
196
|
-
notes = [
|
197
|
-
|
198
|
-
|
199
|
-
|
250
|
+
notes = [
|
251
|
+
default_impl_abstract ? 'default implementation' : nil,
|
252
|
+
from_protocol_extension ? 'extension method' : nil,
|
253
|
+
async ? 'asynchronous' : nil,
|
254
|
+
need_doc_module_note? ? "from #{doc_module_name}" : nil,
|
255
|
+
].compact
|
256
|
+
notes.join(', ').upcase_first unless notes.empty?
|
257
|
+
end
|
258
|
+
|
259
|
+
def readme?
|
260
|
+
false
|
200
261
|
end
|
201
262
|
|
202
263
|
def alternative_abstract
|
@@ -27,6 +27,10 @@ module Jazzy
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
def readme?
|
31
|
+
url == 'index.html'
|
32
|
+
end
|
33
|
+
|
30
34
|
def render_as_page?
|
31
35
|
true
|
32
36
|
end
|
@@ -89,7 +93,7 @@ pod '#{podspec.name}'
|
|
89
93
|
README
|
90
94
|
else
|
91
95
|
<<-README
|
92
|
-
# #{source_module.
|
96
|
+
# #{source_module.readme_title}
|
93
97
|
|
94
98
|
### Authors
|
95
99
|
|
data/lib/jazzy/source_module.rb
CHANGED
@@ -7,28 +7,30 @@ require 'jazzy/source_declaration'
|
|
7
7
|
require 'jazzy/source_host'
|
8
8
|
|
9
9
|
module Jazzy
|
10
|
+
# A cache of info that is common across all page templating, gathered
|
11
|
+
# from other parts of the program.
|
10
12
|
class SourceModule
|
11
|
-
|
13
|
+
include Config::Mixin
|
14
|
+
|
15
|
+
attr_accessor :readme_title
|
12
16
|
attr_accessor :docs
|
13
17
|
attr_accessor :doc_coverage
|
14
18
|
attr_accessor :doc_structure
|
15
19
|
attr_accessor :author_name
|
16
20
|
attr_accessor :author_url
|
17
|
-
attr_accessor :
|
21
|
+
attr_accessor :dash_feed_url
|
18
22
|
attr_accessor :host
|
19
23
|
|
20
|
-
def initialize(
|
24
|
+
def initialize(docs, doc_structure, doc_coverage, docset_builder)
|
21
25
|
self.docs = docs
|
22
26
|
self.doc_structure = doc_structure
|
23
27
|
self.doc_coverage = doc_coverage
|
24
|
-
|
25
|
-
self.
|
26
|
-
self.
|
27
|
-
self.
|
28
|
-
|
29
|
-
|
30
|
-
self.dash_url =
|
31
|
-
"dash-feed://#{ERB::Util.url_encode(options.dash_url.to_s)}"
|
28
|
+
title = config.readme_title || config.module_names.first
|
29
|
+
self.readme_title = title.empty? ? 'Index' : title
|
30
|
+
self.author_name = config.author_name
|
31
|
+
self.author_url = config.author_url
|
32
|
+
self.host = SourceHost.create(config)
|
33
|
+
self.dash_feed_url = docset_builder.dash_feed_url
|
32
34
|
end
|
33
35
|
|
34
36
|
def all_declarations
|