diff --git a/CHANGELOG.md b/CHANGELOG.md index 31cdf0052..dc792d477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ ##### Enhancements +* Mentions of top-level declarations in documentation comments are now + automatically hyperlinked to their reference. + * Render special list items (e.g. Throws, See, etc.). See http://ericasadun.com/2015/06/14/swift-header-documentation-in-xcode-7/ for a complete list. diff --git a/lib/jazzy/doc_builder.rb b/lib/jazzy/doc_builder.rb index d9a46d1a3..78cbc8839 100644 --- a/lib/jazzy/doc_builder.rb +++ b/lib/jazzy/doc_builder.rb @@ -300,7 +300,7 @@ def self.document(source_module, doc_model, path_to_root) doc[:github_url] = source_module.github_url doc[:dash_url] = source_module.dash_url doc[:path_to_root] = path_to_root - doc.render + doc.render.gsub(ELIDED_AUTOLINK_TOKEN, path_to_root) end end end diff --git a/lib/jazzy/sourcekitten.rb b/lib/jazzy/sourcekitten.rb index 2e90df8ca..fd0b8fc41 100644 --- a/lib/jazzy/sourcekitten.rb +++ b/lib/jazzy/sourcekitten.rb @@ -9,6 +9,8 @@ require 'jazzy/source_declaration' require 'jazzy/source_mark' +ELIDED_AUTOLINK_TOKEN = '36f8f5912051ae747ef441d6511ca4cb'.freeze + module Jazzy # This module interacts with the sourcekitten command-line executable module SourceKitten @@ -309,6 +311,35 @@ def self.filter_excluded_files(json) end.compact end + def self.names_and_urls(docs) + docs.flat_map do |doc| + # FIXME: autolink more than just top-level items. + [{ name: doc.name, url: doc.url }] # + names_and_urls(doc.children) + end + end + + def self.autolink_text(text, data, url) + regex = /\b(#{data.map { |d| Regexp.escape(d[:name]) }.join('|')})\b/ + text.gsub(regex) do + name = Regexp.last_match(1) + auto_url = data.find { |d| d[:name] == name }[:url] + if auto_url == url # docs shouldn't autolink to themselves + Regexp.last_match(0) + else + "#{name}" + end + end + end + + def self.autolink(docs, data) + docs.map do |doc| + doc.abstract = autolink_text(doc.abstract, data, doc.url) + doc.return = autolink_text(doc.return, data, doc.url) if doc.return + doc.children = autolink(doc.children, data) + doc + end + end + # Parse sourcekitten STDOUT output as JSON # @return [Hash] structured docs def self.parse(sourcekitten_output, min_acl, skip_undocumented) @@ -321,7 +352,9 @@ def self.parse(sourcekitten_output, min_acl, skip_undocumented) # Remove top-level enum cases because it means they have an ACL lower # than min_acl docs = docs.reject { |doc| doc.type.enum_element? } - [make_doc_urls(docs, []), doc_coverage, @undocumented_tokens] + docs = make_doc_urls(docs, []) + docs = autolink(docs, names_and_urls(docs.flat_map(&:children))) + [docs, doc_coverage, @undocumented_tokens] end end end diff --git a/spec/integration_specs b/spec/integration_specs index 31bfec017..a9e6e81a6 160000 --- a/spec/integration_specs +++ b/spec/integration_specs @@ -1 +1 @@ -Subproject commit 31bfec017d492acc6792ba8d7397b0e0f3be377b +Subproject commit a9e6e81a66d8d844a365d2067536d7ed87066426