Improve Presentation of non-framework Documentation (SR-15434)

Hi all!

I’d like to pitch a small change to Swift-DocC that will allow for better presentation of non-framework documentation.

This work would resolve [SR-15434] [Swift-DocC] Support custom documentation module kinds - Swift.

The proposed implementation is available here: [SR-15434] Add support for custom (non-framework) module kinds by ethan-kusters · Pull Request #33 · apple/swift-docc · GitHub.

Not all documentation built by Swift-DocC is for frameworks. Today, Swift-DocC will build documentation for any symbol graph input it is provided, which is what allows for custom workflows like Swift-DocC’s user documentation on Swift.org. However, Swift-DocC always describes this documentation as a “Framework” on the top-level page, regardless of the contents of that symbol graph.

For example, Swift-DocC’s user documentation on Swift.org is currently described as a “Framework” on the top-level page when the documentation on that page is about using DocC as a “Tool”, not as a “Framework”.

In order to allow for a future in which Swift-DocC supports generating documentation for all sorts of non-framework targets, we should make this “Framework” text customizable.

Proposed Solution

Add support for a new key in the Info.plist file that Swift-DocC looks for in the root of every documentation catalog. This key would allow a documentation author to specify the kind of documentation module being built. This in turn will allow Swift-DocC to accurately render non-framework documentation kinds.

In order to integrate with other tools that may not want to interact with the documentation catalog’s Info.plist, we will also add a new command-line option to provide this information.

Today, Swift-DocC supports the following Info.plist keys:

Info.plist Key Description
CFBundleDisplayName The display name of the bundle.
CFBundleIdentifier The unique identifier of the bundle.
CFBundleVersion The version of the bundle.
CDDefaultCodeListingLanguage The default language identifier for code listings in the bundle.
CDAppleDefaultAvailability The default availability for the various modules in the bundle.

I propose we add a new CDDefaultModuleKind key that would allow authors to specify the default kind that should be used for the various documentation modules in their bundle.

Several of these keys also allow for a fallback version of their value to be passed on the command-line. This allows for integration with external tools that may want to provide this information directly to docc.

Today, Swift-DocC supports the following fallback arguments:

Command-line Argument Corresponding Info.plist Key
--fallback-display-name CFBundleDisplayName
--fallback-bundle-identifier CFBundleIdentifier
--fallback-bundle-version CFBundleVersion
--default-code-listing-language CDDefaultCodeListingLanguage

I propose we also add a new command-line argument, --fallback-default-module-kind that allows for a default module kind to be provided via the command-line in the case where one is not provided in the DocC catalog’s Info.plist. This will allow external tools that integrate with Swift-DocC to inform the documentation compiler of the kind of documentation module being built.

In the case where a default module kind is not provided via the Info.plist or the command-line, we should keep the existing behavior and describe the documentation module as a “Framework”. This will avoid regressing documentation builds for existing projects.

Alternatives Considered

Instead of providing this information via the Info.plist or the command-line, we could instead augment the symbol graph spec to allow for this information to be provided there.

There are a number of benefits to this approach. However, I see benefits in allowing this value to be provided in the documentation catalog even in a world where it can be provided in the symbol graph. There are custom use cases of Swift-DocC where whatever tool producing the symbol graph may not be able to accurately describe the module in a way the documentation author likes. In this scenario, having support for a custom kind provided in the Documentation Catalog will still be useful.

Given this, it makes sense to surface this functionality in Swift-DocC first, and continue to explore how we could also allow for the information to be provided in a symbol graph in the future.

8 Likes

Oh, great to see this addressed :) I swear I thought I reported this as well... maybe not :thinking:

This is great, in the server ecosystem calling things "Framework" sounded very very weird; we mostly deal with "Packages" and call them like that. But I guess the "Vapor" module may want to call itself something else...

+1 to configuring this via CLI, this is flexible enough.

I am wondering if the list of names should be pre-defined or completely open... I guess it does not really matter enough to have those super structured perhaps, so freeform might be fine. Did you consider pre-defining a few types which make sense, or it gets too messy too quickly?

3 Likes

@ktoso Oh this is great feedback! As we're working on SwiftPM integration it may make sense to update the default terminology we use there depending on how the community feels.

I considered a more structured approach here but really the goal of the Info.plist field is to allow for flexibility. If we implement similar functionality in the symbol graph I would think we should take a more structured approach there (as we do today for symbol kinds).

Part of the goal here is to see how the community uses this field, your example of "Package" versus "Framework" being a great one. If we see the community coalesces around certain terminology I think we'll be able to better select what pre-defined values should be supported.

2 Likes

I really like what this enables, and it's a (necessary) step towards supporting documenting more than Frameworks with DocC.

I don't intend to hijack this thread, but where would it be appropriate to discuss what needs to happen (presumably in addition to this) to enable DocC to provide documentation for an application, and not just the libraries that use it. I looked through DocC's JIRA bugs, and didn't see a feature specifically mentioning this - but I'd like to see it happen.

I thought I recalled somewhere talking about the local (module?) application symbols being removed from the symbol graph, but I'm only getting started in understanding the code within swift-docc and am a bit of loss on what it would take to enable this.

Cool thanks -- yeah freeform names sound good :+1: Maybe SwiftPM built docs could default based on some information to some meaningful names based on the target type... but let's leave that to SwiftPM to decide I suppose.

Thanks for proposing and implementing this!

@Joseph_Heck That's great to hear!

Swift-DocC will create documentation pages for all symbols in the symbol graphs its provided. There's definitely discussion to have around how Swift-DocC could best present documentation for projects (like applications) that include primarily internal symbols, but there isn't any limitation to DocC itself that excludes these symbols.

@QuietMisdreavus has recently updated the Swift Symbol Graph tool to support emitting symbols with a specified minimum access-level, so you can try that out with a nightly toolchain if you're interested in producing symbol graphs with internal or private symbols :slight_smile:

brilliant, thank you! I thought there was something (filtering of the symbol graph) inside DocC related to that as well, but I'm delighted that it's all up to the graph itself, and I'll try it out with the the nightly pieces right now!

1 Like

I support this proposal, but just want to acknowledge that this approach conflates catalogs with modules, when catalogs can technically contain multiple modules meant for different purposes. We've been heading down this 1:1 relationship path anyway though so I don't think it's a big concern—if anything, I think it's yet another small step in restricting multi-module catalogs to their originally designed purpose: representing multiple modules as a single conceptual product (e.g. SiriKit and multi-platform frameworks).

@jack I'm actually attempting to avoid conflating those concepts:

This is just the default kind for any of the modules in the catalog. But, given a world where symbol graphs can also include the kind for a specific module, we could conceivably have different kinds for different modules in a single catalog.

We could also look into a more complicated Info.plist or command-line arg scheme to allow passing per-module kinds if this became necessary in the future.

I agree, I think it likely makes sense to have a 1:1 relationship as well but I'm hoping to avoid cementing that reality anymore with this particular proposal.

2 Likes

This is just the default kind for any of the modules in the catalog. But, given a world where symbol graphs can also include the kind for a specific module, we could conceivably have different kinds for different modules in a single catalog.

Aha! Okay, that makes sense. I agree those improvements/extensions could be added incrementally in the future only as needed.

2 Likes

Thank you for all of the great feedback here! The proposed implementation has been merged to Swift-DocC's main branch. :partying_face:

5 Likes
Terms of Service

Privacy Policy

Cookie Policy