Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 50 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ For protocols and essays see [subtypes module](#subtypes).
)
```

Multi-author example:

```typ
#show: project.with(
title: "Lorem ipsum dolor sit",
authors: (
(name: "John Doe", email: "john@example.org"),
(name: "Jane Doe", email: "jane@example.org"),
),
)
```

### Documentation

| `project` | |
Expand Down Expand Up @@ -92,6 +104,7 @@ For protocols and essays see [subtypes module](#subtypes).
| `semester` | optional, content, default: `none` |
| `docent` | optional, content, default: `none` |
| `author` | optional, content, default: `none` |
| `authors` | optional, array, default: `none`, multi-author input (items can be `name` content or dictionaries with `name`, optional `email`, `student-number`, `address`) |
| `date` | optional, datetime or content, default: `datetime.today()` |
| `date-format` | optional, function, default: `(date) => if type(date) == type(datetime.today()) { date.display("[day].[month].[year]") } else { date }` |
| `header-gutter` | optional, length, default: `20%`, overwrite header gutter |
Expand Down Expand Up @@ -213,6 +226,18 @@ _Note:_ The template generates a German statement of authorship as the last page
)
```

Multi-author example:

```typ
#show: seminar-paper.project.with(
title: "Die Intensionalität von dass-Sätzen",
authors: (
(name: "Max Muster", email: "max@uni-musterstadt.uni", student-number: "0123456789"),
(name: "Erika Muster", email: "erika@uni-musterstadt.uni", student-number: "1234567890"),
),
)
```

### Documentation

| `project` | |
Expand All @@ -228,6 +253,7 @@ _Note:_ The template generates a German statement of authorship as the last page
| `semester` | optional, content, default: `"SEMESTER"` |
| `docent` | optional, content, default: `"DOCENT"` |
| `author` | optional, content, default: `"AUTHOR"` |
| `authors` | optional, array, default: `none`, multi-author input (items can be `name` content or dictionaries with `name`, optional `email`, `student-number`, `address`) |
| `student-number` | optional, content, default: `none` |
| `email` | optional, content, default: `"EMAIL"` |
| `address` | optional, content, default: `"ADDRESS"` |
Expand Down Expand Up @@ -310,6 +336,18 @@ _Note:_ The template generates a German statement of authorship as the last page
)
```

Multi-author example:

```typ
#show: slides.with(
title: [Organisatorisches und Einführung in die Logik],
authors: (
(name: "Tristan Pieper", email: "tristan.pieper@uni-rostock.de"),
(name: "Juan Pablo Sierra Useche", email: "juan.pablo@niuitmo.ru"),
),
)
```

### Documentation

| `slides` | |
Expand All @@ -319,7 +357,8 @@ _Note:_ The template generates a German statement of authorship as the last page
| `title` | optional, content, default: `none`, title of the presentation |
| `topics` | optional, array, default: `()`, topics of the presentation |
| `author` | optional, content, default: `none`, author |
| `email` | optional, content, default: `none`, author's email |
| `authors` | optional, array, default: `none`, multi-author input (items can be `name` content or dictionaries with `name`, optional `email`, `student-number`, `address`) |
| `email` | optional, content, default: `none`, legacy single-author email |
| `head-replacement` | optional, content, default: `none`, replace head on title slide with given content |
| `title-replacement` | optional, content, default: `none`, replace title below head on title slide with given content |
| `footer` | optional, content, default: `none`, replace footer on slides with given content |
Expand Down Expand Up @@ -408,7 +447,10 @@ Essay:
seminar: [Seminar],
semester: [Semester],
docent: [Docent],
author: [Author],
authors: (
(name: [Author 1], email: "author1@example.org"),
(name: [Author 2], email: "author2@example.org"),
),
date: [1#super[st] January 1970],
)
```
Expand All @@ -425,7 +467,10 @@ Protocol:
seminar: [Seminar],
semester: [Semester],
docent: [Docent],
author: [Author],
authors: (
(name: [Author 1], email: "author1@example.org"),
(name: [Author 2], email: "author2@example.org"),
),
date: [1#super[st] January 1970],
)
```
Expand All @@ -443,6 +488,7 @@ The base layout of these functions is provided by `exercise.project`.
| `semester` | optional, content, default: `[#todo[Semester]]` |
| `docent` | optional, content, default: `[#todo[Docent]]` |
| `author` | optional, content, default: `[#todo[Author]]` |
| `authors` | optional, array, default: `none`, multi-author input (items can be `name` content or dictionaries with `name`, optional `email`, `student-number`, `address`) |
| `date` | optional, content, default: `[#todo[Date]]` |
| `body` | content, document content |

Expand All @@ -455,6 +501,7 @@ The base layout of these functions is provided by `exercise.project`.
| `semester` | optional, content, default: `[#todo[Semester]]` |
| `docent` | optional, content, default: `[#todo[Docent]]` |
| `author` | optional, content, default: `[#todo[Author]]` |
| `authors` | optional, array, default: `none`, multi-author input (items can be `name` content or dictionaries with `name`, optional `email`, `student-number`, `address`) |
| `date` | optional, content, default: `[#todo[Date]]` |
| `body` | content, document content |

Expand Down
Binary file added examples/exercise02-multi-author.pdf
Binary file not shown.
116 changes: 116 additions & 0 deletions examples/exercise02-multi-author.typ
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we already have enough example files and the examples don't need to display every possible version of a document. So I think it'd be best if no new example files are added.

Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#import "../src/exercise.typ": project, task, subtask

#set text(lang: "GB")

#show: project.with(
no: 4,
type: [Worksheet],
title: [Secure Systems Practice Sheet],
suffix-title: [Input Validation and Policy Checks],
show-outline: true,
abstract: [
This is a complete example configuration for the `exercise.project` template
with fake metadata and multi-author input.
],
document-title: [Systems Security Worksheet],

show-hints: false,
show-solutions: false,

show-namefield: true,
namefield: none,
show-timefield: true,
timefield: (time) => [Time budget: #time min],
max-time: 90,

show-lines: true,
show-point-distribution-in-tasks: true,
show-point-distribution-in-solutions: false,

solutions-as-matrix: false,
show-solution-matrix-comment-field: false,
solution-matrix-comment-field-value: [*Reviewer note:* #v(0.4cm)],

university: [Northbridge Technical University],
faculty: [Faculty of Applied Computing],
institute: [Institute for Systems Engineering],
seminar: [Secure Software Seminar],
semester: [Spring 2026],
docent: [Dr. Avery Morgan],

author: [Legacy Single Author],
authors: (
(name: "Alex Rowan", email: "alex.rowan@example.edu"),
(name: "Samira Hale", email: "samira.hale@example.edu"),
),

date: datetime(year: 2026, month: 2, day: 19),
date-format: (d) => if type(d) == type(datetime.today()) {
d.display("[day].[month].[year]")
} else {
d
},

header: none,
header-gutter: 18%,
header-right: none,
header-middle: none,
header-left: none,
show-header-line: true,

footer: none,
footer-right: none,
footer-middle: none,
footer-left: none,
show-footer-line: true,

task-type: [Task],
extra-task-type: [Bonus task],
box-task-title: [Task],
box-hint-title: [Hint],
box-solution-title: [Suggested solution],
box-definition-title: [Definition],
box-notice-title: [Notice],
box-example-title: [Example],

hint-type: [Hint],
hints-title: [Hints],
solution-type: [Suggested solution],
solutions-title: [Suggested solutions],

solution-matrix-task-header: [Task],
solution-matrix-achieved-points-header: [Points],
distribution-header-point-value: [Points],
distribution-header-point-grade: [Grade],

message: (points-sum, extrapoints-sum) => [
Total available: #points-sum + #extrapoints-sum points.
],
grade-scale: (
([excellent], 0.9),
([good], 0.75),
([pass], 0.6),
([fail], 0.49),
),

page-margins: (top: 5.2cm, bottom: 2.8cm, left: 2.5cm, right: 2.5cm),
text-font: ("Atkinson Hyperlegible",),
math-font: ("New Computer Modern Math",),
fontsize: 11pt,
show-todolist: false,
)

= Multiple-Choice
#task(points: 4, [Input Validation], [
Select the most robust validation strategy for untrusted input.
], [])

= Short Answer
#task(points: 6, lines: 4, [Authorization], [
Explain why authorization checks should be performed server-side.
], [])

= Extra
#task(extra: true, points: 3, [Bonus], [
Give one real-world example of policy drift.
], [])
Binary file added examples/seminar-paper02-multi-author.pdf
Binary file not shown.
79 changes: 79 additions & 0 deletions examples/seminar-paper02-multi-author.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#import "../src/seminar-paper.typ" as seminar-paper

#set text(lang: "GB")

#show: seminar-paper.project.with(
title: [A Comparative Survey of Sandbox Security Models],
subtitle: [Template showcase with fake metadata],

submit-to: [Submitted to],
submit-by: [Submitted by],

university: [Northbridge Technical University],
faculty: [Faculty of Applied Computing],
institute: [Institute for Systems Engineering],
seminar: [Secure Software Seminar],
semester: [Spring 2026],
docent: [Dr. Avery Morgan],

author: "Legacy Single Author",
authors: (
(
name: "Alex Rowan",
email: "alex.rowan@example.edu",
student-number: "NTU-10482",
address: [11 Cedar Lane, Brookfield, MA 01010],
),
(
name: "Samira Hale",
email: "samira.hale@example.edu",
student-number: "NTU-10617",
address: [92 Pine Street, Lakeview, MA 01011],
),
),
student-number: "LEGACY-0000",
email: "legacy.author@example.edu",
address: [Legacy Address, Legacy City],

title-page-part: none,
title-page-part-submit-date: none,
title-page-part-submit-to: none,
title-page-part-submit-by: none,

sentence-supplement: [Example],

date: datetime(year: 2026, month: 2, day: 19),
date-format: (d) => if type(d) == type(datetime.today()) {
d.display("[month repr:long] [day], [year]")
} else {
d
},

header: none,
header-left: none,
header-middle: none,
header-right: none,
show-header-line: true,

footer: none,
footer-left: none,
footer-middle: none,
footer-right: none,
show-footer-line: true,

show-outline: true,
show-todolist: true,
show-declaration-of-independent-work: true,

page-margins: (top: 2.6cm, bottom: 2.6cm, left: 2.6cm, right: 3.8cm),

fontsize: 11pt,
)

= Scope
This file is a full-feature example for `seminar-paper.project` using fake names and sample metadata.

[Replace with your institution data.]

= Notes
The default header uses compact multi-author formatting (`first author, et al.`) when `authors` has more than one entry.
Binary file added examples/slides02-multi-author.pdf
Binary file not shown.
74 changes: 74 additions & 0 deletions examples/slides02-multi-author.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#import "../src/slides.typ": slides, slide, focus-slide

#set text(lang: "GB")

#show: slides.with(
no: 7,
series: [Systems Security Colloquium],
title: [Policy-Driven Access Control],
topics: ([Motivation], [Architecture], [Threat Model], [Conclusions]),

head-replacement: none,
title-replacement: none,
footer: none,

author: [Legacy Single Author],
authors: (
(name: "Alex Rowan", email: "alex.rowan@example.edu"),
(name: "Samira Hale", email: "samira.hale@example.edu"),
),
email: "legacy.author@example.edu",

page-numbering: (n, total) => {
text(size: 0.75em, strong[#n.first()])
text(size: 0.5em, [ \/ #total.first()])
},

show-title-slide: true,
show-author: true,
show-semester: true,
show-date: true,
show-outline: true,
show-todolist: false,
show-footer: true,
show-page-numbers: true,

box-task-title: [Task],
box-hint-title: [Hint],
box-solution-title: [Solution],
box-definition-title: [Definition],
box-notice-title: [Notice],
box-example-title: [Example],
sentence-supplement: [Example],

outline-title-text: [Outline],
outline-depth: 2,
heading-numbering: none,

fontsize: 24pt,
text-font: ("Atkinson Hyperlegible",),
math-font: ("New Computer Modern Math",),

date: datetime(year: 2026, month: 2, day: 19),
date-format: (d) => if type(d) == type(datetime.today()) {
[#d.display("[month repr:short] [day], [year]")]
} else {
d
},
)

#slide[
= Why This Matters
Authorization bugs often appear when policy and implementation drift over time.
]

#slide[
= Model
- Inputs are untrusted.
- Policy decisions are centralized.
- Enforcement is explicit at each boundary.
]

#focus-slide[
Defense-in-depth beats single-point trust.
]
Loading