| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- // ==========================================
- // PRESENTATION: ОБЩАЯ ОСНОВА ВЁРСТКИ
- // ==========================================
- #let design-tokens(company, overrides: (:)) = {
- let defaults = (
- brand-color: company.brand.at("color", default: rgb("e39f49")),
- text-font: "Times New Roman",
- sans-font: "Arial",
- text-size: 12pt,
- small-size: 8pt,
- line-height: 1.5em,
- compact-line-height: 0.65em,
- paper: "a4",
- page-margin: (left: 3cm, right: 1.5cm, top: 2cm, bottom: 2cm),
- )
- let result = defaults
- for (key, value) in overrides {
- if key not in defaults {
- panic("Scientia / design-tokens: неизвестный token " + repr(key))
- }
- result.insert(key, value)
- }
- result
- }
- #let watermark-layer(value, font: "Arial") = {
- if value == none {
- none
- } else {
- [
- #place(center + horizon, dx: -4.8cm, dy: -8.5cm)[
- #rotate(35deg)[#text(font: font, size: 40pt, weight: "bold", fill: rgb("e8c9c9").transparentize(65%))[#value]]
- ]
- #place(center + horizon)[
- #rotate(35deg)[#text(font: font, size: 40pt, weight: "bold", fill: rgb("e8c9c9").transparentize(65%))[#value]]
- ]
- #place(center + horizon, dx: 4.8cm, dy: 8.5cm)[
- #rotate(35deg)[#text(font: font, size: 40pt, weight: "bold", fill: rgb("e8c9c9").transparentize(65%))[#value]]
- ]
- ]
- }
- }
- #let render-media-slot(
- resource,
- policy: "placeholder",
- width: 4cm,
- height: 2cm,
- label: "РЕСУРС НЕ ЗАДАН",
- fit: "contain",
- ) = {
- if policy not in ("hide", "placeholder", "reserve-space") {
- panic("Scientia / media-slot: неизвестная политика " + repr(policy))
- }
- if resource == none {
- if policy == "hide" {
- none
- } else if policy == "reserve-space" {
- box(width: width, height: height)
- } else {
- box(
- width: width,
- height: height,
- stroke: 0.6pt + luma(150),
- fill: luma(245),
- inset: 4pt,
- align(center + horizon)[
- #text(font: "Arial", size: 7pt, fill: luma(110), weight: "bold")[#label]
- ],
- )
- }
- } else if type(resource) == path {
- image(resource, width: width, height: height, fit: fit)
- } else if type(resource) == content {
- box(width: width, height: height, align(center + horizon, resource))
- } else {
- panic("Scientia / media-slot: ожидались none, path или content")
- }
- }
- #let apply-foundation(
- body,
- ctx: none,
- tokens: (:),
- page-options: (:),
- text-options: (:),
- par-options: (:),
- ) = {
- if ctx == none {
- panic("Scientia / foundation: document context обязателен")
- }
- let tokens = design-tokens(ctx.company, overrides: tokens)
- let page-defaults = (
- paper: tokens.paper,
- margin: tokens.at("page-margin"),
- foreground: watermark-layer(ctx.options.watermark, font: tokens.at("sans-font")),
- )
- let resolved-page = page-defaults
- for (key, value) in page-options { resolved-page.insert(key, value) }
- set page(..resolved-page)
- set text(
- font: tokens.at("text-font"),
- size: tokens.at("text-size"),
- lang: "ru",
- ..text-options,
- )
- set par(
- justify: true,
- first-line-indent: (amount: 1.25cm, all: true),
- leading: tokens.at("line-height"),
- ..par-options,
- )
- show table.cell: set par(first-line-indent: 0pt)
- show figure.caption.where(kind: table): set par(first-line-indent: 0pt)
- body
- }
|