mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-07 05:32:41 +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:
@@ -1,11 +1,12 @@
|
|||||||
const _ = require('lodash');
|
|
||||||
const dedent = require('dedent-tabs').default;
|
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 actualPage = 0;
|
||||||
let mappedPage = 0;
|
let mappedPage = 0; // Number displayed in footer
|
||||||
const pages = iframeDocument.querySelectorAll('.page');
|
let pageMap = [];
|
||||||
_.each(pages, (page)=>{
|
|
||||||
|
pages.forEach(page => {
|
||||||
actualPage++;
|
actualPage++;
|
||||||
const doSkip = page.querySelector('.skipCounting');
|
const doSkip = page.querySelector('.skipCounting');
|
||||||
const doReset = page.querySelector('.resetCounting');
|
const doReset = page.querySelector('.resetCounting');
|
||||||
@@ -20,84 +21,58 @@ const mapPages = (iframeDocument, pageMap)=>{
|
|||||||
showPage : !doSkip
|
showPage : !doSkip
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
return pageMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
const recursiveAdd = (title, page, actualPage, targetDepth, child, curDepth=0)=>{
|
const getMarkdown = (headings, pageMap) => {
|
||||||
const anchor = `p${actualPage}`;
|
const levelPad = ['- ###', ' - ####', ' -', ' -', ' -', ' -'];
|
||||||
if(curDepth > 5) return; // Something went wrong.
|
|
||||||
if(curDepth == targetDepth) {
|
let allMarkdown = [];
|
||||||
child.push({
|
let depthChain = [0];
|
||||||
title : title,
|
|
||||||
page : page,
|
headings.forEach(heading => {
|
||||||
anchor : anchor,
|
const page = parseInt(heading.closest('.page').id?.replace(/^p/, ''));
|
||||||
children : []
|
const mappedPage = pageMap[page].mappedPage;
|
||||||
});
|
const showPage = pageMap[page].showPage;
|
||||||
} else {
|
const title = heading.textContent.trim();
|
||||||
if(child.length == 0) {
|
const ToCExclude = getComputedStyle(heading).getPropertyValue('--TOC');
|
||||||
child.push({
|
const depth = parseInt(heading.tagName.substring(1));
|
||||||
title : null,
|
|
||||||
page : page,
|
if(!title || !showPage || ToCExclude == 'exclude')
|
||||||
anchor : anchor,
|
return;
|
||||||
children : []
|
|
||||||
});
|
//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 getTOC = ()=>{
|
||||||
const pageMap = [];
|
|
||||||
const entries = [];
|
|
||||||
|
|
||||||
const iframe = document.getElementById('BrewRenderer');
|
const iframe = document.getElementById('BrewRenderer');
|
||||||
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
||||||
const headings = iframeDocument.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
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);
|
const pageMap = mapPages(pages);
|
||||||
|
return getMarkdown(headings, 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = function(props){
|
module.exports = function(props){
|
||||||
const TOC = getTOC();
|
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`
|
return dedent`
|
||||||
{{toc,wide
|
{{toc,wide
|
||||||
# Contents
|
# Contents
|
||||||
|
|
||||||
${markdown}
|
${TOC}
|
||||||
}}
|
}}
|
||||||
\n`;
|
\n`;
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user