Randomize footnotes and citations HTML IDs with a variable modifier

Hey Herb. For some reason I thought that this was already possible, but apparently I was thinking of Marked 2, which is able to randomize footnote ids to avoid conflicts between footnotes (and presumably citations) when multiple document containing either are displayed on a single web page.

For instance, I’ve generated an HTML document that displays multiple individual notes on a single page. Some of these notes contain footnotes.

What would have to be randomized are the identifying labels (i.e. what follows the colon in a footnote/citation id and its corresponding reference id) attributed to each footnote/citation.

If Document A has a sentence with has a footnote, for example:

<p>
This is a sentence with a footnote. <a href="#fn:1" id="fnref:1" title="see footnote" class="footnote">[1]</a>
</p>

And the footnote itself:

<li id="fn:1">
<p>The footnote <a href="#fnref:1" title="return to article" class="reversefootnote">&#160;&#8617;</a></p>
</li>

And Document B has a footnote of its own, then they will both “share” the fn:1 and fnref:1 IDs, hence conflicting. The footnotes written for Document B will instead link to Document A.

To avoid this, it may help if users were able to append a new merge variable modifier to the body field that can randomize these fn, fnref, cn and cnref IDs into unique alphanumerical strings. For example:

<li id="fn:1avc2">
<p>The footnote <a href="#fnref:1avc2" title="return to article" class="reversefootnote">&#160;&#8617;</a></p>
</li>

This can prove useful when generating web pages like blogs that display all of its posts in their entirety on the front page.

I hope that what I’ve described is coherent. Thanks again for all of your work.

In my capacity as Unofficial Junior Project Umarèl I’m going to label this request as Tentative.

After looking into an alternative approach with a Python script (and ChatGPT) I’ve realized that this may involve a lot of moving parts.

Right now, I’m going to have to think of some ways to achieve randomized footnote and citation links a different way. This would require some changes to my templates and scripts.

Well, first of all, @ThePrinter, I have to thank you for the hearty laugh you gave me when I followed the link for the term you used to describe yourself. I was not familiar with it, but certainly appreciate the wit. And I always appreciate your presence next to the construction site, and your lively commentary on the progress!

I’m wondering whether this request could somehow make use of the Short ID field? Perhaps, for Collections that use this field, the short id for a note could be incorporated seamlessly into the ids? I don’t see how that could hurt anything, and it would help in your use case.

I hesitate to use any sort of randomized number, if only because, after so many years of working in corporate IT, I have a negative reaction to the dehumanizing nature of such things.

1 Like

Thank you Herb. And thank you for being so welcoming to me over the years.

I hadn’t even considered the Short ID field. I think it fulfills the goal of randomizing footnotes perfectly. While looking into this matter, I came across this blog post that describes an effort to randomize Multimarkdown footnotes using Python. The author wrote a script that would transform the required HTML code, for example, from fn:1 into fn:my-footnote-key1.

In Notenik’s case, with Short IDs we could reverse this format. Where fn:1 could become something like fn-short-id:1.[1] And likewise, #fnref:1 could become #fn-short-id-ref:1. Code for citations could follow suit.

So yes, I think Short IDs are the perfect solution to this. Thanks again!

Appendix A

I had a draft post started explaining how I tried out a workaround using Includes. It should do the trick. I was surprised at how simple it was.

This may be helpful to someone in the meantime. Since footnotes are just HTML link anchors, in the event that a variable modifier as discussed is added to Notenik, transitioning from this approach to whichever way the feature would do so shouldn’t break anyone’s web pages.


For those who may be interested in this concept in the future. I’ve found a very simple solution that involved changing about two lines of code in my templates and scripts each.

The solution

This assumes that you’re using the default Website collection.

  • Share each note intended as a post (as opposed to a static page) and export it as an HTML fragment, then write this file to the “includes” directory that is made automatically with the standard Website Collection template. I actually saved each post of mine into a subdirectory within “includes” titled “posts”.

  • Adjust the default “posts” and “teasers”templates in the factory/templates directory accordingly. The main goal is to replace the =$body$= merge command with an include command e.g. <?include "../includes/posts/=$title$=.html" ?>.

Essentially, this is it. Manually sharing your notes as HTML rather than generating them via script is necessary in order to maintain a key element: being able to edit the HTML fragment, because now you can adjust the footnote/citation HTML code to write a unique value for the id and href elements that footnotes/citations use to bounce around the web page.

Keeping the HTML for the posts isolated from the main build process (in that posts themselves are not generated, they are only included into a template) prevents Notenik from reverting any manual changes to the HTML code whenever you regenerate your website in the event that you need to edit a certain post (because Notenik will regenerate pages that have been modified).


  1. I should give credit to John Gruber, who I found using a similar format using timestamps to uniquify footnotes for Daring Fireball ↩︎

1 Like

I have a beta build that should address this issue, through use of Short IDs, as we discussed. Any testing @ThePrinter – or anyone else – could do would be appreciated!

1 Like