Some thoughts on linking to code

Translations: es - Tags: documentation, librsvg

I have been updating the text layout roadmap for librsvg, and part of this involves describing how some of the current code works — for example, how a <text> element gets broken up into a tree of Chunk and Span structures.

Notice how those links go to the generated documentation for the library's internals. In the HTML, rustdoc adds "source" links that in turn take you to the actual source code for that item.

Aside: Chunk has documentation, but Span doesn't; I haven't gotten around to writing it yet. Linking to the documentation for the library's internals helps me see what things are undocumented yet. Maybe a struct Point { x: f64, y: f64 } doesn't need much documetation, but something more complicated like Span definitely does!

Another way of linking to these items would be to link to the actual source for Chunk and Span. Those links go to the HTML version of the source code in GitLab, for a specific commit.

For example, the link to Chunk is https://gitlab.gnome.org/GNOME/librsvg/-/blob/4cd62ad9/src/text.rs#L48-66 and it breaks down like this:

  • gitlab.gnome.org - the server, obviously
  • GNOME - group name
  • librsvg - project name
  • blob/4cd62ad9 - prefix of the git commit id
  • src/text.rs#L48-66 - the file in the librsvg source tree, plus a fragment identifier so that GitLab will highlight a range of source lines.

Obtaining that link takes a bit of work:

  • Go to the project page. Navigate down to the file you want. (Tip: hit t and start typing the filename; you'll get an autocompletion list.)

  • If you are in the wrong branch, change it at the top of the page. Note that the URL is something like .../blob/main/src/my_file.txt

  • Click on the Permalink button near the top of the page. This changes the URL to the actual latest commit id, i.e. blob/123abc/src/...

  • Go to the lines to which you want to link. Click on the first line's number, Shift-click on the second line's number. This changes the URL to a range of lines, with a fragment identifier like #L12-34.

I generally do that when writing descriptions that refer to source lines in specific revisions. Of course, if the code changes, the description may need updating if it's a "permanent" document — but at least there are hopefully never broken links, or links to source code that no longer matches the description.

The first method — linking to the documentation for the library's internals — has the advantage of being actual documentation, with a link to the source code as a bonus. I would probably prefer it if rustdoc generated links to GitLab's display of sources, instead of generating its own embedded copy of the source code, but it's not a big deal.

The second method, linking to specific revisions in GitLab's source view, is perhaps more direct when you want the reader to see the source code immediately, but it's not as easy to navigate. The reader has to read the source and there is no way in GitLab to easily jump to symbol definitions, for example, or to find the implementations for a struct's methods. The generated rustdoc has all that.

Finally, in real-time conversation, I may just link to the blob/main URLs for whatever the latest revision is at the time. I expect my interlocutor to look at the link basically immediately, or really soon after our conversation, so it will show the same context as I was thinking about.

I suppose each method has its place:

  • Link to the generated documentation for the source code — Friendly to the reader if they need more context; good for high-level exploration. Links can go out of date if you rename symbols (we don't store generated docs for each revision).

  • Link to blob/123abc or a specific revision — unambiguous, good for descriptions of code at a specific point in time, and the reader can easily cut&paste that commit id to the git command line or other tooling.

  • Link to blob/main or the latest revision in some branch — easy to do; only takes the GitLab dance to find the line numbers. Good for casual conversation. May remain current for a long time in "permanent" documentation if you are describing code very generally and that code doesn't change a lot.