148 lines
4.3 KiB
Typst
148 lines
4.3 KiB
Typst
// ==========================================
|
|
// PROFILE: ДЕЛОВОЕ ПИСЬМО
|
|
// ==========================================
|
|
#import "../../domain/document.typ": document-profile, fail
|
|
#import "../../domain/attachments.typ": attachment-set
|
|
#import "../../domain/parties.typ": signer
|
|
#import "../foundation.typ": apply-foundation
|
|
#import "../components.typ": attachment-list, appendix-heading, company-footer, letter-header, signature-block
|
|
|
|
#let normalize-letter(metadata) = {
|
|
if type(metadata.attachments) == array {
|
|
metadata.insert("attachments", attachment-set(items: metadata.attachments))
|
|
}
|
|
metadata
|
|
}
|
|
|
|
#let validate-letter(metadata) = {
|
|
if metadata.recipient == none or type(metadata.recipient) != dictionary or metadata.recipient.at("kind", default: none) != "recipient" {
|
|
fail("letter.recipient", "ожидался recipient")
|
|
}
|
|
if metadata.title != none and type(metadata.title) not in (str, content) {
|
|
fail("letter.title", "ожидались none, str или content")
|
|
}
|
|
if metadata.signer != none and (type(metadata.signer) != dictionary or metadata.signer.at("kind", default: none) != "signer") {
|
|
fail("letter.signer", "ожидались none или signer")
|
|
}
|
|
if type(metadata.attachments) != dictionary or metadata.attachments.at("kind", default: none) != "attachment-set" {
|
|
fail("letter.attachments", "ожидался attachment-set")
|
|
}
|
|
metadata
|
|
}
|
|
|
|
#let effective-signer(data, company, include-media: true) = {
|
|
let source = if data.signer == none {
|
|
signer(
|
|
company.director.name,
|
|
company.director.title,
|
|
signature: company.resources.signature,
|
|
stamp: company.resources.stamp,
|
|
)
|
|
} else {
|
|
data.signer
|
|
}
|
|
signer(
|
|
source.name,
|
|
source.title,
|
|
basis: source.basis,
|
|
signature: if include-media { source.signature } else { none },
|
|
stamp: if include-media { source.stamp } else { none },
|
|
)
|
|
}
|
|
|
|
#let render-letter-attachments(attachments, appendix-state) = {
|
|
for (index, item) in attachments.items.enumerate() {
|
|
pagebreak()
|
|
appendix-state.update(true)
|
|
let number = if item.number == auto { index + attachments.start } else { item.number }
|
|
appendix-heading(item, str(number))
|
|
v(0.5cm)
|
|
if type(item.body) == function { (item.body)() } else { item.body }
|
|
}
|
|
}
|
|
|
|
#let render-letter(body, ctx) = {
|
|
let company = ctx.company
|
|
let data = ctx.metadata
|
|
let include-media = ctx.options.mode == "final"
|
|
let person = effective-signer(data, company, include-media: include-media)
|
|
let media-policy = if include-media { ctx.options.at("media-policy") } else { "reserve-space" }
|
|
let appendix-state = state("scientia-letter-in-appendix", false)
|
|
let footer = context {
|
|
if not appendix-state.get() { company-footer(company) }
|
|
}
|
|
let composed = [
|
|
#letter-header(
|
|
company,
|
|
data.recipient,
|
|
date: data.date,
|
|
reference: data.reference,
|
|
title: data.title,
|
|
media_policy: ctx.options.at("media-policy"),
|
|
)
|
|
#v(0.7cm)
|
|
#body
|
|
#if data.attachments.items.len() > 0 {
|
|
v(0.8cm)
|
|
attachment-list(data.attachments)
|
|
}
|
|
#signature-block(
|
|
person,
|
|
company: company,
|
|
media_policy: media-policy,
|
|
show_stamp: data.at("show-stamp"),
|
|
note: data.note,
|
|
)
|
|
#if data.at("render-attachments") and data.attachments.items.len() > 0 {
|
|
render-letter-attachments(data.attachments, appendix-state)
|
|
}
|
|
]
|
|
|
|
apply-foundation(
|
|
composed,
|
|
ctx: ctx,
|
|
tokens: (
|
|
text-font: "Arial",
|
|
text-size: 10pt,
|
|
line-height: 0.65em,
|
|
page-margin: (top: 1.5cm, bottom: 4cm, left: 1.5cm, right: 1.5cm),
|
|
),
|
|
page-options: (
|
|
footer: footer,
|
|
footer-descent: 20%,
|
|
),
|
|
)
|
|
}
|
|
|
|
#let letter-profile(
|
|
recipient: none,
|
|
date: none,
|
|
reference: none,
|
|
title: "Деловое письмо",
|
|
signer: none,
|
|
note: none,
|
|
show_stamp: true,
|
|
attachments: attachment-set(),
|
|
render_attachments: false,
|
|
) = {
|
|
document-profile(
|
|
"letter",
|
|
render-letter,
|
|
metadata: (
|
|
recipient: recipient,
|
|
date: date,
|
|
reference: reference,
|
|
title: title,
|
|
signer: signer,
|
|
note: note,
|
|
show-stamp: show_stamp,
|
|
parties: (),
|
|
attachments: attachments,
|
|
bibliographies: (),
|
|
render-attachments: render_attachments,
|
|
),
|
|
normalize: normalize-letter,
|
|
validate: validate-letter,
|
|
)
|
|
}
|