Skip to content

Commit c864bb5

Browse files
committed
Add gibz-script 0.1.0 (clean rebase onto upstream/main)
1 parent 3149ac3 commit c864bb5

File tree

16 files changed

+664
-0
lines changed

16 files changed

+664
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
MIT No Attribution (MIT-0)
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so.
4+
5+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
## GIBZ Template Package
2+
3+
A template package providing reusable components for teaching and learning material at [GIBZ](https://www.gibz.ch).
4+
It comes with a configurable document setup (`gibz-conf`) and a collection of styled components such as tasks, hints, supplementary material, and more.
5+
6+
---
7+
8+
## Features
9+
10+
- 📄 **Configurable document layout** with title page, table of contents, and headers/footers.
11+
- 🎨 **Consistent styling** through a `base_box` and `icon_box` system.
12+
- ✏️ **Task component** with badges for time, social form, results recording, and evaluation.
13+
- 💡 **Hint**, ❓ **Question**, 🎬 **Video**, 📖 **Supplementary Material** boxes.
14+
- 🔳 **Black code box** for highlighting code snippets.
15+
- 🌍 **Built-in i18n** (currently German and English).
16+
- 🧩 Exposed via a **flat prefixed API** (`gibz-task`, `gibz-hint`, …) and an optional `GIBZ` namespace.
17+
18+
---
19+
20+
## Quick Start
21+
22+
Create a new project from this template in the Typst CLI:
23+
24+
```sh
25+
typst init @preview/gibz-script:0.1.0
26+
```
27+
28+
Or in the [Typst web app](https://typst.app):
29+
**New → From Template → GIBZ**.
30+
31+
---
32+
33+
## Usage
34+
35+
### Import the flat API (recommended)
36+
37+
```typst
38+
#import "@preview/gibz-script:0.1.0": gibz-conf, gibz-task, gibz-supplementary
39+
40+
#show: gibz-script(
41+
moduleNumber: 114,
42+
moduleTitle: "Codierungs-, Kompressions- und Verschlüsselungsverfahren einsetzen",
43+
documentTitle: "Skript",
44+
language: "de",
45+
doc: {
46+
#gibz-hint("Dieses Skript wurde mit Typst geschrieben :-)")
47+
#gibz-supplementary([Cheat Sheet])
48+
}
49+
)
50+
```
51+
52+
### Or use the namespaced API
53+
54+
```typst
55+
#import "@preview/gibz-script:0.1.0": GIBZ
56+
57+
#show: GIBZ.script(
58+
moduleNumber: 114,
59+
moduleTitle: "Codierungs-, Kompressions- und Verschlüsselungsverfahren einsetzen",
60+
documentTitle: "Skript",
61+
language: "de",
62+
doc: {
63+
#GIBZ.hint("Dieses Skript wurde mit Typst geschrieben :-)")
64+
#GIBZ.supplementary([Cheat Sheet])
65+
}
66+
)
67+
```
68+
69+
---
70+
71+
## API Reference
72+
73+
### Configuration
74+
75+
- `gibz-conf(moduleNumber, moduleTitle, documentTitle, language, doc)`
76+
Wraps your document with title page, table of contents, headers/footers, and base styles.
77+
78+
### Components
79+
80+
- `gibz-task(...)` – exercise/task box with time, social form, recording, evaluation.
81+
- `gibz-hint(content)` – hint box with 💡 icon.
82+
- `gibz-question(question, task: none)` – question box with ❓ icon, optional task description.
83+
- `gibz-video(url, title, description: none)` – video reference with 🎬 icon.
84+
- `gibz-supplementary(body, title: none)` – supplementary material box with 📖 icon.
85+
- `gibz-black_code_box(body, codly-opts: (:), box-opts: (:))` – code box with dark background.
86+
87+
### Utilities
88+
89+
- `gibz-base_box(body, style: (:))` – low-level styled container.
90+
- `gibz-icon_box(icon, content, style: (:))` – container with icon + content layout.
91+
- `gibz-colors.blue` – standard accent color.
92+
- `gibz-t(key, lang: none)` – translation lookup (DE/EN).
93+
94+
---
95+
96+
## Localization
97+
98+
The package supports German (`de`) and English (`en`) for static labels (e.g., _Exercise_, _Supplementary Material_, _Table of Contents_).
99+
The language is set via `gibz-conf(language: "de" | "en")`.
100+
101+
---
102+
103+
## License
104+
105+
This package is licensed under the [MIT-0 License](LICENSE), allowing reuse with minimal restrictions.
106+
107+
---
108+
109+
## Contributing
110+
111+
Issues and pull requests are welcome!
112+
The source is maintained on [GitLab](https://gitlab.com/GIBZ/public/typst-template), with mirrored contributions published to [Typst Universe](https://github.com/typst/packages).
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// lib.typ — public entrypoint with flat gibz_ API + optional GIBZ namespace.
2+
3+
// Import only what we want to expose
4+
#import "src/colors.typ": gibz-blue
5+
#import "src/state.typ": gibz-lang // kept internal; not re-exported
6+
#import "src/layout.typ": _conf
7+
#import "src/components/base_box.typ": base-box
8+
#import "src/components/icon_box.typ": icon-box
9+
#import "src/components/boxes.typ": hint, question, supplementary, video
10+
#import "src/components/codebox.typ": black-code-box
11+
#import "src/components/task.typ": task
12+
#import "src/i18n.typ": t
13+
14+
#import "src/code.typ": code as gibz-code, code_wrap as _gibz-codly, set_code_style as gibz-set-code-style
15+
16+
17+
// ── Flat API (prefixed) ──────────────────────────────────────────────────────
18+
#let gibz-script = _conf
19+
#let gibz-task = task
20+
#let gibz-hint = hint
21+
#let gibz-question = question
22+
#let gibz-video = video
23+
#let gibz-supplementary = supplementary
24+
#let gibz-black-code-box = black-code-box
25+
#let gibz-icon-box = icon-box
26+
#let gibz-base-box = base-box
27+
#let gibz-t = t
28+
29+
// Colors (both single and grouped)
30+
#let gibz-blue = gibz-blue
31+
#let gibz-colors = (blue: gibz-blue)
32+
33+
// ── Optional convenience namespace (no duplication; just references) ────────
34+
#let GIBZ = (
35+
script: gibz-script,
36+
task: gibz-task,
37+
hint: gibz-hint,
38+
question: gibz-question,
39+
video: gibz-video,
40+
supplementary: gibz-supplementary,
41+
black_code_box: gibz-black-code-box,
42+
icon_box: gibz-icon-box,
43+
base_box: gibz-base-box,
44+
colors: gibz-colors,
45+
t: gibz-t,
46+
)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#import "@preview/codly:1.3.0": *
2+
3+
#let _code_overrides = state("gibz-code-overrides", (:))
4+
5+
#let set_code_style(opts: (:)) = {
6+
if type(opts) == dictionary {
7+
_code_overrides.update(_code_overrides.get() + opts)
8+
}
9+
}
10+
11+
// Lokaler Wrapper für Blöcke
12+
#let code(block, opts: (:)) = {
13+
context {
14+
let ov = _code_overrides.get()
15+
let local_opts = if type(opts) == dictionary { ov + opts } else { ov }
16+
codly(..local_opts)
17+
block
18+
}
19+
}
20+
21+
// Alternative Syntax: #GIBZ.codly(...)[ body ]
22+
#let code_wrap(opts: (:), body) = {
23+
context {
24+
let ov = _code_overrides.get()
25+
let local_opts = if type(opts) == dictionary { ov + opts } else { ov }
26+
codly(..local_opts)
27+
body
28+
}
29+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Central color definitions
2+
#let gibz-blue = rgb(0, 119, 192, 255)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// A reusable visual container with sensible defaults.
2+
// Override any style via the `style` dict.
3+
#let base-box(body, style: (:)) = {
4+
let defaults = (
5+
width: 100%,
6+
fill: luma(98%),
7+
stroke: (paint: gray, thickness: 0.5pt),
8+
radius: 6pt,
9+
inset: 12pt,
10+
)
11+
12+
// Merge defaults with caller-provided styles (caller wins).
13+
let s = defaults + style
14+
15+
box(
16+
width: s.width,
17+
fill: s.fill,
18+
stroke: s.stroke,
19+
radius: s.radius,
20+
inset: s.inset,
21+
[ #body ],
22+
)
23+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#import "../colors.typ": gibz-blue
2+
#import "../state.typ": gibz-lang
3+
#import "../i18n.typ": t
4+
#import "./base_box.typ": base-box
5+
6+
// Icon/text two-column box using base_box
7+
#let gibz-box(icon, content) = {
8+
set text(size: 10pt)
9+
base-box(
10+
[
11+
#grid(
12+
columns: (50pt, 1fr),
13+
align: (center + horizon, left + horizon),
14+
[
15+
#set text(size: 20pt)
16+
#pad(right: 15pt, bottom: 5pt, icon)
17+
],
18+
[#content],
19+
)
20+
],
21+
)
22+
}
23+
24+
#let hint(hint) = gibz-box(emoji.lightbulb, hint)
25+
26+
#let question(question, task: none) = gibz-box(
27+
emoji.quest,
28+
{
29+
[
30+
#set text(weight: "bold")
31+
#question
32+
]
33+
if task != none {
34+
linebreak()
35+
[#task]
36+
}
37+
},
38+
)
39+
40+
#let video(url, title, description: none) = {
41+
show link: set text(font: "DejaVu Sans Mono", size: 7pt)
42+
gibz-box(
43+
[#emoji.clapperboard],
44+
[
45+
#[
46+
#set text(weight: "bold")
47+
#title #linebreak()
48+
]
49+
#if description != none { [#description #linebreak()] }
50+
#link(url)
51+
],
52+
)
53+
}
54+
55+
#let supplementary(body, title: none, lang: none) = {
56+
context {
57+
let L = if lang != none { lang } else { gibz-lang.get() }
58+
59+
base-box(
60+
[
61+
#block(below: 6pt, [
62+
#text(size: 0.75em, weight: 600, fill: gibz-blue)[📖 #t("supplementary-material", lang: L)]
63+
])
64+
#v(6pt)
65+
66+
#if title != none {
67+
block(below: 6pt, [ #text(size: 1.15em, weight: 700)[#title] ])
68+
v(3pt)
69+
}
70+
71+
#body
72+
],
73+
)
74+
}
75+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#import "@preview/codly:1.3.0": *
2+
3+
#let _gibz_black_code_box(
4+
body, // Inhalt: i. d. R. ein fenced code block
5+
codly-opts: (:), // optionale Codly-Overrides lokal für diesen Block
6+
box-opts: (:), // optionale Box-Optionen (inset, radius, ...)
7+
) = {
8+
// Codly-Defaults innerhalb der schwarzen Box
9+
let codly-defaults = (
10+
zebra-fill: none,
11+
number-format: none,
12+
display-name: false,
13+
stroke: none,
14+
fill: black,
15+
)
16+
let codly-final = codly-defaults + codly-opts
17+
18+
box(
19+
width: 100%,
20+
fill: black,
21+
inset: 5pt,
22+
radius: 5pt,
23+
stroke: none,
24+
..box-opts,
25+
[
26+
#set text(fill: white)
27+
#context {
28+
codly(..codly-final)
29+
body
30+
}
31+
],
32+
)
33+
}
34+
35+
// Öffentlicher Alias wie bisher
36+
#let black-code-box = _gibz_black_code_box
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#import "./base_box.typ": base-box
2+
3+
// A reusable "icon + content" box built on base_box
4+
#let icon-box(icon, content, style: (:)) = {
5+
base-box(
6+
[
7+
#grid(
8+
columns: (50pt, 1fr),
9+
align: (center + horizon, left + horizon),
10+
[
11+
#set text(size: 20pt)
12+
#pad(right: 15pt, bottom: 5pt, icon)
13+
],
14+
[#content],
15+
)
16+
],
17+
style: (
18+
fill: gray.lighten(85%),
19+
radius: 10pt,
20+
inset: 15pt,
21+
)
22+
+ style,
23+
)
24+
}

0 commit comments

Comments
 (0)