Skip to content
Astera Technology

Generate the required blank duplex page

Preserve an intentional blank when the next section must start on a front page.

Download complete case notes and answer keys ↓

Set the decision and its input

This fictional document declares odd page numbers as front sides. Its prior section ends on page three and the next section must start on a front. The generator explicitly inserts blank page four, placing NEWSECTION on five. Removing all blank pages would break the supplied parity rule.

Filled local test worksheet
CaseInput JSON
Base test{"priorPages":3,"frontRequired":true}
Download editable CSV ↓

Run the supplied comparison

Actual PDF extraction verifies page count, the blank page and the section marker. This exercises an explicit page-generation rule; it does not certify a physical duplex device or rely on an untested side-break property.

Faulty and required outputs
PathOutput JSON
Faulty path{"newSectionPage":4,"blankPages":[],"pageCount":4}
Required path{"newSectionPage":5,"blankPages":[4],"pageCount":5}
Download editable CSV ↓
Node24.14.1 programme; Playwright1.63 Chromium and PDF.js6.4.299 required
import assert from 'node:assert/strict';
import {createRequire} from 'node:module';
import {pathToFileURL} from 'node:url';
const htmlEscape=s=>String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
async function withPage(action,options={}){
  const require=createRequire(import.meta.url);const {chromium}=require('playwright');
  const browser=await chromium.launch({headless:true});
  try{const context=await browser.newContext(options);const page=await context.newPage();
    const requests=[];await page.route('**/*',route=>{requests.push(route.request().url());return route.abort();});
    return await action(page,context,requests);
  }finally{await browser.close();}
}
async function pdfObservation(html){
  const bytes=await withPage(async page=>{await page.setContent(html);return page.pdf({preferCSSPageSize:true,printBackground:true});});
  const require=createRequire(import.meta.url);
  const {getDocument}=await import(pathToFileURL(require.resolve('pdfjs-dist/legacy/build/pdf.mjs')).href);
  const loadingTask=getDocument({data:Uint8Array.from(bytes),useSystemFonts:true,disableFontFace:true});
  try{const document=await loadingTask.promise;const pages=[];for(let n=1;n<=document.numPages;n++){
    const page=await document.getPage(n);const content=await page.getTextContent();
    pages.push(content.items.filter(x=>typeof x.str==='string'&&x.str).map(x=>({text:x.str,x:x.transform[4],y:x.transform[5]})));
  }return {pageCount:document.numPages,pages};}finally{await loadingTask.destroy();}
}
const printStyle='<style>@page{size:100mm 100mm;margin:10mm}body{margin:0;font:10px Arial}p{margin:0}</style>';

const run=async function run(i,corrected=true){
    if(typeof i.frontRequired!=='boolean'||![2,3].includes(i.priorPages))return {held:true};
    const blank=corrected&&i.frontRequired&&i.priorPages%2===1?'<section class="prior"></section>':'';
    const html=printStyle+'<style>.prior{height:80mm;break-after:page}.next{break-before:page}</style>'+Array.from({length:i.priorPages},(_,n)=>'<section class="prior">PRIOR'+(n+1)+'</section>').join('')+blank+'<section class="next">NEWSECTION</section>';
    const out=await pdfObservation(html);return {newSectionPage:out.pages.findIndex(p=>p.some(x=>x.text==='NEWSECTION'))+1,blankPages:out.pages.map((p,n)=>p.length?null:n+1).filter(n=>n!==null),pageCount:out.pageCount};
  };
const cases=[{"input":{"priorPages":3,"frontRequired":true},"corrected":false,"expected":{"newSectionPage":4,"blankPages":[],"pageCount":4}},{"input":{"priorPages":3,"frontRequired":true},"corrected":true,"expected":{"newSectionPage":5,"blankPages":[4],"pageCount":5}},{"input":{"priorPages":2,"frontRequired":true},"corrected":true,"expected":{"newSectionPage":3,"blankPages":[],"pageCount":3}},{"input":{"priorPages":3,"frontRequired":null},"corrected":true,"expected":{"held":true}}];
for(const test of cases){const actual=await run(test.input,test.corrected);assert.deepEqual(actual,test.expected);console.log(actual);}
Download runnable example ↓

Choose from the boundary evidence

If the prior section ends on page two, page three already meets the rule. An absent front-side requirement is held.

  1. Read the declared front-page parity
  2. Generate any required blank
  3. Verify section and blank positions

Do not infer a printer’s physical side rule from this synthetic document rule.

Editable boundary inputs and outputs
ConditionInput JSONExpected output JSON
prior section ends on a back page{"priorPages":2,"frontRequired":true}{"newSectionPage":3,"blankPages":[],"pageCount":3}
front-side rule absent{"priorPages":3,"frontRequired":null}{"held":true}
Download editable CSV ↓

Is blank page four an error in the base output?

Show the worked answer

No. It is required so the new section starts on page five, the next declared front side. The generated PDF has five pages.

Example files

Related resources