simonw/til

Fragment links on headings

simonw opened this issue · 8 comments

I want to be able to easily link to headings within TILs.

They already have (flawed) markup:

<h2>
  <a id="user-content-features" class="anchor" aria-hidden="true" href="#features">
    <span aria-hidden="true" class="octicon octicon-link"></span>
  </a>
  Features
</h2>

The original, un-indented version:

<h2><a id="user-content-features" class="anchor" aria-hidden="true" href="#features"><span aria-hidden="true" class="octicon octicon-link"></span></a>Features</h2>

I'm inclined to strip those out entirely, since they're broken (Link to #features but the ID is #user-content-features).

Here's where the Markdown conversation happens at the moment:

til/build_database.py

Lines 81 to 89 in e9781fa

response = httpx.post(
"https://api.github.com/markdown",
json={
# mode=gfm would expand #13 issue links and suchlike
"mode": "markdown",
"text": body,
},
headers=headers,
)

API docs - https://docs.github.com/en/rest/markdown/markdown?apiVersion=2022-11-28 - nothing there that would influence the #user-content-features bit.

My ideal HTML would be more like this:

<h2 id="ref-features">Features</h2>

Or something other than ref-. Maybe anchor- ?

Then I kind of want to add the # indicators using JavaScript rather than bake them into the HTML of the page.

Prototype using JavaScript entirely:

document.querySelectorAll('h2,h3,h4,h5,h6').forEach(el => {
  let a = el.querySelector('a.anchor');
  if (!a) {
    return;
  }
  let id = a.getAttribute('id');
  el.removeChild(a);
  el.setAttribute('id', id);
  // Add '#' link
  let a2 = document.createElement('a');
  a2.style.textDecoration = 'none';
  // Pale grey
  a2.style.color = '#b7b3b3';
  a2.style.fontSize = '0.8em';
  a2.setAttribute('href', '#' + id);
  a2.innerText = '#';
  // Add a space to the h2 first
  el.appendChild(document.createTextNode(' '));
  // Add that link
  el.appendChild(a2);
})

Looks like this:

CleanShot 2023-08-19 at 07 36 56@2x

I decided to stick with #user-content-features to avoid existing links out there in the world to sections within my documents.

I implemented this entirely in JavaScript, to avoid having to add a further HTML processing step in Python - and because I'm sticking to the existing initial ID design.

Deploy will take half an hour because it's going to need to rebuild all 450 screenshots due to an (invisible) change to the entry HTML.