Skip to content

[docs] Add basic documentation on using Snippets to DocC documentation #1166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

heckj
Copy link
Member

@heckj heckj commented Mar 5, 2025

Work towards resolving #417

Summary

Adds some base line documentation that describes how to use the snippets feature built in to DocC and the DocC Plugin.

  • how to add snippets to your project
  • how to run and verify the snippets
  • how to make slices in a snippet
  • how to reference the snippet, or a slice from a snippet, from within another DocC catalog entry

Dependencies & Testing

  • no dependencies
  • visually inspected with a local preview build of the DocC documentation for testing

Checklist

Make sure you check off the following items. If they cannot be completed, provide a reason.

  • Added tests (no tests, doc updates only)
  • Ran the ./bin/test script and it succeeded
  • Updated documentation if necessary

(this pull request is the combined work of https://github.com/JacobHearst and myself, I just happen to be submitting it)

@heckj heckj changed the title Add basic documentation on using Snippets to DocC documentation [docs] Add basic documentation on using Snippets to DocC documentation Mar 5, 2025
@d-ronnqvist d-ronnqvist added the documentation Improvements or additions to documentation label Mar 6, 2025
@d-ronnqvist
Copy link
Contributor

(this pull request is the combined work of https://github.com/JacobHearst and myself, I just happen to be submitting it)

FYI: You can coauthor commits by including a line like this in the commit message:

Co-authored-by: Jacob Hearst <[email protected]>

@heckj
Copy link
Member Author

heckj commented May 2, 2025

@JacobHearst @d-ronnqvist sorry for the delay in writing an overview. Added one based on @d-ronnqvist feedback, see what you think.

@heckj heckj requested a review from d-ronnqvist May 2, 2025 18:25
@heckj heckj force-pushed the snippets-docs branch from 6edd0fc to 9827d8b Compare May 2, 2025 21:21
@heckj
Copy link
Member Author

heckj commented May 2, 2025

@swift-ci please test

@heckj heckj self-assigned this May 6, 2025
@heckj
Copy link
Member Author

heckj commented May 7, 2025

@swift-ci please tests

@swiftlang swiftlang deleted a comment from d-ronnqvist May 7, 2025
Copy link
Contributor

@patshaughnessy patshaughnessy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great! Thank you so much for writing these docs 👏 This is a very cool feature that most people aren't even aware of.

Just a curation issue and another minor tweak please.

@heckj
Copy link
Member Author

heckj commented May 9, 2025

Thanks @patshaughnessy - accepted all suggestions and added a commit to rename the file per your suggestion.

@heckj heckj requested a review from patshaughnessy May 9, 2025 20:15
@heckj
Copy link
Member Author

heckj commented May 9, 2025

@swift-ci please test

@patshaughnessy
Copy link
Contributor

Hello @heckj - sorry for the delay.

I wasn't able to make this work following the instructions in your new article. I suspect that Swift DocC users have to add the Swift DocC Plugin as a dependency in their Package.swift, and then build the docs using the swift package generate-documentation CLI command. (Is there a way to use this feature from Xcode without SPM?)

Would you mind updating the article to show how to do this?

For example, the article might include details about these steps:

  • Create an example SPM project (e.g. "Hello World")
  • Add https://github.com/apple/swift-docc-plugin as a dependency
  • Create a snippet (you have this already)
  • Reference the snippet using the @Snippet directive (you have this already)
  • Build the docs using the Swift DocC Plugin (swift package generate-documentation)
  • View the snippet by opening a Ruby/Python web server from the subdirectory the plugin displays.

Without all of this information spelled out, I don't know how many readers will be able to use the feature successfully.

Let me know if you need help and I can push a draft of what this might look like.

@heckj
Copy link
Member Author

heckj commented May 22, 2025

Thanks for looking @patshaughnessy !

I don't think you strictly need the plugin to do this, but it's certainly easier than wrangling the independent steps of using docc on the command-line from the toolchain. I can (and will) revise to include your suggested path as a walk-through to make it easier for someone to use the features described.

To my knowledge, this capability hasn't been enabled with Xcode, and is only functional when building and rendering documentation using the Swift Package Manager. The core pieces for building the snippets are part of that project, and generally I do tend to add the swift-docc-plugin to a package when I'm working on such documentation.

@heckj
Copy link
Member Author

heckj commented Jun 6, 2025

@patshaughnessy I added in an early section explicitly calling out adding the swift-docc-plugin in order to view the snippets, but stopped short of adding sections that illustrate creating a project and making this more of a tutorial-like walkthrough, since that's not done for any of the other proximate documentation.

Give it a read and see what you think, and I'd happily take updates or a draft of what you'd like to see to make this easier to use. (I've also rebased this branch to catch it up a bit)

@heckj
Copy link
Member Author

heckj commented Jun 6, 2025

@swift-ci please test

make it clear where the snippets go, and also where the documentation
catalog goes.

Also show a concrete example of how to reference a snippet.

Fix a typo.
Copy link
Contributor

@patshaughnessy patshaughnessy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great thank you!

FYI I added a couple of things to your article that I hope will make things a bit more clear for readers:

  • An ASCII art diagram of where the files go. I was confused by how the Snippets folder goes under the root directory, while the documentation catalog goes under the Sources directory. I couldn't get it all working until I realized this.
  • A complete markdown example, showing how the module name goes in the @Snippet directory (as you explained) but also in the H1 tag at the top, which I forgot about.

Hope this helps!

FYI this bit didn't work for me:

DocC parses contiguous comments within the code of a snippet as markdown to annotate your code when embedded in documentation. DocC will attempt to reference symbols from within these comments just like any other documentation content. You can reference symbols from your API, which DocC converts into hyperlinks to that symbol when displaying the content.

I don't know if there's a bug, or if I misunderstood what you were saying. But we can figure that out later in another PR. This is a huge step forward in the docs, so let's merge it.

@patshaughnessy
Copy link
Contributor

Let me know if my additions look good to you, and I'll merge it. Thanks again.

@heckj
Copy link
Member Author

heckj commented Jun 13, 2025

Looks great @patshaughnessy - Thanks for the additions!

No worries with the comments in snippets as markdown - happy to leave that to follow ups and just get the baseline docs out there!

@heckj
Copy link
Member Author

heckj commented Jun 13, 2025

@swift-ci please test

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Snippet doesn't have a documentation comment, we could move this documentation there instead.

That makes it easier to edit the general description and the parameters in the same place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure where you have in mind to place it.

I tried dropping it on the the class itself with the following block:

/// Embeds a code example from the project's code snippets.
///
/// ```markdown
/// @Snippet(path: "my-package/Snippets/example-snippet", slice: "setup")
/// ```
///
/// Place the `Snippet` directive to embed a code example from the project's snippet directory.
/// The path to the snippet ///is identified with three parts:
///
/// 1. The package name as defined in `Package.swift`
///
/// 2. The directory path to the snippet file, starting with "Snippets".
///
/// 3. The name of your snippet file without the `.swift` extension
///
/// If the snippet had slices annotated within it, an individual slice of the snippet can be referenced with the ///`slice` option.
/// Without the option defined, the directive embeds the entire snippet.

But with the sidecar page from the catalog removed, the content didn't appear.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to run swift run generate-symbol-graph to update the directives symbol graph with the latest source changes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 Of course - Thank you - I'll make another pass at updating this

Comment on lines +22 to +41
For example, use the command:

```bash
swift package add-dependency https://github.com/apple/swift-docc-plugin --from 1.1.0
```

Or edit your `Package.swift` to add the dependency:

```
let package = Package(
// name, platforms, products, etc.
dependencies: [
// other dependencies
.package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.1.0"),
],
targets: [
// targets
]
)
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: I feel that we could defer to the plugin's README for this information.

Copy link
Contributor

@d-ronnqvist d-ronnqvist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's at least two issues that we should fix before merging this:

  • the parameter documentation is duplicated on the Snippet directive's page
  • the introduced version is different for the Snippet directive's page and the article about snippets.

@heckj
Copy link
Member Author

heckj commented Jun 13, 2025

Thanks David - I'll go back and revise to align properly and shift some of the content - hadn't clued into @ DirectiveArgumentWrapped - thanks for that reference!

Comment on lines +105 to +121
In the example package above, the `YourProject.md` file might contain this markdown:

```markdown
# ``YourProject``

Add a single sentence or sentence fragment, which DocC uses as the page’s abstract or summary.

## Overview

Add one or more paragraphs that introduce your content overview.

This paragraph appears before the snippet.

@Snippet(path: "YourProject/Snippets/example-snippet")

This paragraph appears after the snippet.
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: AFAICT the main bit of information that this markdown example conveys is that snippets appear inline between paragraphs. If there's nothing more, I feel like it would both be clearer and more concise to spell that out explicitly.

This paragraph appears after the snippet.
```

Without any additional annotations in your snippet, Docc includes the entirety of your code example as the snippet.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: This sentence didn't make sense to me until I had read the rest of the paragraph.

Would it make sense to flip the order around and start with a problem statement and then how to solve it? For example:

If your snippet code requires setup—like imports or variable definitions—that distract from the snippet's main focus you can add // snippet.hide and // snippet.show lines in the snippet code to exclude the lines in between from displaying in your documentation.

Comment on lines 80 to 88
Each code example file you create becomes it's own module.
The name of the code example file you create is the name of the module that Swift creates.
Use the `swift run` command in a terminal to compile and run the module to verify it compiles does what you expect.

Run the earlier code example file named `example-snippet.swift` using the following command:

```bash
swift run example-snippet
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: I feel that this is technical on a level that the reader mostly isn't concerned with. IMO this is the why that explains the example below, but I would think the developer is more interested in how first.

Here's an alternate phrasing that focus on how without going into the module information:

You and consumers of your library can run your snippets from the command line using swift run snippet-name where "snippet-name" corresponds to a file name in your Snippets directory without the ".swift" file extension.

This section could also be a possible place for some of the information about imports from the section above. For example:

Your snippets can import targets defined in your local package, as well as products from its direct dependencies.
Each snippet is its own unit and can't access code from other snippet files.

etc...
```

> Note: Unlike `Snippets`, your Swift package's documentation catalog should be located as a subdirectory of `Sources`, where all of your other Swift source code files are located. For example, see `YourProject.docc` above.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read this as suggestion that the catalog should be a direct subdirectory of the "Sources" directory which AFAIK isn't correct.

minor: Bringing up the DocC catalog and Snippets differences this way feels backwards to me. However, it feels worthwhile calling out that the Snippets directory doesn't go inside the documentation catalog (and doesn't even go inside the Sources).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Snippets aren't a per-target thing like Documentation catalogs, so maybe that's a better way to wrangle the wording.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the phrasing to hopefully be more direct

Comment on lines +142 to +150
### Preview your content

Use the [swift-docc-plugin](https://github.com/swiftlang/swift-docc-plugin) to preview content that includes snippets.
To run the preview, use the following command from a terminal.
Replace `YourTarget` with a target from your package to preview:

```bash
swift package --disable-sandbox preview-documentation --target YourTarget
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: I'm not sure if this article needs to cover how to preview documentation. The main reason why I feel that it could be worth doing so is to call out that snippets only work with swift package [generate|preview]-documentation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why it was added - @patshaughnessy walked through the article by itself, and wasn't able to get it to work because there's no support for Snippets in Xcode, which means you've got to go through the extended steps of generating everything on the CLI to get what you want - hence the longer description and more detail about "how to see your work", which is especially useful while you're assembling snippets and documentation together.

@heckj heckj requested a review from d-ronnqvist June 16, 2025 20:27
Comment on lines +15 to +17
// NOTE: If you update the DocC content, remember to run
// `swift run generate-symbol-graph` to regenerate the DocC
// symbol content for the DocC Documentation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think a specific directive file is the right place for this information.

It's also not just about the documentation comment about the public properties of this class (and their documentation). This also applies to all AutomaticDirectiveConvertible types (including the introduction of new types).

If anything, maybe this information belongs in a section of the Directives file in the contributor documentation similar to how the Benchmarking file has a section about adding new metrics and there's an entire article about adding feature flags.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, it was a note to future me in case there was additional editing - as I've missed this repeatedly. I'd suggest that all of the files where this applies might benefit from a comment like this. I can pull it out if you feel strongly about it.

@heckj heckj requested a review from d-ronnqvist June 17, 2025 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants