Is there a direct path to getting a list of the DocC symbol hashes for functions in an extension?

I understand there's at least some limitations with DocC when it comes to extensions, so this may just be an existing issue - but if anyone has a workaround, I'd love to know about it.

I'm adding some docs to the open source project Euclid โ€” for a variety of reasons โ€” but also because it's a good excuse to work the corners of my knowledge on how to apply DocC to libraries to better understand it. While I was doing so, I started adding in some curation within on the structs to organize its properties and methods.

What I found is that the properties and methods that were directly defined were a piece of cake to add. I added the ## Topics then ### Creating Vectors and started in adding the various initializers. There's only one defined directly in that core struct. That all works great.

The issue is with initializers that are defined in a public extension - same file, just lower down. The code completion of Xcode sees them all - so it looks like I can easily add them, but when I do, they show up as identical symbol characters.

In this case. there's an init(_:) that takes a Double, another takes an SCNVector3, etc. Since they're identical other than the type information, I was expecting there'd be one of the extension-hash bits that needed to get added on, but the code-completion bits didn't provide it.

The abstracts for these initializers DO show up in the rendered documentation, it just seemed like I couldn't curate them.

After poking through a variety of avenues, I found I could curate them - IF I had the proper DocC symbol names with the extension hashes on them. The code completion in Xcode (13.2.1) isn't providing them, and I can't spot a way to get a list of them to use.

The only way I've found to get to these little hash codes is by doing the CLI process to generate hosted documentation in a mini-browser with docc preview, and then look at the URL provided in the hosted HTML content after navigating to the relevant symbol:

mkdir -p .build/symbol-graphs
swift build --target Euclid -Xswiftc -emit-symbol-graph \
    -Xswiftc -emit-symbol-graph-dir -Xswiftc .build/symbol-graphs
xcrun docc preview Sources/Euclid.docc --fallback-display-name Euclid \
    --fallback-bundle-identifier com.github.nicklockwood.Euclid \
    --fallback-bundle-version 0.1.0 \
    --additional-symbol-graph-dir .build/symbol-graphs

Is there anywhere else this is exposed? That workflow is kind of hideous when you're trying to just knock docs out within xCode, but maybe that's the only recourse right now if they're not automagically showing up in Xcode.

I was hoping that maybe there's a way to dump a quick index into a file or something for the various symbols found - which would make assembling the docs significantly easier than having to browse to the right thing in HTML, copy a portion of the URL, and then jump back to
Xcode to build up the curation.

Or maybe just a pointer to what structure within DocC contains these symbols so I can write a quick little script to dump a quick text index of those guys next to the code declaration so that I've got a way to look it up without endless navigating in HTML and clicking in Safari URL bars to find the right details.

(And yes, since I expect this is related to an issue with Xcode and code completion of those hashes, I did open a feedback with this detail and reproduction: FB9858746)

Hi @Joseph_Heck!

Sorry to hear you're running into an issue here. Really appreciate you filing the Feedback :slight_smile:

The workaround you already found of using docc preview is what I would have recommended first, but, you're right, it's definitely less than optimal.

If you'd like a more data-driven way to do this, you could try to use the linkable-entities.json file that docc will emit in the root of your archive if you pass the --emit-digest flag.

This will include information like the following for each symbol in the DocC archive:

{
    "usr": "s:6Euclid4MeshV8WrapModeO4tubeyA2EmF",
    "fragments": [
        {
            "kind": "keyword",
            "text": "case"
        },
        {
            "kind": "text",
            "text": " "
        },
        {
            "kind": "identifier",
            "text": "tube"
        }
    ],
    "title": "Mesh.WrapMode.tube",
    "referenceURL": "doc:\/\/Euclid\/documentation\/Euclid\/Mesh\/WrapMode\/tube",
    "language": "swift",
    "taskGroups": [
        
    ],
    "path": "\/documentation\/euclid\/mesh\/wrapmode\/tube",
    "kind": "org.swift.docc.kind.enumerationCase",
    "availableLanguages": [
        "swift"
    ]
},

You're likely only interested in the referenceURL property of each element and then likely only the path components after the module name: documentation\/Euclid\/<relevant-path-components>.

The OpenAPI spec for linkable-entities is here: swift-docc/LinkableEntities.json at main ยท apple/swift-docc ยท GitHub

Hope this helps,
- Ethan

1 Like

Thank you @ethankusters!

That helped quite lot. I also found some of what I wanted within the rendered JSON files that docc preview generated - so a bit of strangling the bash shell and I have at least a list of the symbols by pulling out their identifiers:

find Sources/Euclid.docc/.docc-build -name "*.json" -exec jq '.identifier.url' {} \;

Which may be enough for me to work with, at least for starters. I'll dig around in the LinkableEntities schema and maybe cobble a quick swift script that I can use to drop out both the identifier and the original declaration line (so I can see what types are involved for the relevant identifier). Looks like I'll need to reassemble some JSON elements to get it back into a string format for quick'n'easy perusal.

1 Like