initial commit

This commit is contained in:
2024-09-14 02:06:51 +02:00
commit d9ae6527a1
13 changed files with 704 additions and 0 deletions

154
src/menu.typ Normal file
View File

@@ -0,0 +1,154 @@
#let path = sys.inputs.at("path", default: "menus.json")
#let categories = sys.inputs.at("categories", default: "E,D,C,V").split(",")
#let days = json(path)
#let nbsp = sym.space.nobreak
#let width = if days.len() > 1 {20cm} else {10cm}
#set page(margin: 0cm, height: auto, width: width)
#let parse-date(date-txt) = {
let (year, month, day) = date-txt.split("-")
return datetime(year: int(year), month: int(month), day: int(day))
}
#let fmt-number(
number,
decimals: 2,
decimal-sep: ".",
thousands-sep: "'"
) = {
let integer = calc.trunc(number)
let decimal = calc.fract(number)
let res = str(integer).clusters()
.rev()
.chunks(3)
.map(c => c.join(""))
.join(thousands-sep)
.rev()
if decimals != 0 {
res += decimal-sep
decimal = decimal * calc.pow(10, decimals)
decimal = calc.round(decimal)
decimal = str(decimal) + ("0" * decimals)
res += decimal.slice(0, decimals)
}
return res
}
#let day-names = (
"Lundi",
"Mardi",
"Mercredi",
"Jeudi",
"Vendredi",
"Samedi",
"Dimanche"
)
#let display-menus(
days,
categories,
day-sep-stroke: rgb("#82BC00") + 1pt,
title-underline-stroke: rgb("#e34243") + 2pt,
menu-sep-stroke: rgb("#ababab") + 1pt,
price-categ-color: rgb("#577F25")
) = {
set text(font: "Liberation Sans", hyphenate: true)
let cols = calc.min(2, days.len())
let cells = ()
for day in days {
let weekday = parse-date(day.date).weekday() - 1
let day-name = day-names.at(weekday)
let menus = ()
for menu in day.menus {
let price-cell = grid.cell(rowspan: 2)[]
let prices = menu.at(
"prices",
default: (:)
)
if menu.keys().contains("price") {
prices = ("": menu.price)
}
let pairs = prices.pairs()
.filter(p => p.first() in categories)
.sorted(key: p => p.last())
let prices = pairs.map(p => {
let categ = emph(
text(
fill: price-categ-color,
p.first()
)
)
let price = fmt-number(p.last())
categ + ":" + nbsp + "CHF" + nbsp + price
})
price-cell = grid.cell(
rowspan: menu.extra.len() + 1,
stack(dir: ttb, spacing: .4em, ..prices)
)
//let price = "CHF" + sym.space.nobreak + str(menu.price)
menus.push(
grid(
columns: (1fr, auto),
column-gutter: .4em,
row-gutter: .4em,
[*#menu.name*],
price-cell,
..menu.extra.map(l => text(10pt, l))
)
)
}
let title = align(
center,
text(size: 14pt, weight: "bold", day-name)
)
let title-box = box(
width: 50%,
inset: .6em,
stroke: (bottom: title-underline-stroke),
title
)
let title-cell = grid.cell(align: center, title-box)
cells.push(box(width: 100%, grid(
columns: (100%),
inset: (x, y) => (
top: if y == 0 {0pt} else {.8em},
bottom: if y == 0 {0pt} else {2em}
),
stroke: (_, y) => (top: if y < 2 {none} else {menu-sep-stroke}),
title-cell,
..menus
)))
}
if calc.rem(cells.len(), 2) == 1 {
cells.last() = grid.cell(colspan: calc.min(2, cols), cells.last())
}
grid(
columns: (100% / cols,) * cols,
inset: (x: 1.5em, y: .8em),
stroke: (x, y) => {
let borders = (:)
if x != 0 {
borders.insert("left", day-sep-stroke)
}
if y != 0 {
borders.insert("top", day-sep-stroke)
}
return borders
},
..cells
)
}
#display-menus(days, categories)