Skip to content

Commit

Permalink
web: add speechbubble post-processor
Browse files Browse the repository at this point in the history
  • Loading branch information
nzbr committed Jan 4, 2024
1 parent 568083d commit 2390202
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
},
"dependencies": {
"@fontsource/jetbrains-mono": "^5.0.2",
"@fontsource/roboto-slab": "^5.0.2"
"@fontsource/roboto-slab": "^5.0.2",
"@nzbr/parcel-transformer-postprocess-html": "github:nzbr/parcel-transformer-postprocess-html"
},
"peerDependencies": {
"sharp": "^0.31.1"
},
"devDependencies": {
"@types/node": "^20.10.6",
"typescript": "^5.3.3",
"base16-builder": "^1.3.0"
}
}
1 change: 1 addition & 0 deletions web/html-postprocessors/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.js
79 changes: 79 additions & 0 deletions web/html-postprocessors/speechbubbles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as path from 'path';
import * as fs from 'fs';
import type { StepInputs } from '@nzbr/parcel-transformer-postprocess-html/src';
import { toPosixPath } from '@nzbr/parcel-transformer-postprocess-html/src';

export function generateSpeechbubbles({ $, asset, options }: StepInputs): void {
const root = toPosixPath(options.projectRoot);
const stickers = path.posix.join(root, 'src', 'stickers');

asset.invalidateOnFileCreate({
glob: path.posix.join(stickers, '*'),
});

fs.readdirSync(stickers).forEach((character) => {
const characterDir = path.posix.join(stickers, character);
const cssClass = character.toLowerCase().trim().replaceAll(' ', '-');
$(`.${cssClass}`).each((_, el) => {
asset.invalidateOnFileCreate({
glob: path.posix.join(characterDir, '*'),
});

const stickers = fs
.readdirSync(characterDir)
.filter((file) => !file.endsWith('.txt'))
.map((file) => {
const stickerName = file.split('.').slice(0, -1).join('.');

return {
stickerName,
stickerFile: path.posix.join(characterDir, file),
stickerAltFile: path.posix.join(characterDir, stickerName + '.txt'),
stickerCssClass: stickerName.toLowerCase().trim().replaceAll(' ', '-'),
};
});

const defaultSticker = stickers.find(
(sticker) => sticker.stickerName === character,
);
const variants = stickers.filter((sticker) => sticker.stickerName !== character);

const sticker = variants
.concat(defaultSticker ? [defaultSticker] : [])
.find((sticker) => $(el).hasClass(sticker.stickerCssClass));

if (!sticker) {
asset.invalidateOnFileCreate({
glob: path.posix.join(characterDir, `${character}.*`),
});
throw new Error(`No sticker found for ${character} in ${asset.filePath}`);
}

if (!fs.existsSync(sticker.stickerAltFile)) {
asset.invalidateOnFileCreate({
glob: path.posix.join(characterDir, `${sticker.stickerName}.txt`),
});
throw new Error(
`No alt text found for ${sticker.stickerName} in ${asset.filePath}`,
);
}

asset.invalidateOnFileChange(sticker.stickerAltFile);
const alt = fs.readFileSync(sticker.stickerAltFile, 'utf-8').trim();

const url = asset.addURLDependency(
`/${path.posix.relative(root, sticker.stickerFile)}`,
{},
);

$(el).addClass('speechbubble');
$(el).html(`
<img src="${url}" title=${character} alt="${alt}" width='128' />
<div class="text">
${$(el).html() ?? ''}
</div>
`);
// width=128 is a fallback for the reader mode, because it ignores the CSS
});
});
}
13 changes: 13 additions & 0 deletions web/html-postprocessors/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"include": [
"*.ts"
],
"exclude": [],
"compilerOptions": {
"module": "CommonJS",
"outDir": ".",
"lib": [
"ES2021"
]
}
}

0 comments on commit 2390202

Please sign in to comment.