My theme for forester (+plugins)
at d095938b1ecadc0ac776b0b4794dea01656d6944 96 lines 2.8 kB view raw
1import 'ninja-keys'; 2import 'katex'; 3 4import autoRenderMath from 'katex/contrib/auto-render'; 5 6function partition(array, isValid) { 7 return array.reduce(([pass, fail], elem) => { 8 return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]]; 9 }, [[], []]); 10} 11 12window.addEventListener("load", (event) => { 13 autoRenderMath(document.body) 14 15 const openAllDetailsAbove = elt => { 16 while (elt != null) { 17 if (elt.nodeName == 'DETAILS') { 18 elt.open = true 19 } 20 21 elt = elt.parentNode; 22 } 23 } 24 25 const jumpToSubtree = evt => { 26 if (evt.target.tagName === "A") { 27 return; 28 } 29 30 const link = evt.target.closest('span[data-target]') 31 const selector = link.getAttribute('data-target') 32 const tree = document.querySelector(selector) 33 openAllDetailsAbove(tree) 34 window.location = selector 35 } 36 37 38 [...document.querySelectorAll("[data-target^='#']")].forEach( 39 el => el.addEventListener("click", jumpToSubtree) 40 ); 41}); 42 43const ninja = document.querySelector('ninja-keys'); 44 45fetch("./forest.json") 46 .then((res) => res.json()) 47 .then((data) => { 48 const items = [] 49 50 const editIcon = '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M480-120v-71l216-216 71 71-216 216h-71ZM120-330v-60h300v60H120Zm690-49-71-71 29-29q8-8 21-8t21 8l29 29q8 8 8 21t-8 21l-29 29ZM120-495v-60h470v60H120Zm0-165v-60h470v60H120Z"/></svg>' 51 const bookmarkIcon = '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M120-40v-700q0-24 18-42t42-18h480q24 0 42.5 18t18.5 42v700L420-167 120-40Zm60-91 240-103 240 103v-609H180v609Zm600 1v-730H233v-60h547q24 0 42 18t18 42v730h-60ZM180-740h480-480Z"/></svg>' 52 53 if (window.sourcePath) { 54 items.push({ 55 id: 'edit', 56 title: 'Edit current tree in Visual Studio Code', 57 section: 'Commands', 58 hotkey: 'cmd+e', 59 icon: editIcon, 60 handler: () => { 61 window.location.href = `vscode://file/${window.sourcePath}` 62 } 63 }) 64 } 65 66 const isTopTree = (addr) => { 67 const item = data[addr] 68 return item.tags ? item.tags.includes('top') : false 69 } 70 71 const addItemToSection = (addr, section, icon) => { 72 const item = data[addr] 73 const title = 74 item.taxon 75 ? (item.title ? `${item.taxon}. ${item.title}` : item.taxon) 76 : (item.title ? item.title : "Untitled") 77 const fullTitle = `${title} [${addr}]` 78 items.push({ 79 id: addr, 80 title: fullTitle, 81 section: section, 82 icon: icon, 83 handler: () => { 84 window.location.href = item.route 85 } 86 }) 87 } 88 89 const [top, rest] = partition(Object.keys(data), isTopTree) 90 top.forEach((addr) => addItemToSection(addr, "Top Trees", bookmarkIcon)) 91 rest.forEach((addr) => addItemToSection(addr, "All Trees", null)) 92 93 ninja.data = items 94 }); 95 96