Skip to content

Commit

Permalink
MM: docset title independent of module name
Browse files Browse the repository at this point in the history
  • Loading branch information
johnfairh committed Feb 9, 2024
1 parent 2604e12 commit 69e0cd3
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 42 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

##### Enhancements

* Add `--docset-title` to set the title of a docset separately
to the module name.
[John Fairhurst](https://github.com/johnfairh)

* Support Swift 5.9 symbolgraph extension symbols.
[John Fairhurst](https://github.com/johnfairh)
[#1368](https://github.com/realm/jazzy/issues/1368)
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,24 @@ jazzy --swift-version 5.7
DEVELOPER_DIR=/Applications/Xcode_14.app/Contents/Developer jazzy
```
### Dash Docset Support
As well as the browsable HTML documentation, Jazzy creates a _docset_ for use
with the [Dash][dash] app.
By default the docset is created at `docs/docsets/ModuleName.tgz`. Use
`--docset-path` to create it somewhere else; use `--docset-title` to change
the docset's title.

Use `--docset-playground-url` and `--docset-icon` to further customize the
docset.

If you set both `--root-url` to be the (https://) URL where you plan to deploy
your documentation and `--version` to give your documentation a version number
then Jazzy also creates a docset feed XML file and includes an "Install in Dash"
button on the site. This lets users who are browsing your documentation on the
web install and start using the docs in Dash locally.

## Linux

Jazzy uses [SourceKitten][sourcekitten] to communicate with the Swift build
Expand Down Expand Up @@ -576,3 +594,4 @@ read [our blog](https://realm.io/news) or say hi on twitter
[bundler]: https://rubygems.org/gems/bundler
[mustache]: https://mustache.github.io "Mustache"
[spm]: https://swift.org/package-manager/ "Swift Package Manager"
[dash]: https://kapeli.com/dash/ "Dash"
14 changes: 7 additions & 7 deletions lib/jazzy/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,13 @@ def hide_objc?
command_line: '--docset-path DIRPATH',
description: 'The relative path for the generated docset'

config_attr :docset_title,
command_line: '--docset-title TITLE',
description: 'The title of the generated docset. A simplified version ' \
'is used for the filenames associated with the docset. If the ' \
'option is not set then the name of the module being documented is ' \
'used as the docset title.'

# ──────── URLs ────────

config_attr :root_url,
Expand Down Expand Up @@ -524,13 +531,6 @@ def self.parse!
config.parse_config_file
PodspecDocumenter.apply_config_defaults(config.podspec, config)

if config.root_url
config.dash_url ||= URI.join(
config.root_url,
"docsets/#{config.module_name}.xml", # XXX help
)
end

config.set_module_configs

config.validate
Expand Down
21 changes: 11 additions & 10 deletions lib/jazzy/doc_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,9 @@ def self.build(options)

# Build & write HTML docs to disk from structured docs array
# @param [String] output_dir Root directory to write docs
# @param [Array] docs Array of structured docs
# @param [Config] options Build options
# @param [Array] doc_structure @see #doc_structure_for_docs
def self.build_docs(output_dir, docs, source_module)
each_doc(output_dir, docs) do |doc, path|
# @param [SourceModule] source_module All info to generate docs
def self.build_docs(output_dir, source_module)
each_doc(output_dir, source_module.docs) do |doc, path|
prepare_output_dir(path.parent, false)
depth = path.relative_path_from(output_dir).each_filename.count - 1
path_to_root = '../' * depth
Expand Down Expand Up @@ -126,10 +124,13 @@ def self.build_site(docs, coverage, options)

docs << SourceDocument.make_index(options.readme_path)

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

output_dir = options.output
build_docs(output_dir, source_module.docs, source_module)

docset_builder = DocsetBuilder.new(output_dir)

source_module = SourceModule.new(docs, structure, coverage, docset_builder)

build_docs(output_dir, source_module)

unless options.disable_search
warn 'building search index'
Expand All @@ -139,7 +140,7 @@ def self.build_site(docs, coverage, options)
copy_extensions(source_module, output_dir)
copy_theme_assets(output_dir)

DocsetBuilder.new(output_dir, source_module).build!
docset_builder.build!(source_module.all_declarations)

generate_badge(source_module.doc_coverage, options)

Expand Down Expand Up @@ -259,7 +260,7 @@ def self.new_document(source_module, doc_model)
doc[:github_url] = doc[:source_host_url]
doc[:github_token_url] = doc[:source_host_item_url]
end
doc[:dash_url] = source_module.dash_url
doc[:dash_url] = source_module.dash_feed_url
end
end

Expand Down
57 changes: 44 additions & 13 deletions lib/jazzy/docset_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,51 @@ class DocsetBuilder
attr_reader :source_module
attr_reader :docset_dir
attr_reader :documents_dir
attr_reader :name

def initialize(generated_docs_dir, source_module)
@source_module = source_module
def initialize(generated_docs_dir)
@name = config.docset_title || config.module_names.first
docset_path = config.docset_path ||
"docsets/#{source_module.name}.docset"
"docsets/#{safe_name}.docset"
@docset_dir = generated_docs_dir + docset_path
@generated_docs_dir = generated_docs_dir
@output_dir = docset_dir.parent
@documents_dir = docset_dir + 'Contents/Resources/Documents/'
end

def build!
def build!(all_declarations)
docset_dir.rmtree if docset_dir.exist?
copy_docs
copy_icon if config.docset_icon
write_plist
create_index
create_index(all_declarations)
create_archive
create_xml if config.version && config.root_url
end

private

def safe_name
name.gsub(/[^a-z0-9_\-]+/i, '_')
end

def write_plist
info_plist_path = docset_dir + 'Contents/Info.plist'
info_plist_path.open('w') do |plist|
template = Pathname(__dir__) + 'docset_builder/info_plist.mustache'
plist << Mustache.render(
template.read,
lowercase_name: source_module.name.downcase,
name: source_module.name,
lowercase_name: name.downcase,
lowercase_safe_name: safe_name.downcase,
name: name,
root_url: config.root_url,
playground_url: config.docset_playground_url,
)
end
end

def create_archive
target = "#{source_module.name}.tgz"
target = "#{safe_name}.tgz"
source = docset_dir.basename.to_s
options = {
chdir: output_dir.to_s,
Expand All @@ -70,30 +76,55 @@ def copy_docs
end

def copy_icon
FileUtils.cp config.docset_icon, @docset_dir + 'icon.png'
FileUtils.cp config.docset_icon, docset_dir + 'icon.png'
end

def create_index
def create_index(all_declarations)
search_index_path = docset_dir + 'Contents/Resources/docSet.dsidx'
SQLite3::Database.new(search_index_path.to_s) do |db|
db.execute('CREATE TABLE searchIndex(' \
'id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);')
db.execute('CREATE UNIQUE INDEX anchor ON ' \
'searchIndex (name, type, path);')
source_module.all_declarations.select(&:type).each do |doc|
all_declarations.select(&:type).each do |doc|
db.execute('INSERT OR IGNORE INTO searchIndex(name, type, path) ' \
'VALUES (?, ?, ?);', [doc.name, doc.type.dash_type, doc.filepath])
end
end
end

def create_xml
(output_dir + "#{source_module.name}.xml").open('w') do |xml|
url = URI.join(config.root_url, "docsets/#{source_module.name}.tgz")
(output_dir + "#{safe_name}.xml").open('w') do |xml|
url = URI.join(config.root_url, "docsets/#{safe_name}.tgz")
xml << "<entry><version>#{config.version}</version><url>#{url}" \
"</url></entry>\n"
end
end

# The web URL where the user intends to place the docset XML file.
def dash_url
return nil unless config.dash_url || config.root_url

config.dash_url ||
URI.join(
config.root_url,
"docsets/#{safe_name}.xml",
)
end

public

# The dash-feed:// URL that links from the Dash icon in generated
# docs. This is passed to the Dash app and encodes the actual web
# `dash_url` where the user has placed the XML file.
#
# Unfortunately for historical reasons this is *also* called the
# 'dash_url' where it appears in mustache templates and so on.
def dash_feed_url
dash_url&.then do |url|
"dash-feed://#{ERB::Util.url_encode(url.to_s)}"
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/jazzy/docset_builder/info_plist.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.jazzy.{{lowercase_name}}</string>
<string>com.jazzy.{{lowercase_safe_name}}</string>
<key>CFBundleName</key>
<string>{{name}}</string>
<key>DocSetPlatformFamily</key>
Expand Down
21 changes: 11 additions & 10 deletions lib/jazzy/source_module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,29 @@
require 'jazzy/source_host'

module Jazzy
# A cache of info that is common across all page templating, gathered
# from other parts of the program.
class SourceModule
include Config::Mixin

attr_accessor :name
attr_accessor :docs
attr_accessor :doc_coverage
attr_accessor :doc_structure
attr_accessor :author_name
attr_accessor :author_url
attr_accessor :dash_url
attr_accessor :dash_feed_url
attr_accessor :host

def initialize(options, docs, doc_structure, doc_coverage)
def initialize(docs, doc_structure, doc_coverage, docset_builder)
self.docs = docs
self.doc_structure = doc_structure
self.doc_coverage = doc_coverage
self.name = options.module_configs.first.module_name # XXX what actually is this type for
self.author_name = options.author_name
self.author_url = options.author_url
self.host = SourceHost.create(options)
return unless options.dash_url

self.dash_url =
"dash-feed://#{ERB::Util.url_encode(options.dash_url.to_s)}"
self.name = config.module_names.first # XXX what actually is this type for
self.author_name = config.author_name
self.author_url = config.author_url
self.host = SourceHost.create(config)
self.dash_feed_url = docset_builder.dash_feed_url
end

def all_declarations
Expand Down
2 changes: 1 addition & 1 deletion spec/integration_specs
Submodule integration_specs updated 37 files
+1 −0 jazzy_multi_modules/after/docs/Categories/NSURL(MyCategory).html
+1 −0 jazzy_multi_modules/after/docs/Classes/AlphaClass.html
+1 −0 jazzy_multi_modules/after/docs/Classes/AlphaClass/Nested.html
+1 −0 jazzy_multi_modules/after/docs/Classes/BetaClass.html
+1 −0 jazzy_multi_modules/after/docs/Classes/GammaClass.html
+1 −0 jazzy_multi_modules/after/docs/Extensions/MultiKitAlpha+String.html
+1 −0 jazzy_multi_modules/after/docs/Extensions/MultiKitBeta+String.html
+1 −0 jazzy_multi_modules/after/docs/MultKitGamma.html
+1 −0 jazzy_multi_modules/after/docs/MultiKitAlpha.html
+1 −0 jazzy_multi_modules/after/docs/MultiKitBeta.html
+5 −3 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Info.plist
+1 −0 ...les/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/Categories/NSURL(MyCategory).html
+1 −0 ...multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/Classes/AlphaClass.html
+1 −0 ...odules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/Classes/AlphaClass/Nested.html
+1 −0 ..._multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/Classes/BetaClass.html
+1 −0 ...multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/Classes/GammaClass.html
+1 −0 .../after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/Extensions/MultiKitAlpha+String.html
+1 −0 ...s/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/Extensions/MultiKitBeta+String.html
+1 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/MultKitGamma.html
+1 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/MultiKitAlpha.html
+1 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/MultiKitBeta.html
+0 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/css/highlight.css
+0 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/css/jazzy.css
+ jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/img/carat.png
+ jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/img/dash.png
+ jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/img/spinner.gif
+1 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/index.html
+0 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/js/jazzy.js
+0 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/js/jazzy.search.js
+0 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/js/jquery.min.js
+0 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/js/lunr.min.js
+0 −0 ..._multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/js/typeahead.jquery.js
+0 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/Documents/search.json
+0 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.docset/Contents/Resources/docSet.dsidx.csv
+1 −0 jazzy_multi_modules/after/docs/docsets/Jazzy_MultiKit.xml
+1 −0 jazzy_multi_modules/after/docs/index.html
+3 −0 jazzy_multi_modules/before/.jazzy.yaml

0 comments on commit 69e0cd3

Please sign in to comment.