Module: Jazzy::Grouper

Extended by:
Config::Mixin
Defined in:
lib/jazzy/grouper.rb

Overview

This module deals with arranging top-level declarations and guides into groups automatically and/or using a custom list.

Class Method Summary collapse

Methods included from Config::Mixin

config

Class Method Details

.group_custom_categories(docs, doc_index) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/jazzy/grouper.rb', line 50

def self.group_custom_categories(docs, doc_index)
  group = config.custom_categories.map do |category|
    children = category['children'].map do |selector|
      selected = select_docs(doc_index, selector)
      selected.map do |doc|
        unless doc.parent_in_code.nil?
          warn "WARNING: Declaration \"#{doc.fully_qualified_module_name}\" " \
            'specified in categories file exists but is not top-level and ' \
            'cannot be included here'
          next nil
        end
        docs.delete(doc)
      end
    end.flatten.compact
    # Category config overrides alphabetization
    children.each.with_index { |child, i| child.nav_order = i }
    make_group(children, category['name'], '')
  end
  [group.compact, docs]
end

.group_docs(docs, doc_index) ⇒ Object

Group root-level docs by custom categories (if any) and type or module



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/jazzy/grouper.rb', line 10

def self.group_docs(docs, doc_index)
  custom_categories, docs = group_custom_categories(docs, doc_index)
  unlisted_prefix = config.custom_categories_unlisted_prefix
  type_category_prefix = custom_categories.any? ? unlisted_prefix : ''
  all_categories =
    custom_categories +
    if config.merge_modules == :all
      group_docs_by_type(docs, type_category_prefix)
    else
      group_docs_by_module(docs, type_category_prefix)
    end
  merge_consecutive_marks(all_categories)
end

.group_docs_by_module(docs, type_category_prefix) ⇒ Object

Group root-level docs by module name



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/jazzy/grouper.rb', line 34

def self.group_docs_by_module(docs, type_category_prefix)
  guide_categories, docs = group_guides(docs, type_category_prefix)

  module_categories = docs
    .group_by(&:doc_module_name)
    .map do |name, module_docs|
      make_group(
        module_docs,
        name,
        "The following declarations are provided by module #{name}.",
      )
    end

  guide_categories + module_categories
end

.group_docs_by_type(docs, type_category_prefix) ⇒ Object

Group root-level docs by type



25
26
27
28
29
30
31
# File 'lib/jazzy/grouper.rb', line 25

def self.group_docs_by_type(docs, type_category_prefix)
  type_groups = SourceDeclaration::Type.all.map do |type|
    children, docs = docs.partition { |doc| doc.type == type }
    make_type_group(children, type, type_category_prefix)
  end
  merge_categories(type_groups.compact) + docs
end

.group_guides(docs, prefix) ⇒ Object



85
86
87
88
89
90
# File 'lib/jazzy/grouper.rb', line 85

def self.group_guides(docs, prefix)
  guides, others = docs.partition { |doc| doc.type.markdown? }
  return [[], others] unless guides.any?

  [[make_type_group(guides, guides.first.type, prefix)], others]
end

.make_group(group, name, abstract, url_name = nil) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/jazzy/grouper.rb', line 114

def self.make_group(group, name, abstract, url_name = nil)
  group.reject! { |decl| decl.name.empty? }
  unless group.empty?
    SourceDeclaration.new.tap do |sd|
      sd.type     = SourceDeclaration::Type.overview
      sd.name     = name
      sd.url_name = url_name
      sd.abstract = Markdown.render(abstract)
      sd.children = group
    end
  end
end

.make_type_group(docs, type, type_category_prefix) ⇒ Object



92
93
94
95
96
97
98
99
# File 'lib/jazzy/grouper.rb', line 92

def self.make_type_group(docs, type, type_category_prefix)
  make_group(
    docs,
    type_category_prefix + type.plural_name,
    "The following #{type.plural_name.downcase} are available globally.",
    type_category_prefix + type.plural_url_name,
  )
end

.merge_categories(categories) ⇒ Object

Join categories with the same name (eg. ObjC and Swift classes)



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/jazzy/grouper.rb', line 102

def self.merge_categories(categories)
  merged = []
  categories.each do |new_category|
    if existing = merged.find { |cat| cat.name == new_category.name }
      existing.children += new_category.children
    else
      merged.append(new_category)
    end
  end
  merged
end

.merge_consecutive_marks(docs) ⇒ Object

Merge consecutive sections with the same mark into one section Needed because of pulling various decls into groups



129
130
131
132
133
134
135
136
137
138
# File 'lib/jazzy/grouper.rb', line 129

def self.merge_consecutive_marks(docs)
  prev_mark = nil
  docs.each do |doc|
    if prev_mark&.can_merge?(doc.mark)
      doc.mark = prev_mark
    end
    prev_mark = doc.mark
    merge_consecutive_marks(doc.children)
  end
end

.select_docs(doc_index, selector) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/jazzy/grouper.rb', line 71

def self.select_docs(doc_index, selector)
  if selector.is_a?(String)
    unless single_doc = doc_index.lookup(selector)
      warn 'WARNING: No documented top-level declarations match ' \
        "name \"#{selector}\" specified in categories file"
      return []
    end
    [single_doc]
  else
    doc_index.lookup_regex(selector['regex'])
      .sort_by(&:name)
  end
end