204 lines
6.6 KiB
JavaScript
204 lines
6.6 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Transform collecting-asteroids-2.html into collecting-asteroids-3.html
|
|
* Output goes to stdout for review before saving.
|
|
*/
|
|
|
|
import { readFileSync } from 'fs';
|
|
import { resolve } from 'path';
|
|
|
|
const root = resolve(import.meta.dirname, '../..');
|
|
const v2Html = readFileSync(resolve(root, 'output/html/collecting-asteroids-2.html'), 'utf-8');
|
|
|
|
// Page configs for v3
|
|
const pages = [
|
|
{
|
|
comment: 'PAGE 1: ships 11(2), 9(2), 13(6) — R-L-R',
|
|
hero: 'splitter4', footer: 'cabin3',
|
|
cargoBays: [7, 8, 9],
|
|
ships: [11, 9, 13],
|
|
oldAsteroidTypes: ['asteroid7', 'asteroid14'],
|
|
newAsteroidTypes: ['asteroid3', 'asteroid10'],
|
|
asteroidValues: [3, 2, 1, 4, 5, 2, 3, 6, 5, 4, 1, 6],
|
|
},
|
|
{
|
|
comment: 'PAGE 2: ships 12(3), 12(3), 18(4) — L-R-L',
|
|
hero: 'splitter7', footer: 'cabin6',
|
|
cargoBays: [1, 2, 3],
|
|
ships: [12, 12, 18],
|
|
oldAsteroidTypes: ['asteroid4', 'asteroid11'],
|
|
newAsteroidTypes: ['asteroid6', 'asteroid13'],
|
|
asteroidValues: [4, 5, 3, 6, 2, 7, 4, 3, 5, 2, 6, 4],
|
|
},
|
|
{
|
|
comment: 'PAGE 3: ships 9(5), 11(3), 11(2) — R-L-R',
|
|
hero: 'splitter1', footer: 'cabin9',
|
|
cargoBays: [4, 5, 6],
|
|
ships: [9, 11, 11],
|
|
oldAsteroidTypes: ['asteroid10', 'asteroid3'],
|
|
newAsteroidTypes: ['asteroid2', 'asteroid8'],
|
|
asteroidValues: [2, 4, 1, 3, 5, 2, 1, 3, 4, 6, 5, 2],
|
|
},
|
|
{
|
|
comment: 'PAGE 4: ships 15(4), 17(5), 11(2) — L-R-L',
|
|
hero: 'splitter6', footer: 'cabin2',
|
|
cargoBays: [7, 8, 9],
|
|
ships: [15, 17, 11],
|
|
oldAsteroidTypes: ['asteroid16', 'asteroid5'],
|
|
newAsteroidTypes: ['asteroid12', 'asteroid15'],
|
|
asteroidValues: [4, 3, 5, 2, 6, 1, 3, 4, 6, 2, 5, 4],
|
|
},
|
|
{
|
|
comment: 'PAGE 5: ships 7(2), 9(4), 7(2) — R-L-R',
|
|
hero: 'splitter2', footer: 'cabin5',
|
|
cargoBays: [1, 2, 3],
|
|
ships: [7, 9, 7],
|
|
oldAsteroidTypes: ['asteroid2', 'asteroid13'],
|
|
newAsteroidTypes: ['asteroid1', 'asteroid9'],
|
|
asteroidValues: [3, 1, 4, 2, 5, 1, 6, 2, 3, 4, 5],
|
|
},
|
|
{
|
|
comment: 'PAGE 6: ships 18(4), 18(5), 14(3) — L-R-L',
|
|
hero: 'splitter8', footer: 'cabin7',
|
|
cargoBays: [4, 5, 6],
|
|
ships: [18, 18, 14],
|
|
oldAsteroidTypes: ['asteroid8', 'asteroid12'],
|
|
newAsteroidTypes: ['asteroid5', 'asteroid16'],
|
|
asteroidValues: [3, 4, 5, 6, 2, 4, 7, 3, 2, 5, 6, 4, 3, 7],
|
|
},
|
|
{
|
|
comment: 'PAGE 7: ships 10(2), 16(3), 22(6) — R-L-R',
|
|
hero: 'splitter9', footer: 'cabin4',
|
|
cargoBays: [7, 8, 9],
|
|
ships: [10, 16, 22],
|
|
oldAsteroidTypes: ['asteroid15', 'asteroid6'],
|
|
newAsteroidTypes: ['asteroid11', 'asteroid7'],
|
|
asteroidValues: [4, 3, 2, 6, 5, 3, 7, 4, 5, 2, 6, 4],
|
|
},
|
|
{
|
|
comment: 'PAGE 8: ships 26(0), 18(0), 30(0) — UNSOLVABLE — L-R-L',
|
|
hero: 'splitter5', footer: 'cabin1',
|
|
cargoBays: [1, 2, 3],
|
|
ships: [26, 18, 30],
|
|
oldAsteroidTypes: ['asteroid9', 'asteroid1'],
|
|
newAsteroidTypes: ['asteroid14', 'asteroid4'],
|
|
asteroidValues: [6, 4, 5, 3, 7, 2, 4, 6, 5, 7, 3, 4, 6],
|
|
},
|
|
{
|
|
comment: 'PAGE 9: ships 8(2), 18(3), 28(8) — R-L-R',
|
|
hero: 'splitter3', footer: 'cabin8',
|
|
cargoBays: [4, 5, 6],
|
|
ships: [8, 18, 28],
|
|
oldAsteroidTypes: ['asteroid11', 'asteroid4'],
|
|
newAsteroidTypes: ['asteroid10', 'asteroid6'],
|
|
asteroidValues: [4, 3, 2, 5, 6, 3, 4, 7, 2, 5, 4, 6, 3, 7, 5],
|
|
},
|
|
];
|
|
|
|
// Split HTML into pages
|
|
// Pages are delimited by <!-- PAGE N comments
|
|
const pageRegex = /<!-- PAGE \d+/g;
|
|
const matches = [...v2Html.matchAll(pageRegex)];
|
|
|
|
// Extract page blocks
|
|
const pageBlocks = [];
|
|
for (let i = 0; i < matches.length; i++) {
|
|
const start = matches[i].index;
|
|
const end = i + 1 < matches.length ? matches[i + 1].index : v2Html.lastIndexOf('</body>');
|
|
pageBlocks.push(v2Html.substring(start, end));
|
|
}
|
|
|
|
// Extract header (before first page) and footer (after last page)
|
|
const header = v2Html.substring(0, matches[0].index);
|
|
const footer = v2Html.substring(v2Html.lastIndexOf('</body>'));
|
|
|
|
function transformPage(block, config, pageIdx) {
|
|
let html = block;
|
|
|
|
// 1. Replace page comment
|
|
html = html.replace(/<!-- PAGE \d+:.*?-->/, `<!-- ${config.comment} -->`);
|
|
|
|
// 2. Replace hero image
|
|
html = html.replace(
|
|
/splitters\/splitter\d+\.png/,
|
|
`splitters/${config.hero}.png`
|
|
);
|
|
|
|
// 3. Replace footer image
|
|
html = html.replace(
|
|
/footers\/cabin\d+\.jpeg/,
|
|
`footers/${config.footer}.jpeg`
|
|
);
|
|
|
|
// 4. Replace cargo bay images (3 per page, in order)
|
|
let cbIdx = 0;
|
|
html = html.replace(
|
|
/pack4-cargobay\/cargo-bay\d+\.png/g,
|
|
(match) => `pack4-cargobay/cargo-bay${config.cargoBays[cbIdx++]}.png`
|
|
);
|
|
|
|
// 5. Replace ship capacity numbers (text-xl spans inside blue circles)
|
|
let shipIdx = 0;
|
|
html = html.replace(
|
|
/(<span class="text-white font-extrabold text-xl">)(\d+)(<\/span>)/g,
|
|
(match, pre, val, post) => `${pre}${config.ships[shipIdx++]}${post}`
|
|
);
|
|
|
|
// 6. Replace asteroid type images
|
|
for (let i = 0; i < config.oldAsteroidTypes.length; i++) {
|
|
const oldType = config.oldAsteroidTypes[i];
|
|
const newType = config.newAsteroidTypes[i];
|
|
html = html.replaceAll(
|
|
`pack3-asteroids/${oldType}.png`,
|
|
`pack3-asteroids/${newType}.png`
|
|
);
|
|
}
|
|
|
|
// 7. Replace asteroid values (text-2xl spans, sequential)
|
|
let avIdx = 0;
|
|
html = html.replace(
|
|
/(<span class="text-white font-extrabold text-2xl"[^>]*>)(\d+)(<\/span>)/g,
|
|
(match, pre, val, post) => {
|
|
if (avIdx < config.asteroidValues.length) {
|
|
return `${pre}${config.asteroidValues[avIdx++]}${post}`;
|
|
}
|
|
return match;
|
|
}
|
|
);
|
|
|
|
// Sanity check
|
|
if (shipIdx !== 3) {
|
|
console.error(`WARNING: Page ${pageIdx + 1} — replaced ${shipIdx} ship values (expected 3)`);
|
|
}
|
|
if (avIdx !== config.asteroidValues.length) {
|
|
console.error(`WARNING: Page ${pageIdx + 1} — replaced ${avIdx} asteroid values (expected ${config.asteroidValues.length})`);
|
|
}
|
|
if (cbIdx !== 3) {
|
|
console.error(`WARNING: Page ${pageIdx + 1} — replaced ${cbIdx} cargo bay refs (expected 3)`);
|
|
}
|
|
|
|
return html;
|
|
}
|
|
|
|
// Transform all pages
|
|
const newPages = pageBlocks.map((block, i) => transformPage(block, pages[i], i));
|
|
|
|
// Assemble
|
|
const result = header + newPages.join('') + footer;
|
|
|
|
// Write to temp file
|
|
import { writeFileSync } from 'fs';
|
|
const tmpPath = resolve(root, 'output/html/.collecting-asteroids-3-tmp.html');
|
|
writeFileSync(tmpPath, result);
|
|
console.log(`Output written to: ${tmpPath}`);
|
|
console.log(`Total lines: ${result.split('\n').length}`);
|
|
|
|
// Print summary of changes per page
|
|
for (let i = 0; i < pages.length; i++) {
|
|
const p = pages[i];
|
|
console.log(`\nPage ${i + 1}: hero=${p.hero} footer=${p.footer} cargoBays=[${p.cargoBays}]`);
|
|
console.log(` Ships: [${p.ships}] Asteroids: [${p.asteroidValues}]`);
|
|
console.log(` Types: ${p.oldAsteroidTypes} → ${p.newAsteroidTypes}`);
|
|
}
|