Skip to content

Commit e4b7ef0

Browse files
authored
sheetstorm:0.3.3 (#3112)
1 parent 100b59b commit e4b7ef0

File tree

16 files changed

+702
-0
lines changed

16 files changed

+702
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Rasmus Buurman
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# sheetstorm
2+
A Typst template for university exercise sheets.
3+
4+
## Quick Start
5+
6+
### Template CLI
7+
```sh
8+
typst init @preview/sheetstorm
9+
```
10+
11+
### Manual
12+
```typst
13+
#import "@preview/sheetstorm:0.3.3"
14+
15+
#show: sheetstorm.setup.with(
16+
course: smallcaps[A very interesting course 101],
17+
title: "Assignment 42",
18+
authors: (
19+
(name: "John Doe", id: 123456),
20+
(name: "Erika Mustermann", id: 654321),
21+
),
22+
23+
info-box-enabled: true,
24+
)
25+
```
26+
27+
## Preview
28+
![Preview of the sheetstorm template](./thumbnail.png)
29+
30+
There are more [examples](./examples).
31+
32+
## Development
33+
For local development, install the package to the `@local` namespace.
34+
35+
This is very easy with a tool like [typship](https://github.com/sjfhsjfh/typship):
36+
```sh
37+
typship install local
38+
```
39+
40+
Then, you can use it in a Typst file:
41+
```typst
42+
#import "@local/sheetstorm:0.3.3"
43+
```
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#import "@preview/sheetstorm:0.3.3" as sheetstorm: task
2+
3+
#set text(lang: "de")
4+
5+
#show: sheetstorm.setup.with(
6+
title: "Deutsches Beispiel",
7+
authors: "Max Mustermann",
8+
)
9+
10+
#task(points: 42)[
11+
Es ist sehr einfach, das Template für deutschsprachige Dokumente zu benutzen.
12+
Es muss lediglich die Sprache umgestellt werden:
13+
```typst
14+
#set text(lang: "de")
15+
```
16+
]
17+
18+
#task(lorem(1000))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#import "@preview/sheetstorm:0.3.3" as sheetstorm: task
2+
3+
#show: sheetstorm.setup.with(
4+
title: "Minimal Example",
5+
authors: "John Doe",
6+
)
7+
8+
#task[
9+
This is how the template looks with no/minimal configuration.
10+
]
11+
12+
#task(lorem(1000))
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#import "@preview/sheetstorm:0.3.3" as sheetstorm: task
2+
3+
#show: sheetstorm.setup.with(
4+
title: "Task Configuration Example",
5+
authors: "John Doe",
6+
initial-task-number: 3,
7+
)
8+
9+
#let my-custom-numbering-pattern(depth) = {
10+
if depth == 1 { "i)" }
11+
else if depth == 2 { "1." }
12+
else { "(a)" }
13+
}
14+
15+
// You can customize the task command like so:
16+
#let task = task.with(
17+
counter-show: false,
18+
subtask-numbering: true,
19+
subtask-numbering-pattern: my-custom-numbering-pattern,
20+
)
21+
22+
#task(name: "Unnumbered Task")[
23+
Now, the task numbers are disabled for the whole document.
24+
25+
Also, we have our custom numbering pattern enabled by default:
26+
+ Hi
27+
+ Hey
28+
+ Ho
29+
]
30+
31+
#task(counter-show: true)[Unless you explicitely enable the counter.]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#import "i18n.typ"
2+
#import "util.typ": is-some
3+
4+
/// Helper function that takes an array of content and puts it together as a block
5+
#let header-section(xs) = box(
6+
for i in xs.filter(is-some).intersperse(linebreak()) { i }
7+
)
8+
9+
/// Create the contents of the header
10+
#let header-content(
11+
course: none,
12+
title: none,
13+
authors: none,
14+
tutor: none,
15+
16+
date: datetime.today(),
17+
date-format: none,
18+
19+
show-title-on-first-page: false,
20+
21+
extra-left: none,
22+
extra-center: none,
23+
extra-right: none,
24+
) = {
25+
let header = grid(
26+
columns: (1fr, 3fr, 1fr),
27+
align: (left, center, right),
28+
rows: (auto, auto),
29+
row-gutter: 0.5em,
30+
31+
// left
32+
header-section((
33+
if date != none {
34+
context date.display(if date-format != none { date-format } else { i18n.default-date() })
35+
},
36+
if date-format != none { datetime.today().display(date-format) },
37+
if tutor != none [Tutor: #tutor],
38+
extra-left,
39+
)),
40+
41+
// center
42+
header-section((
43+
course,
44+
if show-title-on-first-page { title } else {
45+
context {
46+
let n = counter(page).get().first()
47+
if n != 1 { title }
48+
}
49+
},
50+
extra-center,
51+
)),
52+
53+
// right
54+
header-section(authors + (extra-right,)),
55+
56+
grid.hline(),
57+
)
58+
59+
return pad(top: 0.8cm, bottom: 1cm, header)
60+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#let default-date() = {
2+
if text.lang == "de" { "[day].[month].[year]" }
3+
else { "[day] [month repr:long] [year]" }
4+
}
5+
6+
#let task() = {
7+
if text.lang == "de" { "Aufgabe" }
8+
else { "Task" }
9+
}
10+
11+
#let points() = {
12+
if text.lang == "de" { "Punkte" }
13+
else { "Points" }
14+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#import "setup.typ": setup
2+
#import "task.typ": task
3+
#import "widgets.typ" as widgets
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#let default-numbering-pattern(depth) = {
2+
if calc.rem(depth, 3) == 1 { "1." }
3+
else if calc.rem(depth, 3) == 2 { "a." }
4+
else { "i." }
5+
}
6+
7+
#let subtask-numbering-pattern(depth) = {
8+
if depth == 1 { "(a)" }
9+
else if depth > 1 and calc.rem(depth, 2) == 0 { "1." }
10+
else { "i." }
11+
}
12+
13+
#let apply-numbering-pattern(
14+
numbering-pattern: default-numbering-pattern,
15+
..nums,
16+
) = {
17+
let nums = nums.pos()
18+
numbering(numbering-pattern(nums.len()), nums.last())
19+
}

0 commit comments

Comments
 (0)