Evidence

Keep short comparative tables and equation lead-ins readable across page breaks.

Download source fileOpen in research workspace
from pathlib import Path
import subprocess,sys,json,hashlib,re,math
root=Path(__file__).resolve().parents[1]
kind=sys.argv[1]
stem={'main':'490d_Chronological_Families_Explanation_C1431','technical':'490d_Technical_Companion_C1431'}[kind]
src=root/'deliverables'/(stem+'.md');dest=root/'deliverables'/(stem+'_Print.pdf')
work=root/'prep'/'render';work.mkdir(exist_ok=True)
portable_map=root/'assets'/'Chronological_Families_Map.png'
lines=src.read_text().splitlines();title=lines[0][2:];body='\n'.join(lines[1:]).lstrip().replace('sandbox:','')
if portable_map.exists():
 body=re.sub(r'(!\[Six source routes[^\]]*\]\()[^)]+(\))',lambda m:m.group(1)+str(portable_map)+m.group(2),body)
if kind=='main':
 start=body.index('![Six source routes');stop=body.index('## Local changes become',start)
 body=body[:start]+'\\clearpage\n\n'+body[start:stop]+'\\clearpage\n\n'+body[stop:]
 # Start the comparative chapter on a fresh page; its source summary is self-contained.
 body=body.replace('## The same spine operation in LXX and SP','\\clearpage\n\n## The same spine operation in LXX and SP')
 body=body.replace('## How the three inverse families connect internally','\\clearpage\n\n## How the three inverse families connect internally')
body=body.replace('## Babylonian spans connect the inverse, Covenant and calendar families',r'\clearpage'+'\n\n## Babylonian spans connect the inverse, Covenant and calendar families')
# Keep short comparative tables and equation lead-ins readable across page breaks.
body=re.sub(r'(?m)^(### .+)$',lambda m:r'\Needspace{5\baselineskip}'+'\n\n'+m.group(1),body)
body=body.replace("\\Needspace{5\\baselineskip}\n\n### The 2700-year shift reaches Abram's reflected birth","\\Needspace{28\\baselineskip}\n\n### The 2700-year shift reaches Abram's reflected birth")
body=body.replace('Both endpoints of the 4900-year interval therefore move forward together:',r'\Needspace{18\baselineskip}'+'\n\n'+'Both endpoints of the 4900-year interval therefore move forward together:')
blocks=body.split('\n\n')
for i,block in enumerate(blocks):
    if block.lstrip().startswith('\\[') and i and not blocks[i-1].lstrip().startswith(('|','#','\\')):
        n=min(13,math.ceil(len(blocks[i-1])/90)+4)
        blocks[i-1]='\\Needspace{'+str(n)+r'\baselineskip}'+'\n\n'+blocks[i-1]
    if block.lstrip().startswith('|') and len(block.splitlines())<=11:
        blocks[i]='\\Needspace{18'+r'\baselineskip}'+'\n\n'+block
body='\n\n'.join(blocks)
if kind=='technical':
    body=body.replace('## 4. Original-span register theorem',r'\clearpage'+'\n\n## 4. Original-span register theorem')
prepared=work/(kind+'.md');prepared.write_text(body)
header=work/'header.tex';header.write_text(r'''\let\oldtableofcontents\tableofcontents
\renewcommand{\tableofcontents}{\oldtableofcontents\clearpage}
\usepackage{etoolbox}
\usepackage{needspace}
\AtBeginEnvironment{longtable}{\small}
\AtBeginEnvironment{equation*}{\Needspace{3\baselineskip}}
\emergencystretch=3em
''')
cmd=['pandoc',str(prepared),'-f','markdown+tex_math_single_backslash','--standalone','--pdf-engine=xelatex','--toc','--toc-depth=2','-V','mainfont=DejaVu Serif','-V','sansfont=DejaVu Sans','-V','mathfont=Latin Modern Math','-V','monofont=DejaVu Sans Mono','-V','fontsize=10pt','-V','geometry:margin=0.7in','-V','linestretch=1.08','-V','papersize=a4','-M','title='+title,'-M','date=September 29, 2026 UTC — comparison through C1634','--include-in-header='+str(header),'-o',str(dest)]
r=subprocess.run(cmd,text=True,capture_output=True);(work/(kind+'.log')).write_text(r.stdout+r.stderr)
if r.returncode:print(r.stderr);raise SystemExit(r.returncode)
print(json.dumps({'kind':kind,'pdf':str(dest),'bytes':dest.stat().st_size,'warnings':r.stderr}))
Edition and provenance

render_readers.py

SHA-256 5a1c35fd0c8fc10522f1b9df93441fbf1fee25f01d7c4818b71fa673cdfcb785

C480–C1634/Research_Cycles/C1585_C1634/prep/render_readers.py