Poster sizes: the ladder offers eight sizes (paper, 18x24, 36x36, 36x48, 36x60, 36x66, 66x66, 60x96)
Every size up to 36x66 prints on one sheet; 66x66 is two 36x66 sheets glued side by side over 6 in, and 60x96 is three 36x60 sheets stacked over 6 in overlaps. 36x48 moves from legacy into the ladder (3x4ft still resolves to it); 24x36 stays legacy. check:poster-sizes now also refuses a size that is both offered and legacy, and a glued size other than 66x66 and 60x96; its self-test refuses 10 broken tables.
This commit is contained in:
parent
e1c79fb19f
commit
1bfe4d7353
2 changed files with 17 additions and 5 deletions
|
|
@ -6,7 +6,8 @@
|
||||||
* geometry. So the table itself must be right: a wrong sheet count or overlap prints a poster that does not
|
* geometry. So the table itself must be right: a wrong sheet count or overlap prints a poster that does not
|
||||||
* glue up to its size, and a landscape size breaks the portrait-only rule.
|
* glue up to its size, and a landscape size breaks the portrait-only rule.
|
||||||
*
|
*
|
||||||
* ASSERTS: the picker order lists exactly the ladder; every key is dot-free (i18n paths, URLs); every size is
|
* ASSERTS: the picker order lists exactly the ladder; no size is both offered and legacy; only 66x66 and 60x96
|
||||||
|
* are glued from several sheets; every key is dot-free (i18n paths, URLs); every size is
|
||||||
* PORTRAIT (h ≥ w); the sheets glue up to the finished size (count × sheet − overlaps, in `direction`); a
|
* PORTRAIT (h ≥ w); the sheets glue up to the finished size (count × sheet − overlaps, in `direction`); a
|
||||||
* photo slot is allowed on exactly the large sizes (66x66, 60x96); paper prints through the browser and the
|
* photo slot is allowed on exactly the large sizes (66x66, 60x96); paper prints through the browser and the
|
||||||
* rest through a print-shop PDF; every alias resolves; paperFor() picks Letter or A4 by region.
|
* rest through a print-shop PDF; every alias resolves; paperFor() picks Letter or A4 by region.
|
||||||
|
|
@ -18,6 +19,8 @@ const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
|
||||||
const S = await import(pathToFileURL(join(ROOT, 'library/constants/posterSizes.js')).href)
|
const S = await import(pathToFileURL(join(ROOT, 'library/constants/posterSizes.js')).href)
|
||||||
|
|
||||||
const PHOTO_SIZES = ['66x66', '60x96']
|
const PHOTO_SIZES = ['66x66', '60x96']
|
||||||
|
// Every size up to 36x66 prints on ONE sheet; only these two are glued from several.
|
||||||
|
const MULTI_SHEET = ['66x66', '60x96']
|
||||||
function audit({ ladder, order, legacy, aliases }) {
|
function audit({ ladder, order, legacy, aliases }) {
|
||||||
const bad = []
|
const bad = []
|
||||||
const keys = Object.keys(ladder)
|
const keys = Object.keys(ladder)
|
||||||
|
|
@ -33,6 +36,9 @@ function audit({ ladder, order, legacy, aliases }) {
|
||||||
if (W !== w || H !== h) bad.push(`${k}: ${s.count} sheet(s) of ${s.sheetW}×${s.sheetH} (${s.direction}, ${s.joinIn} in overlap) glue up to ${W}×${H}, not ${w}×${h}`)
|
if (W !== w || H !== h) bad.push(`${k}: ${s.count} sheet(s) of ${s.sheetW}×${s.sheetH} (${s.direction}, ${s.joinIn} in overlap) glue up to ${W}×${H}, not ${w}×${h}`)
|
||||||
if (s.count === 1 && s.joinIn !== 0) bad.push(`${k}: one sheet cannot have a ${s.joinIn} in overlap`)
|
if (s.count === 1 && s.joinIn !== 0) bad.push(`${k}: one sheet cannot have a ${s.joinIn} in overlap`)
|
||||||
}
|
}
|
||||||
|
for (const k of Object.keys(legacy)) if (ladder[k]) bad.push(`${k} is both offered and legacy`)
|
||||||
|
const multi = keys.filter((k) => ladder[k].sheets.count > 1)
|
||||||
|
if (multi.join() !== MULTI_SHEET.join()) bad.push(`glued sizes are [${multi}], expected [${MULTI_SHEET}]; every other size is one sheet`)
|
||||||
const photos = keys.filter((k) => ladder[k].photos)
|
const photos = keys.filter((k) => ladder[k].photos)
|
||||||
if (photos.join() !== PHOTO_SIZES.join()) bad.push(`photo slots are allowed on [${photos}], expected [${PHOTO_SIZES}] (the large sizes)`)
|
if (photos.join() !== PHOTO_SIZES.join()) bad.push(`photo slots are allowed on [${photos}], expected [${PHOTO_SIZES}] (the large sizes)`)
|
||||||
for (const k of keys) {
|
for (const k of keys) {
|
||||||
|
|
@ -60,6 +66,8 @@ if (process.argv.includes('--self-test')) {
|
||||||
['order drift', (t) => { t.order.reverse() }],
|
['order drift', (t) => { t.order.reverse() }],
|
||||||
['a dangling alias', (t) => { t.aliases['4x6ft'] = '48x72' }],
|
['a dangling alias', (t) => { t.aliases['4x6ft'] = '48x72' }],
|
||||||
['paper through a PDF', (t) => { t.ladder.paper.path = 'pdf' }],
|
['paper through a PDF', (t) => { t.ladder.paper.path = 'pdf' }],
|
||||||
|
['offered and legacy at once', (t) => { t.legacy['36x48'] = t.ladder['36x48'] }],
|
||||||
|
['a single-sheet size split in two', (t) => { t.ladder['36x66'].sheets = { sheetW: 36, sheetH: 36, count: 2, direction: 'vertical', joinIn: 6 } }],
|
||||||
]
|
]
|
||||||
let missed = 0
|
let missed = 0
|
||||||
for (const [name, poison] of poisons) { const t = clone(); poison(t); const caught = audit(t).length > 0; console.log(` ${name}: ${caught ? 'caught' : 'NOT CAUGHT'}`); if (!caught) missed++ }
|
for (const [name, poison] of poisons) { const t = clone(); poison(t); const caught = audit(t).length > 0; console.log(` ${name}: ${caught ? 'caught' : 'NOT CAUGHT'}`); if (!caught) missed++ }
|
||||||
|
|
|
||||||
|
|
@ -115,23 +115,27 @@ export function listByCategory(category) {
|
||||||
export const POSTER_LADDER = {
|
export const POSTER_LADDER = {
|
||||||
paper: { id: 'paper', inches: { w: 8.5, h: 11 }, paper: true,
|
paper: { id: 'paper', inches: { w: 8.5, h: 11 }, paper: true,
|
||||||
sheets: { sheetW: 8.5, sheetH: 11, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'print' },
|
sheets: { sheetW: 8.5, sheetH: 11, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'print' },
|
||||||
|
'18x24': { id: '18x24', inches: { w: 18, h: 24 },
|
||||||
|
sheets: { sheetW: 18, sheetH: 24, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
||||||
'36x36': { id: '36x36', inches: { w: 36, h: 36 },
|
'36x36': { id: '36x36', inches: { w: 36, h: 36 },
|
||||||
sheets: { sheetW: 36, sheetH: 36, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
sheets: { sheetW: 36, sheetH: 36, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
||||||
|
'36x48': { id: '36x48', inches: { w: 36, h: 48 },
|
||||||
|
sheets: { sheetW: 36, sheetH: 48, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
||||||
'36x60': { id: '36x60', inches: { w: 36, h: 60 },
|
'36x60': { id: '36x60', inches: { w: 36, h: 60 },
|
||||||
sheets: { sheetW: 36, sheetH: 60, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
sheets: { sheetW: 36, sheetH: 60, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
||||||
|
'36x66': { id: '36x66', inches: { w: 36, h: 66 },
|
||||||
|
sheets: { sheetW: 36, sheetH: 66, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
||||||
'66x66': { id: '66x66', inches: { w: 66, h: 66 },
|
'66x66': { id: '66x66', inches: { w: 66, h: 66 },
|
||||||
sheets: { sheetW: 36, sheetH: 66, count: 2, direction: 'horizontal', joinIn: 6 }, photos: true, path: 'pdf' },
|
sheets: { sheetW: 36, sheetH: 66, count: 2, direction: 'horizontal', joinIn: 6 }, photos: true, path: 'pdf' },
|
||||||
'60x96': { id: '60x96', inches: { w: 60, h: 96 },
|
'60x96': { id: '60x96', inches: { w: 60, h: 96 },
|
||||||
sheets: { sheetW: 60, sheetH: 36, count: 3, direction: 'vertical', joinIn: 6 }, photos: true, path: 'pdf' },
|
sheets: { sheetW: 60, sheetH: 36, count: 3, direction: 'vertical', joinIn: 6 }, photos: true, path: 'pdf' },
|
||||||
}
|
}
|
||||||
/** The picker's order, smallest first. */
|
/** The picker's order, smallest first. Every size up to 36x66 is one sheet; 66x66 and 60x96 are glued. */
|
||||||
export const POSTER_LADDER_ORDER = ['paper', '36x36', '36x60', '66x66', '60x96']
|
export const POSTER_LADDER_ORDER = ['paper', '18x24', '36x36', '36x48', '36x60', '36x66', '66x66', '60x96']
|
||||||
/** A size that still resolves (stored choices, today's defaults) but is NOT offered in the picker. */
|
/** A size that still resolves (stored choices, today's defaults) but is NOT offered in the picker. */
|
||||||
export const POSTER_LADDER_LEGACY = {
|
export const POSTER_LADDER_LEGACY = {
|
||||||
'24x36': { id: '24x36', inches: { w: 24, h: 36 },
|
'24x36': { id: '24x36', inches: { w: 24, h: 36 },
|
||||||
sheets: { sheetW: 24, sheetH: 36, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
sheets: { sheetW: 24, sheetH: 36, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
||||||
'36x48': { id: '36x48', inches: { w: 36, h: 48 },
|
|
||||||
sheets: { sheetW: 36, sheetH: 48, count: 1, direction: 'vertical', joinIn: 0 }, photos: false, path: 'pdf' },
|
|
||||||
}
|
}
|
||||||
/** Older names for the same sizes (poster-render's FORMATS, Bless's PRESETS, the map exporter). */
|
/** Older names for the same sizes (poster-render's FORMATS, Bless's PRESETS, the map exporter). */
|
||||||
export const POSTER_LADDER_ALIASES = {
|
export const POSTER_LADDER_ALIASES = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue