Introducing Documentation Generation for Swift Packages


(Jeremy David Giesbrecht) #1

I just completed and released a new feature for Workspace. It now has an in‐house documenter designed specifically for packages (it no longer uses Jazzy).

There are still bugs to fix, and I imagine the soon release of Swift 4.2 will throw a wrench in things, but I thought I’d put it out there anyway for anyone else who might already find it useful as‐is, or who wants to pitch in to help find and fix bugs.

Using it is as simple as running this in the package root:

$ workspace document

(Though you would have to configure a localization once first.)

Installation instructions are here, though as a Swift package, you can also use it any way you would another package tool (e.g. $ swift run workspace ...)

In contrast to Jazzy, this documenter is pure Swift and built on the Swift Package Manager and SwiftSyntax with no reliance on Xcode. This enables it to run on Linux and to understand multi‐target packages and #if conditions. Since it does not need to build the package, it is fully aware of macOS‐only or Linux‐only symbols even when run on the opposite system.

It has also been designed from the ground up with localized documentation in mind, though that aspect is not complete yet.

However, to give Jazzy the respect it is due—I have used it for years and contributed several bug fixes—, there are some things Jazzy does which Workspace will never do. Jazzy can document Objective C, and it natively deals with Xcode projects. If either of those are important to you, Jazzy will always be your tool of choice.

(Jeremy David Giesbrecht) #2

The latest release is now stable on and for Swift 4.2.

(^) #3

Hi, I am trying to use this for my project kelvin13/png, and I’m running into a lot of issues.

The proofreader is doing a lot of weird stuff such as

Line 2481
“>=” is obsolete. Use the greater‐than‐or‐equal sign (≥). (unicode)
                precondition(chunkSize >= 1, "chunk size must be positive")
                precondition(chunkSize ≥ 1, "chunk size must be positive")


Line 67
U+0022 is obsolete. Use quotation marks (“, ”) or double prime (′′). (unicode)
  ///     let names = ["Jacqueline", "Ian", "Amy", "Juan", "Soroush", "Tiffany"]

It seems to think this colon in a doccomment is a swift colon

Line 4600
Colons should be preceded by spaces when denoting protocols or superclasses. (colonSpacing)
        - Returns: A chunk iterator, if the PNG magic signature was read from the
        - Returns : A chunk iterator, if the PNG magic signature was read from the

I cannot seem to turn off the colon rule using a custom .swiftlint.yml file

  - colon

it also just hangs on this step

$ swiftlint lint --strict --reporter emoji

when I run

png$ ~/.SDG/Tools/Workspace/workspace validate

Other than that, this seems like a really interesting tool and I would really like some help to get it working for my project

(Jeremy David Giesbrecht) #4

First of all, its great to hear from you!

I will answer each issue separately.

  1. You didn’t actually ask this, but if you just want to use the documentation generator this thread is about and not the other utilities (which is where all the errors are occurring), you can just run $ workspace document or $ workspace validate documentation instead of the general workspace validate (which is what the provided script does).

The unicode rule discourages ASCII workarounds in favour of real Unicode. is a valid operator in Swift. Workspace tries to recognize operator aliases like this one and not complain when the operator is just used in order to create a better alias for it. (The linked function does not trigger a violation.)

You can also configure Workspace to disable the unicode rule entirely:

let configuration = WorkspaceConfiguration()

This is also the unicode rule at work. It allows syntactic use of the ASCII quote in Swift source, but prevents them in strings, documentation and comments. Workspace does not check comments to see if they might be commented source. I’m not sure how it would be possible to reliably tell the difference.

This one is a bug. I cannot reproduce it, so more context will be necessary to figure out what is wrong. Please report it over of GitHub. In the meantime you can disable it the same as described above. (It is a native Workspace colon rule, not SwiftLint’s colon rule. That is why the .swiftlint.yml is having no effect.)

It may just be fetching and building SwiftLint if Workspace cannot locate it already on the system (such as within Xcode’s sandbox. Though it gets cached, it can take a while the first time (maybe 5 mins), and depending on the number of cores and the environment, Workspace might not be getting the output until swift run completely finishes.

Another alternative is that SwiftLint itself is hanging... which I can do little about.

Is kelvin13/png the project that encountered this? If so, I can troubleshoot it in more depth myself.

(^) #5

It seems to be asking for a localization which I don’t know how to provide

png$ ~/tools/sources/Workspace/.build/release/workspace document

Generating documentation... (§1)

Loading “Workspace.swift”...
There are no localizations specified. (documentation.localizations)

✗ Failed to generate documentation. (See Ctrl + F “§1”)

“PNG” fails validation.

Are you sure this is a good default setting? Very very few mature Swift projects allow let alone encourage unicode operators.

Again, I don’t know how much value this provides. Straight quotes in body copy indicate “computer strings” as opposed to English words or phrases, which take curly quotes.

Some of these substitutions also seem just wrong:

Line 73
U+2026 may be lost in normalization; use “...” instead. (compatibilityCharacters)
### **
### **

... and should never be considered interchangeable, this comes straight from Butterick’s Practical Typography. Very modern fonts are capable of spacing the three-periods version correctly via a ligature but few text rendering engines support this.

Right now this is failing with

$ swiftlint lint --strict --reporter emoji
Fatal error: POSIX command failed with error: 13: file Foundation/Process.swift, line 543
Illegal instruction (core dumped)


(^) #6

I got the documentation running but I’m running into a few more issues:

  • Symbols which have @_specialize-ations seem to get omitted from the documentation. Symbols which have @inlinable seem to lose their documentation.

  • The parsed declatations seem completely messed up:

static func convert(rgba: [, size: (, to code: Code, chromaKey: RGBA<UInt16>? = default, path outputPath: String, level: Int = default) throws
  • This declaration for the PNG.rgba(path:of:) method is missing the generic parameters, making for some odd spellings
static func rgba(path: String, of type: Type) throws -> (
  • The index.html in the root of the docs/ folder redirects me to png/docs/🇺🇸EN/index.html which 404s.

  • It seems to not be finding documentation for some documented symbols. For example, it claims

A symbol has no description:

But it does. It also seems to think it only has one case.

(Jeremy David Giesbrecht) #7


I will take a closer look at all of these in direct connection with your project in the next few days. You have just bumped them all to the top of my to‐do list.

I have created a central GitHub issue for this in general, and will spin off the particulars as I look into them. You can watch that issue to track my progress.

Your feedback is very useful. Thank you.

(Jeremy David Giesbrecht) #8


I’ve finished reading over your comments more closely and spinning of separate issues for each aspect on GitHub. (Here.) Some I was already aware of and already planned a fix, but just hadn’t had time to implement yet (those tagged “Designed”). Others are new to me and will take longer to narrow down where the problem really is.

The next thing I will do is look at the set‐up for your particular project. I will do that before closing the catch‐all issue as a duplicate.

The only thing I will still comment on here in the forums is what you say about the ellipse:

I wholeheartedly agree with you, but our hands are tied by Unicode.

The violation is coming from the compatibilityCharacters rule, not the unicode one. This rule is not about the right way to encode text, but about the reliable way.

I wish the ellipse were not a compatibility character. The Unicode Consortium designed it wrong. Unicode defines a “compatibility character” as a character which “would not have been encoded except for compatibility and round‐trip convertibility with other standards”. They are marked in the code charts with the “≈” symbol. Unicode allows compliant programs to normalize them away by replacement with the way they would have been encoded had they been initially designed directly for Unicode. Use of any such characters is what the rule is designed to flag.

Why Unicode decided an ellipse should be encoded as three full stops is a mystery to me. It seems to go directly against their general rule of representing semantics instead of glyphs. The two characters don’t mean anything close to the same thing. The ellipse should have been a character in its own right. But unfortunately, in Unicode’s eyes, the only reason the separate, compatibility ellipse (U+2026) is available at all is that it was inherited from Windows‐1252 (hex byte 85).

Because any Unicode‐compliant program is free to normalize it to three full stops at any time, it is unsafe to rely on any distinction between that character and three full stops, either for meaning or appearance. Those of us who want our ellipses to display correctly—hopefully all of us—have to select a font that does it right, because workarounds involving U+2026 aren’t reliable. For the same reason, we cannot rely on the presence of U+2026 for any distinction when parsing strings for syntax or semantics, whether in a human or computer language. Anyone using U+2026 needs to be aware that it might vanish, which is why the rule flags it with a warning:

U+2026 may be lost in normalization; use “...” instead. (compatibilityCharacters)

(^) #9

The ellipsis is so common in prose and documentation, and this ligature is supported in so few fonts (I believe this is because many font designers actually oppose implementing this at the font level), that there should at least be a way to suppress this warning. I would rather my s be typeset correctly, and risk them getting converted to ...s by other applications, than ruin them manually.

(Jeremy David Giesbrecht) #10

Of course. And that is exactly what I did for you in the pull request I just submitted to your project.

(^) #11

can I whitelist just the U+2026 character?

(Jeremy David Giesbrecht) #12

Sorry, right now you can only whitelist the entire rule.