{esc(r["text"])}"""Self-contained review HTML. OCR text is escaped, never executed."""
import base64,html,json
from pathlib import Path
from display_language import english_message
def render(job,cfg):
esc=lambda s:html.escape(str(s),quote=True)
from context_export import page_context, adoption_notice
sections=[]
for idx in cfg['selected']:
folder=Path(job)/f'page-{idx+1:05d}'
if not (folder/'source.png').exists():continue
image=base64.b64encode((folder/'source.png').read_bytes()).decode()
error=json.loads((folder/'review-error.json').read_text()).get('error','') if (folder/'review-error.json').exists() else ''
status='Suggestions available; approve or reject in the app' if (folder/'review.json').exists() else 'Not reviewed by Gemma'
blocks=[]
if (folder/'regions.json').exists():
regions=json.loads((folder/'regions.json').read_text())['regions']
for r in regions:
blocks.append(f'{esc(r["text"])}
No region data; using the saved OCR reading order.
{esc(text)}']
context=page_context(folder)
blocks.insert(0,''+esc(context['status'])+'
'+esc(context['text'])+'
'+esc(json.dumps(context['edits'],ensure_ascii=False,indent=2))+'
'+esc(json.dumps(context['pending'],ensure_ascii=False,indent=2))+'
Unverified model notes: '+esc(' / '.join(context['notes']))+'
{esc(english_message(error or status))}
Region order is detected automatically. Check it against the images. Original OCR is preserved. Model input text is original OCR or explicitly adopted content, including optional Quick mode candidates without manual verification. Unapproved suggestions are listed separately for review.
'+esc(adoption_notice(job,cfg))+'
'+''.join(sections)+''