Relationship between swift-docc, swift-docc-render, and swift-docc-plugin

Although I’ve been using DocC (through its Swift compiler plugin) for a while, I’m new to contributing to DocC. So I have some beginner’s questions.

My understanding so far is that:

  1. swift-docc transforms in-source documentation into a symbol graph.
  2. swift-docc-render transforms that symbol graph into a Vue.js SPA.
  3. The swift-docc-plugin (namely, its generate-documentation command) does #1 then #2.

Assuming the three descriptions above are all reasonably accurate, which they may very well not be,

  • Why does the swift-docc-plugin README state that swift-docc outputs a documentation archive, not a symbol graph?
    • As far as I know, the documentation archive and the symbol graph are both JSON representations of the symbols in the source code: the former is packaged as a .doccarchive file, and the latter is technically a conceptual graph implemented as a Swift struct that’s then encoded into JSON. But what is the relationship between the two?
  • Why does swift-docc depend on swift-docc-plugin? Shouldn’t it be the other way around? (The dependency is declared here. Even more curiously, the dependency on swift-docc-plugin doesn’t seem to actually be used by any compilation targets.)
  • Similarly, why doesn’t swift-docc-plugin depend on swift-docc-render? If assumption #3 is correct, then swift-docc-plugin’s generate-documentation command is essentially just swift-docc followed by swift-docc-render.
  • Why does swift-docc-render include a script for generating a symbol graph? Isn’t that the purview of swift-docc?

Thanks!

1 Like

Hey, here's my understanding of how these parts relate:

DocC turns documentation markup (and DocC catalogs) into DocC archives (which hold the render JSON used by DocC render to show docs websites).

A tool like swiftc -emit-symbol-graph is what gives DocC its knowledge of the in-source docs and the associated declarations / symbol relationships. DocC further transforms the symbol graph info when it has it.

Yeah, the plugin bundles up bunch of the steps. However, I think its intended use case is for SwiftPM packages or similar where you have source code (and potentially dependencies). The plain DocC tool can operate on a bare DocC bundle and on symbol graphs that it might have received without the associated source code.

The symbol graph is an input to DocC; the output is render JSON (often inside a DocC archive), which DocC render uses as input.

I don't know, but it hasn't always. From the PR where Ethan added the dependency, it seems like it might be a way to get a fresh copy of DocC render when building everything locally.

I think both DocC and DocC render come bundled in every environment where you get Swift (like the swift.org toolchains), so they're dependencies but not in the SwiftPM sense.

That's code specific to generating a symbol graph for Vue components, which is something DocC doesn't normally support but that it uses for its own self-documentation. For example the TabNavigator directive docs come from that script.


Hope this helps! There might be a couple inaccuracies or over simplifications, but if nothing else that'll give someone who works on DocC on a more daily basis a springboard to add more info.

3 Likes

This is probably the major misunderstanding. A "symbol graph" is a representation of source code that Swift-DocC loads to create documentation. It's generated by Clang and Swift (and anything else that wants to get loaded by Swift-DocC, like the Vue components in Swift-DocC-Render) and provided as an input to Swift-DocC.

See above, but the README is correct. The JSON files ending in .symbol.json and loaded by Swift-DocC are "symbol graphs", loaded into data structure definitions defined in SymbolKit, and reflect the source code being documented. The JSON files in the "documentation archive" are called "Render JSON", and reflect a rendered documentation page, including any visual styling that may occur. This is represented in code by Swift-DocC's RenderNode type and its constituent types, and is provided as an input to Swift-DocC-Render.

This is a quirk of SwiftPM command plugins. swift-docc-plugin provides the swift package generate-documentation command, for quickly building the documentation for a Swift package. However, it can only ever be added to a package's dependencies; due to limitations in SwiftPM, it can't be installed globally. So here, adding swift-docc-plugin to Swift-DocC's dependencies is just a way for Swift-DocC contributors to easily generate documentation for Swift-DocC outside of Xcode.

swift-docc-plugin uses Swift-DocC from an installed toolchain. In toolchains that ship from swift.org or in Xcode, Swift-DocC-Render is packaged alongside Swift-DocC in a well-known path, that Swift-DocC will determine on its own. This way, you don't need to build Swift-DocC-Render yourself, or download the pre-built artifact either. If you want to use a specific build of Swift-DocC-Render for testing, you'll need to set the DOCC_HTML_DIR environment variable yourself.

Swift-DocC was originally written to document Swift and Objective-C projects, but it doesn't integrate directly into either compiler. As mentioned earlier, it uses symbol graphs to load the source code representation. Swift-DocC-Render uses this script to create a symbol graph of its own so that it can use Swift-DocC for documentation, despite not being written in Swift. (Similarly, this approach could be taken for any source language or data format, so long as you can map it into a symbol graph...)


Hope this helps! I know @krilnon added some information, but i wanted to come in here and flesh it out more (and provide a bunch of links :sweat_smile:) so that it could be a bit more authoritative.

6 Likes