This post is a continuation from the announcement on the Swift blog, with additional details for members of the Swift community that may want to contribute to Swift-DocC. To quickly summarize, Swift-DocC is a documentation system that parses Markdown comments within Swift code, as well as standalone article and tutorial files contained in the repository, to produce rich, inter-linked documentation.
The documentation team within Apple originally created Swift-DocC for internal authoring of SDK documentation and tutorials. Since those early iterations, the entire stack was re-engineered to be useful for the whole Swift developer community. Swift-DocC is included as part of Xcode 13, and today it officially launches as an open source project.
What makes Swift-DocC special
The main goal for the Swift-DocC project from the very beginning was to unify the documentation experience across API reference docs, conceptual articles, and tutorials. And of course, to manage all the links and interdependencies among all the related docs for the author.
Swift has supported writing API reference documentation, in the form of specially-formatted comments, from its early days. Extra features for these comments have long been supported in Xcode and other tools. The Swift community has since created popular documentation tools such as Jazzy and SwiftDoc, which extract these comments from a codebase and generate documentation websites. This existing support means that a lot of Swift files already have great comments written alongside the code. This sort of API reference documentation has proven itself incredibly helpful to the entire Swift community.
Additionally, conceptual documentation is often equally important, and complementary to API reference. Conceptual articles can provide higher-level instructions for using different APIs together to perform a more complex task. This high level view of a package is essential when introducing a newcomer to a package’s concepts and design patterns. Going further, step-by-step tutorials are a great way to directly help a new user become familiar with a package, by walking them through the code with examples, screenshots, and diagrams.
Finally, bringing documentation right into the developer workflow, integrated into the existing workflow, means more documentation will be written. So it will always be a high priority for Swift-DocC to integrate as seamlessly as possible into the way developers like to work.
How Swift-DocC works
Swift-DocC (GitHub) supports authoring three types of rich documentation — API reference, conceptual articles, and tutorials. Documentation is written using Markdown syntax directly in source code files, or in plain text files that live inside the same repository. Developers can then use whatever editor, IDE, or SCM tools they already prefer. By using the simple file and folder conventions of Swift-DocC, for instance a .docc
folder along side your source, the docc
compiler tool is able to automatically manage links, produce diagnostics, and build even large documentation libraries very quickly.
Swift-DocC has several powerful features:
- Integrated with the Swift compiler to generate documentation using rich semantic information
- Built to integrate tightly with tools to power rich authoring experiences including autocompletion and diagnostics
- Documentation text that can directly link to other symbols across the doc library using double-backtick syntax
- Validation engine to verify links, and report other content errors and warnings
- Conceptual articles can be included within the repository with links to other API and article documents
- Ability to override portions of the default generated documentation using extension files
- Integrated tutorial engine using graphics and sample code, great for introducing packages to new users
- Supports very large codebases of Swift code (with a near-term goal to support C and Objective-C)
- Excellent build-time performance, appropriate for continuous integration
The Details
For folks that may want to contribute, or are just interested in the inner-workings of Swift-DocC, let’s dive a little deeper into how it all works.
Inputs
At its core, the Swift-DocC compiler accepts two kinds of inputs:
-
A machine-readable representation of a Swift module’s API in the form of symbol graph files. Symbol graph files list all the APIs available in a module, including their documentation comments and relationship with one another. The format is designed to be programming language–agnostic, in that compilers for other languages can integrate with Swift-DocC by emitting symbol graph files. Symbol graph files are processed by the
docc
compiler to generate an internal graph of the documentation content. Swift 5.5 already emits symbol graph files as part of the compilation process. -
A folder of additional content called the Documentation Catalog, which can include:
- Article files containing free-form Markdown describing a topic conceptually
- Assets such as images, videos, and code files
- Tutorial files containing structured Markdown to produce step-by-step tutorials
- Documentation extension files, which contain additional documentation for a specific API of the documented module
- An Info.plist file containing metadata such as the name of the documented module. This file is optional and the information it contains can be passed via the command line
These inputs are provided to docc
via the command line:
docc convert \
<path to .docc catalog> \
--additional-symbol-graph-dir <path to folder of symbol graph files>
Syntax
Swift-DocC understands the GitHub Flavored Markdown dialect of Markdown and extends the syntax to support:
- Symbol links, e.g.,
MySymbol
, which provide a lightweight syntax to link to an API's documentation - Directives, e.g.,
@Tutorial { … }
, which allow the writing of structured Markdown content. Directives are attributed markdown containers that provide a declarative way to author rich content like tutorials. Because the set of supported directives and their child content is known by the compiler, DocC can emit precise diagnostics and IDEs can provide rich structural autocompletion and folding facilities.
Markdown parsing is provided by the Swift Markdown library, which uses cmark-gfm
internally.
To organize documentation into a hierarchical structure, Swift-DocC documentation declares a Topics
section with a list of links to documentation organized in topic groups. This structure allows interweaving API reference documentation with conceptual documentation articles, as well as step-by-step tutorials.
## Topics
### Essentials
- <doc:GettingStarted>
- ``Sloth``
### Creating Sloths
- ``SlothGenerator``
- ``NameGenerator``
Outputs
With these inputs, Swift-DocC produces a folder in the Documentation Archive format (extension .doccarchive
), which contains a machine-readable output of the documentation that a renderer can use to produce rendered documentation.
Documentation Archives use the following structure:
<name>.doccarchive
├── data // JSON files for each documentation page.
│ └── documentation
│ ├── <module name>
│ │ ├── <top-level API>.json
│ │ │ └── <member API>.json
│ ┆ ┆── <article name>.json
├── index // An index of the documentation content.
├── metadata.json // Metadata about the produced documentation.
├── …Swift-DocC-Render template files…
┆
The content for each documentation page is written to files in the Render JSON format (see schema), which are emitted in the data/
folder of documentation archives. Render JSON files fully describe documentation pages and allow other documentation tools to integrate with Swift-DocC. Swift-DocC’s renderer, Swift-DocC-Render, is a web app that understands Render JSON and generates styled pages for the web.
Integration in Swift tools
A future proposal will describe how to implement Swift-DocC with Swift Package Manager to support the creation of rendered documentation through a single command-line invocation:
swift package build-documentation
This will be a great opportunity for the community to identify common workflows, such as generating documentation to deploy it to a web server, or generating documentation locally to learn about a package’s dependencies.
What’s Next
Today Swift-DocC starts its journey, and there is a lot more work to do, even in the initial feature set. The code will appear in nightly toolchains shortly, so give it a spin!
Among the first tasks to add to the project will be to integrate with SwiftPM, so the doc building experience is more seamless. Additionally, there is already a pretty exciting list of new features and other short-term improvements set for this project, including:
- Support for Objective-C documentation
- Enable hosting documentation in static file server environments (e.g., GitHub Pages)
- Custom themes for the web renderer
- Generate documentation from app code, including private or internal APIs
Of course, the community will surely have even more ideas. Let’s get started! As mentioned in the blog post, there are many ways to get involved:
- Get started by trying out Swift-DocC on GitHub, as well as Swift-DocC-Render, Swift-Markdown, and Swift-DocC-SymbolKit
- Read the Swift-DocC documentation by building the documentation catalog for DocC (written using Swift-DocC!)
- Discuss the tools and get help in the newly-created Swift-DocC forum
- File a bug report for problems you find, or ideas for improvements
- And as always, pull requests are welcome!