Initial roast planner webapp: fillable worksheet, live ledger, curve, URL prefill, .alog reference curve
- shared/ ports the worksheet's ledger math, time parsing, and reference tables (cultivars/processes/roast-levels/machine bands) as browser-safe ESM, imported by both the server and the browser so the arithmetic can't drift between them. - server/prefill.js runs a zero-tool Pi Coding Agent SDK turn to extract page facts from a bean product URL, then derives worksheet field IDs deterministically from reference-data.js — the model never invents a first-crack anchor or a modifier. - server/alog.js ports the Python alog_parser.py's format handling, including the tokenizer-based Python-dict-literal-to-JSON conversion the real files need. - public/ is the worksheet reproduced as a live HTML form: worksheet.css is a verbatim copy of the paper worksheet's print CSS, print.js bakes values into the print layout so the same DOM renders both on screen and on paper. - Ledger math verified against both of the paper worksheet's worked examples; alog parser verified against all 14 real logs in ref/roasts/. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
// Bakes live input values into their sibling .pv span before printing (so text doesn't clip
|
||||
// at a fixed .f width the way a raw <input> would), then clears them after. One DOM, one
|
||||
// rendering — see app.css's @media print block for the corresponding display swap.
|
||||
|
||||
export function initPrint({ form }) {
|
||||
document.getElementById("btn-print").addEventListener("click", () => window.print());
|
||||
|
||||
window.addEventListener("beforeprint", () => bakeValues(form));
|
||||
window.addEventListener("afterprint", () => clearBaked(form));
|
||||
}
|
||||
|
||||
function bakeValues(form) {
|
||||
for (const el of form.querySelectorAll("input.ws-input, textarea.ws-input")) {
|
||||
if (el.type === "radio" || el.type === "checkbox") continue;
|
||||
const pv = el.nextElementSibling;
|
||||
if (pv && pv.classList.contains("pv")) pv.textContent = el.value || "";
|
||||
}
|
||||
}
|
||||
|
||||
function clearBaked(form) {
|
||||
for (const pv of form.querySelectorAll(".pv")) pv.textContent = "";
|
||||
}
|
||||
Reference in New Issue
Block a user