Switch to .with logic, set defaults, added other warning signs, reworked signgrid

This commit is contained in:
Waldo 2025-11-10 23:56:07 +01:00
parent 85f13e5d46
commit 5855428633

149
main.typ
View file

@ -2,96 +2,85 @@
#import "@preview/one-liner:0.2.0": fit-to-width #import "@preview/one-liner:0.2.0": fit-to-width
#import "@preview/subpar:0.2.2" #import "@preview/subpar:0.2.2"
#import "@preview/typsium:0.3.0":* #import "@preview/typsium:0.3.0":*
#import "@preview/typsium-iso-7010:0.1.0": *
#let chemscript( #let chemscript(
lan, language: ("en"),
title, title: ("Die Methan-Mamba"),
title_fontsize, title_fontsize: (25pt),
ghs_signs, signs_gridlength: 9,
tablebreak_bias, ghs_signs: (1,2,3,4,5,),
step_descriptions, fire_signs: (1,),
step_image_paths, warning_signs: (1,1,1),
step_image_size, mandatory_actions_signs: (1,1,1,),
image_paths, tablebreak_bias: (6),
image_radius, step_descriptions: ("adwa", "asdwa"),
amounts, step_image_paths: (),
material_names, step_image_size: (5cm),
safety_notices, image_paths: (),
explanation, image_radius: 2pt,
observation material_names: ("asdaw", "asda"),
materials: ((amount: "20", name: "fischascwd"),(amount: "20", name: "fischascwd")),
chemicals: ((amount: "20", name: "fischascwd"),(amount: "20", name: "fischascwd")),
safety_notices: ("asdw",),
observation: ["asdwa",],
interpretation: [],
doc
) = { ) = {
//tranforms dictionaries to array
let material_names = materials.map(material => text(material.name))
let material_amounts = materials.map(material => text(material.amount))
let chemical_names = chemicals.map(chemical => text(chemical.name))
let chemical_amounts = materials.map(chemical => text(chemical.amount))
let tablecolumns = calc.ceil(material_names.len() / tablebreak_bias)
let tablecolumns = calc.ceil(amounts.len() / tablebreak_bias)
let materials = material_names.map(name => text(name))
let has_images = step_image_paths.any(path => path != "" and path != "none") let has_images = step_image_paths.any(path => path != "" and path != "none")
set text(lang:lan) set text(lang:language)
//Create a breakable Table
let repeated-table(num-repeats: 2, ..args) = { let repeated-table(num-repeats: 2, ..args) = {
let options = args.named() let options = args.named()
let data = args.pos() let data = args.pos()
// STEP 1: transform table options to apply to a multiple of the original columns
let columns = options.at("columns", default: ()) let columns = options.at("columns", default: ())
let (column-count, columns) = if type(columns) == int { let (column-count, columns) = if type(columns) == int {
// for numbers, that's number of columns
(columns, columns * num-repeats) (columns, columns * num-repeats)
} else if type(columns) == array and columns != () { } else if type(columns) == array and columns != () {
// for arrays with elements, the number of elements is number of columns
(columns.len(), columns * num-repeats) (columns.len(), columns * num-repeats)
} else { } else {
// lengths, auto or an empty array mean there's one column
(1, (auto,) * num-repeats) (1, (auto,) * num-repeats)
} }
options.columns = columns
// TODO transform other per-column fields, such as align
// STEP 2: separate header and footer from the table body, with repeated cells
let header = if data.len() > 0 and type(data.first()) == content and data.first().func() == table.header { let header = if data.len() > 0 and type(data.first()) == content and data.first().func() == table.header {
let (children, ..args) = data.remove(0).fields() let (children, ..args) = data.remove(0).fields()
table.header(..args, ..children * num-repeats) table.header(..args, ..children * num-repeats)
} }
let footer = if data.len() > 0 and type(data.last()) == content and data.last().func() == table.footer { let footer = if data.len() > 0 and type(data.last()) == content and data.last().func() == table.footer {
let (children, ..args) = data.pop().fields() let (children, ..args) = data.pop().fields()
table.footer(..args, ..children * num-repeats) table.footer(..args, ..children * num-repeats)
} }
// STEP 3: rearrange the data, so that after a number of rows the next repetition begins
// split into rows
let rows = data.chunks(column-count) let rows = data.chunks(column-count)
// split into repeats of rows
let num-rows = calc.ceil(rows.len() / num-repeats) let num-rows = calc.ceil(rows.len() / num-repeats)
let repeats = rows.chunks(num-rows) let repeats = rows.chunks(num-rows)
// pad the last repeat so that all have the same number of rows
let empty-row = (none,) * column-count let empty-row = (none,) * column-count
repeats.last() += (empty-row,) * (num-rows - repeats.last().len()) repeats.last() += (empty-row,) * (num-rows - repeats.last().len())
// join repeats into combined rows
let rows = array.zip(..repeats) let rows = array.zip(..repeats)
// combine into flat data
data = rows.flatten() data = rows.flatten()
// STEP 4: re-add header and footer to the data
if header != none { if header != none {
data.insert(0, header) data.insert(0, header)
} }
if footer != none { if footer != none {
data.push(footer) data.push(footer)
} }
// STEP 5: produce table
table(..options, ..data) table(..options, ..data)
} }
// Style changes to Subpar
let my-subfig(..args) = subpar.grid( let my-subfig(..args) = subpar.grid(
show-sub-caption: (num, it) => { show-sub-caption: (num, it) => {
@ -102,12 +91,8 @@ let my-subfig(..args) = subpar.grid(
..args ..args
) )
// Define your image paths
// NOTE: For Linebreaks, use \n in the text
let steps = step_descriptions.enumerate().map(((i, desc)) => { let steps = step_descriptions.enumerate().map(((i, desc)) => {
let img = if i < step_image_paths.len() { step_image_paths.at(i) } else { "none" } let img = if i < step_image_paths.len() { step_image_paths.at(i) } else { "none" }
grid( grid(
@ -140,21 +125,43 @@ let figures = image_paths.map(path => block(
image(path) image(path)
)) ))
//title and hazard
let signgrid = (range(0, signs_gridlength).map(_ => 1fr))
let fillerrow1 = calc.clamp(0,signs_gridlength - ghs_signs.len(),1000)
let fillerrow2 = calc.clamp(0,signs_gridlength - (fire_signs.len() + warning_signs.len() + mandatory_actions_signs.len()),1000)
grid( grid(
columns: (1fr, auto), columns: (1fr, 1fr),
align: (horizon, right+horizon), align: (horizon, right),
stroke: (bottom:0.5pt + black), stroke: (bottom:0.5pt + black),
inset: (5pt), inset: (5pt),
par( par(
text(title, size: title_fontsize)), text(title, size: title_fontsize)),
grid( grid(
columns: ghs_signs.len(), columns: 1,
rows: 30pt, rows: 2,
..ghs_signs.map(x=> ghs(x)) align: right,
grid(
columns: signgrid,
rows: auto,
..(grid.cell(y: 0)[],) * fillerrow1,
..(ghs_signs.map(x => ghs(x)))
),
grid(
inset: (left: 1.5pt,right: 1.5pt,top: 1.5pt,bottom: 1.5pt),
columns: signgrid,
rows: auto,
..(grid.cell(y: 0)[],) * fillerrow2,
..(fire_signs.map(x => fire-sign(x)) +
warning_signs.map(x => warning-sign(x)) +
mandatory_actions_signs.map(x => mandatory-actions-sign(x)))
) )
) ))
//safety //safety
v(-0.3cm) v(-0.3cm)
@ -187,7 +194,7 @@ grid(
columns: (auto, auto), columns: (auto, auto),
align: (right, left), align: (right, left),
..for x in amounts.zip(material_names) {( ..for x in material_amounts.zip(material_names) {(
..for y in x {( ..for y in x {(
[#y], [#y],
)} )}
@ -221,17 +228,7 @@ grid(
//Interpretation //Interpretation
grid(
columns: (1fr),
stroke: (bottom:0.5pt + black),
inset: (top: 0pt, bottom: 5pt, left: 5pt, right: 5pt),
grid(
rows: (auto),
text("Interpretation", weight: "bold"),
v(0.4cm),
explanation
),
)
//observation //observation
grid( grid(
@ -245,7 +242,19 @@ grid(
observation, observation,
), ),
) )
// Safety Notices
grid(
columns: (1fr),
stroke: (bottom:0.5pt + black),
inset: (top: 0pt, bottom: 5pt, left: 5pt, right: 5pt),
grid(
rows: (auto),
text("Interpretation", weight: "bold"),
v(0.4cm),
interpretation
),
)
// Safety Notices
doc
} }
// Interpretation // Interpretation