URL reversing in rendered output

While working on the subject of Browsable Markdown files while on GitHub, I realized that it is a case of URL reversing (see for instance the Django explanation of the feature).

The ability to “adjust the canonical path” of a page, as the Permalinks doc explains, is needed not only in templates, but also in the output rendered from the markup content.

If I want to link to the content/post/sample-entry.md page from another page, currently I have to hard-wire the /2013/11/sample-entry/ URL in the content, so that it conforms to the current page and site config, including uglyURLs and canonifyURLs.

I’d like to postprocess the output rendered from the markup so that all content links are replaced with the respective permalinks. What data structure, accessible during rendering, contains a map from all canonical paths to their permalinks? Is this a reasonable approach?

I use my x shortcode for this; I may try to figure out how to make this happen within Hugo itself without a shortcode:

{{ $ref := .Get "ref" }}{{ $title := .Get "title" }}{{ $inner := .Inner }}{{ range first 1 (where .Page.Node.Site.Pages "Name" $ref) }}{{ if len $title }}<a href="{{ .Permalink }}">{{ $title }}</a>{{ else }}{{ if len $inner }}<a href="{{ .Permalink }}">{{ $inner }}</a>{{ else }}<a href="{{ .Permalink }}">{{ .Title }}</a>{{ end }}{{ end }}{{ end }}

It gets used like {{% x ref="licence" %}} where it finds licence.md and uses the .Permalink. (It should probably use .RelPermalink instead of .Permalink, but I haven’t made that change, yet. You can also set the title {{% x ref="ontario-votes-voting-format-referendum" title="earlier post" %}} although it uses the referenced post’s Title or the .Inner value if that isn’t present.