diff --git a/examples/qualification-thesis/bibliography.yml b/examples/qualification-thesis/bibliography.yml new file mode 100644 index 0000000..ea19de3 --- /dev/null +++ b/examples/qualification-thesis/bibliography.yml @@ -0,0 +1,26 @@ +typst: + type: Web + title: Typst + author: + - Mädje + - Laurenz + - Haug + - Martin + - Typst Projekta Izstrādātāji + url: {value: "https://typst.app/", date: 2025-01-01} +lvs_68: + type: Book + title: Programmatūras prasību specifikācijas ceļvedis + author: Institūcija SIA "Latvijas standarts" + issue: 68 + date: 1996-03-27 + organization: Latvijas Nacionālais standartizācijas un metroloģijas centrs + page-total: 22 +lvs_72: + type: Book + title: Ieteicamā prakse programmatūras projektējuma aprakstīšanai + author: Institūcija SIA "Latvijas standarts" + issue: 72 + date: 1996-03-27 + organization: Latvijas Nacionālais standartizācijas un metroloģijas centrs + page-total: 13 diff --git a/examples/qualification-thesis/main.typ b/examples/qualification-thesis/main.typ new file mode 100644 index 0000000..3036e6b --- /dev/null +++ b/examples/qualification-thesis/main.typ @@ -0,0 +1,286 @@ +#import "@preview/fletcher:0.5.8" as fletcher: diagram, edge, node +#import fletcher.shapes: cylinder, ellipse +#import "@preview/solo-lu-df:0.0.1": ludf +#import "utils/tables.typ": function-table +#import "utils/diagrams.typ": data-store, dpd-database, dpd-edge, process + +#show: ludf.with( + title: "Darba Nosaukums", + thesis-type: "Kvalifikācijas Darbs", + authors: ( + ( + name: "Jānis Bērziņš", + code: "jb12345", + location: [Riga, Latvia], + email: "jb12345@edu.lu.lv", + ), + ( + name: "Zane Kalniņa", + code: "zk67890", + location: [Riga, Latvia], + email: "zk67890@edu.lu.lv", + ), + ), + date: ( + year: 2025, + ), + place: "Rīga", + bibliography: bibliography("bibliography.yml"), + abstract: ( + primary: ( + text: [ + #lorem(50) + + #lorem(30) + + #lorem(20) + ], + keywords: ( + "Foo", + "Bar", + "Baz", + ), + ), + secondary: ( + text: [ + #lorem(20) + + #lorem(30) + + #lorem(50) + ], + keywords: ( + "foo", + "bar", + "baz", + ), + ), + ), +) + + +#set heading(numbering: none) += Apzīmējumu saraksts +/ Docs: Typst dokumentācija.#footnote[https://typst.com/docs/] +/ Universe: Typst kopienas paketes un šabloni.#footnote[https://typst.app/universe/] + += Ievads +== Nolūks +#lorem(100) + +== Darbības sfēra + +== Saistība ar citiem dokumentiem +PPS ir izstrādāta, ievērojot LVS 68:1996 "Programmatūras prasību specifikācijas +ceļvedis" @lvs_68 un LVS 72:1996 "Ieteicamā prakse programmatūras projektējuma +aprakstīšanai" standarta prasības @lvs_72. + +== Pārskats + +#set heading(numbering: "1.1.") + += Vispārējais apraksts +== Esošā stāvokļa apraksts +== Pasūtītājs +== Produkta perspektīva +== Darījumprasības +== Sistēmas lietotāji + +Skatīt @dpd-0 + +#figure( + caption: [\0. līmeņa DPD], + diagram( + data-store((0, 0), [Lietotājs]), + dpd-edge("rr,ddd,ll", align(center)[Ievades ierīces\ dati]), + process((0, 3), [Sistēma], inset: 20pt), + dpd-edge( + "lll,uuu,rrr", + align(center)[Vizuālās\ izvades dati], + ), + dpd-edge( + "l,uuu,r", + align(center)[Audio\ izvades dati], + ), + ), +) + +/// Or use an image +// +// #figure( +// caption: "0. līmeņa DPD", +// image("path/to/image"), +// ) + +== Vispārējie ierobežojumi + += Programmatūras prasību specifikācija +== Konceptuālais datu bāzes apraksts +== Funkcionālās prasības + +#figure( + caption: [\1. līmeņa DPD], + diagram({ + dpd-database((0, 0), [Datubāze], snap: -1) + dpd-edge("ldd", align(center)[Neapstrādāti\ ārējie dati]) + dpd-edge("rrr,d", align(center)[Neapstrādāti\ dati]) + + process( + (-1, 2), + [Ārējs apstrādātājs], + inset: 20pt, + stroke: (thickness: 1pt, dash: "dashed"), + ) + dpd-edge("r,uu", align(center)[Apstrādāti\ ārējie dati]) + + data-store((0, -2), [Lietotājs]) + dpd-edge("dd", align(center)[Neapstrādāti\ lietotāja dati]) + + process((3, 1), [A modulis], inset: 20pt) + dpd-edge("lllu", align(center)[Apstrādāti dati], shift: 20pt) + }), +) + +=== Funkciju sadalījums moduļos +Funkciju sadalījums moduļos ir aprakstīts tabulā (@function-modules[tab]). + +#figure( + caption: "Funkciju sadalījums pa moduļiem", + table( + columns: (auto, 1fr, auto), + align: left, + table.header([Modulis], [Funkcija], [Identifikators]), + + table.cell(rowspan: 1)[A modulis], + [A saskarne], [#link()[AF01]], + + table.cell(rowspan: 2)[B modulis], + [B saskarne], [#link()[BF01]], + [B apstrāde], [#link()[BF02]], + ), +) + +=== A Modulis +#function-table( + "A Saskarne", + "AF01", + [#lorem(15)], + [ + + #lorem(4) + + #lorem(5) + + #lorem(6) + ], + [ + + #lorem(4) + + #lorem(5) + + #lorem(6) + + #lorem(7) + + #lorem(8) + - #lorem(2) + - #lorem(1) + - #lorem(3) + - #lorem(1) + ], + [ + + #lorem(10) + + #lorem(10) + ], +) + +=== B Modulis + +#function-table( + "B Saskarne", + "BF01", + [#lorem(15)], + [ + + #lorem(4) + + #lorem(5) + + #lorem(6) + ], + [ + + #lorem(4) + + #lorem(5) + + #lorem(6) + + #lorem(7) + + #lorem(8) + - #lorem(2) + - #lorem(1) + - #lorem(3) + - #lorem(1) + ], + [ + + #lorem(10) + + #lorem(10) + ], + [ + + #lorem(10) + + #lorem(10) + ], +) + + +#function-table( + "B Apstrāde", + "BF02", + [#lorem(15)], + [ + + #lorem(4) + + #lorem(5) + + #lorem(6) + ], + [ + + #lorem(4) + + #lorem(5) + + #lorem(6) + + #lorem(7) + + #lorem(8) + - #lorem(2) + - #lorem(1) + - #lorem(3) + - #lorem(1) + ], + [ + + #lorem(10) + + #lorem(10) + ], +) + +== Nefunkcionālās prasības +=== Veiktspējas prasības + += Programmatūras projektējuma apraksts +== Datu bāzes projektējums +=== Datu bāzes loģiskais ER modelis +Skatīt @logical-erd + +#figure( + caption: "Datu bāzes loģiskais ER modelis", + [\], + // image("path/to/image") +) + +=== Datu bāzes fiziskais ER modelis +Skatīt @physical-erd[attēlu]. + +#figure( + caption: "Datu bāzes loģiskais ER modelis", + [\], + // image("path/to/image") +) + +=== Datu bāzes tabulu apraksts + +== Daļējs funkciju projektējums + +== Daļējs lietotāju saskarņu projektējums +=== Navigācija +sk. @view-flow-diagram + +#figure( + caption: "Ekrānskatu plūsmas diagramma", + [\], + // image("path/to/image") +) + +=== Ekrānskati diff --git a/examples/qualification-thesis/utils/diagrams.typ b/examples/qualification-thesis/utils/diagrams.typ new file mode 100644 index 0000000..2a6dc99 --- /dev/null +++ b/examples/qualification-thesis/utils/diagrams.typ @@ -0,0 +1,48 @@ +#import "@preview/fletcher:0.5.8" as fletcher: diagram, edge, node +#import fletcher.shapes: cylinder, diamond, ellipse + +#let default-node-stroke = 1pt +#let default-edge-stroke = 1pt + +/// Read https://github.com/typst/packages/raw/main/packages/preview/fletcher/0.5.8/docs/manual.pdf for more information + +#let data-store(pos, text) = { + node( + pos, + text, + inset: 20pt, + stroke: default-node-stroke, + ) +} + +#let process(..args) = { + node( + inset: 10pt, + shape: ellipse, + stroke: default-node-stroke, + ..args, + ) +} + +#let dpd-edge(..args) = { + edge( + label-pos: 0.5, + stroke: default-edge-stroke, + label-anchor: "center", + label-fill: white, + corner-radius: 4pt, + label-size: 10pt, + ..args, + "-|>", + ) +} + +#let dpd-database(..args) = { + node( + shape: cylinder, + height: 6em, + width: 10em, + stroke: default-node-stroke, + ..args, + ) +} diff --git a/examples/qualification-thesis/utils/tables.typ b/examples/qualification-thesis/utils/tables.typ new file mode 100644 index 0000000..bdf29a8 --- /dev/null +++ b/examples/qualification-thesis/utils/tables.typ @@ -0,0 +1,56 @@ +/// Creates a two-column "function" table with a caption. +/// +/// Intended for "Funkciju sadalījums moduļos" section +/// +/// Parameters: +/// - caption: optional caption; defaults to the first positional item. +/// - title: tuple of column/section titles (defaults provided). +/// - items: positional cells; first two items populate the top row, +/// remaining items are paired with the titles ["Apraksts", "Ievade", ...] +/// +/// Behavior: +/// - Renders the first two titles as table headers and the first two +/// positional items beneath them. +/// - For titles from index 2 onward, each title is rendered as a full-width +/// (colspan 2) bold row followed by a full-width row containing the +/// corresponding positional item. Missing items become empty strings. +/// - Safe for fewer/more items: missing values are coerced to "", extra +/// items beyond the paired section are ignored. +/// +/// Default caption to the first positional item if none provided. +#let function-table( + caption: "", + titles: ( + "Funkcijas nosaukums", + "Funkcijas identifikators", + "Apraksts", + "Ievade", + "Apstrāde", + "Izvade", + "Paziņojumi", + ), + ..items, +) = { + if caption == "" { + caption = items.pos().first() + } + + let cells = titles + .slice(2) // start from "Apraksts" + .zip(items.pos().slice(2)) + .map(pair => ( + table.cell(colspan: 2, strong(pair.at(0))), + table.cell(colspan: 2, pair.at(1)), + )) + .flatten() + + figure( + caption: caption, + table( + columns: (1fr, 1fr), + strong(titles.at(0)), strong(titles.at(1)), + items.pos().at(0), items.pos().at(1), + ..cells, + ), + ) +} diff --git a/lib.typ b/src/lib.typ similarity index 83% rename from lib.typ rename to src/lib.typ index 10452c0..9024f75 100644 --- a/lib.typ +++ b/src/lib.typ @@ -1,5 +1,5 @@ #import "@preview/headcount:0.1.0": * -#import "utils.typ": render-abstract +#import "utils.typ": make-abstract, make-documentary-page, make-title #let indent = 1cm @@ -217,44 +217,17 @@ ) - // Display the paper's title and authors at the top of the page, - // spanning all columns (hence floating at the scope of the - // columns' parent, which is the page). - // The page can contain a logo if you pass one with `logo: "logo.png"`. - align(center, upper(text(size: 16pt, [ - #university\ - #faculty - ]))) - - v(1fr) - - align(center, upper(text(20pt, weight: "bold", title))) - - v(0.2fr) - - align(center, upper(text(size: 16pt, thesis-type))) - - v(1fr) - - // Author information - context [ - #set par(first-line-indent: 0pt) - #if authors.len() > 1 { "Autori:" } else { "Autors:" } - #authors.map(author => strong(author.name)).join(", ") - - #if authors.len() > 1 { "Studentu" } else { "Studenta" } - apliecības Nr.: #authors.map(author => author.code).join(", ") - - #if advisors.len() > 0 [ - Darba #if advisors.len() > 1 { "vadītāji:" } else { "vadītājs:" } - #advisors.map(advisor => [#advisor.title #advisor.name]).join("\n") - ] - ] - - v(0.5fr) - - align(center, upper([#place #date.year])) - + make-title( + title, + authors, + advisors, + university, + faculty, + thesis-type, + date, + place, + logo, + ) // Start page numbering set page(numbering: "1", number-align: center) @@ -262,8 +235,8 @@ // Display abstract and keywords. if abstract != none { - render-abstract("primary", abstract.primary) - render-abstract("secondary", abstract.secondary) + make-abstract("primary", abstract.primary) + make-abstract("secondary", abstract.secondary) } // Table of contents. @@ -279,4 +252,6 @@ // Display bibliography. bibliography + + make-documentary-page() } diff --git a/src/utils.typ b/src/utils.typ new file mode 100644 index 0000000..8ed5898 --- /dev/null +++ b/src/utils.typ @@ -0,0 +1,98 @@ +#let merge(a, b) = { + let result = a + for (k, v) in b { result.at(k) = v } + result +} + +#let make-abstract(role, abstract) = { + // Define role-based defaults + let defaults = if role == "primary" { + ( + lang: "lv", + title: "Anotācija", + keyword-title: "Atslēgvārdi", + text: [], + keywords: [], + ) + } else { + ( + lang: "en", + title: "Abstract", + keyword-title: "Keywords", + text: [], + keywords: [], + ) + } + + // Merge defaults with overrides + let abs = merge(defaults, abstract) + + context [ + #set text(lang: abs.lang) + #heading( + level: 1, + outlined: false, + numbering: none, + abs.title, + ) + + // Abstract body text + #abs.text + + // Keywords + #par(first-line-indent: 0cm)[ *#abs.keyword-title*: ] + #abs.keywords.join(", "). + ] +} + +// Display the paper's title and authors at the top of the page, +// spanning all columns (hence floating at the scope of the +// columns' parent, which is the page). +// The page can contain a logo if you pass one with `logo: "logo.png"`. +#let make-title( + title, + authors, + advisors, + university, + faculty, + thesis-type, + date, + place, + logo, +) = { + align(center, upper(text(size: 16pt, [ + #university\ + #faculty + ]))) + + v(1fr) + + align(center, upper(text(20pt, weight: "bold", title))) + + v(0.2fr) + + align(center, upper(text(size: 16pt, thesis-type))) + + v(1fr) + + // Author information + context [ + #set par(first-line-indent: 0pt) + #if authors.len() > 1 { "Autori:" } else { "Autors:" } + #authors.map(author => strong(author.name)).join(", ") + + #if authors.len() > 1 { "Studentu" } else { "Studenta" } + apliecības Nr.: #authors.map(author => author.code).join(", ") + + #if advisors.len() > 0 [ + Darba #if advisors.len() > 1 { "vadītāji:" } else { "vadītājs:" } + #advisors.map(advisor => [#advisor.title #advisor.name]).join("\n") + ] + ] + + v(0.5fr) + + align(center, upper([#place #date.year])) +} + +#let make-documentary-page() = {} diff --git a/typst.toml b/typst.toml index f85ea53..364137c 100644 --- a/typst.toml +++ b/typst.toml @@ -2,7 +2,7 @@ name = "solo-lu-df" version = "0.0.1" compiler = "0.13.0" -entrypoint = "lib.typ" +entrypoint = "src/lib.typ" repository = "https://github.com/kristoferssolo/LU-DF-Typst-Template" authors = ["Kristofers Solo "] license = "MIT" diff --git a/utils.typ b/utils.typ deleted file mode 100644 index 66841de..0000000 --- a/utils.typ +++ /dev/null @@ -1,46 +0,0 @@ -#let merge(a, b) = { - let result = a - for (k, v) in b { result.at(k) = v } - result -} - -#let render-abstract(role, abstract) = { - // Define role-based defaults - let defaults = if role == "primary" { - ( - lang: "lv", - title: "Anotācija", - keyword-title: "Atslēgvārdi", - text: [], - keywords: [], - ) - } else { - ( - lang: "en", - title: "Abstract", - keyword-title: "Keywords", - text: [], - keywords: [], - ) - } - - // Merge defaults with overrides - let abs = merge(defaults, abstract) - - context [ - #set text(lang: abs.lang) - #heading( - level: 1, - outlined: false, - numbering: none, - abs.title, - ) - - // Abstract body text - #abs.text - - // Keywords - #par(first-line-indent: 0cm)[ *#abs.keyword-title*: ] - #abs.keywords.join(", "). - ] -}