diff --git a/themes/V3/5ePHB/snippets/tableOfContents.gen.js b/themes/V3/5ePHB/snippets/tableOfContents.gen.js index 44655c625..49a8c168a 100644 --- a/themes/V3/5ePHB/snippets/tableOfContents.gen.js +++ b/themes/V3/5ePHB/snippets/tableOfContents.gen.js @@ -1,11 +1,12 @@ -const _ = require('lodash'); const dedent = require('dedent-tabs').default; -const mapPages = (iframeDocument, pageMap)=>{ +// Map each actual page to its footer label, accounting for skips or numbering resets +const mapPages = (pages)=>{ let actualPage = 0; - let mappedPage = 0; - const pages = iframeDocument.querySelectorAll('.page'); - _.each(pages, (page)=>{ + let mappedPage = 0; // Number displayed in footer + let pageMap = []; + + pages.forEach(page => { actualPage++; const doSkip = page.querySelector('.skipCounting'); const doReset = page.querySelector('.resetCounting'); @@ -20,84 +21,58 @@ const mapPages = (iframeDocument, pageMap)=>{ showPage : !doSkip }; }); + return pageMap; }; -const recursiveAdd = (title, page, actualPage, targetDepth, child, curDepth=0)=>{ - const anchor = `p${actualPage}`; - if(curDepth > 5) return; // Something went wrong. - if(curDepth == targetDepth) { - child.push({ - title : title, - page : page, - anchor : anchor, - children : [] - }); - } else { - if(child.length == 0) { - child.push({ - title : null, - page : page, - anchor : anchor, - children : [] - }); +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); } - recursiveAdd(title, page, anchor, targetDepth, _.last(child).children, curDepth+1,); - } -}; + let markdown = `${levelPad[depthChain.length - 2]} [{{ ${title}}}{{ ${mappedPage}}}](#p${page})`; + allMarkdown.push(markdown); + }); + return allMarkdown.join('\n'); +}; const getTOC = ()=>{ - const pageMap = []; - const entries = []; - const iframe = document.getElementById('BrewRenderer'); const iframeDocument = iframe.contentDocument || iframe.contentWindow.document; const headings = iframeDocument.querySelectorAll('h1, h2, h3, h4, h5, h6'); - const headerDepth = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']; + const pages = iframeDocument.querySelectorAll('.page'); - mapPages(iframeDocument, pageMap); - - _.each(headings, (heading)=>{ - const onPage = parseInt(heading.closest('.page').id?.replace(/^p/, '')); - const ToCExclude = getComputedStyle(heading).getPropertyValue('--TOC'); - - if(ToCExclude != 'exclude') { - recursiveAdd(heading.textContent.trim(), pageMap[onPage], onPage, headerDepth.indexOf(heading.tagName), entries); - } - }); - return entries; -}; - - -const ToCIterate = (entries, curDepth=0)=>{ - const levelPad = ['- ###', ' - ####', ' - ', ' - ', ' - ', ' - ']; - const toc = []; - if(entries.title !== null){ - if(entries.page.showPage) toc.push(`${levelPad[curDepth]} [{{ ${entries.title}}}{{ ${entries.page.mappedPage}}}](#${entries.anchor})`); - } - if(entries.children.length) { - _.each(entries.children, (entry, idx)=>{ - const children = ToCIterate(entry, entry.title == null ? curDepth : curDepth+1); - if(children.length) { - toc.push(...children); - } - }); - } - return toc; + const pageMap = mapPages(pages); + return getMarkdown(headings, pageMap); }; module.exports = function(props){ const TOC = getTOC(); - const markdown = _.reduce(TOC, (r, g1, idx1)=>{ - r.push(ToCIterate(g1).join('\n')); - return r; - }, []).join('\n').replace('\n\n', '\n'); return dedent` {{toc,wide # Contents - ${markdown} + ${TOC} }} \n`; -}; +}; \ No newline at end of file