0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2025-12-27 11:32:38 +00:00

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.
This commit is contained in:
Trevor Buckner
2024-09-09 23:16:56 -04:00
parent 2cb3ca6880
commit 5c906ee722

View File

@@ -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`;
};
};