Module: Jazzy::DocBuilder

Defined in:
lib/jazzy/doc_builder.rb

Overview

This module handles HTML generation, file writing, asset copying, and generally building docs given sourcekitten output

Class Method Summary collapse

Class Method Details

.build(options) ⇒ Object

Build documentation from the given options

Parameters:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/jazzy/doc_builder.rb', line 42

def self.build(options)
  if options.sourcekitten_sourcefile
    file_contents = options.sourcekitten_sourcefile.read
    build_docs_for_sourcekitten_output(file_contents, options)
  else
    stdout = SourceKitten.run_sourcekitten(options.xcodebuild_arguments)
    exitstatus = $?.exitstatus
    if exitstatus == 0
      warn 'building site'
      build_docs_for_sourcekitten_output(stdout, options)
    else
      warn 'Please pass in xcodebuild arguments using -x'
      warn 'If build arguments are correct, please file an issue on ' \
      'https://github.com/realm/jazzy/issues'
      exit exitstatus || 1
    end
  end
end

.build_docs(output_dir, docs, source_module, depth) ⇒ Object

Build & write HTML docs to disk from structured docs array

Parameters:

  • output_dir (String)

    Root directory to write docs

  • docs (Array)

    Array of structured docs

  • options (Config)

    Build options

  • depth (Integer)

    Number of parents. Used to calculate path_to_root for web.

  • doc_structure (Array)

    @see #doc_structure_for_docs



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/jazzy/doc_builder.rb', line 68

def self.build_docs(output_dir, docs, source_module, depth)
  docs.each do |doc|
    next if doc.name != 'index' && doc.children.count == 0
    prepare_output_dir(output_dir, false)
    path = output_dir + "#{doc.name}.html"
    path_to_root = ['../'].cycle(depth).to_a.join('')
    path.open('w') do |file|
      file.write(document(source_module, doc, path_to_root))
    end
    next if doc.name == 'index'
    build_docs(
      output_dir + doc.name,
      doc.children,
      source_module,
      depth + 1,
    )
  end
end

.build_docs_for_sourcekitten_output(sourcekitten_output, options) ⇒ Object

Build docs given sourcekitten output

Parameters:

  • sourcekitten_output (String)

    Output of sourcekitten command

  • options (Config)

    Build options



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/jazzy/doc_builder.rb', line 90

def self.build_docs_for_sourcekitten_output(sourcekitten_output, options)
  output_dir = options.output
  prepare_output_dir(output_dir, options.clean)

  (docs, coverage) = SourceKitten.parse(sourcekitten_output)

  structure = doc_structure_for_docs(docs)

  docs << SourceDeclaration.new.tap { |sd| sd.name = 'index' }

  source_module = SourceModule.new(options, docs, structure, coverage)
  build_docs(output_dir, source_module.docs, source_module, 0)

  copy_assets(output_dir)

  puts "jam out ♪♫ to your fresh new docs in `#{output_dir}`"
end

.copy_assets(destination) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/jazzy/doc_builder.rb', line 108

def self.copy_assets(destination)
  origin = Pathname(__FILE__).parent + '../../lib/jazzy/assets/.'
  FileUtils.cp_r(origin, destination)
  Pathname.glob(destination + 'css/**/*.scss').each do |scss|
    contents = scss.read
    css = Sass::Engine.new(contents, syntax: :scss).render
    css_filename = scss.sub(/\.scss$/, '')
    css_filename.open('w') { |f| f.write(css) }
    FileUtils.rm scss
  end
end

.doc_structure_for_docs(docs) ⇒ Array

Generate doc structure to be used in sidebar navigation

Returns:

  • (Array)

    doc structure comprised of section names & child names & URLs



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/jazzy/doc_builder.rb', line 27

def self.doc_structure_for_docs(docs)
  structure = []
  docs.each do |doc|
    structure << {
      section: doc.name,
      children: doc.children.map do |child|
        { name: child.name, url: child.url }
      end,
    }
  end
  structure
end

.document(source_module, doc_model, path_to_root) ⇒ Object

Build Mustache document from single parsed doc

Parameters:

  • options (Config)

    Build options

  • doc_model (Hash)

    Parsed doc. @see SourceKitten.parse

  • path_to_root (String)
  • doc_structure (Array)

    doc structure comprised of section names and child names and URLs. @see doc_structure_for_docs



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/jazzy/doc_builder.rb', line 201

def self.document(source_module, doc_model, path_to_root)
  # @todo render README here
  if doc_model.name == 'index'
    return document_index(source_module, path_to_root)
  end

  doc = Doc.new # Mustache model instance
  doc[:doc_coverage] = source_module.doc_coverage
  doc[:name] = doc_model.name
  doc[:kind] = doc_model.kindName
  doc[:overview] = Jazzy.markdown.render(doc_model.abstract || '')
  doc[:structure] = source_module.doc_structure
  doc[:tasks] = render_tasks(source_module, doc_model)
  doc[:module_name] = source_module.name
  doc[:author_name] = source_module.author_name
  doc[:author_website] = source_module.author_url
  doc[:github_url] = source_module.github_url
  doc[:dash_url] = source_module.dash_url
  doc[:path_to_root] = path_to_root
  doc.render
end

.document_index(source_module, path_to_root) ⇒ Object

Build index Mustache document

Parameters:

  • options (Config)

    Build options

  • path_to_root (String)
  • doc_structure (Array)

    doc structure comprised of section names and child names and URLs. @see doc_structure_for_docs



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/jazzy/doc_builder.rb', line 125

def self.document_index(source_module, path_to_root)
  doc = Doc.new # Mustache model instance
  doc[:name] = source_module.name
  doc[:overview] = Jazzy.markdown.render(
    "This is the index page for #{source_module.name} docs. " \
    'Navigate using the links on the left.',
  )
  doc[:doc_coverage] = source_module.doc_coverage
  doc[:structure] = source_module.doc_structure
  doc[:module_name] = source_module.name
  doc[:author_name] = source_module.author_name
  doc[:author_website] = source_module.author_url
  doc[:github_url] = source_module.github_url
  doc[:dash_url] = source_module.dash_url
  doc[:path_to_root] = path_to_root
  doc.render
end

.gh_token_url(item, source_module) ⇒ Object

Construct Github token URL

Parameters:

  • item (Hash)

    Parsed doc child item

  • options (Config)

    Build options



146
147
148
149
150
151
152
153
# File 'lib/jazzy/doc_builder.rb', line 146

def self.gh_token_url(item, source_module)
  if source_module.github_file_prefix && item.file
    gh_prefix = source_module.github_file_prefix
    relative_file_path = item.file.gsub(`pwd`.strip, '')
    gh_line = "#L#{item.line}"
    gh_prefix + relative_file_path + gh_line
  end
end

.prepare_output_dir(output_dir, clean) ⇒ Object

mkdir -p output directory and clean if option is set



19
20
21
22
# File 'lib/jazzy/doc_builder.rb', line 19

def self.prepare_output_dir(output_dir, clean)
  FileUtils.rm_r output_dir if clean && output_dir.directory?
  FileUtils.mkdir_p output_dir
end

.render_item(item, source_module) ⇒ Object

Build mustache item for a top-level doc

Parameters:

  • item (Hash)

    Parsed doc child item

  • options (Config)

    Build options



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/jazzy/doc_builder.rb', line 158

def self.render_item(item, source_module)
  # Combine abstract and discussion into abstract
  abstract = (item.abstract || '') + (item.discussion || '')
  item_render = {
    name: item.name,
    abstract: Jazzy.markdown.render(abstract),
    declaration: item.declaration,
    usr: item.usr,
  }
  gh_token_url = gh_token_url(item, source_module)
  item_render[:github_token_url] = gh_token_url if gh_token_url
  item_render[:return] = Jazzy.markdown.render(item.return) if item.return
  item_render[:parameters] = item.parameters if item.parameters.length > 0
  item_render
end

.render_tasks(source_module, doc_model) ⇒ Object

Render tasks for Mustache document

Parameters:

  • options (Config)

    Build options

  • doc_model (Hash)

    Parsed doc. @see SourceKitten.parse



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/jazzy/doc_builder.rb', line 177

def self.render_tasks(source_module, doc_model)
  tasks = []
  # @todo parse mark-style comments and use as task names
  tasknames = ['Children']
  tasknames.each do |taskname|
    items = []
    doc_model.children.each do |item|
      items << render_item(item, source_module)
    end
    tasks << {
      name: '',
      uid: URI.encode(taskname),
      items: items,
    }
  end
  tasks
end