The map template draws a map-only vertical page for the prayer packet
Page 1 of a prayer packet is a lightweight vertical one-pager showing the zone's geography and every pin with its numbered name - not the poster. Until now the packet lifted the 3x4 poster (1500x2000, its own title, facts table, vision columns, networks and closing verse), shrank it to 62% and pasted it under the packet's title: a small poster on a page, with the English poster prose baked into the artwork. FORMAT=packet is a new sheet format: 1500x1941, the packet's own page, with the top band left EMPTY for the title the packet draws in the reader's language, a slim foot, and everything between given to the map and its label columns - about 1,600px of height against the letter sheet's ~1,200, so the names get the larger type the sparse posters use. It omits all the poster furniture, and its root <svg> says data-sheet="map-only" so the packet can tell it from a poster. Paper formats no longer overwrite the poster. Every format used to write out/posters/<zone>.html, so FORMAT=letter silently replaced the 3x4 the wall and the site serve. packet and letter sheets are now <zone>.packet.html and <zone>.letter.html, with their own manifest; 3x4 and 3x3 keep the bare name, which every consumer fetches. publish-html.mjs read everything before ".html" as the zone id and so skipped every paper sheet as an unknown zone; it now strips the suffix. The two fail-loud guards (header overflow, verse off the sheet) stay armed for posters and stand down only for a sheet that does not draw the furniture they measure. Proof that posters are untouched: the default 3x4 output for sudan, asia-india-kerala, deaf and west-africa is byte-identical before and after, generated with POSTER_DATE pinned. The first attempt was NOT identical - an HTML comment added inside the SVG template literal is emitted into every poster - so the notes live in JS comments instead. check-zone-census counted paper sheets as posters (it would read 56 for 28 zones); it now counts posters and reports paper sheets apart.
This commit is contained in:
parent
502d7107e3
commit
c121c63834
3 changed files with 66 additions and 18 deletions
|
|
@ -42,7 +42,12 @@ if (!existsSync(POSTERS)) {
|
||||||
console.log(`ZONE-CENSUS: SKIP — no posters at ${POSTERS} (run generate.mjs first).`)
|
console.log(`ZONE-CENSUS: SKIP — no posters at ${POSTERS} (run generate.mjs first).`)
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
}
|
}
|
||||||
const built = new Set(readdirSync(POSTERS).filter((f) => f.endsWith('.html')).map((f) => f.slice(0, -5)))
|
// ⚠ POSTERS ONLY. generate.mjs also writes PAPER sheets beside them (<zone>.packet.html, packet page 1;
|
||||||
|
// <zone>.letter.html), and counting those as posters would print "posters built: 56" for 28 zones.
|
||||||
|
const PAPER = /\.(packet|letter)\.html$/
|
||||||
|
const htmls = readdirSync(POSTERS).filter((f) => f.endsWith('.html'))
|
||||||
|
const built = new Set(htmls.filter((f) => !PAPER.test(f)).map((f) => f.slice(0, -5)))
|
||||||
|
const paperSheets = htmls.filter((f) => PAPER.test(f)).length
|
||||||
const missing = leaves.map((z) => z.id).filter((id) => !built.has(id))
|
const missing = leaves.map((z) => z.id).filter((id) => !built.has(id))
|
||||||
|
|
||||||
// Definitions that exist in the data but are NOT reachable — reported as context,
|
// Definitions that exist in the data but are NOT reachable — reported as context,
|
||||||
|
|
@ -55,7 +60,7 @@ for (const k of ['lists', 'deaf_lists', 'asia_lists', 'uncovered_lists']) {
|
||||||
const unreachable = [...declared].filter((id) => !leaves.some((z) => z.id === id))
|
const unreachable = [...declared].filter((id) => !leaves.some((z) => z.id === id))
|
||||||
|
|
||||||
console.log(` selectable zones : ${leaves.length}`)
|
console.log(` selectable zones : ${leaves.length}`)
|
||||||
console.log(` posters built : ${built.size}`)
|
console.log(` posters built : ${built.size}${paperSheets ? ` (+ ${paperSheets} paper sheet(s), not counted)` : ''}`)
|
||||||
console.log(` unreachable defs : ${unreachable.length}${unreachable.length ? ` (${unreachable.join(', ')}) — superseded, not a gap` : ''}`)
|
console.log(` unreachable defs : ${unreachable.length}${unreachable.length ? ` (${unreachable.join(', ')}) — superseded, not a gap` : ''}`)
|
||||||
|
|
||||||
if (missing.length) {
|
if (missing.length) {
|
||||||
|
|
|
||||||
|
|
@ -343,8 +343,31 @@ const FORMATS = {
|
||||||
// match it, which is what makes an ordinary printer produce a full-bleed-free,
|
// match it, which is what makes an ordinary printer produce a full-bleed-free,
|
||||||
// correctly-scaled sheet instead of "fit to page" guesswork.
|
// correctly-scaled sheet instead of "fit to page" guesswork.
|
||||||
letter: { w: 1500, h: 1941, gutter: 330, page: 'letter portrait', pageWidthIn: 8.5 },
|
letter: { w: 1500, h: 1941, gutter: 330, page: 'letter portrait', pageWidthIn: 8.5 },
|
||||||
|
// ★ PACKET PAGE 1 — THE MAP ALONE, ON A VERTICAL PAGE. Not the poster: page 1 of a prayer packet is
|
||||||
|
// a lightweight one-pager showing the geography and every pin with its numbered name, and nothing of
|
||||||
|
// the poster's furniture (the facts table, the two vision columns, the three networks, the closing
|
||||||
|
// verse). Those are English prose baked into the artwork, which is also why the poster could never be
|
||||||
|
// page 1 of a translated packet: the packet draws its OWN title into the reserved band, from the
|
||||||
|
// locale's strings, and this sheet supplies only what needs no translation — the map, the pins and
|
||||||
|
// the people-group names.
|
||||||
|
//
|
||||||
|
// SAME 1500x1941 AS `letter` AND AS THE PACKET'S OWN SHEET (packet-render.js W/H), so it drops onto
|
||||||
|
// page 1 at 1:1 with no rescale. `header` is the band left EMPTY for the packet's title block and
|
||||||
|
// `footer` the band for its fine print; everything between goes to the map and its label columns —
|
||||||
|
// about 1,600px of height against the letter sheet's ~1,200, which is what lets the names grow.
|
||||||
|
// Output: <zone>.packet.html beside the posters (see FILE_SUFFIX), never over them.
|
||||||
|
packet: { w: 1500, h: 1941, gutter: 330, page: 'letter portrait', pageWidthIn: 8.5, mapOnly: true, header: 250, footer: 90 },
|
||||||
};
|
};
|
||||||
const FMT = FORMATS[process.env.FORMAT || '3x4'] || FORMATS['3x4'];
|
const FMT_KEY = FORMATS[process.env.FORMAT] ? process.env.FORMAT : '3x4';
|
||||||
|
const FMT = FORMATS[FMT_KEY];
|
||||||
|
// Map-only sheets (packet page 1) skip the poster's header and footer furniture — see FORMATS.packet.
|
||||||
|
const MAP_ONLY = FMT.mapOnly === true;
|
||||||
|
// ★ A FORMAT THAT IS NOT A POSTER MUST NOT OVERWRITE THE POSTER. Every format used to write
|
||||||
|
// out/posters/<zone>.html, so `FORMAT=letter` silently replaced the 3x4 poster the wall and the site
|
||||||
|
// serve — which is part of why no letter or packet sheet was ever generated alongside them. The paper
|
||||||
|
// formats get their own names. 3x4 and 3x3 keep the bare name: they ARE the poster, whichever was
|
||||||
|
// built last, and renaming them would break every consumer that fetches posters/<zone>.html.
|
||||||
|
const FILE_SUFFIX = { letter: '.letter', packet: '.packet' }[FMT_KEY] || '';
|
||||||
// Stamped at generation time. Overridable so a rebuild can reproduce an existing
|
// Stamped at generation time. Overridable so a rebuild can reproduce an existing
|
||||||
// sheet byte-for-byte — print determinism matters more than always-now.
|
// sheet byte-for-byte — print determinism matters more than always-now.
|
||||||
const POSTER_DATE = process.env.POSTER_DATE
|
const POSTER_DATE = process.env.POSTER_DATE
|
||||||
|
|
@ -458,7 +481,7 @@ const HEADER_BASE = SPARSE ? 355 : 460;
|
||||||
// no city poster rendered at all. 280 clears it with ~8px of slack for the
|
// no city poster rendered at all. 280 clears it with ~8px of slack for the
|
||||||
// per-zone wrapping the block's height depends on. This costs 25px of map height,
|
// per-zone wrapping the block's height depends on. This costs 25px of map height,
|
||||||
// which is the documented trade this constant exists to make.
|
// which is the documented trade this constant exists to make.
|
||||||
const FOOTER = SPARSE ? 316 : 280;
|
const FOOTER = MAP_ONLY ? FMT.footer : SPARSE ? 316 : 280;
|
||||||
// GUTTER was 300px A SIDE — 600 of 1350 (44% of the sheet) given to text, leaving
|
// GUTTER was 300px A SIDE — 600 of 1350 (44% of the sheet) given to text, leaving
|
||||||
// the map only 750px wide. The names are short and do not need that; the MAP does.
|
// the map only 750px wide. The names are short and do not need that; the MAP does.
|
||||||
// At 210 a side the map grows 750 -> 930 (+24% width, +24% linear scale), which is
|
// At 210 a side the map grows 750 -> 930 (+24% width, +24% linear scale), which is
|
||||||
|
|
@ -470,7 +493,7 @@ const GUTTER = FMT.gutter, GPAD = 16;
|
||||||
const MAP_X = GUTTER;
|
const MAP_X = GUTTER;
|
||||||
const MAP_W = PW - 2 * GUTTER;
|
const MAP_W = PW - 2 * GUTTER;
|
||||||
// Set per-zone by setMapBox() before each poster renders.
|
// Set per-zone by setMapBox() before each poster renders.
|
||||||
let HEADER = SPARSE ? 355 : 460;
|
let HEADER = MAP_ONLY ? FMT.header : SPARSE ? 355 : 460;
|
||||||
let MAP_Y = HEADER;
|
let MAP_Y = HEADER;
|
||||||
let MAP_H = PH - HEADER - FOOTER;
|
let MAP_H = PH - HEADER - FOOTER;
|
||||||
const setMapBox = (headerPx) => {
|
const setMapBox = (headerPx) => {
|
||||||
|
|
@ -712,7 +735,9 @@ function layoutLabels(pins, project) {
|
||||||
// sheet's largest index. `pins.length` is the count for the whole sheet.
|
// sheet's largest index. `pins.length` is the count for the whole sheet.
|
||||||
const MAXNUM_L = pins.length;
|
const MAXNUM_L = pins.length;
|
||||||
col.forEach((it) => { it.maxNum = MAXNUM_L; });
|
col.forEach((it) => { it.maxNum = MAXNUM_L; });
|
||||||
const MAXF = SPARSE ? 19 : 15;
|
// A map-only sheet frees the header and footer bands the same way SPARSE frees the vision
|
||||||
|
// columns, so it gets SPARSE's ceiling; the solver still only uses what the column can hold.
|
||||||
|
const MAXF = (SPARSE || MAP_ONLY) ? 19 : 15;
|
||||||
// AVAIL IS THE COLUMN, AND THE NAME DOES NOT GET ALL OF IT.
|
// AVAIL IS THE COLUMN, AND THE NAME DOES NOT GET ALL OF IT.
|
||||||
// The renderer draws the name starting one number-column IN from the column's
|
// The renderer draws the name starting one number-column IN from the column's
|
||||||
// map-facing edge (`nameEdge = tx ± numColW`) but does not shrink its budget by
|
// map-facing edge (`nameEdge = tx ± numColW`) but does not shrink its budget by
|
||||||
|
|
@ -867,7 +892,9 @@ async function renderPoster(zone, pins, zoneFC) {
|
||||||
// derived from the prediction, so a smaller header automatically yields a
|
// derived from the prediction, so a smaller header automatically yields a
|
||||||
// taller map — and the label columns re-pitch to the same band, which is what
|
// taller map — and the label columns re-pitch to the same band, which is what
|
||||||
// spaces the names out to match.
|
// spaces the names out to match.
|
||||||
setMapBox(measureHeader(zone, pins, ctry, prov));
|
// A map-only sheet has no header CONTENT to measure — the band is reserved, at a fixed height,
|
||||||
|
// for the title the packet draws itself.
|
||||||
|
setMapBox(MAP_ONLY ? FMT.header : measureHeader(zone, pins, ctry, prov));
|
||||||
}
|
}
|
||||||
// bbox: prefer resolved polygons; fallback to pins
|
// bbox: prefer resolved polygons; fallback to pins
|
||||||
let bbox;
|
let bbox;
|
||||||
|
|
@ -2151,7 +2178,9 @@ async function renderPoster(zone, pins, zoneFC) {
|
||||||
// did once: the last "Ways to use this map" line landed on the map frame and the
|
// did once: the last "Ways to use this map" line landed on the map frame and the
|
||||||
// markup checks all passed, because an overlap is valid SVG. Only the render
|
// markup checks all passed, because an overlap is valid SVG. Only the render
|
||||||
// showed it. This turns that class of regression into a build error.
|
// showed it. This turns that class of regression into a build error.
|
||||||
if (HEAD_BOTTOM > HEADER) {
|
// A map-only sheet computes the header content but never EMITS it (see the assembly below), so
|
||||||
|
// there is nothing to overflow — the guard would only be measuring a block that is thrown away.
|
||||||
|
if (!MAP_ONLY && HEAD_BOTTOM > HEADER) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`[generate] header overflows the map frame: content ends at y=${HEAD_BOTTOM} `
|
`[generate] header overflows the map frame: content ends at y=${HEAD_BOTTOM} `
|
||||||
+ `but HEADER=${HEADER} (zone ${zone.zoneKey}). Raise HEADER or tighten the header copy.`
|
+ `but HEADER=${HEADER} (zone ${zone.zoneKey}). Raise HEADER or tighten the header copy.`
|
||||||
|
|
@ -2268,7 +2297,8 @@ async function renderPoster(zone, pins, zoneFC) {
|
||||||
// The reference baseline sits at VERSE_RULE_Y + 44; the attribution line is at
|
// The reference baseline sits at VERSE_RULE_Y + 44; the attribution line is at
|
||||||
// PH - 4. Keeping the ref's descender clear of it needs +44 <= PH - 12, so the
|
// PH - 4. Keeping the ref's descender clear of it needs +44 <= PH - 12, so the
|
||||||
// real limit is +56, not the +46/PH-8 pair that was guarding an imagined 8px.
|
// real limit is +56, not the +46/PH-8 pair that was guarding an imagined 8px.
|
||||||
if (VERSE_RULE_Y + 56 > PH) {
|
// Same reasoning as the header guard: map-only sheets never emit the below-map block.
|
||||||
|
if (!MAP_ONLY && VERSE_RULE_Y + 56 > PH) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`[generate] below-map block runs off the sheet: verse rule would sit at `
|
`[generate] below-map block runs off the sheet: verse rule would sit at `
|
||||||
+ `y=${VERSE_RULE_Y.toFixed(0)} on a ${PH}px sheet (zone ${zone.zoneKey}). `
|
+ `y=${VERSE_RULE_Y.toFixed(0)} on a ${PH}px sheet (zone ${zone.zoneKey}). `
|
||||||
|
|
@ -2377,7 +2407,15 @@ async function renderPoster(zone, pins, zoneFC) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${PW} ${PH}" width="${PW}" height="${PH}">
|
// data-sheet="map-only" tells the packet this sheet reserves the top band for the packet's own
|
||||||
|
// title (packet-render.js liftMap), as opposed to a poster that carries its own.
|
||||||
|
// ★ EVERYTHING FROM THE TITLE TO THE CLOSING VERSE, AND THE WHITE EDGE, IS POSTER FURNITURE, and a
|
||||||
|
// map-only sheet (packet page 1) omits all of it: the title, the facts table and vision columns
|
||||||
|
// (headBlock), the goal question and three networks (footBlock), and the verse. The packet supplies
|
||||||
|
// its own title in the reserved band, in the reader's language.
|
||||||
|
// ⚠ These notes are JS comments, NOT <!-- --> inside the literal: an HTML comment there is EMITTED
|
||||||
|
// into every poster, which made the default 3x4 output differ from before this mode existed.
|
||||||
|
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${PW} ${PH}" width="${PW}" height="${PH}"${MAP_ONLY ? ' data-sheet="map-only"' : ''}>
|
||||||
<rect width="${PW}" height="${PH}" fill="var(--paper)"/>
|
<rect width="${PW}" height="${PH}" fill="var(--paper)"/>
|
||||||
<defs>
|
<defs>
|
||||||
<!-- Two-part shadow: a tight dark edge for definition, plus a wide soft one
|
<!-- Two-part shadow: a tight dark edge for definition, plus a wide soft one
|
||||||
|
|
@ -2442,7 +2480,7 @@ async function renderPoster(zone, pins, zoneFC) {
|
||||||
At y=46 its cap-height started ~32 — only 6px clear of the 26px border, so
|
At y=46 its cap-height started ~32 — only 6px clear of the 26px border, so
|
||||||
it read as pinned to the edge. The band runs 26..(title cap-top ~78), so
|
it read as pinned to the edge. The band runs 26..(title cap-top ~78), so
|
||||||
its optical middle is ~57. -->
|
its optical middle is ~57. -->
|
||||||
<text x="${PW / 2}" y="57" text-anchor="middle" class="h1over">${esc(POSTER_TEXT.kicker || 'Unengaged People Groups')}</text>
|
${MAP_ONLY ? '' : `<text x="${PW / 2}" y="57" text-anchor="middle" class="h1over">${esc(POSTER_TEXT.kicker || 'Unengaged People Groups')}</text>
|
||||||
<text x="${PW / 2}" y="104" text-anchor="middle" class="h1" font-size="${H1_SIZE}"><tspan class="h1qual">${esc(POSTER_TEXT.titleQualifier || 'Unengaged of')}</tspan> ${esc(title)}</text>
|
<text x="${PW / 2}" y="104" text-anchor="middle" class="h1" font-size="${H1_SIZE}"><tspan class="h1qual">${esc(POSTER_TEXT.titleQualifier || 'Unengaged of')}</tspan> ${esc(title)}</text>
|
||||||
<!-- (The series line is emitted INSIDE headBlock, not here. Absolutely placing
|
<!-- (The series line is emitted INSIDE headBlock, not here. Absolutely placing
|
||||||
it at a fixed y while the scripture flowed from headY is what made the
|
it at a fixed y while the scripture flowed from headY is what made the
|
||||||
|
|
@ -2466,7 +2504,7 @@ async function renderPoster(zone, pins, zoneFC) {
|
||||||
whole thing reads as ONE centred line. It was left-aligned with the ref
|
whole thing reads as ONE centred line. It was left-aligned with the ref
|
||||||
pushed to the right margin, which split it into two objects at opposite
|
pushed to the right margin, which split it into two objects at opposite
|
||||||
ends of the sheet rather than one closing statement. -->
|
ends of the sheet rather than one closing statement. -->
|
||||||
<text x="${PW / 2}" y="${VERSE_RULE_Y + 30}" text-anchor="middle" class="verse">“${esc(verse.text)}”<tspan class="vref"> ${esc(verse.ref)}</tspan></text>
|
<text x="${PW / 2}" y="${VERSE_RULE_Y + 30}" text-anchor="middle" class="verse">“${esc(verse.text)}”<tspan class="vref"> ${esc(verse.ref)}</tspan></text>`}
|
||||||
<!-- GENERATION DATE, bottom-left. Deliberately NO hard counts of the global
|
<!-- GENERATION DATE, bottom-left. Deliberately NO hard counts of the global
|
||||||
unengaged total on this poster: that number changes as research updates, and
|
unengaged total on this poster: that number changes as research updates, and
|
||||||
a printed figure would silently go stale on a wall. What CAN be stated
|
a printed figure would silently go stale on a wall. What CAN be stated
|
||||||
|
|
@ -2475,8 +2513,8 @@ async function renderPoster(zone, pins, zoneFC) {
|
||||||
<!-- THE WHITE SHEET EDGE. Drawn last so it trims anything reaching the paper's
|
<!-- THE WHITE SHEET EDGE. Drawn last so it trims anything reaching the paper's
|
||||||
edge. A stroked rect inset by half its own width paints a band exactly
|
edge. A stroked rect inset by half its own width paints a band exactly
|
||||||
SHEET_EDGE wide around the whole poster. -->
|
SHEET_EDGE wide around the whole poster. -->
|
||||||
<rect x="${SHEET_EDGE / 2}" y="${SHEET_EDGE / 2}" width="${PW - SHEET_EDGE}" height="${PH - SHEET_EDGE}"
|
${MAP_ONLY ? '' : `<rect x="${SHEET_EDGE / 2}" y="${SHEET_EDGE / 2}" width="${PW - SHEET_EDGE}" height="${PH - SHEET_EDGE}"
|
||||||
fill="none" stroke="#FFFFFF" stroke-width="${SHEET_EDGE}"/>
|
fill="none" stroke="#FFFFFF" stroke-width="${SHEET_EDGE}"/>`}
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
|
||||||
const html = `<!doctype html><html><head><meta charset="utf-8">
|
const html = `<!doctype html><html><head><meta charset="utf-8">
|
||||||
|
|
@ -2933,13 +2971,14 @@ for (const z of zones) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const { html, title, octiOK, crossings, diagFrac } = rendered;
|
const { html, title, octiOK, crossings, diagFrac } = rendered;
|
||||||
const file = `${z.zoneKey}.html`;
|
const file = `${z.zoneKey}${FILE_SUFFIX}.html`;
|
||||||
writeFileSync(join(POSTERS, file), html);
|
writeFileSync(join(POSTERS, file), html);
|
||||||
manifest.push({ zoneKey: z.zoneKey, title, count: pins.length, octilinear: octiOK, crossings, diagFrac, html: `posters/${file}`, png: `posters/${z.zoneKey}.png` });
|
manifest.push({ zoneKey: z.zoneKey, title, count: pins.length, octilinear: octiOK, crossings, diagFrac, html: `posters/${file}`, png: `posters/${z.zoneKey}${FILE_SUFFIX}.png` });
|
||||||
made++;
|
made++;
|
||||||
console.log(` ✓ ${z.zoneKey.padEnd(34)} ${String(pins.length).padStart(3)} pins octi=${octiOK?'Y':'N'} d=${diagFrac} cross=${crossings}`);
|
console.log(` ✓ ${z.zoneKey.padEnd(34)} ${String(pins.length).padStart(3)} pins octi=${octiOK?'Y':'N'} d=${diagFrac} cross=${crossings}`);
|
||||||
}
|
}
|
||||||
if (!ONLY) writeFileSync(join(OUT, 'manifest.json'), JSON.stringify({ generated: 'live', count: manifest.length, posters: manifest }, null, 2));
|
// The poster manifest is what the wall reads; a paper-format run writes its own beside it.
|
||||||
|
if (!ONLY) writeFileSync(join(OUT, `manifest${FILE_SUFFIX}.json`), JSON.stringify({ generated: 'live', count: manifest.length, posters: manifest }, null, 2));
|
||||||
console.log(`\n${made} poster(s) → ${POSTERS}${ONLY ? ' (ONLY=' + ONLY + ')' : ', manifest.json written'}`);
|
console.log(`\n${made} poster(s) → ${POSTERS}${ONLY ? ' (ONLY=' + ONLY + ')' : ', manifest.json written'}`);
|
||||||
// FAIL THE RUN, but only after every good poster is on disk. A non-zero exit keeps
|
// FAIL THE RUN, but only after every good poster is on disk. A non-zero exit keeps
|
||||||
// this a build error rather than a warning somebody scrolls past, and the census
|
// this a build error rather than a warning somebody scrolls past, and the census
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,11 @@ let bytes = 0;
|
||||||
const skipped = [];
|
const skipped = [];
|
||||||
for (const file of readdirSync(SRC)) {
|
for (const file of readdirSync(SRC)) {
|
||||||
if (!file.endsWith('.html')) continue;
|
if (!file.endsWith('.html')) continue;
|
||||||
const id = file.slice(0, -5);
|
// ★ PAPER FORMATS CARRY A SUFFIX (generate.mjs FILE_SUFFIX): <zone>.packet.html is page 1 of the
|
||||||
|
// prayer packet, <zone>.letter.html the poster on letter paper. The zone id is what precedes it —
|
||||||
|
// taking everything before ".html" as the id reported every packet sheet as an unknown zone and
|
||||||
|
// silently skipped it.
|
||||||
|
const id = file.slice(0, -5).replace(/\.(packet|letter)$/, '');
|
||||||
if (ONLY && id !== ONLY) continue;
|
if (ONLY && id !== ONLY) continue;
|
||||||
if (!zoneIds.has(id)) { skipped.push(id); continue; }
|
if (!zoneIds.has(id)) { skipped.push(id); continue; }
|
||||||
const html = readFileSync(join(SRC, file), 'utf8');
|
const html = readFileSync(join(SRC, file), 'utf8');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue