Skip to content

Instantly share code, notes, and snippets.

@MadcapJake
Forked from 2sh/kokanu.mjs
Last active September 22, 2023 17:46
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 MadcapJake/0bbe0ad22e21d9175e5d4075d7606786 to your computer and use it in GitHub Desktop.
Save MadcapJake/0bbe0ad22e21d9175e5d4075d7606786 to your computer and use it in GitHub Desktop.
convert powerpoint pdf svgs into pngs for use on courses
#!/usr/bin/env node
// mkdir input && mkdir cleaned && mkdir raster
// pdf2svg Logography\ for\ Kokanu.pdf input/kokanu_%d.svg all
// node kokanu.mjs pre
// node kokanu.mjs post
import fs from 'fs/promises'
import fsx from 'fs'
import readline from 'readline'
import { spawn } from 'child_process'
const inputDirectory = 'input'
const cleanedDirectory = 'cleaned'
const rasterDirectory = 'raster'
async function removeFluff(inFileName, outFileName)
{
const fileStream = fsx.createReadStream(`${inputDirectory}/${inFileName}.svg`)
const lineReader = readline.createInterface(
{
input: fileStream,
crlfDelay: Infinity
})
const lines = []
for await (const line of lineReader)
{
lines.push(line)
}
const cleaned = lines
.filter(line =>
line.startsWith("<?xml")
|| line.startsWith("<svg")
|| line.startsWith("</svg>")
|| (line.startsWith("<path")
&& line.includes("stroke-width")))
.join("\n")
await fs.writeFile(`${cleanedDirectory}/${outFileName}.svg`, cleaned)
}
async function finalize(fileName)
{
const convertToPNG = spawn('convert', [
'-background', 'none',
'+level-colors', 'transparent,black',
'-gravity', 'center',
'-extent', '400x400',
'-format', 'png',
`${cleanedDirectory}/${fileName}.svg`,
`${rasterDirectory}/${fileName}.png`])
await new Promise((resolve, reject) => {
convertToPNG.on('close', resolve);
});
const trimPNG = spawn('mogrify', [
'-trim',
`${rasterDirectory}/${fileName}.png`])
await new Promise((resolve, reject) => {
trimPNG.on('close', resolve);
});
const resizePNG = spawn('mogrify', [
'-background', 'transparent',
'-resize', '400x400',
'-gravity', 'center',
'-extent', '400x400',
`${rasterDirectory}/${fileName}.png`])
await new Promise((resolve, reject) => {
resizePNG.on('close', resolve);
});
}
let end = false
async function main()
{
var args = process.argv.slice(2);
const fileStream = fsx.createReadStream(`words.txt`)
const lineReader = readline.createInterface(
{
input: fileStream,
crlfDelay: Infinity
})
const words = []
for await (const line of lineReader)
{
words.push(line)
}
await words.forEach(async (word, i) =>
{
if (args[0] == 'pre')
{
await removeFluff(`kokanu_${i+3}`, word)
}
else if (args[0] == 'post')
{
await finalize(word)
} else
{
throw new Error("invalid subcommand")
}
})
end = true
}
main()
function wait()
{
if (!end) setTimeout(wait, 1000)
}
wait()
@MadcapJake
Copy link
Author

I then use this to fix the ones that have been filled in incorrectly:

LOGOGRAM=napa && convert -background none -gravity center -extent 400x400 -format png cleaned/$LOGOGRAM.svg raster/$LOGOGRAM.png && mogrify -trim raster/$LOGOGRAM.png && m
ogrify -transparent white -fuzz 70% raster/$LOGOGRAM.png && convert +level-colors transparent,black raster/$LOGOGRAM.png raster/$LOGOGRAM.png && mogrify -background transparent -r
esize 400x400 -gravity center -extent 400x400 raster/$LOGOGRAM.png

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment