Skip to content

Instantly share code, notes, and snippets.

@codingchili
Created April 21, 2022 13:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codingchili/b4ca9d886020c67cadd65af1378b2702 to your computer and use it in GitHub Desktop.
Save codingchili/b4ca9d886020c67cadd65af1378b2702 to your computer and use it in GitHub Desktop.
Netacad2PDF (requires a _lot_ of memory)
function extract_chapter_links() {
return [...document.querySelectorAll('a.navlink')]
.map(link => {
return {
name: link.querySelector('.navlink_name').innerText,
label: link.querySelector('.navlink_label').innerText,
href: link.href
}
}).filter(link => !link.href.includes('#'));
}
function filter_top_links(links) {
return links.filter(link => (/.+?\.1$/mgi.test(link.label)));
}
function create_iframe(link) {
let iframe = document.createElement('iframe');
iframe.src = link.href;
iframe.setAttribute('frameborder', '0');
iframe.style.width = `-webkit-fill-available`;
return iframe;
}
function await_loaded(iframe) {
return new Promise((resolve => {
iframe.addEventListener('load', () => {
setTimeout(() => {
resolve(iframe);
}, 3000);
});
}));
}
function run_in_iframe(iframe, functions) {
functions.forEach(fn => iframe.contentWindow.eval(`(${fn})()`));
}
function hide_navbar() {
document.querySelector('#side-nav').style.display = 'none';
document.querySelectorAll('.nav-visible').forEach(element => {
element.classList.remove('nav-visible');
})
}
function inject_theme() {
document.querySelectorAll('.block-container h1').forEach(element => {
element.style.background = `linear-gradient(90deg,#8f370e 0,#000000)`
});
}
function remove_interactive() {
// tbd
}
function remove_header() {
document.querySelectorAll('.app-header, #breadcrumb-wrapper')
.forEach(element => element.remove());
}
async function insert_iframes(iframes) {
for (let i = 0; i < iframes.length; i++) {
let iframe = iframes[i];
document.documentElement.append(iframe)
await await_loaded(iframe);
// hack to get rid of scrolling and set full height.
iframe.height = iframe.contentWindow.document.documentElement.scrollHeight + 'px';
document.getElementById('status').innerText =
`loading pdf content.. ${(((i + 1) / iframes.length) * 100).toFixed(0)}%`;
}
}
function write_head(links) {
document.write(`
<style>
h2, h3 {
text-align: center;
}
.title {
margin-top: 128px;
}
.toc {
display: flex;
margin-top: 100vh;
min-height: 100vh;
}
.name {
display: block;
margin-left: 24px;
}
</style>
<div id="loader">
<h2 class="title">${document.querySelector('.page-title').innerText}</h2>
<h3 id="status"></h3>
</div>
`);
}
let links = extract_chapter_links();
let iframes = filter_top_links(links).map(create_iframe);
write_head(links);
insert_iframes(iframes).then(() => {
iframes.forEach(iframe => run_in_iframe(iframe, [
hide_navbar, inject_theme, remove_header, remove_interactive
]))
document.getElementById('loader').remove();
document.body.remove();
window.print();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment