From 23325bdab3108c42f0157625f995b532a13096c7 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Wed, 28 Feb 2024 23:20:32 -0500 Subject: Um... Version bump anybody? - Corrected treatment of "WIP" and "UNLISTED" posts. - Add wrapper for make4ht. - Improved html5 compliance (still not fully compliant tho). - Node 22 compatibility. --- generator/make4htwrapper.js | 105 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100755 generator/make4htwrapper.js (limited to 'generator/make4htwrapper.js') diff --git a/generator/make4htwrapper.js b/generator/make4htwrapper.js new file mode 100755 index 0000000..b8e0c3a --- /dev/null +++ b/generator/make4htwrapper.js @@ -0,0 +1,105 @@ +#!/usr/bin/node +//Copyright Chris Xiong 2024 +//License: Expat (MIT) + +const content_dir='../content'; +const image_dir='../content/img'; + +const process = require('node:process'); +const path = require('node:path'); +const util = require('node:util'); +const fs = require('node:fs'); +const jsdom = require('jsdom'); +const spawn = require('child_process').spawn; +const image_size = require('image-size'); + +function promote_header(doc) +{ + for (let i = 2; i <= 6; ++i) + { + const list = doc.querySelectorAll(`h${i}`); + for (let j = list.length - 1; j >= 0; --j) + { + const e = list[j]; + const newe = doc.createElement(`h${i-1}`); + newe.innerHTML = e.innerHTML; + e.parentNode.replaceChild(newe, e); + } + } +} + +function image_unsquash(doc, wd) +{ + for (let im of doc.querySelectorAll('img')) + { + const d = image_size(path.join(wd, im.src)); + if (d.width > d.height) + im.removeAttribute('width'); + else if (d.width < d.height) + im.removeAttribute('height'); + } +} + +function image_relocate(doc, wd, imd) +{ + for (let im of doc.querySelectorAll('img')) + { + fs.copyFileSync(path.join(wd, im.src), path.join(imd, im.src)); + im.src = `//filestorage.chrisoft.org/blog/img/${im.src}`; + } +} + +function css_embed(doc, cssc) +{ + const style = doc.createElement('style'); + style.textContent = cssc.replaceAll('font-family', 'not-font-family'); + const body = doc.querySelector('body'); + body.insertBefore(style, body.childNodes[0]); +} + +async function main() +{ + process.stdin.setEncoding('utf8'); + + const input = await new Promise((resolv, rej) => { + let d = ''; + process.stdin.on('readable', () => { const r = process.stdin.read(); if (r) d += r; }); + process.stdin.on('end',() => { resolv(d.trim()); }); + }); + + const wd = path.resolve(path.join(content_dir, path.dirname(input))); + const fn = path.basename(input); + const fnb = path.basename(input, '.tex'); + + const make4htp = spawn('make4ht', ['-f', 'html5', fn, '"fn-in"'], { + cwd: wd, + shell: true, + stdio: ['ignore', 'pipe', 'pipe'] + }); + make4htp.stdout.setEncoding('utf8'); + make4htp.stderr.setEncoding('utf8'); + make4htp.stdout.on('data', (d) => { console.error(d); }); + make4htp.stderr.on('data', (d) => { console.error(d); }); + try { + await new Promise((resolv, rej) => { + make4htp.on('close', (r) => r ? rej(r) : resolv()) + }); + } catch (e) { + console.error(`make4ht failed with exitcode ${e}`); + return; + } + + const htmlc = fs.readFileSync(path.join(wd, `${fnb}.html`), 'utf8'); + const cssc = fs.readFileSync(path.join(wd, `${fnb}.css`), 'utf8'); + const domrt = new jsdom.JSDOM(htmlc); + + promote_header(domrt.window.document); + image_unsquash(domrt.window.document, wd); + image_relocate(domrt.window.document, wd, path.resolve(image_dir)); + css_embed(domrt.window.document, cssc); + + process.stdout.setEncoding('utf8'); + process.stdout.write(domrt.window.document.querySelector('body').innerHTML); +} + +main() -- cgit v1.2.3