Skip to content

Instantly share code, notes, and snippets.

@sunnysideup
Created January 26, 2022 01:07
Show Gist options
  • Save sunnysideup/d2a6f531bc6e03de77526022cecf22fb to your computer and use it in GitHub Desktop.
Save sunnysideup/d2a6f531bc6e03de77526022cecf22fb to your computer and use it in GitHub Desktop.
// prepare the array by adding level, ID and parent to each item of the array
function prepare (array) {
let level, t
for (let i = 0, n = array.length; i < n; i++) {
t = array[i]
t.el = t
level = parseInt(t.tagName[1], 10)
t.level = level
t.idt = i + 1
if (level <= 1) t.parent = 0
if (i) {
if (array[i - 1].level < level) {
t.parent = array[i - 1].idt
} else if (array[i - 1].level === level) {
t.parent = array[i - 1].parent
} else {
for (let j = i - 1; j >= 0; j--) {
if (array[j].level === level - 1) {
t.parent = array[j].idt
break
}
}
}
}
}
return array
}
// transform a flat array in a hierarchical array
function hierarchical (items) {
const hashTable = Object.create(null)
items.forEach(item => hashTable[item.idt] = { ...item, subitems: [] })
const tree = []
items.forEach(item => {
if (item.parent) {
hashTable[item.parent].subitems.push(hashTable[item.idt])
} else {
tree.push(hashTable[item.idt])
}
})
return tree
}
// return an UL containing each title in a LI and possibly other items in UL sub-lists.
function addList (titles) {
let li, a, anchor
// let base = document.querySelector('head base')['href']+'admin-update/';
const base = document.location.href.split('#')[0]
const ol = document.createElement('ol')
if (titles && titles.length) {
let t
for (t of titles) {
if (t.el.id) anchor = t.el.id
else anchor = t.el.textContent
if (!anchor) anchor = 'inconnu'
anchor = anchor.replace(/\W/g, '')
t.el.id = anchor
li = document.createElement('li')
a = document.createElement('a')
a.href = base + `#${anchor}`
a.innerHTML = t.el.textContent
li.append(a)
if (t.subitems && t.subitems.length) {
li.append(addList(t.subitems))
}
ol.append(li)
}
}
return ol
}
// get the toc element
const divtoc = document.getElementById('toc')
// get the article element
const article = document.getElementById('content')
if (divtoc && article) {
let titles = article.querySelectorAll('h1, h2, h3')
titles = prepare(titles)
titles = hierarchical(titles)
const olRacine = addList(titles)
divtoc.append(olRacine)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment