From 4fd088ce3fc87c54e92ce7a383b1535890e2933f Mon Sep 17 00:00:00 2001 From: servostar Date: Mon, 8 Jul 2024 21:50:13 +0200 Subject: [PATCH 01/14] added: format script --- run-fmt.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 run-fmt.sh diff --git a/run-fmt.sh b/run-fmt.sh new file mode 100755 index 0000000..09bf12f --- /dev/null +++ b/run-fmt.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +function format() { + # format file + # typstyle --format $1 + + if [ -z "$1" ]; then + return + fi + + local wd=$(dirname $(realpath "$1")) + + echo "processing file $1..." + typstyle "$2" "$1" > /dev/null + if [ $? -eq 1 ]; then + echo "failed format validation: $1" + exit 1 + fi + + local imports=$(rg "#import \"([a-z0-9/\-]+\.typ)\"" -Nor '$1' "$1") + + # format all included files + while IFS= read -r line; do + if [ -z "$line" ]; then + continue + fi + format "$wd/$line" "$2" + done <<< "$imports" +} + +case $1 in + "--format") + format "$2" "--inplace" + ;; + "--check") + format "$2" "--check" + ;; + *) + echo "unknown option: $1" + exit 1 + ;; +esac \ No newline at end of file From d648d5121c43d2a3651d8a0801b9c9cbadd45c04 Mon Sep 17 00:00:00 2001 From: servostar Date: Mon, 8 Jul 2024 21:57:23 +0200 Subject: [PATCH 02/14] changed: formatted source files --- src/branding.typ | 10 +-- src/conf.typ | 26 +++---- src/glossarium.typ | 147 ++++++++++++++++++++++------------------ src/glossary.typ | 116 ++++++++++++++++--------------- src/lib.typ | 39 ++++++----- src/pages/abstract.typ | 2 +- src/pages/outline.typ | 61 +++++++++-------- src/pages/titlepage.typ | 46 ++++--------- src/style.typ | 72 ++++++++++++++------ 9 files changed, 280 insertions(+), 239 deletions(-) diff --git a/src/branding.typ b/src/branding.typ index c80ca6c..079a875 100644 --- a/src/branding.typ +++ b/src/branding.typ @@ -3,16 +3,16 @@ // https://brand.abb/portal/en/branding-principles/basic-brand-elements/color // ABB branding colors -#let ABB-RED = cmyk(0%, 100%, 95%, 0%) -#let ABB-BLACK = cmyk(0%, 0%, 0%, 100%) +#let ABB-RED = cmyk(0%, 100%, 95%, 0%) +#let ABB-BLACK = cmyk(0%, 0%, 0%, 100%) #let ABB-GRAY-01 = cmyk(0%, 0%, 0%, 90%) #let ABB-GRAY-02 = cmyk(0%, 0%, 0%, 75%) #let ABB-GRAY-03 = cmyk(0%, 0%, 0%, 55%) #let ABB-GRAY-04 = cmyk(0%, 0%, 0%, 35%) #let ABB-GRAY-05 = cmyk(0%, 0%, 0%, 15%) #let ABB-GRAY-06 = cmyk(0%, 0%, 0%, 5%) -#let ABB-WHITE = cmyk(0%, 0%, 0%, 0%) +#let ABB-WHITE = cmyk(0%, 0%, 0%, 0%) // ABB branding functinal colors -#let ABB-BLUE = cmyk(100%, 53%, 2%, 16%) -#let ABB-GREEN = cmyk(91%, 4%, 100%, 25%) +#let ABB-BLUE = cmyk(100%, 53%, 2%, 16%) +#let ABB-GREEN = cmyk(91%, 4%, 100%, 25%) #let ABB-YELLOW = cmyk(0%, 9%, 100%, 0%) diff --git a/src/conf.typ b/src/conf.typ index cfc76ed..ae2ba05 100644 --- a/src/conf.typ +++ b/src/conf.typ @@ -53,9 +53,9 @@ page: ( format: "a4", margin: ( - left: 3cm, - right: 2.5cm, - top: 2.5cm, + left: 3cm, + right: 2.5cm, + top: 2.5cm, bottom: 2.5cm)), text: ( size: 12pt, @@ -81,20 +81,20 @@ } for (key, val) in base { - if key in update { - let update_val = update.at(key) + if key in update { + let update_val = update.at(key) - if type(val) == dictionary and type(update_val) == dictionary { - base.insert(key, deep-insert-checked(val, update_val)) - } else if val == none or type(val) == type(update_val) { - base.insert(key, update_val) - } else { - panic("missmatched dictionary entry `" + key + "` type: expected `" + type(val) + "` got `" + type(update_val) + "`") - } + if type(val) == dictionary and type(update_val) == dictionary { + base.insert(key, deep-insert-checked(val, update_val)) + } else if val == none or type(val) == type(update_val) { + base.insert(key, update_val) } else { - base.insert(key, val) + panic("missmatched dictionary entry `" + key + "` type: expected `" + type(val) + "` got `" + type(update_val) + "`") } + } else { + base.insert(key, val) } + } return base } diff --git a/src/glossarium.typ b/src/glossarium.typ index 5fb8bae..143e12d 100644 --- a/src/glossarium.typ +++ b/src/glossarium.typ @@ -30,7 +30,10 @@ SOFTWARE.*/ #let __query_labels_with_key(loc, key, before: false) = { if before { query( - selector(label(__glossary_label_prefix + key)).before(loc, inclusive: false), + selector(label(__glossary_label_prefix + key)).before( + loc, + inclusive: false, + ), loc, ) } else { @@ -40,7 +43,7 @@ SOFTWARE.*/ // key not found error #let __not-found-panic-error-msg(key) = { - __glossarium_error_prefix+"key '"+key+"' not found" + __glossarium_error_prefix + "key '" + key + "' not found" } // Reference a term @@ -49,20 +52,25 @@ SOFTWARE.*/ let __glossary_entries = __glossary_entries.final(here()) if key in __glossary_entries { let entry = __glossary_entries.at(key) - + let gloss = __query_labels_with_key(here(), key, before: true) - + let is_first = gloss == () let entlong = entry.at("long", default: "") let textLink = if display != none { [#display] - } else if (is_first or long == true) and entlong != [] and entlong != "" and long != false { + } else if ( + is_first or long == true + ) and entlong != [] and entlong != "" and long != false { [#entlong (#entry.short#suffix)] } else { [#entry.short#suffix] } - - [#link(label(entry.key), textLink)#label(__glossary_label_prefix + entry.key)] + + [#link( + label(entry.key), + textLink, + )#label(__glossary_label_prefix + entry.key)] } else { panic(__not-found-panic-error-msg(key)) } @@ -76,14 +84,14 @@ SOFTWARE.*/ let __glossary_entries = __glossary_entries.final(here()) if key in __glossary_entries { let entry = __glossary_entries.at(key) - + let gloss = __query_labels_with_key(here(), key, before: true) - + let is_first = gloss == () - let entlongplural = entry.at("longplural", default: ""); + let entlongplural = entry.at("longplural", default: "") let entlong = if entlongplural == [] or entlongplural == "" { // if the entry long plural is not provided, then fallback to adding 's' suffix - let entlong = entry.at("long", default: ""); + let entlong = entry.at("long", default: "") if entlong != [] and entlong != "" { [#entlong#suffix] } else { @@ -92,21 +100,26 @@ SOFTWARE.*/ } else { [#entlongplural] } - - let entplural = entry.at("plural", default: ""); + + let entplural = entry.at("plural", default: "") let short = if entplural == [] or entplural == "" { [#entry.short#suffix] } else { [#entplural] } - - let textLink = if (is_first or long == true) and entlong != [] and entlong != "" and long != false { + + let textLink = if ( + is_first or long == true + ) and entlong != [] and entlong != "" and long != false { [#entlong (#short)] } else { [#short] } - - [#link(label(entry.key), textLink)#label(__glossary_label_prefix + entry.key)] + + [#link( + label(entry.key), + textLink, + )#label(__glossary_label_prefix + entry.key)] } else { panic(__not-found-panic-error-msg(key)) } @@ -152,69 +165,73 @@ SOFTWARE.*/ for entry in entry_list { x.insert(entry.key, entry) } - + x }) let groups = entries.map(x => x.at("group")).dedup() - + for group in groups.sorted() { if group != "" [#heading(group, level: 1, outlined: false) ] for entry in entries.sorted(key: x => x.key) { if entry.group == group { [ #show figure.where(kind: __glossarium_figure): it => it.caption - #figure( - supplement: "", - kind: __glossarium_figure, - numbering: none, - caption: { - context { - let term_references = __query_labels_with_key(here(), entry.key) - if term_references.len() != 0 or show-all { - let desc = entry.at("desc", default: "") - let long = entry.at("long", default: "") - let hasLong = long != "" and long != [] - let hasDesc = desc != "" and desc != [] - grid( - columns: 2, - column-gutter: 1em, - text(weight: "bold", entry.short), - { - if hasLong { - text(weight: "bold", entry.long) - } - if hasLong and hasDesc [:] - if hasDesc [ #desc ] else [. ] - if disable-back-references != true { - term_references.map(x => x.location()).sorted(key: x => x.page()).fold( - (values: (), pages: ()), - ((values, pages), x) => if pages.contains(x.page()) { - (values: values, pages: pages) - } else { - values.push(x) - pages.push(x.page()) - (values: values, pages: pages) - }, - ).values.map(x => { - let page-numbering = x.page-numbering(); - if page-numbering == none { - page-numbering = "1" - } - link(x)[#numbering(page-numbering, ..counter(page).at(x))] - } - ).join(", ") - } + #figure( + supplement: "", + kind: __glossarium_figure, + numbering: none, + caption: { + context { + let term_references = __query_labels_with_key(here(), entry.key) + if term_references.len() != 0 or show-all { + let desc = entry.at("desc", default: "") + let long = entry.at("long", default: "") + let hasLong = long != "" and long != [] + let hasDesc = desc != "" and desc != [] + grid( + columns: 2, + column-gutter: 1em, + text(weight: "bold", entry.short), + { + if hasLong { + text(weight: "bold", entry.long) } - ) - } + if hasLong and hasDesc [:] + if hasDesc [ #desc ] else [. ] + if disable-back-references != true { + term_references.map(x => x.location()).sorted(key: x => x.page()).fold( + (values: (), pages: ()), + ((values, pages), x) => if pages.contains(x.page()) { + (values: values, pages: pages) + } else { + values.push(x) + pages.push(x.page()) + (values: values, pages: pages) + }, + ).values.map(x => { + let page-numbering = x.page-numbering() + if page-numbering == none { + page-numbering = "1" + } + link(x)[#numbering( + page-numbering, + ..counter(page).at(x), + )] + }).join(", ") + } + }, + ) } - }, - )[] #label(entry.key) + } + }, + )[] #label(entry.key) #parbreak() ] } } - if enable-group-pagebreak { pagebreak(weak: true) } + if enable-group-pagebreak { + pagebreak(weak: true) + } } }; \ No newline at end of file diff --git a/src/glossary.typ b/src/glossary.typ index 3fb0aef..4a9555f 100644 --- a/src/glossary.typ +++ b/src/glossary.typ @@ -9,66 +9,72 @@ #let glossary(entries) = { + assert( + type(entries) == dictionary, + message: "The glossary is not a dictionary", + ) + + for (k, v) in entries.pairs() { assert( - type(entries) == dictionary, - message: "The glossary is not a dictionary", + type(v) == dictionary, + message: "The glossary entry `" + k + "` is not a dictionary", ) - for (k, v) in entries.pairs() { + for key in v.keys() { assert( - type(v) == dictionary, - message: "The glossary entry `" + k + "` is not a dictionary") - - for key in v.keys() { - assert( - key in ("short", "long", "desc", "group"), - message: "Found unexpected key `" + key + "` in glossary entry `" + k) - } - - assert( - type(v.short) == str, - message: "The short form of glossary entry `" + k + "` is not a string") - - if "long" in v { - assert( - type(v.long) == str, - message: "The long form of glossary entry `" + k + "` is not a string") - } - - if "desc" in v { - assert( - type(v.desc) == str, - message: "The description of glossary entry `" + k + "` is not a string") - } - - if "group" in v { - assert( - type(v.group) == str, - message: "The optional group of glossary entry `" + k + "` is not a string") - } else { - let group = if "long" in v { - if (context text.lang) == "de" { - "Akronyme" - } else { - "Acronyms" - } - } else { - if (context text.lang) == "de" { - "Begriffe" - } else { - "Terms" - } - } - - entries.at(k).group = group - } + key in ("short", "long", "desc", "group"), + message: "Found unexpected key `" + key + "` in glossary entry `" + k, + ) } + assert( + type(v.short) == str, + message: "The short form of glossary entry `" + k + "` is not a string", + ) + + if "long" in v { + assert( + type(v.long) == str, + message: "The long form of glossary entry `" + k + "` is not a string", + ) + } + + if "desc" in v { + assert( + type(v.desc) == str, + message: "The description of glossary entry `" + k + "` is not a string", + ) + } + + if "group" in v { + assert( + type(v.group) == str, + message: "The optional group of glossary entry `" + k + "` is not a string", + ) + } else { + let group = if "long" in v { + if (context text.lang) == "de" { + "Akronyme" + } else { + "Acronyms" + } + } else { + if (context text.lang) == "de" { + "Begriffe" + } else { + "Terms" + } + } + + entries.at(k).group = group + } + } + return entries.pairs().map(((key, entry)) => ( - key: key, - short: eval(entry.short, mode: "markup"), - long: eval(entry.at("long", default: ""), mode: "markup"), - desc: eval(entry.at("desc", default: ""), mode: "markup"), - group: entry.at("group", default: "") - )) + key: key, + short: eval(entry.short, mode: "markup"), + long: eval(entry.at("long", default: ""), mode: "markup"), + desc: eval(entry.at("desc", default: ""), mode: "markup"), + group: entry.at("group", default: ""), + )) } \ No newline at end of file diff --git a/src/lib.typ b/src/lib.typ index 905e383..f3098cd 100644 --- a/src/lib.typ +++ b/src/lib.typ @@ -7,20 +7,20 @@ // Edited: 27.06.2024 // License: MIT - #import "conf.typ": validate-config - #import "branding.typ": * - #import "style.typ": global_styled_doc, content_styled, end_styled - #import "glossary.typ": glossary - #import "pages/titlepage.typ": new_title_page - #import "pages/declaration-of-authorship.typ": new_declaration_of_authorship - #import "pages/confidentiality-statement.typ": new_confidentiality_statement_page - #import "pages/prerelease-note.typ": new_prerelease_note - #import "pages/outline.typ": new_outline - #import "pages/abstract.typ": new_abstract - #import "pages/preface.typ": new-preface - #import "pages/appendix.typ": show-appendix +#import "conf.typ": validate-config +#import "branding.typ": * +#import "style.typ": global_styled_doc, content_styled, end_styled +#import "glossary.typ": glossary +#import "pages/titlepage.typ": new_title_page +#import "pages/declaration-of-authorship.typ": new_declaration_of_authorship +#import "pages/confidentiality-statement.typ": new_confidentiality_statement_page +#import "pages/prerelease-note.typ": new_prerelease_note +#import "pages/outline.typ": new_outline +#import "pages/abstract.typ": new_abstract +#import "pages/preface.typ": new-preface +#import "pages/appendix.typ": show-appendix -#let group-break()= { +#let group-break() = { [#pagebreak()] } @@ -36,12 +36,14 @@ #set document( author: config.author.name, keywords: config.thesis.keywords, - title: config.thesis.title) + title: config.thesis.title, + ) // configure text locale #set text( lang: config.lang, - region: config.region) + region: config.region, + ) // preppend title page #new_title_page(config) @@ -57,7 +59,7 @@ #new-preface(config) #new_outline() - // glossary is built inline here because the links must be + // glossary is built inline here because the links must be // exposed to the entire document #import "glossarium.typ": * #show: make-glossary @@ -68,10 +70,11 @@ print-glossary( disable-back-references: true, enable-group-pagebreak: true, - glossary(config.thesis.glossary)) + glossary(config.thesis.glossary), + ) pagebreak(weak: true) - } + } #counter(page).update(1) // mark end of prelude diff --git a/src/pages/abstract.typ b/src/pages/abstract.typ index f2feb5a..67e73a3 100644 --- a/src/pages/abstract.typ +++ b/src/pages/abstract.typ @@ -7,7 +7,7 @@ // License: MIT #let new_abstract(config) = context { - + set align(center + horizon) // only include summary when a language other than english is used diff --git a/src/pages/outline.typ b/src/pages/outline.typ index 0811949..e0b3d8d 100644 --- a/src/pages/outline.typ +++ b/src/pages/outline.typ @@ -9,63 +9,65 @@ // render an outline of figures // with a specific title and filter by a specifc kind of figure // can optionally insert a pagebreak after the outline -// NOTE: will not render in case the listing is empty +// NOTE: will not render in case the listing is empty #let render_filtered_outline(title: str, kind: selector) = context { let elems = query(figure.where(kind: kind), here()) let count = elems.len() - + // only show outline if there is something to list if count > 0 { pagebreak(weak: true) outline( title: title, - target: figure.where(kind: kind)) + target: figure.where(kind: kind), + ) } } #let render_figures_outline() = context { let title = if (text.lang == "de") { - "Abbildungsverzeichnis" - } else if text.lang == "en" { - "List of Figures" - } + "Abbildungsverzeichnis" + } else if text.lang == "en" { + "List of Figures" + } render_filtered_outline(title: title, kind: image) } #let render_table_outline() = context { let title = if (text.lang == "de") { - "Tabellenverzeichnis" - } else if text.lang == "en" { - "List of Tables" - } + "Tabellenverzeichnis" + } else if text.lang == "en" { + "List of Tables" + } render_filtered_outline(title: title, kind: table) } #let render_raw_outline() = context { let title = if (text.lang == "de") { - "Quelltextverzeichnis" - } else if text.lang == "en" { - "Code Snippets" - } + "Quelltextverzeichnis" + } else if text.lang == "en" { + "Code Snippets" + } render_filtered_outline(title: title, kind: raw) } #let render_heading_outline() = context { let title = if (text.lang == "de") { - "Inhaltsverzeichnis" - } else if text.lang == "en" { - "Table of Contents" - } - + "Inhaltsverzeichnis" + } else if text.lang == "en" { + "Table of Contents" + } + pagebreak(weak: true) outline( - target: heading.where(supplement: [chapter]), - title: title, - indent: auto) + target: heading.where(supplement: [chapter]), + title: title, + indent: auto, + ) } #let render_appendix_outline() = context { @@ -81,21 +83,20 @@ } else if text.lang == "en" { "Table of Appendices" } - + pagebreak(weak: true) outline( - target: heading.where(supplement: supplement), - title: title, - indent: auto) + target: heading.where(supplement: supplement), + title: title, + indent: auto, + ) } } #let new_outline() = { pagebreak(weak: true) - show outline.entry.where( - level: 1, - ): it => { + show outline.entry.where(level: 1): it => { v(1.5em, weak: true) strong(it) } diff --git a/src/pages/titlepage.typ b/src/pages/titlepage.typ index d77268b..d289053 100644 --- a/src/pages/titlepage.typ +++ b/src/pages/titlepage.typ @@ -60,24 +60,14 @@ column-gutter: 1cm, align: left, stroke: none, - - [*Verfasser:*], - author.name, - - [*Bearbeitungszeitraum:*], - thesis.timeframe, - + [*Verfasser:*], author.name, + [*Bearbeitungszeitraum:*], thesis.timeframe, [*Matrikelnummer, Kurs:*], str(author.matriculation-number) + ", " + author.course, - [*Ausbildungsbetrieb:*], - author.company, - - [*Betrieblicher Betreuer:*], - author.supervisor, - - [*Abgabedatum:*], - thesis.submission-date + [*Ausbildungsbetrieb:*], author.company, + [*Betrieblicher Betreuer:*], author.supervisor, + [*Abgabedatum:*], thesis.submission-date, ) ] else if text.lang == "en" [ #table( @@ -85,30 +75,21 @@ column-gutter: 1cm, align: left, stroke: none, - - [*Author:*], - author.name, - - [*Editing period:*], - thesis.timeframe, - + [*Author:*], author.name, + [*Editing period:*], thesis.timeframe, [*Matriculation number, course:*], str(author.matriculation-number) + ", " + author.course, - [*Training company:*], - author.company, - - [*Company supervisor:*], - author.supervisor, - - [*Submission date:*], - thesis.submission-date + [*Training company:*], author.company, + [*Company supervisor:*], author.supervisor, + [*Submission date:*], thesis.submission-date, ) ] else [ #context panic("no translation for language: ", text.lang) ] - #align(bottom, + #align( + bottom, grid( // set width of columns // we need two, so make both half the page width @@ -121,7 +102,8 @@ #context panic("no translation for language: ", text.lang) ] ), - align(right, {line(length: 6cm)}))) + align(right, {line(length: 6cm)})), + ) #counter(page).update(0) ] diff --git a/src/style.typ b/src/style.typ index e8c6966..779e2ce 100644 --- a/src/style.typ +++ b/src/style.typ @@ -9,14 +9,15 @@ #import "branding.typ": * -#let watermark-color = luma(50%).transparentize(70%) +#let watermark-color = luma(50%).transparentize(70%) #let watermark(config) = if config.draft { rotate(-22.5deg)[ #rect( - radius: 1em, - inset: 1em, - stroke: watermark-color)[ + radius: 1em, + inset: 1em, + stroke: watermark-color, + )[ #text(size: 4em, weight: "bold", fill: watermark-color, "DRAFT") #linebreak() #text(size: 1.25em, weight: "bold", fill: watermark-color)[ @@ -24,7 +25,11 @@ #linebreak() document version. #linebreak() - #text(size: 0.75em, "Further usage without the authors consent is not permitted.")]]]} + #text( + size: 0.75em, + "Further usage without the authors consent is not permitted.", + )]]] +} // global style of document #let global_styled_doc(config, body) = { @@ -37,11 +42,13 @@ hyphenate: true, dir: ltr, font: style.text.font, - fill: ABB-BLACK) + fill: ABB-BLACK, + ) show heading: set text( font: style.heading.font, - weight: "semibold") + weight: "semibold", + ) set heading(supplement: [chapter]) @@ -55,7 +62,8 @@ // set theme for code blocks set raw( tab-size: style.code.tab-size, - theme: style.code.theme) + theme: style.code.theme, + ) show raw: set text(font: style.code.font) show figure: set block(breakable: true) @@ -67,8 +75,20 @@ stroke: (x, y) => ( left: none, right: none, - top: if y == 0 { 1.5pt } else if y < 2 { 1pt } else { 0pt }, - bottom: if y == 0 { 1pt } else { 1.5pt } )) + top: if y == 0 { + 1.5pt + } else if y < 2 { + 1pt + } else { + 0pt + }, + bottom: if y == 0 { + 1pt + } else { + 1.5pt + }, + ), + ) // make table header bold show table.cell.where(y: 0): set text(weight: "bold") @@ -77,7 +97,8 @@ set par( justify: true, first-line-indent: 1em, - leading: 1em) + leading: 1em, + ) // give links a color show link: set text(fill: style.link.color) @@ -93,10 +114,11 @@ top: style.page.margin.top + style.header.logo-height + style.header.underline-top-padding + style.header.content-padding, bottom: style.page.margin.bottom + style.footer.content-padding, left: style.page.margin.left, - right: style.page.margin.right), + right: style.page.margin.right, + ), numbering: (..nums) => { let current-page = here().page() - if current-page == 1{ + if current-page == 1 { [] } else if query().first().location().page() > current-page { numbering("I", nums.pos().first()) @@ -115,7 +137,11 @@ } else if query().first().location().page() > page-number { numbering("I", page-counter) } else if query().first().location().page() >= page-number { - numbering("1 / 1", page-counter, counter(page).at().last()) + numbering( + "1 / 1", + page-counter, + counter(page).at().last(), + ) } else { numbering("a", page-counter) } @@ -134,14 +160,18 @@ align(right, image("res/DHBW.svg", height: style.header.logo-height))) } else if query().first().location().page() <= here().page() { - let headers-before = query(selector(heading.where(numbering: "1.", level: 1)).before(here())) + let headers-before = query( + selector(heading.where(numbering: "1.", level: 1)).before(here()), + ) let header-title = thesis.title if headers-before.len() > 0 { header-title = headers-before.last().body } else { - let headers-after = query(selector(heading.where(numbering: "1.", level: 1)).after(here())) + let headers-after = query( + selector(heading.where(numbering: "1.", level: 1)).after(here()), + ) if headers-after.len() > 0 { header-title = headers-after.first().body @@ -152,8 +182,9 @@ columns: (1fr, auto), align: (horizon, bottom), context [ _ #header-title _ ], - image("res/DHBW.svg", height: style.header.logo-height)) - + image("res/DHBW.svg", height: style.header.logo-height), + ) + v(style.header.underline-top-padding - 1em) line(length: 100%) } else { @@ -161,12 +192,13 @@ columns: (1fr, auto), align: (horizon, bottom), context [ _ #config.thesis.title _ ], - image("res/DHBW.svg", height: style.header.logo-height) + image("res/DHBW.svg", height: style.header.logo-height), ) v(style.header.underline-top-padding - 1em) line(length: 100%) } - }) + }, + ) body } From 4a1fcd0a35c0f4f40ead9e454f013042eeebc117 Mon Sep 17 00:00:00 2001 From: servostar Date: Mon, 8 Jul 2024 22:56:56 +0200 Subject: [PATCH 03/14] changed: CI runs on nix shell --- .gitea/workflows/ci.yml | 13 +++++-------- shell.nix | 13 +++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 shell.nix diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 14f897c..1ed65c2 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -5,15 +5,12 @@ on: [push] jobs: run-ci-linux: runs-on: ubuntu-latest - env: - TYPST_INSTALL: /usr/local - TYPST_VERSION: 0.11.1 steps: - name: Check out repository code uses: actions/checkout@v3 - - name: Install Typst CLI - run: curl -fsSL https://typst.community/typst-install/install.sh | sh -s "$TYPST_VERSION" - - name: Set up Python 3 - run: apt update -y && apt install python3-pip -y + - name: Setup Nix Shell + - uses: cachix/install-nix-action@v18 + with: + nix_path: nixpkgs=channel:nixos-unstable - name: Run CI - run: bash -c ./run-ci.sh + run: nix-shell --run ./run-ci.sh diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..61ee97a --- /dev/null +++ b/shell.nix @@ -0,0 +1,13 @@ +let + nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05"; + pkgs = import nixpkgs { config = {}; overlays = []; }; +in + +pkgs.mkShellNoCC { + packages = with pkgs; [ + python312 + python312Packages.pyyaml + typst + typstyle + ]; +} From 9ba1fea4d73681a79bd78448e5e4224a69c26998 Mon Sep 17 00:00:00 2001 From: servostar Date: Mon, 8 Jul 2024 22:58:13 +0200 Subject: [PATCH 04/14] changed: ci action syntax --- .gitea/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 1ed65c2..b2aa604 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -8,8 +8,8 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@v3 - - name: Setup Nix Shell - - uses: cachix/install-nix-action@v18 + - name: Setup Nix + uses: cachix/install-nix-action@v18 with: nix_path: nixpkgs=channel:nixos-unstable - name: Run CI From 2daf7bb6c97dd7a8114bd4797738be4a116a038c Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 19:34:46 +0200 Subject: [PATCH 05/14] updated nix action to v27 --- .gitea/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index b2aa604..21c31e5 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Setup Nix - uses: cachix/install-nix-action@v18 + uses: cachix/install-nix-action@v27 with: nix_path: nixpkgs=channel:nixos-unstable - name: Run CI From 201e991ac422a984a60fbebfc2de9e95e74c0dfa Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 19:36:24 +0200 Subject: [PATCH 06/14] added sudo to action runner --- .gitea/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 21c31e5..c2b5e1d 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -8,6 +8,10 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@v3 + - name: Install dependencies for Nix setup action + run: | + apt update -y + apt install sudo -y - name: Setup Nix uses: cachix/install-nix-action@v27 with: From 7ad138dc004734607045874a77725fc76a050354 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 19:50:09 +0200 Subject: [PATCH 07/14] fix CI failing (#18) --- run-ci.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/run-ci.sh b/run-ci.sh index 40d2c65..233f6f7 100755 --- a/run-ci.sh +++ b/run-ci.sh @@ -25,7 +25,8 @@ function enter-section() { printf "\\n" eval "$2" - if [ $? -neq $3 ]; then + exit_status=$? + if ! [ $exit_status -eq $3 ]; then abort "command: $2 failed in section: $1" fi From 946a16fce6a0541723bfadf80fe8e7b77431a354 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 19:50:31 +0200 Subject: [PATCH 08/14] add typstyle check to CI (#13) --- run-ci.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/run-ci.sh b/run-ci.sh index 233f6f7..f20cbae 100755 --- a/run-ci.sh +++ b/run-ci.sh @@ -34,6 +34,7 @@ function enter-section() { log "INFO" "section $1 completed successfully" } +enter-section "Typstyle checking" "./run-fmt.sh --check src/lib.typ" 0 enter-section "BUILD: ABB code theme" "./generate-theme.sh" 0 enter-section "Compiling template..." "typst compile template/main.typ --root . example.pdf" 0 enter-section "TEST: local template import" "typst compile tests/local-import/main.typ --root ." 0 From 093ed09293a191b57c016ce562bab004d408f75c Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 19:52:07 +0200 Subject: [PATCH 09/14] fixed format of template for (#13) --- src/glossarium.typ | 50 +++++--- src/pages/abstract.typ | 30 ++--- src/pages/appendix.typ | 58 ++++----- src/pages/confidentiality-statement.typ | 66 +++++----- src/pages/declaration-of-authorship.typ | 68 ++++++----- src/pages/outline.typ | 148 ++++++++++++----------- src/pages/prerelease-note.typ | 78 ++++++------ src/pages/titlepage.typ | 154 ++++++++++++------------ src/style.typ | 19 ++- 9 files changed, 358 insertions(+), 313 deletions(-) diff --git a/src/glossarium.typ b/src/glossarium.typ index 143e12d..522079d 100644 --- a/src/glossarium.typ +++ b/src/glossarium.typ @@ -129,7 +129,9 @@ SOFTWARE.*/ // show rule to make the references for glossarium #let make-glossary(body) = { show ref: r => { - if r.element != none and r.element.func() == figure and r.element.kind == __glossarium_figure { + if r.element != none and r.element.func() == figure and r + .element + .kind == __glossarium_figure { // call to the general citing function gls(str(r.target), suffix: r.citation.supplement) } else { @@ -200,25 +202,33 @@ SOFTWARE.*/ if hasLong and hasDesc [:] if hasDesc [ #desc ] else [. ] if disable-back-references != true { - term_references.map(x => x.location()).sorted(key: x => x.page()).fold( - (values: (), pages: ()), - ((values, pages), x) => if pages.contains(x.page()) { - (values: values, pages: pages) - } else { - values.push(x) - pages.push(x.page()) - (values: values, pages: pages) - }, - ).values.map(x => { - let page-numbering = x.page-numbering() - if page-numbering == none { - page-numbering = "1" - } - link(x)[#numbering( - page-numbering, - ..counter(page).at(x), - )] - }).join(", ") + term_references + .map(x => x.location()) + .sorted(key: x => x.page()) + .fold( + (values: (), pages: ()), + ((values, pages), x) => if pages.contains( + x.page(), + ) { + (values: values, pages: pages) + } else { + values.push(x) + pages.push(x.page()) + (values: values, pages: pages) + }, + ) + .values + .map(x => { + let page-numbering = x.page-numbering() + if page-numbering == none { + page-numbering = "1" + } + link(x)[#numbering( + page-numbering, + ..counter(page).at(x), + )] + }) + .join(", ") } }, ) diff --git a/src/pages/abstract.typ b/src/pages/abstract.typ index 67e73a3..6da09e2 100644 --- a/src/pages/abstract.typ +++ b/src/pages/abstract.typ @@ -6,22 +6,24 @@ // Edited: 28.06.2024 // License: MIT -#let new_abstract(config) = context { +#let new_abstract(config) = ( + context { - set align(center + horizon) + set align(center + horizon) - // only include summary when a language other than english is used - if text.lang == "de" [ - // Summary is supposed to be on separate page - #pagebreak(weak: true) + // only include summary when a language other than english is used + if text.lang == "de" [ + // Summary is supposed to be on separate page + #pagebreak(weak: true) - = Zusammenfassung - #config.thesis.summary - ] + = Zusammenfassung + #config.thesis.summary + ] - // abstract is supposed to be on separate page - pagebreak(weak: true) + // abstract is supposed to be on separate page + pagebreak(weak: true) - heading("Abstract") - config.thesis.abstract -} \ No newline at end of file + heading("Abstract") + config.thesis.abstract + } +) \ No newline at end of file diff --git a/src/pages/appendix.typ b/src/pages/appendix.typ index dca3987..09b33f4 100644 --- a/src/pages/appendix.typ +++ b/src/pages/appendix.typ @@ -6,37 +6,39 @@ // Edited: 28.06.2024 // License: MIT -#let show-appendix(config: dictionary) = context { - counter(heading).update(0) +#let show-appendix(config: dictionary) = ( + context { + counter(heading).update(0) - let title = if text.lang == "en" { - "Appendix" - } else { - "Anhang" - } - - if "appendices" in config.thesis { - pagebreak(weak: true) - - heading(level: 1, numbering: none, title) - v(-2em) - - // APA style appendix - show heading: it => { - let number = if it.numbering != none { - counter(heading).display(it.numbering) - } - block()[ - #title #number - #it.body - ] + let title = if text.lang == "en" { + "Appendix" + } else { + "Anhang" } - show heading.where(level: 1): it => v(2em) + it + v(1em) - show heading.where(level: 2): it => v(1em) + it + v(0.5em) - show heading.where(level: 3): it => v(0.5em) + it + v(0.25em) + if "appendices" in config.thesis { + pagebreak(weak: true) - set heading(numbering: "A.1", supplement: title) + heading(level: 1, numbering: none, title) + v(-2em) - config.thesis.appendices + // APA style appendix + show heading: it => { + let number = if it.numbering != none { + counter(heading).display(it.numbering) + } + block()[ + #title #number - #it.body + ] + } + + show heading.where(level: 1): it => v(2em) + it + v(1em) + show heading.where(level: 2): it => v(1em) + it + v(0.5em) + show heading.where(level: 3): it => v(0.5em) + it + v(0.25em) + + set heading(numbering: "A.1", supplement: title) + + config.thesis.appendices + } } -} +) diff --git a/src/pages/confidentiality-statement.typ b/src/pages/confidentiality-statement.typ index 4a85795..931479f 100644 --- a/src/pages/confidentiality-statement.typ +++ b/src/pages/confidentiality-statement.typ @@ -6,51 +6,52 @@ // Edited: 28.06.2024 // License: MIT -#let new_confidentiality_statement_page(config) = context { +#let new_confidentiality_statement_page(config) = ( + context { - pagebreak(weak: true) + pagebreak(weak: true) - let thesis = config.thesis - let author = config.author + let thesis = config.thesis + let author = config.author - if text.lang == "de" [ - #heading(level: 1, "Sperrvermerk", supplement: [special]) - ] else if text.lang == "en" [ - #heading(level: 1, "Confidentiality Statement", supplement: [special]) - ] + if text.lang == "de" [ + #heading(level: 1, "Sperrvermerk", supplement: [special]) + ] else if text.lang == "en" [ + #heading(level: 1, "Confidentiality Statement", supplement: [special]) + ] - if text.lang == "de" [ - Der Inhalt der dieser Arbeit mit dem Thema - ] else if text.lang == "en" [ - The content of this work with the topic - ] + if text.lang == "de" [ + Der Inhalt der dieser Arbeit mit dem Thema + ] else if text.lang == "en" [ + The content of this work with the topic + ] - v(1em) + v(1em) - set align(center) + set align(center) - text(weight: "bold", thesis.title) + text(weight: "bold", thesis.title) - if thesis.subtitle != none { - linebreak() - thesis.subtitle - } + if thesis.subtitle != none { + linebreak() + thesis.subtitle + } - set align(left) + set align(left) - v(1em) + v(1em) - set par(justify: true) + set par(justify: true) - if text.lang == "de" [ - darf weder als Ganzes noch in Auszügen Personen außerhalb des Prüfungsprozesses und des Evalua-tionsverfahrens zugänglich gemacht werden, sofern keine anderslautende Genehmigung der Ausbildungsstätte vorliegt. - ] else if text.lang == "en" [ - may not be made accessible to persons outside the examination process and the evaluation procedure, either as a whole or in excerpts, unless otherwise authorized by the training institution. - ] + if text.lang == "de" [ + darf weder als Ganzes noch in Auszügen Personen außerhalb des Prüfungsprozesses und des Evalua-tionsverfahrens zugänglich gemacht werden, sofern keine anderslautende Genehmigung der Ausbildungsstätte vorliegt. + ] else if text.lang == "en" [ + may not be made accessible to persons outside the examination process and the evaluation procedure, either as a whole or in excerpts, unless otherwise authorized by the training institution. + ] - set align(horizon) + set align(horizon) - grid( + grid( // set width of columns // we need two, so make both half the page width columns: (50%, 50%), @@ -59,4 +60,5 @@ align(left, {line(length: 6cm)}), align(left, if text.lang == "de" [ Ort, Datum ] else if text.lang == "en" [ Place, Date ] else { panic("no translation for language: ", text.lang) }), align(left, if text.lang == "de" [ Unterschrift ] else if text.lang == "en" [ Signature ] else { panic("no translation for language: ", text.lang) })) -} \ No newline at end of file + } +) \ No newline at end of file diff --git a/src/pages/declaration-of-authorship.typ b/src/pages/declaration-of-authorship.typ index c2c3a42..7f94b27 100644 --- a/src/pages/declaration-of-authorship.typ +++ b/src/pages/declaration-of-authorship.typ @@ -6,53 +6,54 @@ // Edited: 28.06.2024 // License: MIT -#let new_declaration_of_authorship(config) = context { +#let new_declaration_of_authorship(config) = ( + context { - pagebreak(weak: true) + pagebreak(weak: true) - let thesis = config.thesis - let author = config.author + let thesis = config.thesis + let author = config.author - if text.lang == "de" [ - #heading("Selbständigkeitserklärung") - ] else if text.lang == "en" [ - #heading("Declaration of Authorship") - ] + if text.lang == "de" [ + #heading("Selbständigkeitserklärung") + ] else if text.lang == "en" [ + #heading("Declaration of Authorship") + ] - v(1em) + v(1em) - if text.lang == "de" [ - Ich versichere hiermit, dass ich meine Prüfung mit dem Thema - ] else if text.lang == "en" [ - I hereby confirm that I have written this thesis with the subject - ] + if text.lang == "de" [ + Ich versichere hiermit, dass ich meine Prüfung mit dem Thema + ] else if text.lang == "en" [ + I hereby confirm that I have written this thesis with the subject + ] - v(1em) + v(1em) - set align(center) + set align(center) - text(weight: "bold", thesis.title) + text(weight: "bold", thesis.title) - if thesis.subtitle != none { - linebreak() - thesis.subtitle - } + if thesis.subtitle != none { + linebreak() + thesis.subtitle + } - set align(left) + set align(left) - v(1em) + v(1em) - set par(justify: true) + set par(justify: true) - if text.lang == "de" [ - selbständig verfasst und keine anderen als die angegebenen Quellen und Hilfsmittel benutzt habe. Ich versichere zudem, dass die eingereichte elektronische Fassung mit der gedruckten Fassung übereinstimmt. - ] else if text.lang == "en" [ - independently and have not used any sources or aids other than those specified. I also confirm that the electronic version submitted is identical to the printed version. - ] + if text.lang == "de" [ + selbständig verfasst und keine anderen als die angegebenen Quellen und Hilfsmittel benutzt habe. Ich versichere zudem, dass die eingereichte elektronische Fassung mit der gedruckten Fassung übereinstimmt. + ] else if text.lang == "en" [ + independently and have not used any sources or aids other than those specified. I also confirm that the electronic version submitted is identical to the printed version. + ] - set align(horizon) + set align(horizon) - grid( + grid( // set width of columns // we need two, so make both half the page width columns: (50%, 50%), @@ -61,4 +62,5 @@ align(left, {line(length: 6cm)}), align(left, if text.lang == "de" [ Ort, Datum ] else if text.lang == "en" [ Place, Date ] else { panic("no translation for language: ", text.lang) }), align(left, if text.lang == "de" [ Unterschrift ] else if text.lang == "en" [ Signature ] else { panic("no translation for language: ", text.lang) })) -} \ No newline at end of file + } +) \ No newline at end of file diff --git a/src/pages/outline.typ b/src/pages/outline.typ index e0b3d8d..8bbd03a 100644 --- a/src/pages/outline.typ +++ b/src/pages/outline.typ @@ -10,88 +10,100 @@ // with a specific title and filter by a specifc kind of figure // can optionally insert a pagebreak after the outline // NOTE: will not render in case the listing is empty -#let render_filtered_outline(title: str, kind: selector) = context { +#let render_filtered_outline(title: str, kind: selector) = ( + context { - let elems = query(figure.where(kind: kind), here()) - let count = elems.len() + let elems = query(figure.where(kind: kind), here()) + let count = elems.len() - // only show outline if there is something to list - if count > 0 { - pagebreak(weak: true) - outline( - title: title, - target: figure.where(kind: kind), - ) + // only show outline if there is something to list + if count > 0 { + pagebreak(weak: true) + outline( + title: title, + target: figure.where(kind: kind), + ) + } } -} +) -#let render_figures_outline() = context { - let title = if (text.lang == "de") { - "Abbildungsverzeichnis" - } else if text.lang == "en" { - "List of Figures" - } - - render_filtered_outline(title: title, kind: image) -} - -#let render_table_outline() = context { - let title = if (text.lang == "de") { - "Tabellenverzeichnis" - } else if text.lang == "en" { - "List of Tables" - } - - render_filtered_outline(title: title, kind: table) -} - -#let render_raw_outline() = context { - let title = if (text.lang == "de") { - "Quelltextverzeichnis" - } else if text.lang == "en" { - "Code Snippets" - } - - render_filtered_outline(title: title, kind: raw) -} - -#let render_heading_outline() = context { - let title = if (text.lang == "de") { - "Inhaltsverzeichnis" - } else if text.lang == "en" { - "Table of Contents" - } - - pagebreak(weak: true) - outline( - target: heading.where(supplement: [chapter]), - title: title, - indent: auto, - ) -} - -#let render_appendix_outline() = context { - let supplement = if text.lang == "en" { - [Appendix] - } else { - [Anhang] - } - - if query(heading.where(supplement: supplement)).len() > 0 { +#let render_figures_outline() = ( + context { let title = if (text.lang == "de") { - "Anhangsverzeichnis" + "Abbildungsverzeichnis" } else if text.lang == "en" { - "Table of Appendices" + "List of Figures" + } + + render_filtered_outline(title: title, kind: image) + } +) + +#let render_table_outline() = ( + context { + let title = if (text.lang == "de") { + "Tabellenverzeichnis" + } else if text.lang == "en" { + "List of Tables" + } + + render_filtered_outline(title: title, kind: table) + } +) + +#let render_raw_outline() = ( + context { + let title = if (text.lang == "de") { + "Quelltextverzeichnis" + } else if text.lang == "en" { + "Code Snippets" + } + + render_filtered_outline(title: title, kind: raw) + } +) + +#let render_heading_outline() = ( + context { + let title = if (text.lang == "de") { + "Inhaltsverzeichnis" + } else if text.lang == "en" { + "Table of Contents" } pagebreak(weak: true) outline( - target: heading.where(supplement: supplement), + target: heading.where(supplement: [chapter]), title: title, indent: auto, ) } -} +) + +#let render_appendix_outline() = ( + context { + let supplement = if text.lang == "en" { + [Appendix] + } else { + [Anhang] + } + + if query(heading.where(supplement: supplement)).len() > 0 { + let title = if (text.lang == "de") { + "Anhangsverzeichnis" + } else if text.lang == "en" { + "Table of Appendices" + } + + pagebreak(weak: true) + outline( + target: heading.where(supplement: supplement), + title: title, + indent: auto, + ) + } + } +) #let new_outline() = { pagebreak(weak: true) diff --git a/src/pages/prerelease-note.typ b/src/pages/prerelease-note.typ index 86d79a0..eb73bf0 100644 --- a/src/pages/prerelease-note.typ +++ b/src/pages/prerelease-note.typ @@ -6,51 +6,53 @@ // Edited: 28.06.2024 // License: MIT -#let new_prerelease_note(config) = context { +#let new_prerelease_note(config) = ( + context { - pagebreak(weak: true) + pagebreak(weak: true) - let thesis = config.thesis - let author = config.author + let thesis = config.thesis + let author = config.author - if text.lang == "de" [ - #heading("Vorabfassung") - ] else if text.lang == "en" [ - #heading("Preliminary Version") - ] + if text.lang == "de" [ + #heading("Vorabfassung") + ] else if text.lang == "en" [ + #heading("Preliminary Version") + ] - v(1em) + v(1em) - if text.lang == "de" [ - Bei dieser Ausgabe der Arbeit mit dem Thema - ] else if text.lang == "en" [ - This edition of the work with the subject - ] + if text.lang == "de" [ + Bei dieser Ausgabe der Arbeit mit dem Thema + ] else if text.lang == "en" [ + This edition of the work with the subject + ] - v(1em) + v(1em) - set align(center) + set align(center) - text(weight: "bold", thesis.title) + text(weight: "bold", thesis.title) - if thesis.subtitle != none { - linebreak() - thesis.subtitle + if thesis.subtitle != none { + linebreak() + thesis.subtitle + } + + set align(left) + + v(1em) + + set par(justify: true) + + if text.lang == "de" [ + handelt es sich _nicht_ um die fertige Fassung. Das Dokument kann Inhaltliche-, Grammatikalische- sowie Format-Fehler enthalten. Das Dokument ist im Rahmen der Aufgabenstellung von Seiten der #author.university nicht zur Bewertung freigegeben und ein anderer Verwendungszweck als eine Vorschau ist nicht gestattet. + ] else if text.lang == "en" [ + is not the final version. The document may contain errors in content, grammar and formatting. The document may not be released for evaluation to #author.university as part of the assignment, and any use other than a preview is not permitted. + ] + + v(1em) + h(1em) + [#author.name, #datetime.today().display()] } - - set align(left) - - v(1em) - - set par(justify: true) - - if text.lang == "de" [ - handelt es sich _nicht_ um die fertige Fassung. Das Dokument kann Inhaltliche-, Grammatikalische- sowie Format-Fehler enthalten. Das Dokument ist im Rahmen der Aufgabenstellung von Seiten der #author.university nicht zur Bewertung freigegeben und ein anderer Verwendungszweck als eine Vorschau ist nicht gestattet. - ] else if text.lang == "en" [ - is not the final version. The document may contain errors in content, grammar and formatting. The document may not be released for evaluation to #author.university as part of the assignment, and any use other than a preview is not permitted. - ] - - v(1em) - h(1em) - [#author.name, #datetime.today().display()] -} \ No newline at end of file +) \ No newline at end of file diff --git a/src/pages/titlepage.typ b/src/pages/titlepage.typ index d289053..138627a 100644 --- a/src/pages/titlepage.typ +++ b/src/pages/titlepage.typ @@ -6,91 +6,92 @@ // Edited: 28.06.2024 // License: MIT -#let new_title_page(config) = context [ +#let new_title_page(config) = ( + context [ - #let thesis = config.thesis - #let author = config.author + #let thesis = config.thesis + #let author = config.author - #set align(center) + #set align(center) - // title - #v(2cm) - #text(size: 2em, weight: "semibold", thesis.title) + // title + #v(2cm) + #text(size: 2em, weight: "semibold", thesis.title) - // subtitle - #text(size: 1.5em, thesis.subtitle) + // subtitle + #text(size: 1.5em, thesis.subtitle) - // type of paper - #v(1cm) - #text(size: 1.5em, weight: "bold", thesis.kind) + // type of paper + #v(1cm) + #text(size: 1.5em, weight: "bold", thesis.kind) + + // faculty + #pad(top: 0.5cm)[ + #if text.lang == "de" [ + Praxisphase des #author.semester Studienjahrs an der Fakultät für #author.faculty + #linebreak() + im Studiengang #author.program + ] else if text.lang == "en" [ + Practical phase of the #author.semester academic year at the Faculty of #author.faculty + #linebreak() + in the degree program #author.program + ] else [ + #context panic("no translation for language: ", text.lang) + ] + ] + + // university + #pad(top: 0.5cm)[ + #if text.lang == "de" [ + an der + ] else if text.lang == "en" [ + at + ] else [ + #context panic("no translation for language: ", text.lang) + ] + #linebreak() + #author.university + ] + + #set align(horizon + left) - // faculty - #pad(top: 0.5cm)[ #if text.lang == "de" [ - Praxisphase des #author.semester Studienjahrs an der Fakultät für #author.faculty - #linebreak() - im Studiengang #author.program + #table( + columns: 2, + column-gutter: 1cm, + align: left, + stroke: none, + [*Verfasser:*], author.name, + [*Bearbeitungszeitraum:*], thesis.timeframe, + [*Matrikelnummer, Kurs:*], + str(author.matriculation-number) + ", " + author.course, + + [*Ausbildungsbetrieb:*], author.company, + [*Betrieblicher Betreuer:*], author.supervisor, + [*Abgabedatum:*], thesis.submission-date, + ) ] else if text.lang == "en" [ - Practical phase of the #author.semester academic year at the Faculty of #author.faculty - #linebreak() - in the degree program #author.program + #table( + columns: 2, + column-gutter: 1cm, + align: left, + stroke: none, + [*Author:*], author.name, + [*Editing period:*], thesis.timeframe, + [*Matriculation number, course:*], + str(author.matriculation-number) + ", " + author.course, + + [*Training company:*], author.company, + [*Company supervisor:*], author.supervisor, + [*Submission date:*], thesis.submission-date, + ) ] else [ #context panic("no translation for language: ", text.lang) ] - ] - // university - #pad(top: 0.5cm)[ - #if text.lang == "de" [ - an der - ] else if text.lang == "en" [ - at - ] else [ - #context panic("no translation for language: ", text.lang) - ] - #linebreak() - #author.university - ] - - #set align(horizon + left) - - #if text.lang == "de" [ - #table( - columns: 2, - column-gutter: 1cm, - align: left, - stroke: none, - [*Verfasser:*], author.name, - [*Bearbeitungszeitraum:*], thesis.timeframe, - [*Matrikelnummer, Kurs:*], - str(author.matriculation-number) + ", " + author.course, - - [*Ausbildungsbetrieb:*], author.company, - [*Betrieblicher Betreuer:*], author.supervisor, - [*Abgabedatum:*], thesis.submission-date, - ) - ] else if text.lang == "en" [ - #table( - columns: 2, - column-gutter: 1cm, - align: left, - stroke: none, - [*Author:*], author.name, - [*Editing period:*], thesis.timeframe, - [*Matriculation number, course:*], - str(author.matriculation-number) + ", " + author.course, - - [*Training company:*], author.company, - [*Company supervisor:*], author.supervisor, - [*Submission date:*], thesis.submission-date, - ) - ] else [ - #context panic("no translation for language: ", text.lang) - ] - - #align( - bottom, - grid( + #align( + bottom, + grid( // set width of columns // we need two, so make both half the page width columns: (60%, 40%), @@ -103,7 +104,8 @@ ] ), align(right, {line(length: 6cm)})), - ) + ) - #counter(page).update(0) -] + #counter(page).update(0) + ] +) diff --git a/src/style.typ b/src/style.typ index 779e2ce..6543f89 100644 --- a/src/style.typ +++ b/src/style.typ @@ -111,7 +111,9 @@ header-ascent: style.header.content-padding, footer-descent: style.header.content-padding, margin: ( - top: style.page.margin.top + style.header.logo-height + style.header.underline-top-padding + style.header.content-padding, + top: style.page.margin.top + style.header.logo-height + style + .header + .underline-top-padding + style.header.content-padding, bottom: style.page.margin.bottom + style.footer.content-padding, left: style.page.margin.left, right: style.page.margin.right, @@ -120,9 +122,15 @@ let current-page = here().page() if current-page == 1 { [] - } else if query().first().location().page() > current-page { + } else if query() + .first() + .location() + .page() > current-page { numbering("I", nums.pos().first()) - } else if query().first().location().page() >= current-page { + } else if query() + .first() + .location() + .page() >= current-page { numbering("1", nums.pos().first()) } else { numbering("a", nums.pos().first()) @@ -159,7 +167,10 @@ // right align logo of DHBW align(right, image("res/DHBW.svg", height: style.header.logo-height))) - } else if query().first().location().page() <= here().page() { + } else if query() + .first() + .location() + .page() <= here().page() { let headers-before = query( selector(heading.where(numbering: "1.", level: 1)).before(here()), ) From 9c3ae5c9e7d8a8871edc79a08f7bd427ba38fe81 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 20:27:41 +0200 Subject: [PATCH 10/14] switched to unstable nix channel --- run-fmt.sh | 6 +++--- shell.nix | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/run-fmt.sh b/run-fmt.sh index 09bf12f..b4fee1c 100755 --- a/run-fmt.sh +++ b/run-fmt.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash function format() { # format file @@ -16,7 +16,7 @@ function format() { echo "failed format validation: $1" exit 1 fi - + local imports=$(rg "#import \"([a-z0-9/\-]+\.typ)\"" -Nor '$1' "$1") # format all included files @@ -39,4 +39,4 @@ case $1 in echo "unknown option: $1" exit 1 ;; -esac \ No newline at end of file +esac diff --git a/shell.nix b/shell.nix index 61ee97a..a71ba0e 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,5 @@ let - nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05"; + nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-unstable"; pkgs = import nixpkgs { config = {}; overlays = []; }; in From ae729230bb2dfb4c01435e29a18ab552b9fe09a1 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 20:28:50 +0200 Subject: [PATCH 11/14] made generate-theme executable --- generate-theme.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 generate-theme.sh diff --git a/generate-theme.sh b/generate-theme.sh old mode 100644 new mode 100755 From 6c8f94e4b7af018879519dcb6897feecedb4e377 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 20:36:21 +0200 Subject: [PATCH 12/14] fixed test local import --- tests/local-import/main.typ | 51 ++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/tests/local-import/main.typ b/tests/local-import/main.typ index 9197122..89d1865 100644 --- a/tests/local-import/main.typ +++ b/tests/local-import/main.typ @@ -1,29 +1,28 @@ #import "../../src/lib.typ": dhbw-template -#show: dhbw-template.with( - config: ( - lang: "en", - region: "en", - author: ( - name: "Sven Vogel", - semester: 4, - program: "Informationtechnology", - course: "TINF19IT1", - faculty: "Technik", - university: "DHBW Mannheim", - company: "ABB AG", - supervisor: "Benny Goodman", - matriculation-number: 123456789), - thesis: ( - title: "Unofficial ABB/DHBW Typst template", - subtitle: "for reports and thesises", - submission-date: "23rd march 2020", - timeframe: "1st january 2020 - 20th march 2020", - kind: "T2000", - summary: none, - abstract: none, - keywords: ( "IT", "other stuff" ), - bibliography: none, - glossary: none, - appendices: none))) +#show: dhbw-template(( + lang: "en", + region: "en", + author: ( + university: "DHBW Mannheim", + company: "ABB AG", + supervisor: "Vivaldi", + matriculation-number: 123456789, + ), + thesis: ( + title: "Unofficial ABB/DHBW Typst template", + subtitle: "for reports and thesises", + submission-date: "23rd march 2020", + timeframe: "1st january 2020 - 20th march 2020", + kind: "T2000", + summary: none, + abstract: none, + keywords: ("IT", "other stuff"), + bibliography: none, + glossary: none, + appendices: none, + ), +))[ + test +] From dabe0a2ef57682f1eae5e27c60cbf68a366fc54a Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 20:54:33 +0200 Subject: [PATCH 13/14] fixed failing tests --- run-ci.sh | 23 ++++++++---- tests/invalid-config/test-case-1.typ | 3 +- tests/invalid-config/test-case-2.typ | 56 ++++++++++++++-------------- tests/invalid-config/test-case-3.typ | 44 +++++++++++----------- tests/local-import/main.typ | 6 +-- 5 files changed, 71 insertions(+), 61 deletions(-) diff --git a/run-ci.sh b/run-ci.sh index f20cbae..02934d7 100755 --- a/run-ci.sh +++ b/run-ci.sh @@ -26,8 +26,17 @@ function enter-section() { eval "$2" exit_status=$? - if ! [ $exit_status -eq $3 ]; then - abort "command: $2 failed in section: $1" + + if [ "$3" == "should fail" ]; then + log "INFO" "expected to fail..." + if [ $exit_status -eq 0 ]; then + abort "command: $2 failed in section: $1 with: $exit_status" + fi + else + log "INFO" "expected to pass..." + if [ ! $exit_status -eq 0 ]; then + abort "command: $2 failed in section: $1 with: $exit_status" + fi fi printf "\\n" @@ -36,10 +45,10 @@ function enter-section() { enter-section "Typstyle checking" "./run-fmt.sh --check src/lib.typ" 0 enter-section "BUILD: ABB code theme" "./generate-theme.sh" 0 -enter-section "Compiling template..." "typst compile template/main.typ --root . example.pdf" 0 -enter-section "TEST: local template import" "typst compile tests/local-import/main.typ --root ." 0 -enter-section "TEST: invalid config case 1" "typst compile tests/invalid-config/test-case-1.typ --root ." 1 -enter-section "TEST: invalid config case 2" "compile tests/invalid-config/test-case-2.typ" 0 -enter-section "TEST: invalid config case 3" "typst compile tests/invalid-config/test-case-3.typ --root ." 1 +enter-section "Compiling template..." "typst compile template/main.typ --root . example.pdf" +enter-section "TEST: local template import" "typst compile tests/local-import/main.typ --root ." +enter-section "TEST: invalid config case 1" "typst compile tests/invalid-config/test-case-1.typ --root ." "should fail" +enter-section "TEST: invalid config case 2" "typst compile tests/invalid-config/test-case-2.typ --root ." +enter-section "TEST: invalid config case 3" "typst compile tests/invalid-config/test-case-3.typ --root ." "should fail" log "INFO" "CI completed successfully" diff --git a/tests/invalid-config/test-case-1.typ b/tests/invalid-config/test-case-1.typ index 92d7098..5059966 100644 --- a/tests/invalid-config/test-case-1.typ +++ b/tests/invalid-config/test-case-1.typ @@ -1,8 +1,7 @@ #import "../../src/lib.typ": dhbw-template -#show: dhbw-template.with( - config: ( +#show: dhbw-template.with(( lang: none, region: "en", author: ( diff --git a/tests/invalid-config/test-case-2.typ b/tests/invalid-config/test-case-2.typ index 10793ca..d3ec335 100644 --- a/tests/invalid-config/test-case-2.typ +++ b/tests/invalid-config/test-case-2.typ @@ -1,30 +1,32 @@ #import "../../src/lib.typ": dhbw-template -#show: dhbw-template.with( - config: ( - lang: "en", - this-key-is-not-in-config: "Ha Ha", - region: "en", - author: ( - name: "Sven Vogel", - semester: 4, - program: "Informationtechnology", - course: "TINF19IT1", - faculty: "Technik", - university: "DHBW Mannheim", - company: "ABB AG", - supervisor: "Benny Goodman", - matriculation-number: 123456789), - thesis: ( - title: "Unofficial ABB/DHBW Typst template", - subtitle: "for reports and thesises", - submission-date: "23rd march 2020", - timeframe: "1st january 2020 - 20th march 2020", - kind: "T2000", - summary: none, - abstract: none, - keywords: ( "IT", "other stuff" ), - bibliography: none, - glossary: none, - appendices: none))) +#show: dhbw-template.with(( + lang: "en", + this-key-is-not-in-config: "Ha Ha", + region: "en", + author: ( + name: "Sven Vogel", + semester: 4, + program: "Informationtechnology", + course: "TINF19IT1", + faculty: "Technik", + university: "DHBW Mannheim", + company: "ABB AG", + supervisor: "Benny Goodman", + matriculation-number: 123456789, + ), + thesis: ( + title: "Unofficial ABB/DHBW Typst template", + subtitle: "for reports and thesises", + submission-date: "23rd march 2020", + timeframe: "1st january 2020 - 20th march 2020", + kind: "T2000", + summary: none, + abstract: none, + keywords: ("IT", "other stuff"), + bibliography: none, + glossary: none, + appendices: none, + ), +)) diff --git a/tests/invalid-config/test-case-3.typ b/tests/invalid-config/test-case-3.typ index ef42dd8..f274b60 100644 --- a/tests/invalid-config/test-case-3.typ +++ b/tests/invalid-config/test-case-3.typ @@ -1,24 +1,26 @@ #import "../../src/lib.typ": dhbw-template -#show: dhbw-template.with( - config: ( - lang: "en", - region: "en", - author: ( - university: "DHBW Mannheim", - company: "ABB AG", - supervisor: none, - matriculation-number: 123456789), - thesis: ( - title: "Unofficial ABB/DHBW Typst template", - subtitle: "for reports and thesises", - submission-date: "23rd march 2020", - timeframe: "1st january 2020 - 20th march 2020", - kind: "T2000", - summary: none, - abstract: none, - keywords: ( "IT", "other stuff" ), - bibliography: none, - glossary: none, - appendices: none))) +#show: dhbw-template.with(( + lang: "en", + region: "en", + author: ( + university: "DHBW Mannheim", + company: "ABB AG", + supervisor: none, + matriculation-number: 123456789, + ), + thesis: ( + title: "Unofficial ABB/DHBW Typst template", + subtitle: "for reports and thesises", + submission-date: "23rd march 2020", + timeframe: "1st january 2020 - 20th march 2020", + kind: "T2000", + summary: none, + abstract: none, + keywords: ("IT", "other stuff"), + bibliography: none, + glossary: none, + appendices: none, + ), +)) diff --git a/tests/local-import/main.typ b/tests/local-import/main.typ index 89d1865..169829d 100644 --- a/tests/local-import/main.typ +++ b/tests/local-import/main.typ @@ -1,7 +1,7 @@ #import "../../src/lib.typ": dhbw-template -#show: dhbw-template(( +#show: dhbw-template.with(( lang: "en", region: "en", author: ( @@ -23,6 +23,4 @@ glossary: none, appendices: none, ), -))[ - test -] +)) From 1548bf8c5b09aed1758cb9f002784f78c9800dc8 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 27 Aug 2024 20:58:01 +0200 Subject: [PATCH 14/14] changed release pipeline to make use of nix --- .gitea/workflows/release.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 39496c8..f2f6809 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -1,28 +1,31 @@ name: release -on: +on: push: tags: - - '*' + - 'v*.*.*' jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - name: Check out repository code + uses: actions/checkout@v3 + - name: Install dependencies for Nix setup action + run: | + apt update -y + apt install sudo -y + - name: Setup Nix + uses: cachix/install-nix-action@v27 with: - fetch-depth: 0 - - name: Install Typst CLI - run: curl -fsSL https://typst.community/typst-install/install.sh | sh -s "$TYPST_VERSION" - - name: Set up Python 3 - run: apt update -y && apt install python3-pip -y + nix_path: nixpkgs=channel:nixos-unstable - name: Run CI - run: bash -c ./run-ci.sh + run: nix-shell --run ./run-ci.sh - name: Setup go uses: https://github.com/actions/setup-go@v4 with: go-version: '>=1.20.1' - - name: Create release + - name: Create release id: create-release uses: https://gitea.com/actions/release-action@main with: