jazzy 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/CHANGELOG.md +72 -0
  4. data/CONTRIBUTING.md +3 -1
  5. data/Gemfile.lock +31 -29
  6. data/README.md +11 -10
  7. data/circle.yml +12 -0
  8. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Resources +1 -0
  9. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/SourceKittenFramework +1 -0
  10. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Commandant +1 -0
  11. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Resources +1 -0
  12. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Versions/Current +1 -0
  13. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Resources +1 -0
  14. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Result +1 -0
  15. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Versions/Current +1 -0
  16. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/Resources +1 -0
  17. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/SWXMLHash +1 -0
  18. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/Versions/Current +1 -0
  19. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Yams.framework/Resources +1 -0
  20. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Yams.framework/Versions/Current +1 -0
  21. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Yams.framework/Yams +1 -0
  22. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/Current +1 -0
  23. data/lib/jazzy/config.rb +16 -2
  24. data/lib/jazzy/doc_builder.rb +60 -8
  25. data/lib/jazzy/gem_version.rb +1 -1
  26. data/lib/jazzy/jazzy_markdown.rb +37 -25
  27. data/lib/jazzy/podspec_documenter.rb +3 -4
  28. data/lib/jazzy/search_builder.rb +21 -0
  29. data/lib/jazzy/source_declaration.rb +1 -1
  30. data/lib/jazzy/source_declaration/type.rb +7 -0
  31. data/lib/jazzy/source_document.rb +9 -0
  32. data/lib/jazzy/sourcekitten.rb +112 -60
  33. data/lib/jazzy/themes/apple/assets/js/jazzy.js +6 -0
  34. data/lib/jazzy/themes/fullwidth/assets/css/jazzy.css.scss +62 -0
  35. data/lib/jazzy/themes/fullwidth/assets/img/spinner.gif +0 -0
  36. data/lib/jazzy/themes/fullwidth/assets/js/jazzy.js +6 -0
  37. data/lib/jazzy/themes/fullwidth/assets/js/jazzy.search.js +62 -0
  38. data/lib/jazzy/themes/fullwidth/assets/js/lunr.min.js +6 -0
  39. data/lib/jazzy/themes/fullwidth/assets/js/typeahead.jquery.js +1538 -0
  40. data/lib/jazzy/themes/fullwidth/templates/doc.mustache +5 -0
  41. data/lib/jazzy/themes/fullwidth/templates/header.mustache +8 -0
  42. data/spec/integration_spec.rb +11 -9
  43. metadata +19 -4
  44. data/.travis.yml +0 -17
  45. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/SourceKittenFramework +0 -0
  46. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Commandant +0 -0
  47. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Result +0 -0
  48. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/SWXMLHash +0 -0
  49. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Yams.framework/Yams +0 -0
@@ -1,3 +1,3 @@
1
1
  module Jazzy
2
- VERSION = '0.7.3'.freeze unless defined? Jazzy::VERSION
2
+ VERSION = '0.7.4'.freeze unless defined? Jazzy::VERSION
3
3
  end
@@ -19,30 +19,40 @@ module Jazzy
19
19
  "<h#{header_level} id='#{text_slug}'>#{text}</h#{header_level}>\n"
20
20
  end
21
21
 
22
- SPECIAL_LIST_TYPES = %w(Attention
23
- Author
24
- Authors
25
- Bug
26
- Complexity
27
- Copyright
28
- Date
29
- Experiment
30
- Important
31
- Invariant
32
- Note
33
- Parameter
34
- Postcondition
35
- Precondition
36
- Remark
37
- Requires
38
- Returns
39
- See
40
- SeeAlso
41
- Since
42
- TODO
43
- Throws
44
- Version
45
- Warning).freeze
22
+ # List from
23
+ # https://github.com/apple/swift/blob/master/include/swift/Markup/SimpleFields.def
24
+ UNIQUELY_HANDLED_CALLOUTS = %w(parameters
25
+ parameter
26
+ returns).freeze
27
+ GENERAL_CALLOUTS = %w(attention
28
+ author
29
+ authors
30
+ bug
31
+ complexity
32
+ copyright
33
+ date
34
+ experiment
35
+ important
36
+ invariant
37
+ keyword
38
+ mutatingvariant
39
+ nonmutatingvariant
40
+ note
41
+ postcondition
42
+ precondition
43
+ recommended
44
+ recommendedover
45
+ remark
46
+ remarks
47
+ requires
48
+ see
49
+ seealso
50
+ since
51
+ todo
52
+ throws
53
+ version
54
+ warning).freeze
55
+ SPECIAL_LIST_TYPES = (UNIQUELY_HANDLED_CALLOUTS + GENERAL_CALLOUTS).freeze
46
56
 
47
57
  SPECIAL_LIST_TYPE_REGEX = %r{
48
58
  \A\s* # optional leading spaces
@@ -57,7 +67,9 @@ module Jazzy
57
67
  def list_item(text, _list_type)
58
68
  if text =~ SPECIAL_LIST_TYPE_REGEX
59
69
  type = Regexp.last_match(2)
60
- return ELIDED_LI_TOKEN if type =~ /parameter|returns/
70
+ if UNIQUELY_HANDLED_CALLOUTS.include? type.downcase
71
+ return ELIDED_LI_TOKEN
72
+ end
61
73
  return render_aside(type, text.sub(/#{Regexp.escape(type)}:\s+/, ''))
62
74
  end
63
75
  str = '<li>'
@@ -25,13 +25,12 @@ module Jazzy
25
25
 
26
26
  targets.map do |t|
27
27
  args = %W(doc --module-name #{podspec.module_name} -- -target #{t})
28
- if config.swift_version
29
- args << "SWIFT_VERSION=\"#{config.swift_version}\""
30
- end
28
+ swift_version = (config.swift_version || '3')[0] + '.0'
29
+ args << "SWIFT_VERSION=\"#{swift_version}\""
31
30
  SourceKitten.run_sourcekitten(args)
32
31
  end
33
32
  end
34
- stdout.reduce([]) { |a, s| a + JSON.load(s) }.to_json
33
+ stdout.reduce([]) { |a, s| a + JSON.parse(s) }.to_json
35
34
  end
36
35
  end
37
36
 
@@ -0,0 +1,21 @@
1
+ module Jazzy
2
+ module SearchBuilder
3
+ def self.build(source_module, output_dir)
4
+ decls = source_module.all_declarations.select do |d|
5
+ d.type && d.name && !d.name.empty?
6
+ end
7
+ index = Hash[decls.map do |d|
8
+ [d.url,
9
+ {
10
+ name: d.name,
11
+ abstract: d.abstract && d.abstract.split(/\n/).map(&:strip).first,
12
+ parent_name: d.parent_in_code && d.parent_in_code.name,
13
+ }.reject { |_, v| v.nil? || v.empty? }]
14
+ end
15
+ ]
16
+ File.open(File.join(output_dir, 'search.json'), 'w') do |f|
17
+ f.write(index.to_json)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -78,7 +78,7 @@ module Jazzy
78
78
  attr_accessor :nav_order
79
79
 
80
80
  def overview
81
- alternative_abstract || "#{abstract}\n\n#{discussion}".strip
81
+ "#{alternative_abstract}\n\n#{abstract}\n\n#{discussion}".strip
82
82
  end
83
83
 
84
84
  def alternative_abstract
@@ -23,6 +23,13 @@ module Jazzy
23
23
  @type && @type[:jazzy]
24
24
  end
25
25
 
26
+ def name_controlled_manually?
27
+ !kind.start_with?('source')
28
+ # "'source'.lang..." for Swift
29
+ # or "'source'kitten.source..." for Objective-C
30
+ # but not "Overview" for navigation groups.
31
+ end
32
+
26
33
  def plural_name
27
34
  name.pluralize
28
35
  end
@@ -7,6 +7,15 @@ module Jazzy
7
7
  attr_accessor :overview
8
8
  attr_accessor :readme_path
9
9
 
10
+ def self.make_index(readme_path)
11
+ SourceDocument.new.tap do |sd|
12
+ sd.name = 'index'
13
+ sd.children = []
14
+ sd.type = SourceDeclaration::Type.new 'document.markdown'
15
+ sd.readme_path = readme_path
16
+ end
17
+ end
18
+
10
19
  def config
11
20
  Config.instance
12
21
  end
@@ -11,6 +11,38 @@ require 'jazzy/source_mark'
11
11
 
12
12
  ELIDED_AUTOLINK_TOKEN = '36f8f5912051ae747ef441d6511ca4cb'.freeze
13
13
 
14
+ def autolink_regex(middle_regex, after_highlight)
15
+ start_tag_re, end_tag_re =
16
+ if after_highlight
17
+ [/<span class="(?:n|kt|nc)">/, '</span>']
18
+ else
19
+ ['<code>', '</code>']
20
+ end
21
+ /(#{start_tag_re})[ \t]*(#{middle_regex})[ \t]*(#{end_tag_re})/
22
+ end
23
+
24
+ class String
25
+ def autolink_block(doc_url, middle_regex, after_highlight)
26
+ gsub(autolink_regex(middle_regex, after_highlight)) do
27
+ original = Regexp.last_match(0)
28
+ start_tag, raw_name, end_tag = Regexp.last_match.captures
29
+ link_target = yield(raw_name)
30
+
31
+ if link_target &&
32
+ !link_target.type.extension? &&
33
+ link_target.url &&
34
+ link_target.url != doc_url.split('#').first && # Don't link to parent
35
+ link_target.url != doc_url # Don't link to self
36
+ start_tag +
37
+ "<a href=\"#{ELIDED_AUTOLINK_TOKEN}#{link_target.url}\">" +
38
+ raw_name + '</a>' + end_tag
39
+ else
40
+ original
41
+ end
42
+ end
43
+ end
44
+ end
45
+
14
46
  module Jazzy
15
47
  # This module interacts with the sourcekitten command-line executable
16
48
  module SourceKitten
@@ -21,7 +53,8 @@ module Jazzy
21
53
  def self.group_docs(docs)
22
54
  custom_categories, docs = group_custom_categories(docs)
23
55
  type_categories, uncategorized = group_type_categories(
24
- docs, custom_categories.any? ? 'Other ' : '')
56
+ docs, custom_categories.any? ? 'Other ' : ''
57
+ )
25
58
  custom_categories + type_categories + uncategorized
26
59
  end
27
60
 
@@ -48,19 +81,32 @@ module Jazzy
48
81
  make_group(
49
82
  children,
50
83
  type_category_prefix + type.plural_name,
51
- "The following #{type.plural_name.downcase} are available globally.")
84
+ "The following #{type.plural_name.downcase} are available globally.",
85
+ )
52
86
  end
53
87
  [group.compact, docs]
54
88
  end
55
89
 
56
90
  def self.make_group(group, name, abstract)
57
91
  group.reject! { |doc| doc.name.empty? }
58
- SourceDeclaration.new.tap do |sd|
59
- sd.type = SourceDeclaration::Type.overview
60
- sd.name = name
61
- sd.abstract = abstract
62
- sd.children = group
63
- end unless group.empty?
92
+ unless group.empty?
93
+ SourceDeclaration.new.tap do |sd|
94
+ sd.type = SourceDeclaration::Type.overview
95
+ sd.name = name
96
+ sd.abstract = abstract
97
+ sd.children = group
98
+ end
99
+ end
100
+ end
101
+
102
+ def self.sanitize_filename(doc)
103
+ unsafe_filename = doc.name
104
+ sanitzation_enabled = Config.instance.use_safe_filenames
105
+ if sanitzation_enabled && !doc.type.name_controlled_manually?
106
+ return CGI.escape(unsafe_filename).gsub('_', '%5F').tr('%', '_')
107
+ else
108
+ return unsafe_filename
109
+ end
64
110
  end
65
111
 
66
112
  # rubocop:disable Metrics/MethodLength
@@ -72,7 +118,7 @@ module Jazzy
72
118
  # Create HTML page for this doc if it has children or is root-level
73
119
  doc.url = (
74
120
  subdir_for_doc(doc) +
75
- [doc.name + '.html']
121
+ [sanitize_filename(doc) + '.html']
76
122
  ).join('/')
77
123
  doc.children = make_doc_urls(doc.children)
78
124
  else
@@ -198,11 +244,16 @@ module Jazzy
198
244
  # rubocop:enable Metrics/CyclomaticComplexity
199
245
  # rubocop:enable Metrics/PerceivedComplexity
200
246
 
201
- def self.process_undocumented_token(doc, declaration)
247
+ def self.should_mark_undocumented(kind, filepath)
202
248
  source_directory = Config.instance.source_directory.to_s
249
+ (filepath || '').start_with?(source_directory) &&
250
+ kind != 'source.lang.swift.decl.generic_type_param'
251
+ end
252
+
253
+ def self.process_undocumented_token(doc, declaration)
203
254
  filepath = doc['key.filepath']
204
255
  objc = Config.instance.objc_mode
205
- if filepath && (filepath.start_with?(source_directory) || objc)
256
+ if objc || should_mark_undocumented(doc['key.kind'], filepath)
206
257
  @undocumented_decls << declaration
207
258
  end
208
259
  return nil if !documented_child?(doc) && @skip_undocumented
@@ -266,14 +317,14 @@ module Jazzy
266
317
  # rubocop:enable Metrics/PerceivedComplexity
267
318
 
268
319
  def self.make_substructure(doc, declaration)
269
- if doc['key.substructure']
270
- declaration.children = make_source_declarations(
271
- doc['key.substructure'],
272
- declaration,
273
- )
274
- else
275
- declaration.children = []
276
- end
320
+ declaration.children = if doc['key.substructure']
321
+ make_source_declarations(
322
+ doc['key.substructure'],
323
+ declaration,
324
+ )
325
+ else
326
+ []
327
+ end
277
328
  end
278
329
 
279
330
  # rubocop:disable Metrics/MethodLength
@@ -285,7 +336,8 @@ module Jazzy
285
336
  Array(docs).each do |doc|
286
337
  if doc.key?('key.diagnostic_stage')
287
338
  declarations += make_source_declarations(
288
- doc['key.substructure'], parent)
339
+ doc['key.substructure'], parent
340
+ )
289
341
  next
290
342
  end
291
343
  declaration = SourceDeclaration.new
@@ -296,7 +348,8 @@ module Jazzy
296
348
  if declaration.type.swift_enum_case?
297
349
  # Enum "cases" are thin wrappers around enum "elements".
298
350
  declarations += make_source_declarations(
299
- doc['key.substructure'], parent)
351
+ doc['key.substructure'], parent
352
+ )
300
353
  next
301
354
  end
302
355
  next unless declaration.type.should_document?
@@ -343,7 +396,7 @@ module Jazzy
343
396
  # Merges redundant declarations when documenting podspecs.
344
397
  def self.deduplicate_declarations(declarations)
345
398
  duplicate_groups = declarations
346
- .group_by { |d| deduplication_key(d) }
399
+ .group_by { |d| deduplication_key(d, declarations) }
347
400
  .values
348
401
 
349
402
  duplicate_groups.map do |group|
@@ -352,11 +405,18 @@ module Jazzy
352
405
  end
353
406
  end
354
407
 
408
+ # Returns true if an Objective-C declaration is mergeable.
409
+ def self.mergeable_objc?(decl, root_decls)
410
+ decl.type.objc_class? \
411
+ || (decl.type.objc_category? \
412
+ && name_match(decl.objc_category_name[0], root_decls))
413
+ end
414
+
355
415
  # Two declarations get merged if they have the same deduplication key.
356
- def self.deduplication_key(decl)
416
+ def self.deduplication_key(decl, root_decls)
357
417
  if decl.type.swift_extensible? || decl.type.swift_extension?
358
418
  [decl.usr, decl.name]
359
- elsif decl.type.objc_class? || decl.type.objc_category?
419
+ elsif mergeable_objc?(decl, root_decls)
360
420
  name, _ = decl.objc_category_name || decl.name
361
421
  [name, :objc_class_and_categories]
362
422
  else
@@ -393,7 +453,8 @@ module Jazzy
393
453
  decls = typedecls + extensions
394
454
  decls.first.tap do |merged|
395
455
  merged.children = deduplicate_declarations(
396
- decls.flat_map(&:children).uniq)
456
+ decls.flat_map(&:children).uniq,
457
+ )
397
458
  merged.children.each do |child|
398
459
  child.parent_in_code = merged
399
460
  end
@@ -474,21 +535,8 @@ module Jazzy
474
535
  # - method signatures after they've been processed by the highlighter
475
536
  #
476
537
  # The `after_highlight` flag is used to differentiate between the two modes.
477
- # rubocop:disable Metrics/MethodLength
478
- # rubocop:disable Metrics/PerceivedComplexity
479
- # rubocop:disable Metrics/CyclomaticComplexity
480
538
  def self.autolink_text(text, doc, root_decls, after_highlight = false)
481
- start_tag_re, end_tag_re =
482
- if after_highlight
483
- [/<span class="(?:n|kt)">/, '</span>']
484
- else
485
- ['<code>', '</code>']
486
- end
487
-
488
- text.gsub(/(#{start_tag_re})[ \t]*([^\s]+)[ \t]*(#{end_tag_re})/) do
489
- original = Regexp.last_match(0)
490
- start_tag, raw_name, end_tag = Regexp.last_match.captures
491
-
539
+ text.autolink_block(doc.url, '[^\s]+', after_highlight) do |raw_name|
492
540
  parts = raw_name
493
541
  .split(/(?<!\.)\.(?!\.)/) # dot with no neighboring dots
494
542
  .reject(&:empty?)
@@ -499,24 +547,24 @@ module Jazzy
499
547
  name_match(first_part, root_decls)
500
548
 
501
549
  # Traverse children via subsequence components, if any
502
- link_target = name_traversal(parts, name_root)
503
-
504
- if link_target &&
505
- !link_target.type.extension? &&
506
- link_target.url &&
507
- link_target.url != doc.url.split('#').first && # Don't link to parent
508
- link_target.url != doc.url # Don't link to self
509
- start_tag +
510
- "<a href=\"#{ELIDED_AUTOLINK_TOKEN}#{link_target.url}\">" +
511
- raw_name + '</a>' + end_tag
512
- else
513
- original
550
+ name_traversal(parts, name_root)
551
+ end.autolink_block(doc.url, '[+-]\[\w+(?: ?\(\w+\))? [\w:]+\]',
552
+ after_highlight) do |raw_name|
553
+ match = raw_name.match(/([+-])\[(\w+(?: ?\(\w+\))?) ([\w:]+)\]/)
554
+
555
+ # Subject component can match any ancestor or top-level doc
556
+ subject = match[2].delete(' ')
557
+ name_root = ancestor_name_match(subject, doc) ||
558
+ name_match(subject, root_decls)
559
+
560
+ if name_root
561
+ # Look up the verb in the subject’s children
562
+ name_match(match[1] + match[3], name_root.children)
514
563
  end
564
+ end.autolink_block(doc.url, '[+-]\w[\w:]*', after_highlight) do |raw_name|
565
+ name_match(raw_name, doc.children)
515
566
  end
516
567
  end
517
- # rubocop:enable Metrics/CyclomaticComplexity
518
- # rubocop:enable Metrics/PerceivedComplexity
519
- # rubocop:enable Metrics/MethodLength
520
568
 
521
569
  def self.autolink(docs, root_decls)
522
570
  docs.each do |doc|
@@ -525,13 +573,17 @@ module Jazzy
525
573
  doc.return = autolink_text(doc.return, doc, root_decls) if doc.return
526
574
  doc.abstract = autolink_text(doc.abstract, doc, root_decls)
527
575
 
528
- doc.declaration = autolink_text(
529
- doc.declaration, doc, root_decls, true
530
- ) if doc.declaration
576
+ if doc.declaration
577
+ doc.declaration = autolink_text(
578
+ doc.declaration, doc, root_decls, true
579
+ )
580
+ end
531
581
 
532
- doc.other_language_declaration = autolink_text(
533
- doc.other_language_declaration, doc, root_decls, true
534
- ) if doc.other_language_declaration
582
+ if doc.other_language_declaration
583
+ doc.other_language_declaration = autolink_text(
584
+ doc.other_language_declaration, doc, root_decls, true
585
+ )
586
+ end
535
587
  end
536
588
  end
537
589
 
@@ -38,3 +38,9 @@ $(".token").click(function(event) {
38
38
  }
39
39
  event.preventDefault();
40
40
  });
41
+
42
+ // Dumb down quotes within code blocks that delimit strings instead of quotations
43
+ // https://github.com/realm/jazzy/issues/714
44
+ $("code q").replaceWith(function () {
45
+ return ["\"", $(this).contents(), "\""];
46
+ });