0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2025-12-27 22:22:42 +00:00
Files
homebrewery/themes/V3/5ePHB/snippets/tableOfContents.gen.js
Trevor Buckner 5c906ee722 Logic rewrite
Realized we don't need to build a whole descendency tree of all the headers. We can just track the current indendation level and what headers are at each indent. This removes about 1/4 of the code, and lets us put all of the exit conditions (no title, no showPage, ToCExclude) in one place to easily see what is being excluded and what not.
2024-09-09 23:16:56 -04:00

78 lines
2.1 KiB
JavaScript

const dedent = require('dedent-tabs').default;
// Map each actual page to its footer label, accounting for skips or numbering resets
const mapPages = (pages)=>{
let actualPage = 0;
let mappedPage = 0; // Number displayed in footer
let pageMap = [];
pages.forEach(page => {
actualPage++;
const doSkip = page.querySelector('.skipCounting');
const doReset = page.querySelector('.resetCounting');
if(doReset)
mappedPage = 1;
if(!doSkip && !doReset)
mappedPage++;
pageMap[actualPage] = {
mappedPage : mappedPage,
showPage : !doSkip
};
});
return pageMap;
};
const getMarkdown = (headings, pageMap) => {
const levelPad = ['- ###', ' - ####', ' -', ' -', ' -', ' -'];
let allMarkdown = [];
let depthChain = [0];
headings.forEach(heading => {
const page = parseInt(heading.closest('.page').id?.replace(/^p/, ''));
const mappedPage = pageMap[page].mappedPage;
const showPage = pageMap[page].showPage;
const title = heading.textContent.trim();
const ToCExclude = getComputedStyle(heading).getPropertyValue('--TOC');
const depth = parseInt(heading.tagName.substring(1));
if(!title || !showPage || ToCExclude == 'exclude')
return;
//If different header depth than last, remove indents until nearest higher-level header, then indent once
if (depth !== depthChain[depthChain.length -1]) {
while (depth <= depthChain[depthChain.length - 1]) {
depthChain.pop();
}
depthChain.push(depth);
}
let markdown = `${levelPad[depthChain.length - 2]} [{{ ${title}}}{{ ${mappedPage}}}](#p${page})`;
allMarkdown.push(markdown);
});
return allMarkdown.join('\n');
};
const getTOC = ()=>{
const iframe = document.getElementById('BrewRenderer');
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
const headings = iframeDocument.querySelectorAll('h1, h2, h3, h4, h5, h6');
const pages = iframeDocument.querySelectorAll('.page');
const pageMap = mapPages(pages);
return getMarkdown(headings, pageMap);
};
module.exports = function(props){
const TOC = getTOC();
return dedent`
{{toc,wide
# Contents
${TOC}
}}
\n`;
};