Update services: normalizer, html_builder, renderers, utils - fix PDF output to match V5.0 docx
93a688a verified | <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>ISP Handbook</title> | |
| <style>{{ font_css }}</style> | |
| <link rel="stylesheet" href="{{ base_url }}/css/print.css"> | |
| {% if extra_css %} | |
| <style>{{ extra_css }}</style> | |
| {% endif %} | |
| </head> | |
| <body> | |
| {# ── Page Header (hidden; JS extracts img src for Playwright header_template) ── #} | |
| {% if header_image %} | |
| <div class="page-header"> | |
| <img src="{{ header_image }}" alt="" /> | |
| </div> | |
| {% endif %} | |
| {# ── Right-Side Label (position:fixed, repeats on every page) ── #} | |
| {% if label_image %} | |
| <div class="hb-right-label"> | |
| <img src="{{ label_image }}" alt="" /> | |
| </div> | |
| {% endif %} | |
| {# ── Footer (hidden; Playwright footer_template renders page numbers) ── #} | |
| <div class="page-footer"></div> | |
| {# ── Cover Page ── #} | |
| {% if cover_image %} | |
| {% include "partials/cover.html" %} | |
| {% endif %} | |
| {# ── TOC Image Page ── #} | |
| {% if toc_image %} | |
| <div class="cover-page"> | |
| <img class="cover-img" src="{{ toc_image }}" alt="Table of Contents" /> | |
| </div> | |
| {% endif %} | |
| {# ── Page Content Wrapper (padding clears the fixed header/footer) ── #} | |
| <div class="page-content"> | |
| {# ── Dynamic TOC ── #} | |
| {% if not toc_image and toc_items %} | |
| <div class="section-block toc-page" id="toc" data-section-key="table_of_contents" | |
| data-section-title="{{ toc_title | e }}" {% if toc_sort_order is not none %}data-sort="{{ toc_sort_order }}" | |
| {% endif %}> | |
| {% include "partials/toc.html" %} | |
| </div> | |
| {% endif %} | |
| {# ── Global Sections ── #} | |
| {% for gs in general_sections %} | |
| <div class="section-block{{ ' page-break' if gs.page_break else '' }} {{ gs.sec_class }}" | |
| id="{{ gs.anchor | e }}" data-section-key="{{ gs.data.section_key | default('') | e }}" | |
| data-section-title="{{ gs.data.section_title | default('') | e }}" {% if gs.data.sort_order is not none | |
| %}data-sort="{{ gs.data.sort_order }}" {% endif %}> | |
| {% if gs.blocks %} | |
| {% for block in gs.blocks %} | |
| {% include "partials/blocks/render_block.html" %} | |
| {% endfor %} | |
| {% else %} | |
| {{ gs.rendered_html }} | |
| {% endif %} | |
| </div> | |
| {% endfor %} | |
| {# ── Summary of Universities ── #} | |
| {% if summary_block %} | |
| <div class="section-block page-break summary-section sec-summary" id="{{ summary_block.anchor | e }}" | |
| data-section-key="summary_of_universities" | |
| data-section-title="{{ summary_block.data.section_title | default('Summary of Universities') | e }}" {% if | |
| summary_block.data.sort_order is not none %}data-sort="{{ summary_block.data.sort_order }}" {% endif %}> | |
| {% if summary_block.blocks %} | |
| {% for block in summary_block.blocks %} | |
| {% include "partials/blocks/render_block.html" %} | |
| {% endfor %} | |
| {% else %} | |
| {{ summary_block.rendered_html }} | |
| {% endif %} | |
| </div> | |
| {% endif %} | |
| {# ── University Sections (grouped by tier with divider headings) ── #} | |
| {% if university_blocks %} | |
| {% for block in university_blocks %} | |
| {% include "partials/blocks/render_block.html" %} | |
| {% endfor %} | |
| {% elif universities %} | |
| {% for uni in universities %} | |
| {% if uni.tier_group_start and uni.tier_group_label %} | |
| <div class="section-block page-break tier-group-heading" data-tier="{{ uni.tier_label | default('') | e }}"> | |
| <h1 class="h1 hb-heading-1" style="margin-top:0.5em;margin-bottom:0.3em;">{{ uni.tier_group_label | e }} | |
| </h1> | |
| </div> | |
| {% endif %} | |
| {% include "partials/university.html" %} | |
| {% endfor %} | |
| {% endif %} | |
| </div>{# /page-content #} | |
| {# ── Bottom Image Pages ── #} | |
| {% for img_path in bottom_pages %} | |
| <div class="fullpage-img-wrap"> | |
| <img class="fullpage-img" src="{{ img_path }}" alt="Handbook Page Image" /> | |
| </div> | |
| {% endfor %} | |
| {# ── Debug Summary ── #} | |
| {% if debug and stats %} | |
| <div class="page-break"></div> | |
| <div class="section-block debug-block"> | |
| <h2 class="h2">PDF Debug Summary</h2> | |
| <pre style="font-size:10px;">{{ stats | tojson(indent=2) }}</pre> | |
| </div> | |
| {% endif %} | |
| </body> | |
| </html> |