Files
Umbraformat/umbraformat/templates/format.html
bm 166a4849da spec section 2.2 WA style family: authoritative styles + dynamic gutter
- spec: new section 2.2 style table (WA Chapter/Section/NChp Pgr/Nrml Pgr/
  Thkng + TOC mapping), margins 0.40/0.40/0.375 + 0.25 header-footer
  distance, dynamic gutter resolution procedure, header Caladea 10pt caps,
  footer 11pt, justified body without auto-hyphenation, WA Section reserved
  for scene breaks.
- formatter: WA_STYLES rebuilt to the spec values (next-style chain, outline
  level on WA Chapter, automatic color, widow control); content assigned by
  style reference with direct paragraph/run formatting removed; scene breaks
  use WA Section; TOC entries use WA TOC; auto-hyphenation removed; new page
  setup constants; header ALL CAPS 10pt / footer 11pt.
- format_document: inside/gutter margin now computed from the final page
  count (build -> render -> recompute fixed point, cap 3, settle on larger
  gutter on oscillation); inner_margin input ignored (UI selector removed).
- tests: 68 pass, incl. style-family value tests and mocked gutter-loop tests.
2026-09-24 07:53:19 -07:00

261 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}UmbraFormat — Format a Manuscript{% endblock %}
{% block content %}
<div class="row mb-4">
<div class="col">
<h2><i class="bi bi-upload me-2"></i>Format a Manuscript</h2>
<p class="text-secondary">Upload a <code>.docx</code> file to analyze and apply the B.D. Murphy formatting spec.</p>
</div>
</div>
<div class="row mb-4">
<div class="col-12">
<div class="card bg-dark border-secondary">
<div class="card-body">
<div id="dropZone" class="upload-zone text-center p-5" style="cursor: pointer;">
<i class="bi bi-cloud-upload" style="font-size: 3rem;"></i>
<h5 class="mt-3">Drop a .docx file here or click to browse</h5>
<p class="text-secondary small mb-0">Maximum file size: 50 MB</p>
<input type="file" id="fileInput" accept=".docx" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer;">
</div>
<div id="uploadProgress" class="d-none mt-3">
<div class="d-flex justify-content-between mb-1">
<span id="uploadFileName" class="small"></span>
<span id="uploadPercent" class="small">0%</span>
</div>
<div class="progress" style="height: 6px;">
<div id="uploadProgressBar" class="progress-bar" style="width: 0%"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="optionsArea" class="d-none mb-4">
<div class="row">
<div class="col-12">
<div class="card bg-dark border-secondary">
<div class="card-header bg-dark border-secondary">
<h5 class="mb-0"><i class="bi bi-gear me-2"></i>Formatting Options</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="fontSelect" class="form-label">Paragraph Font</label>
<select id="fontSelect" class="form-select">
<option value="Caladea" selected>Caladea</option>
<option value="Garamond">Garamond</option>
<option value="Baskerville">Baskerville</option>
<option value="Palatino">Palatino</option>
</select>
</div>
<div class="col-md-2">
<label for="fontSizeSelect" class="form-label">Font Size</label>
<select id="fontSizeSelect" class="form-select">
<option value="10">10 pt</option>
<option value="11">11 pt</option>
<option value="12" selected>12 pt</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">Inside / Gutter Margin</label>
<div class="form-control bg-light text-secondary" aria-readonly="true">
Computed automatically from the final page count
</div>
</div>
<div class="col-md-4 d-flex align-items-end">
<div id="pageCountInfo" class="text-secondary small">
<i class="bi bi-info-circle me-1"></i>Upload a file to see page count
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-md-3">
<label for="trimSelect" class="form-label">Trim Size</label>
<select id="trimSelect" class="form-select">
<option value="5.5x8.5" selected>5.5 × 8.5 in (trade paperback)</option>
<option value="6x9">6 × 9 in</option>
</select>
</div>
<div class="col-md-3">
<label for="marginTableSelect" class="form-label">Gutter Table</label>
<select id="marginTableSelect" class="form-select">
<option value="umbraformat" selected>UmbraFormat spec (0.50 – 0.75 in)</option>
<option value="kdp">KDP guidance (0.375 – 0.875 in)</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label d-block">&nbsp;</label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="bleedCheck">
<label class="form-check-label" for="bleedCheck">0.125 in bleed (full-bleed graphics)</label>
</div>
<div class="form-check form-switch mt-2">
<input class="form-check-input" type="checkbox" id="padMultipleCheck" checked>
<label class="form-check-label" for="padMultipleCheck">Pad PDF to a multiple of 4 pages</label>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-md-4">
<label for="authorInput" class="form-label">Author (title page)</label>
<input type="text" id="authorInput" class="form-control"
placeholder="e.g. B.D. Murphy">
</div>
<div class="col-md-4">
<label for="imprintInput" class="form-label">Imprint / Publisher</label>
<input type="text" id="imprintInput" class="form-control"
placeholder="e.g. WorstAuthor LLC">
</div>
<div class="col-md-4">
<label for="languageSelect" class="form-label">Language</label>
<select id="languageSelect" class="form-select">
<option value="en" selected>English</option>
<option value="es">Español (Spanish)</option>
<option value="de">Deutsch (German)</option>
<option value="fr">Français (French)</option>
<option value="ar">العربية (Arabic, RTL)</option>
<option value="he">עברית (Hebrew, RTL)</option>
</select>
</div>
</div>
<div class="row mt-3">
<div class="col-md-6">
<label class="form-label d-block">Graphics handling</label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="stripProblematicCheck">
<label class="form-check-label" for="stripProblematicCheck">Remove images that overflow the text box</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="stripGraphicsCheck">
<label class="form-check-label" for="stripGraphicsCheck">Strip decorative images (scene breaks become ***)</label>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<div id="marginRecommendation" class="alert alert-info d-none mb-0">
<i class="bi bi-lightbulb me-2"></i>
<strong>Recommended inner margin:</strong> <span id="recommendedMargin"></span>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-12 text-center">
<button id="formatBtn" class="btn btn-lg btn-primary px-5" disabled>
<i class="bi bi-magic me-2"></i>Format Document
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="resultsArea" class="d-none">
<div class="row">
<div class="col-lg-6 mb-4">
<div class="card bg-dark border-secondary h-100">
<div class="card-header bg-dark border-secondary d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="bi bi-search me-2"></i>Analysis Results</h5>
<span id="issueCount" class="badge bg-warning">0 issues</span>
</div>
<div class="card-body" id="analysisPanel" style="max-height: 600px; overflow-y: auto;">
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card bg-dark border-secondary h-100">
<div class="card-header bg-dark border-secondary d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="bi bi-check-circle me-2"></i>Formatted Output</h5>
<div id="downloadButtons" class="d-none">
<a id="downloadDocx" class="btn btn-sm btn-outline-primary me-1" href="#">
<i class="bi bi-file-earmark-word"></i> DOCX
</a>
<a id="downloadPdf" class="btn btn-sm btn-outline-danger" href="#">
<i class="bi bi-file-earmark-pdf"></i> PDF
</a>
</div>
</div>
<div class="card-body" id="formatPanel" style="max-height: 600px; overflow-y: auto;">
<div class="text-center text-secondary py-5">
<i class="bi bi-arrow-left" style="font-size: 2rem;"></i>
<p class="mt-2">Upload and analyze a file, then click <strong>Format</strong> to see results here.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-12">
<div class="card bg-dark border-secondary">
<div class="card-header bg-dark border-secondary">
<h5 class="mb-0"><i class="bi bi-table me-2"></i>Inner Margin Reference</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-secondary small text-uppercase">UmbraFormat spec</h6>
<table class="table table-sm table-bordered mb-3" style="max-width: 420px;">
<thead>
<tr>
<th>Total Page Count</th>
<th>Gutter / Inside Margin</th>
</tr>
</thead>
<tbody>
<tr><td>under 150 pages</td><td>0.500 in (12.7 mm)</td></tr>
<tr><td>150 to 300 pages</td><td>0.625 in (15.8 mm)</td></tr>
<tr><td>over 300 pages</td><td>0.750 in (19.0 mm)</td></tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<h6 class="text-secondary small text-uppercase">KDP guidance</h6>
<table class="table table-sm table-bordered mb-0" style="max-width: 420px;">
<thead>
<tr>
<th>Total Page Count</th>
<th>Minimum Inner Margin</th>
</tr>
</thead>
<tbody>
<tr><td>24 to 150 pages</td><td>0.375 in (9.6 mm)</td></tr>
<tr><td>151 to 300 pages</td><td>0.500 in (12.7 mm)</td></tr>
<tr><td>301 to 500 pages</td><td>0.625 in (15.9 mm)</td></tr>
<tr><td>501 to 700 pages</td><td>0.750 in (19.1 mm)</td></tr>
<tr><td>701 to 828 pages</td><td>0.875 in (22.3 mm)</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="loadingOverlay" class="d-none">
<div class="loading-spinner">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">Processing...</span>
</div>
<p class="mt-3" id="loadingText">Processing...</p>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
document.getElementById('fontSelect').addEventListener('change', updatePageEstimate);
document.getElementById('fontSizeSelect').addEventListener('change', updatePageEstimate);
document.getElementById('trimSelect').addEventListener('change', updatePageEstimate);
document.getElementById('marginTableSelect').addEventListener('change', updateMarginRecommendation);
</script>
{% endblock %}