Files
test/.template/lib/domain/attachments.typ
T
2026-10-09 04:24:38 +00:00

78 lines
2.2 KiB
Typst

// ==========================================
// DOMAIN: ПРИЛОЖЕНИЯ
// ==========================================
#import "document.typ": fail
#let attachment(
id,
title,
body,
subtitle: none,
number: auto,
outlined: true,
) = {
if type(id) != str or id.trim() == "" {
fail("attachment.id", "нужна непустая строка")
}
if type(title) not in (str, content) {
fail("attachment.title", "ожидались str или content")
}
if type(body) not in (content, function) {
fail("attachment.body", "ожидались content или function")
}
if subtitle != none and type(subtitle) not in (str, content) {
fail("attachment.subtitle", "ожидались none, str или content")
}
(
kind: "attachment",
id: id,
title: title,
subtitle: subtitle,
body: body,
number: number,
outlined: outlined,
)
}
#let attachment-set(items: (), numbering: "arabic", start: 1) = {
if type(items) != array {
fail("attachments.items", "ожидался array")
}
if numbering not in ("arabic", "cyrillic", "none") {
fail("attachments.numbering", "допустимы arabic, cyrillic, none")
}
if type(start) != int or start < 1 {
fail("attachments.start", "нужно положительное целое число")
}
let seen = ()
for item in items {
if type(item) != dictionary or item.at("kind", default: none) != "attachment" {
fail("attachments.items", "каждый элемент должен быть attachment")
}
if item.id in seen {
fail("attachments.items", "повторяющийся id " + repr(item.id))
}
seen.push(item.id)
}
(
kind: "attachment-set",
items: items,
numbering: numbering,
start: start,
)
}
#let validate-attachment-set(value) = {
if type(value) == array {
attachment-set(items: value)
} else if type(value) != dictionary or value.at("kind", default: none) != "attachment-set" {
fail("attachments", "ожидались array или attachment-set")
} else {
attachment-set(
items: value.at("items", default: ()),
numbering: value.at("numbering", default: "arabic"),
start: value.at("start", default: 1),
)
}
}