Skip to content
Merged
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
661 changes: 661 additions & 0 deletions packages/preview/simple-ntnu-report/0.1.1/LICENSE

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions packages/preview/simple-ntnu-report/0.1.1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Unoficcial template for reports at NTNU

## About
This is a small template for writing reports tailored to the most common needs at NTNU in Norway, the goal is to cover everything from exercises to specialization projects.
Note that many subjects have their own requirements for styling, this template is compatible with the requirements for TTK4101 in 2025 and 2026.

## Future plans
- It would be neat to add an appendix system at some point.
- I do not plan to expand the template to handle a full master thesis, the "nifty-ntnu-thesis" seems to solve this already.

## Configuration
The template takes the following arguments:
- length: Optional string, defaults to "short", can be short or long.
- watermark: Optional string, stamps a watermark across all pages.
- title: Required string.
- subtitle: Optional string.
- authors: List of dictionaries, each requires name, each may contain department, organization, location and email.
- group: Optional string, for when group numbers are needed.
- front-image: Optional image content for front page. Only works with long length.
- date: Optional timestamp, will override the current date on the front page.
- abstract: Optional content.
- appendices: Optional content.
- bibfile: Optional parsed bibfile on the form bibliography("path"), required for bibliography.
- bibstyle: Optional string, defaults to "institute-of-electrical-and-electronics-engineers". Many subjects require "american-psychological-association".
- language: Optional string, defaults to "bokmål". One of english, bokmål or nynorsk.
- column-number: Optional int, default 1.
- number-headings: Optional bool, default true. Determines if headings are numbered.
- show-toc: Optional bool, default true. Determines if table of content is printed, only relevant for long reports.
- show-figure-index: Optional bool, default false. Determines if list of figures is printed, only relevant for long reports.
- show-table-index: Optional bool, default false. Determines if list of indices is printed, only relevant for long reports.
- show-listings-index: Optional bool, default false. Determines if list of listings is printed, only relevant for long reports.

## Quality of life
In adition to the template function, this package allso supplies the `un` function, which formats units propperly with a tiny space and no cursive in math mode.
It is intentionally much more lightweight than packages such as **unify**.

The package supplies `<nonumber>`tag, headings and equations tagged with this will not get a number. They still appear in the table of content.

The package allso localizes number formats correctly, use the `num` function from the `zero` pacage imported wiht `#import "@preview/zero:0.5.0": num`.

The codly and codly-languages packages are used to format listings in a nice and readable way.

## Recommended packages
There are a lot of useful features in other packages that are not reimplemented or preconfigured in this package, here are some recommendations that might be useful for NTNU students:
- **subpar** is good for making subfigures, and should be compatible with this template.
- **wordometer** counts words, but is not preconfigured here since the specifics often vary from subject to subject.
- **meander** seams like a good package for non-standard layout requirements.
- **cetz** is good for drawing custom graphics, and is used by packages like **alchemist**, **commute** and **finite**. Remember that many tasks are easily solved with paint.
- **frame-it** creates nice frames for theorems, examples and similar.
- **physica** and **pavemat** solves most missing features in math typesetting.


## License
The boiler plate template located in the template folder is licensed under the MIT No Attribution license, the rest of this project is licensed under the GNU Affero General Public License v3.0 or later.

The logo of NTNU (located at template/figures/NTNU.svg) is owned by NTNU, guidelines for usage is located at https://i.ntnu.no/wiki/-/wiki/Norsk/Bruksregler+for+NTNU-logoen.
The unoficcial logo for ITK at NTNU (located at template/figures/ITK_logo.svg) is owned by Trond Andresen and distributed with permission, more information can be found at https://www.ntnu.no/itk/om/historie/itk-60/jubileumsmotiv.
337 changes: 337 additions & 0 deletions packages/preview/simple-ntnu-report/0.1.1/src/simple-ntnu-report.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
#import "@preview/zero:0.5.0": set-num
#import "@preview/swank-tex:0.1.0": *
#import "@preview/icu-datetime:0.2.0": fmt
#import "@preview/codly:1.3.0": *
#import "@preview/codly-languages:0.1.10": *


// Utility for formatting units in math
#let un(body) = $thin upright(body)$


// Appendix
// Thanks to the elsearticle template for the appendix implementation from which this is derived
#let appendix(supplement, body) = {
set heading(numbering: "A.1.", supplement: supplement)
// Reset heading counter
counter(heading).update(0)

// Equation numbering
let numbering-eq = (..n) => {
let h1 = counter(heading).get().first()
numbering("(A.1a)", h1, ..n)
}
set math.equation(numbering: numbering-eq)

// Figure, Table and Listing numbering
let numbering-fig = n => {
let h1 = counter(heading).get().first()
numbering("A.1", h1, n)
}
show figure.where(kind: image): set figure(numbering: numbering-fig)
show figure.where(kind: table): set figure(numbering: numbering-fig)
show figure.where(kind: raw): set figure(numbering: numbering-fig)

body
}


// Utility function for printing out authors
#let write-authors(
authors) = {
for i in range(calc.ceil(authors.len() / 3)) {
let end = calc.min((i + 1) * 3, authors.len())
let is-last = authors.len() == end
let slice = authors.slice(i * 3, end)
grid(
columns: slice.len() * (1fr,),
gutter: 12pt,
..slice.map(author => align(center, {
text(size: 11pt, author.name)
if "department" in author [
\ #emph(author.department)
]
if "organization" in author [
\ #emph(author.organization)
]
if "location" in author [
\ #author.location
]
if "email" in author {
if type(author.email) == str [
\ #link("mailto:" + author.email)
] else [
\ #author.email
]
}
}))
)
if not is-last {
v(16pt, weak: true)
}
}
}


// The project function defines how your document looks.
// It takes your content and some metadata and formats it.
#let ntnu-report(
length: "short", // One of: short, long
watermark: none, // Any string, such as "DRAFT"
title: none, // Required
subtitle: none, // Optional
authors: (), // Requires: name. Optional: department, organization, location, email
group: none, // Optional, for use in subjects divied into groups
front-image: none, // Image content for front page, only works if length is long
date: datetime.today(), // Required, all reports should have a date
abstract: none, // Optional content for abstract
appendices: none, // Optional content for appendices
bibfile: none, // Optional bibliography content, highly recommended
bibstyle: "institute-of-electrical-and-electronics-engineers", // For example "american-psychological-association" or "institute-of-electrical-and-electronics-engineers"
language: "bokmål", // One of: english, bokmål, nynorsk
column-number: 1, // Should be 1 or 2
number-headings: true, // Determines if headings are numbered
show-toc: true, // Determines if table of content is printed, only relevant for long reports
show-figure-index: false, // Determines if list of figures is printed, only relevant for long reports
show-table-index: false, // Determines if list of indices is printed, only relevant for long reports
show-listings-index: false, // Determines if list of listings is printed, only relevant for long reports
body) = {


// Basic sanity checks
assert(title != none, message: "\"title\" is an obligatory field for this template.")
assert(length in ("short", "long"), message: "Report length " + length + " is not implemented.")

// Set the document's basic properties.
set document(author: authors.map(a => a.name), title: title, date: date)
set text(font: "New Computer Modern", size: 11pt)


// Formatting
set enum(numbering: "1)a)i)")

set math.equation(numbering: "(1)")
show math.equation: set text(weight: 400)
set math.mat(delim: "[")
set math.vec(delim: "[")

let heading-numbering = "1.1"
if not number-headings { heading-numbering = none }
set heading(numbering: heading-numbering)
show selector(<nonumber>): set heading(numbering: none)
show selector(<nonumber>): set math.equation(numbering: none)

set bibliography(style: bibstyle)


// Watermark
set page(foreground: rotate(315deg, text(80pt, fill: rgb("FF000060"))[*#watermark*])) if watermark != none


// Quality of life defaults
show "LaTeX": LaTeX


// Tables & figures
show figure.where(kind: table): set figure.caption(position: top)
show figure.caption: set align(start)
show figure.caption.where(kind: table): set align(center)


// Listings
show: codly-init.with()
codly(languages: codly-languages)


// Set language
set text(lang: "en") if language == "english"
set text(lang: "no") if language in ("bokmål", "nynorsk")

let date-text
let abstract-heading
let heading-supplement
let appendix-supplement
let group-prefix
let decimal-separator
let bib-title
let toc-title
let lot-title
let lof-title
let lol-title
let figure-supplement
let table-supplement
let listings-supplement
if language == "english" {
date-text = fmt(date, locale: "en", length: "long")
abstract-heading = "Abstract"
heading-supplement = "Section"
appendix-supplement = "Appendix"
group-prefix = "Group"
decimal-separator = "."
bib-title = "References"
toc-title = "Contents"
lot-title = "List of Tables"
lof-title = "List of Figures"
lol-title = "List of Listings"
figure-supplement = "Figure"
table-supplement = "Table"
listings-supplement = "Listing"
} else if language == "bokmål" {
date-text = fmt(date, locale: "no", length: "long")
abstract-heading = "Sammendrag"
heading-supplement = "Avsnitt"
appendix-supplement = "Appendiks"
group-prefix = "Gruppe"
decimal-separator = ","
bib-title = "Kilder"
toc-title = "Innholdsfortegnelse"
lot-title = "Tabelliste"
lof-title = "Figurliste"
lol-title = "Kodeliste"
figure-supplement = "Figur"
table-supplement = "Tabell"
listings-supplement = "Kodeblokk"
} else if language == "nynorsk" {
date-text = fmt(date, locale: "no", length: "long")
abstract-heading = "Samandrag"
heading-supplement = "Avsnitt"
appendix-supplement = "Appendiks"
group-prefix = "Gruppe"
decimal-separator = ","
bib-title = "Kilder"
toc-title = "Innhaldsliste"
lot-title = "Tabelliste"
lof-title = "Figurliste"
lol-title = "Kodeliste"
figure-supplement = "Figur"
table-supplement = "Tabell"
listings-supplement = "Kodeblokk"
} else { assert(false, message: "Language " + language + " is not supported by this template.") }

set-num(decimal-separator: decimal-separator)
set bibliography(title: bib-title)
show figure.where(kind: image): set figure(supplement: figure-supplement)
show figure.where(kind: table): set figure(supplement: table-supplement)
show figure.where(kind: raw): set figure(supplement: listings-supplement)

set heading(supplement: heading-supplement)


// DOCUMENT CONTENT //



// Display document
// Long report
if length == "long"{
v(2cm)
align(center)[
#text(weight: 700, 1.75em, title)
#if subtitle != none {text(weight: 600, 1.25em, linebreak() + subtitle)}
#if group != none {
if length == "long" {v(0.8cm)}
[*#group-prefix #group*]
}
]

v(0.8cm, weak: true)

write-authors(authors)

v(0.8cm, weak: true)
align(center)[*#date-text*]

v(1fr)
align(center, front-image)


v(1fr)
if abstract != none {
set text(9pt, weight: 700)
align(center)[= _#{abstract-heading}_ <nonumber>]
abstract
}

set page(numbering: "I", number-align: center)
counter(page).update(1)
if show-toc {
outline(title: toc-title)
pagebreak()
}
if show-figure-index {
outline(title: lof-title, target: figure.where(kind: image))
pagebreak()
}
if show-table-index {
outline(title: lot-title, target: figure.where(kind: table))
pagebreak()
}
if show-listings-index {
outline(title: lol-title, target: figure.where(kind: raw))
pagebreak()
}


set page(numbering: "1", number-align: center)
counter(page).update(1)

set par(justify: true)
set page(columns: column-number)

body

if bibfile != none {
set page(columns: 1)
bibfile
}

pagebreak()
if appendices != none { show: appendix(appendix-supplement, appendices) }

}
// Short report
else if length == "short"{
set page(numbering: "1", number-align: center)
set page(columns: column-number)

place(top + center, scope: "parent", float: true, {
v(0.8cm, weak: true)

// Title row.
if length == "long" {v(2cm)}
text(weight: 700, 1.75em, title)
if subtitle != none {text(weight: 600, 1.25em, linebreak() + subtitle)}
if group != none {
v(0.75cm)
[*#group-prefix #group*]
}

v(0.8cm, weak: true)

// Author information.set page(numbering: "1", number-align: center)
write-authors(authors)

v(0.8cm, weak: true)
align(center)[*#date-text*]
})

set par(justify: true)

if abstract != none {
if column-number == 1 {line(length: 100%)}
set text(9pt, weight: 700)
[= #h(1em) _#{abstract-heading}_ <nonumber>]
abstract
if column-number == 1 {line(length: 100%)}
}

body

if bibfile != none {
bibfile
}

if appendices != none { show: appendix(appendix-supplement, appendices) }

}
}
Loading