| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- // ==========================================
- // DOMAIN: ДОКУМЕНТ И КОНТРАКТ ПРОФИЛЯ
- // ==========================================
- #let fail(scope, message) = panic("Scientia / " + scope + ": " + message)
- #let ensure-dictionary(value, scope) = {
- if type(value) != dictionary {
- fail(scope, "ожидался dictionary, получено " + repr(type(value)))
- }
- value
- }
- #let merge-known(defaults, overrides, scope: "options", allow-extra: false) = {
- let defaults = ensure-dictionary(defaults, scope + ".defaults")
- let overrides = ensure-dictionary(overrides, scope)
- let result = defaults
- for (key, value) in overrides {
- if not allow-extra and key not in defaults {
- fail(scope, "неизвестный параметр " + repr(key))
- }
- result.insert(key, value)
- }
- result
- }
- #let render-options(options: (:)) = {
- let resolved = merge-known(
- (
- mode: "final",
- watermark: none,
- media-policy: "placeholder",
- diagnostics: true,
- ),
- options,
- scope: "render-options",
- )
- if resolved.mode not in ("final", "draft", "clean-copy") {
- fail("render-options.mode", "допустимы final, draft, clean-copy")
- }
- if resolved.at("media-policy") not in ("hide", "placeholder", "reserve-space") {
- fail("render-options.media-policy", "допустимы hide, placeholder, reserve-space")
- }
- resolved
- }
- #let document-profile(
- id,
- render,
- metadata: (:),
- normalize: value => value,
- validate: value => value,
- ) = {
- if type(id) != str or id.trim() == "" {
- fail("document-profile.id", "нужна непустая строка")
- }
- if type(metadata) != dictionary {
- fail("document-profile.metadata", "ожидался dictionary")
- }
- if type(normalize) != function {
- fail("document-profile.normalize", "ожидалась function")
- }
- if type(validate) != function {
- fail("document-profile.validate", "ожидалась function")
- }
- if type(render) != function {
- fail("document-profile.render", "ожидалась function")
- }
- (
- kind: "document-profile",
- id: id,
- metadata: metadata,
- normalize: normalize,
- validate: validate,
- render: render,
- )
- }
- #let validate-profile-contract(profile) = {
- let profile = ensure-dictionary(profile, "profile")
- if profile.at("kind", default: none) != "document-profile" {
- fail("profile.kind", "ожидался document-profile")
- }
- for key in ("id", "metadata", "normalize", "validate", "render") {
- if key not in profile {
- fail("profile", "отсутствует обязательное поле " + repr(key))
- }
- }
- if type(profile.normalize) != function or type(profile.validate) != function or type(profile.render) != function {
- fail("profile", "normalize, validate и render должны быть functions")
- }
- profile
- }
- #let document-context(
- company,
- profile,
- metadata,
- options,
- parties: (),
- attachments: (),
- bibliographies: (),
- ) = {
- (
- kind: "document-context",
- company: company,
- profile-id: profile.id,
- metadata: ensure-dictionary(metadata, "document-context.metadata"),
- options: render-options(options: options),
- parties: parties,
- attachments: attachments,
- bibliographies: bibliographies,
- )
- }
|