Skip to content

Commit

Permalink
Merge pull request #523 from agentk/integrated-markdown
Browse files Browse the repository at this point in the history
Integrated markdown parsing and guide support
  • Loading branch information
jpsim committed Jun 1, 2016
2 parents c7269b9 + c7f9989 commit b903d30
Show file tree
Hide file tree
Showing 12 changed files with 208 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ Icon
Network Trash Folder
Temporary Items
.apdisk
vendor
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
url = https://github.com/jpsim/SourceKitten.git
[submodule "spec/integration_specs"]
path = spec/integration_specs
url = https://github.com/Realm/jazzy-integration-specs.git
url = https://github.com/agentk/jazzy-integration-specs.git
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,38 @@ You can specify which theme to use by passing in the `--theme` option. You can
also provide your own custom theme by passing in the path to your theme
directory.

### Guides

| -- | -- |
| Command line option | `--documentation={file pattern}` |
| Example | `--documentation=Docs/*.md` |
| jazzy.yaml example | `documentation: Docs/*.md` |

Using the `--documentation` option, extra markdown files can be integrated into the generated docs and sidebar navigation.

Any files found matching the file pattern will be parsed and included as a document with the type 'Guide' when generated. If the files are not included using the `custom_categories` config option, they will be grouped under 'Other Guides' in the sidebar navigation.

There are a few limitations:
- File names must be unique from source files.
- Readme should be specified separately using the `readme_path` option.

### Section description abstracts

| -- | -- |
| Command line option | `--abstract={file pattern}` |
| Example | `--abstract=Docs/Sections/*.md` |
| jazzy.yaml example | `abstract: Docs/Sections/*.md` |

Using the `--abstract` options, extra markdown can be included after the heading of section overview pages. Think of it as a template include.

The list of files matching the pattern is compared against the list of sections generated and if a match is found, it's contents will be included in that section before listing source output.

Unlike the `--documentation` option, these files are not included in navigation and if a file does not match a section title, it is not included at all.

This is very helpful when using `custom_categories` for grouping types and including relevant documentation in those sections.

For an example of a project using both `--documentation` and `--abstract` see: [http://reswift.github.io/ReSwift/](http://reswift.github.io/ReSwift/)

## Troubleshooting

#### Swift
Expand Down
10 changes: 10 additions & 0 deletions lib/jazzy/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,16 @@ def expand_path(path)
description: 'The path to a markdown README file',
parse: ->(rp) { expand_path(rp) }

config_attr :documentation_glob,
command_line: '--documentation GLOB',
description: 'Glob that matches available documentation',
parse: ->(dg) { Pathname.glob(dg) }

config_attr :abstract_glob,
command_line: '--abstract GLOB',
description: 'Glob that matches available abstracts for categories',
parse: ->(ag) { Pathname.glob(ag) }

config_attr :podspec,
command_line: '--podspec FILEPATH',
parse: ->(ps) { PodspecDocumenter.create_podspec(Pathname(ps)) if ps },
Expand Down
26 changes: 16 additions & 10 deletions lib/jazzy/doc_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
require 'jazzy/config'
require 'jazzy/doc'
require 'jazzy/docset_builder'
require 'jazzy/documentation_generator'
require 'jazzy/jazzy_markdown'
require 'jazzy/podspec_documenter'
require 'jazzy/readme_generator'
require 'jazzy/source_declaration'
require 'jazzy/source_document'
require 'jazzy/source_module'
require 'jazzy/sourcekitten'

Expand Down Expand Up @@ -91,7 +93,7 @@ def self.build_docs(output_dir, docs, source_module)

def self.each_doc(output_dir, docs, &block)
docs.each do |doc|
next if doc.name != 'index' && doc.children.count == 0
next unless doc.render?
# Assuming URL is relative to documentation root:
path = output_dir + (doc.url || "#{doc.name}.html")
block.call(doc, path)
Expand All @@ -109,9 +111,11 @@ def self.build_site(docs, coverage, options)

structure = doc_structure_for_docs(docs)

docs << SourceDeclaration.new.tap do |sd|
docs << SourceDocument.new.tap do |sd|
sd.name = 'index'
sd.children = []
sd.type = SourceDeclaration::Type.new 'document.markdown'
sd.readme_path = options.readme_path
end

source_module = SourceModule.new(options, docs, structure, coverage)
Expand All @@ -138,7 +142,7 @@ def self.build_docs_for_sourcekitten_output(sourcekitten_output, options)
sourcekitten_output,
options.min_acl,
options.skip_undocumented,
)
DocumentationGenerator.source_docs)

prepare_output_dir(options.output, options.clean)
write_lint_report(undocumented, options)
Expand Down Expand Up @@ -238,15 +242,17 @@ def self.copy_assets(destination)
end
end

# Build index Mustache document
# Build Mustache document from a markdown source file
# @param [Config] options Build options
# @param [Hash] doc_model Parsed doc. @see SourceKitten.parse
# @param [String] path_to_root
# @param [Array] doc_structure doc structure comprised of section names and
# child names and URLs. @see doc_structure_for_docs
def self.document_index(source_module, path_to_root)
def self.document_markdown(source_module, doc_model, path_to_root)
doc = Doc.new # Mustache model instance
doc[:name] = source_module.name
doc[:overview] = ReadmeGenerator.generate(source_module)
name = doc_model.name == 'index' ? source_module.name : doc_model.name
doc[:name] = name
doc[:overview] = Jazzy.markdown.render(doc_model.content(source_module))
doc[:custom_head] = Config.instance.custom_head
doc[:doc_coverage] = source_module.doc_coverage unless
Config.instance.hide_documentation_coverage
Expand Down Expand Up @@ -326,7 +332,7 @@ def self.make_task(mark, uid, items)
# @param [Config] options Build options
# @param [Hash] doc_model Parsed doc. @see SourceKitten.parse
def self.render_tasks(source_module, children)
marks = children.map(&:mark).uniq
marks = children.map(&:mark).uniq.compact
mark_names_counts = {}
marks.map do |mark|
mark_children = children.select { |child| child.mark == mark }
Expand All @@ -349,8 +355,8 @@ def self.render_tasks(source_module, children)
# @param [Array] doc_structure doc structure comprised of section names and
# child names and URLs. @see doc_structure_for_docs
def self.document(source_module, doc_model, path_to_root)
if doc_model.name == 'index'
return document_index(source_module, path_to_root)
if doc_model.type.kind == 'document.markdown'
return document_markdown(source_module, doc_model, path_to_root)
end

doc = Doc.new # Mustache model instance
Expand Down
38 changes: 38 additions & 0 deletions lib/jazzy/documentation_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'pathname'

require 'jazzy/jazzy_markdown'
require 'jazzy/source_document'

module Jazzy
module DocumentationGenerator
extend Config::Mixin

def self.source_docs
documentation_entries.map do |file_path|
SourceDocument.new.tap do |sd|
sd.name = File.basename(file_path, '.md')
sd.url = sd.name.downcase.strip
.tr(' ', '-').gsub(/[^\w-]/, '') + '.html'
sd.type = SourceDeclaration::Type.new 'document.markdown'
sd.children = []
sd.overview = overview Pathname(file_path)
sd.usr = 'documentation.' + sd.name
sd.abstract = ''
sd.return = ''
sd.parameters = []
end
end
end

def self.overview(file_path)
return '' unless file_path && file_path.exist?
file_path.read
end

def self.documentation_entries
return [] unless
config.documentation_glob_configured && config.documentation_glob
config.documentation_glob.select { |e| File.file? e }
end
end
end
29 changes: 28 additions & 1 deletion lib/jazzy/source_declaration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ class SourceDeclaration
# static type of declared element (e.g. String.Type -> ())
attr_accessor :typename

def type?(type_kind)
respond_to?(:type) && type.kind == type_kind
end

def render?
type?('document.markdown') || children.count != 0
end

# Element containing this declaration in the code
attr_accessor :parent_in_code

Expand Down Expand Up @@ -69,7 +77,26 @@ def objc_category_name
attr_accessor :nav_order

def overview
"#{abstract}\n\n#{discussion}".strip
alternative_abstract || "#{abstract}\n\n#{discussion}".strip
end

def alternative_abstract
if file = alternative_abstract_file
Pathname(file).read
end
end

def alternative_abstract_file
abstract_glob.select do |f|
File.basename(f).split('.').first == name
end.first
end

def abstract_glob
return [] unless
Config.instance.abstract_glob_configured &&
Config.instance.abstract_glob
Config.instance.abstract_glob.select { |e| File.file? e }
end
end
end
7 changes: 6 additions & 1 deletion lib/jazzy/source_declaration/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,13 @@ def ==(other)
end

TYPES = {
# Objective-C
# Markdown
'document.markdown' => {
jazzy: 'Guide',
dash: 'Guide',
}.freeze,

# Objective-C
'sourcekitten.source.lang.objc.decl.unexposed' => {
jazzy: 'Unexposed',
dash: 'Unexposed',
Expand Down
72 changes: 72 additions & 0 deletions lib/jazzy/source_document.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
require 'pathname'

require 'jazzy/jazzy_markdown'

module Jazzy
class SourceDocument < SourceDeclaration
attr_accessor :overview
attr_accessor :readme_path

def config
Config.instance
end

def url
name.downcase.strip.tr(' ', '-').gsub(/[^\w-]/, '') + '.html'
end

def content(source_module)
return readme_content(source_module) if name == 'index'
overview
end

def readme_content(source_module)
config_readme || fallback_readme || generated_readme(source_module)
end

def config_readme
readme_path.read if readme_path && readme_path.exist?
end

def fallback_readme
%w(README.md README.markdown README.mdown README).each do |potential_name|
file = config.source_directory + potential_name
return file.read if file.exist?
end
false
end

def generated_readme(source_module)
if podspec = config.podspec
### License

# <a href="#{license[:url]}">#{license[:license]}</a>
<<-EOS
# #{podspec.name}
### #{podspec.summary}
#{podspec.description}
### Installation
```ruby
pod '#{podspec.name}'
```
### Authors
#{source_module.author_name}
EOS
else
<<-EOS
# #{source_module.name}
### Authors
#{source_module.author_name}
EOS
end
end
end
end
2 changes: 1 addition & 1 deletion lib/jazzy/source_module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def all_declarations
d.map(&:children).each { |c| visitor[c] }
end
visitor[docs]
all_declarations
all_declarations.select { |doc| doc.name != 'index' }
end
end
end
4 changes: 2 additions & 2 deletions lib/jazzy/sourcekitten.rb
Original file line number Diff line number Diff line change
Expand Up @@ -493,11 +493,11 @@ def self.reject_objc_enum_typedefs(docs)

# Parse sourcekitten STDOUT output as JSON
# @return [Hash] structured docs
def self.parse(sourcekitten_output, min_acl, skip_undocumented)
def self.parse(sourcekitten_output, min_acl, skip_undocumented, inject_docs)
@min_acl = min_acl
@skip_undocumented = skip_undocumented
sourcekitten_json = filter_excluded_files(JSON.parse(sourcekitten_output))
docs = make_source_declarations(sourcekitten_json)
docs = make_source_declarations(sourcekitten_json).concat inject_docs
docs = ungrouped_docs = deduplicate_declarations(docs)
docs = group_docs(docs)
if Config.instance.objc_mode
Expand Down
2 changes: 1 addition & 1 deletion spec/integration_specs

0 comments on commit b903d30

Please sign in to comment.