From c117ecd9b276922080f242cab0542dc30a2c25e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D1=8B=D1=82=D0=BA=D0=BE=D0=B2=20=D0=A0=D0=BE=D0=BC?= =?UTF-8?q?=D0=B0=D0=BD?= Date: Tue, 26 May 2026 15:26:18 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D1=80=D0=B0=D1=81=D0=B8=D0=B2=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=20=D1=82?= =?UTF-8?q?=D0=B0=D0=B1=D0=BB=D0=B8=D1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Report/includes/common.typ | 105 +++++++++++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 21 deletions(-) diff --git a/Report/includes/common.typ b/Report/includes/common.typ index 07cf22e..c69f4e5 100644 --- a/Report/includes/common.typ +++ b/Report/includes/common.typ @@ -5,32 +5,95 @@ #let pz-appendix-title(body) = heading(level: 1)[#body] -#let pz-table(caption, columns, ..body) = figure( +#let pz-column-count(columns) = if type(columns) == int { + columns +} else if type(columns) == array { + columns.len() +} else { + 1 +} + +// Строка из ..range().map(i => ([a], [b])) в body.pos() — один аргумент-массив. +#let pz-flatten-cells(cells) = cells.fold((), (acc, cell) => { + if type(cell) == array { acc + cell } else { acc + (cell,) } +}) + +#let pz-table-inner(columns, header-cells, tab-num, start-page, ..rows) = { + let col-n = pz-column-count(columns) + let cont-cell = table.cell( + colspan: col-n, + stroke: none, + inset: (x: 0pt, y: 2pt), + align: left, + )[ + #context { + if start-page.get() == none { + start-page.update(here().page()) + } + let first-page = start-page.get() + if first-page != none and here().page() > first-page { + [Продолжение таблицы #tab-num] + } + } + ] + let header-row = if header-cells.len() > 0 { + (cont-cell, ..header-cells) + } else { + (cont-cell,) + } table( columns: columns, - ..body, - ), - caption: caption, -) + table.header(..header-row), + ..rows, + ) +} + +#let pz-table(caption, columns, ..body) = { + let pos = body.pos() + let has-header = pos.len() > 0 and pos.first().func() == table.header + let header-cells = if has-header { pos.first().children } else { () } + let tail = pz-flatten-cells(if has-header { pos.slice(1) } else { pos }) + let start-page = state("pz-table-start-page", none) + figure( + kind: table, + context { + let fig-loc = here() + let tab-num = counter(figure.where(kind: table)).at(fig-loc).first() + start-page.update(none) + pz-table-inner(columns, header-cells, tab-num, start-page, ..arguments(..tail)) + }, + caption: caption, + ) +} // Реестры unit-тестов: перенос длинных идентификаторов (camelCase, _); сетка как в примере Typst. -#let pz-test-table(caption, columns, ..body) = figure( - { - show table: set text(hyphenate: true, size: 9pt) - show table.cell: cell => { - show regex("[a-z0-9][A-Z]"): m => { - m.text.first() + sym.zws + m.text.last() +#let pz-test-table(caption, columns, ..body) = { + let pos = body.pos() + let has-header = pos.len() > 0 and pos.first().func() == table.header + let header-cells = if has-header { pos.first().children } else { () } + let tail = pz-flatten-cells(if has-header { pos.slice(1) } else { pos }) + let start-page = state("pz-table-start-page", none) + figure( + kind: table, + { + show table: set text(hyphenate: true, size: 9pt) + show table.cell: cell => { + show regex("[a-z0-9][A-Z]"): m => { + m.text.first() + sym.zws + m.text.last() + } + show regex("[_]"): it => it + sym.zws + cell } - show regex("[_]"): it => it + sym.zws - cell - } - table( - columns: columns, - ..body, - ) - }, - caption: caption, -) + context { + let fig-loc = here() + let tab-num = counter(figure.where(kind: table)).at(fig-loc).first() + start-page.update(none) + pz-table-inner(columns, header-cells, tab-num, start-page, ..arguments(..tail)) + } + }, + caption: caption, + ) +} #let pz-fig(path, caption, lbl) = [ #figure(