How to reference an article in a different module?

taking a look at the syntax for a DocC codelink, it seems we have a way to reference an article from the same module:

<doc:GettingStarted>

but we cannot use leading-slash syntax to specify a module-relative path because that is already occupied by the tutorials namespace:

<doc:/tutorials/SlothCreator>

how to reference an article from a different module?

It's not yet supported outside for stock DocC - or more specifically, a public solution hasn't yet been made available. There's bits in the earlier DocC code about external reference resolvers that allowed some of that process, and @ronnqvist has been working on a newer solution ("hierarchical resolver") - but I've only followed a few of the PRs (a recent one pulled out a lot of older code: Add successfully resolved external references to reference index by d-ronnqvist · Pull Request #582 · apple/swift-docc · GitHub) and don't know the details of what is additionally needed to make it work end to end.

Like Joe pointed out; the short answer is that links across modules isn't supported out-of-the-box* and that it's something we're working on. There's a longer answer but I'll save that for last since I think your question is mostly focused around what the link syntax would be for referencing non-symbols in other modules.

The current link syntax

The syntax for general DocC documentation links (<doc:> links) has two main components; an optional identifier—(the "host" component of the link) which isn't needed for local links—and a path to the page.

For authoring convenience DocC allow the developer to omit the leading path components of the path. For example; in the SlothCreator sample, all of these are links to the GettingStarted article:

- <doc:GettingStarted>
- <doc:SlothCreator/GettingStarted>
- <doc:documentation/SlothCreator/GettingStarted>
- <doc://SlothCreator/GettingStarted>
- <doc://SlothCreator/SlothCreator/GettingStarted>
- <doc://SlothCreator/documentation/SlothCreator/GettingStarted>

(In the last 3 links, the documentation bundle identifier happens to be the same as the target module name)

The same behavior applies to tutorial content, where the tutorial overview page is another "root page" — meaning that the tutorial overview page is not a descendant of the module page.

In the SlothCreator example it would be possible to link to the tutorial overview as just <doc:SlothCreator> except that that link is ambiguous because the tutorial overview page has the same name as the module and for historical reasons—which is a behavior we've kept for backwards compatibility—the module page is preferred over the tutorial overview page in this collision. If you rename the file to "MeetSlothCreator.tutorial" you can link to it using <doc:MeetSlothCreator>. Without renaming it, <doc:tutorials/SlothCreator> is the shortest path that unambiguously refers to the tutorial overview page.

Today we have more options for disambiguating links, so you should also be able to write <doc:SlothCreator-tutorial> but when I tested it just now that doesn't work so I need to look into that.

How that applies to external links

If we do nothing more to the documentation link syntax, then the way you would reference an external article in the current syntax would be something along the lines of <doc://NameOfArchive/path/to/SomeArticle>.

Of course, you'd need some way to get make the external content available to DocC, which there isn't an out-of-box-solution for today.

Resolving links across targets today

Resolving links between modules isn't supported out-of-the-box. That said, if you really, really want to do this today, you can.

All the way back since the initial open source release, DocC has had the infrastructure to bridge with other documentation systems with one feature to resolve links to external systems and one feature to expose all the pages and landmarks of the DocC content that other systems can link to.

This system is primarily meant to bridge with other documentation systems and it wasn't originally designed for other DocC content. Because of this, you'll be working against the API in some cases trying to use it to resolve external DocC content. It has gotten better over the last year but there are still one or two obstacles in the design that make this harder to do than it should be.

I've been hoping to deprecate that system at some point but we'd need something to replace it with. Whether or not DocC content would have its own integration or if everything would go through the same system is still not decided.

So, if anyone really, really wants to do this today, you can message me about it—or post in this Forum thread or something—and I can provide some pointers on how to get set up and what code you'll need to write for your documentation bridge. Just know that you'd be using a feature that we're working on replacing.

3 Likes

what is the difference between <doc:/tutorials/SlothCreator> and <doc:tutorials/SlothCreator> ?

There shouldn't be a difference. If there is that's probably a bug.

1 Like

which of these components are case-sensitive? if there are two bundles named SlothCreator and slothcreator (both valid module names), is it possible to disambiguate?

All the components of documentation links (and symbol links) are case sensitive.

when did this happen? i recall codelinks were case-insensitive so things like dictionary/keys needed disambiguation. (but i cannot find any trace of that in the guide anymore)

I can see why you'd recall that. Links used to require disambiguation as if they were case insensitive but they were always case sensitive (with redundant disambiguation).

An unfortunate implementation detail before 5.9 coupled the link to the page's "topic reference" (not a user-facing term) which is related to the page's file path within the .doccarchive.

DocC adds disambiguation to these file paths so that the documentation archive can be hosted on servers with both case-sensitive and case-insensitive file systems. Because this disambiguation is also reflected in the "topic reference" and links were previously tied to topic references, links had to use disambiguation they didn't really need.

For example, a type and a property like this

enum Something {}
var something: Something

needed to be written as Something-swift.enum and something-swift.property to match those "topic references". If the enum link was lowercase—like something-swift.enum—it wouldn't resolve.

In 5.9, the link is decoupled from the "topic reference" spelling which means that links can leverage their case sensitivity to avoid disambiguation and that links can contain characters which aren't allowed in file paths or in URLs.