#let sender-block(sender) = if type(sender) == dictionary { text(weight: "medium", tracking: 0.03em)[#smallcaps(sender.name)] if sender.at("address", default: none) != none { v(0.35em) text(size: 0.85em, fill: luma(30%))[#sender.address] } } else { sender } #let recipient-block(recipient) = if type(recipient) == dictionary { recipient.name if recipient.at("address", default: none) != none { linebreak() text(size: 0.9em, fill: luma(30%))[#recipient.address] } } else { recipient } #let letter( sender: none, recipient: none, place: none, date: none, subject: none, opening: [Madame, Monsieur,], closing: [Veuillez agréer, Madame, Monsieur, l'expression de mes salutations distinguées.], signature: none, lang: "fr", region: "FR", font: "EB Garamond", size: 11pt, doc, ) = { set page(paper: "a4", margin: (x: 26mm, top: 30mm, bottom: 26mm), numbering: none) set par(justify: true, leading: 0.72em, spacing: 1.3em) set text(font: font, size: size, lang: lang, region: region, number-type: "old-style") let dateline = if place != none and date != none { [#place, le #date] } else if date != none { [le #date] } else { place } let sign = if signature != none { signature } else if type(sender) == dictionary { sender.name } else { none } grid( columns: (1fr, 1fr), align: (left + top, right + top), sender-block(sender), { recipient-block(recipient) if dateline != none { if recipient != none { v(1.4em) } dateline } }, ) v(1.9em) line(length: 100%, stroke: 0.4pt) v(1.9em) if subject != none { [#text(weight: "bold")[Objet :] #subject] v(1.4em) } opening v(0.6em) doc v(1.6em) closing if sign != none { v(3.2em) align(right, smallcaps(sign)) } }