diff --git a/CLAUDE.md b/CLAUDE.md index bb4221f..92d03df 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -92,6 +92,7 @@ src/ orderedListTypes, historyLog, colorDebug) math/ – formula AST: LaTeX parser/serializer, MathML, OMML export/ import/ spell/ storage/ styles/ – ODF+DOCX I/O, spell-check, persistence, named styles + templates/ – built-in document templates: registry + one localized module each styles/ – global.css + editor.css ``` diff --git a/src/lib/components/CLAUDE.md b/src/lib/components/CLAUDE.md index 6d0fa69..d3aa281 100644 --- a/src/lib/components/CLAUDE.md +++ b/src/lib/components/CLAUDE.md @@ -199,6 +199,15 @@ per page in unscaled document px. The watermark is an `` b fontwork shape **stretches** its text to its box instead of setting it at a size — a font size alone makes a short word far too small and a long one overflow the page. +## Built-in templates (`TemplateGalleryDialog.svelte`, `lib/templates/`) + +"New from template" in both chromes opens the gallery; a card applies its entry via +`App.svelte`'s `applyTemplate` — `resetDocumentState()` (the extracted body of New), +then the template's content, margins, styles and fold marks. `documentName` becomes the +localized template name and no file handle is bound, so the first Save asks where. The +DIN letter's mm positions were verified headlessly (45mm address field, 125mm info +column); its module documents the arithmetic. + ## Fold marks (`FoldMarkLayer.svelte`, `storage/foldMarks.ts`) Fold + punch marks at the DIN 5008 positions, drawn per page in the left margin from diff --git a/src/lib/templates/din5008b.ts b/src/lib/templates/din5008b.ts index a9f6590..9cfff65 100644 --- a/src/lib/templates/din5008b.ts +++ b/src/lib/templates/din5008b.ts @@ -25,8 +25,12 @@ const BOLD = { type: 'bold' }; function buildLetter(): TemplateData { const L = t().templates.letter; + // An info line with no address half indents to the column instead of leading with + // a tab (a tab with nothing before it stays on the default grid). const addressRow = (attrs: N | null, addr: N[], info: N[]): N => - P({ ...(attrs ?? {}), tabStops: INFO_TAB }, ...addr, T('\t'), ...info); + addr.length + ? P({ ...(attrs ?? {}), tabStops: INFO_TAB }, ...addr, T('\t'), ...info) + : P({ ...(attrs ?? {}), indent: 10 }, ...info); const date: N = { type: 'dateTimeField', attrs: { kind: 'date', format: DEFAULT_DATE_FORMAT, fixed: true, value: toDateValue(new Date()) } }; return { margins: { top: 2, bottom: 2, left: 2.5, right: 2 }, @@ -36,7 +40,8 @@ function buildLetter(): TemplateData { content: [ P(null, PLH(L.companyName, BOLD)), // The one-line return address opens the address field at 45mm from the top. - P({ spaceBefore: RETURN_SPACE_BEFORE_PT, spaceAfter: RETURN_SPACE_AFTER_PT }, PLH(L.returnAddress, SMALL)), + // fontSize also shrinks the paragraph mark, so the line box is 8pt tall. + P({ spaceBefore: RETURN_SPACE_BEFORE_PT, spaceAfter: RETURN_SPACE_AFTER_PT, fontSize: '8pt' }, PLH(L.returnAddress, SMALL)), addressRow(null, [PLH(L.recipientCompany)], [T(L.yourRef), PLH(L.reference)]), addressRow(null, [PLH(L.recipientName)], [T(L.yourMessage), PLH(L.date)]), addressRow(null, [PLH(L.recipientStreet)], [T(L.ourRef), PLH(L.reference)]),