1
0

39 Commits
v0.0.0 ... main

Author SHA1 Message Date
151f1c9128 feat(template): add asserts 2025-06-11 18:06:39 +03:00
6207d2d82a feat(style)!: remove reference styling & fix figure numbering for appendices
Use `@some_label[див. фігуру]` to get a "див. фігуру 42" link.
2025-05-19 17:24:36 +03:00
c2755772e1 feat(template)!: "pz-lb" template rewrite as a "general" one 2025-05-14 10:53:49 +03:00
f4a5ebc7fe feat(style)!: extract styling to style.typ, bump version to 0.2.0 2025-05-12 10:31:53 +03:00
3ca8409e58 fix: heading numbering when no title 2025-04-26 18:38:36 +03:00
e0811afaae fix: move appendix styling out of the coursework template
It is now possible to style headings as appendices in the pz-lb template via `#show: appendices_style`.
2025-04-20 21:21:16 +03:00
7ec79ee898 fix: make variant in authors truly optional
In `pz-lb` template the `authors.variant` may be omitted now.
2025-04-16 22:05:22 +03:00
47117749cf fix: set fallback monospace font
Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-04-08 21:22:16 +03:00
e214656166 docs(readme): update readme, add a note
Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-03-24 00:27:50 +02:00
99234a73a9 README.md: add an image
assets/pz-lb_title_page.png: the image added

Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-03-24 00:10:21 +02:00
901d670a1c Merge pull request 'feat: add some random subjects to config/universities.yaml' (#13) from sekomi/typst_nure_template:0.1.0 into 0.1.0
Reviewed-on: pencelheimer/typst_nure_template#13
2025-03-23 23:58:41 +02:00
594e908bb1 feat: add some random subjects to config/universities.yaml 2025-03-23 23:41:32 +02:00
32c6a1663c feat: make mentor.degree in pz-lb optional
fix: remove personal font preference

Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-03-23 16:15:49 +02:00
9cc7229851 style: reformat with "typstyle -c 120"
Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-03-20 16:45:59 +02:00
1646f5249b fix: update templates accordingly
Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-03-20 16:44:46 +02:00
2de5cb4c58 feat!: rename "cw-template" to "coursework"
feat!: rename "pz-lb-template" to "pz-lb"

Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-03-20 16:41:59 +02:00
dec7c58db2 lib.typ: make title in pz-lb-template optional
Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-03-20 15:52:22 +02:00
2653e7dba2 style: remove quotes
fix: fix 125 department name

Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-03-20 15:42:23 +02:00
816d07f745 fix!: change "СПМ" to "СМП"
feat: add more subjects, sort them
2025-03-20 14:41:15 +02:00
7799435039 Merge pull request 'version 0.1.0' (#12) from unexplrd/typst_nure_template:main into 0.1.0
Reviewed-on: pencelheimer/typst_nure_template#12
2025-03-18 12:28:54 +02:00
5be6cea4fb fix: fix multiple authors
docs(config): adjust and fix typo
2025-03-15 16:36:16 +02:00
5bc79a196e WIP: introduce yaml config examples in a template 2025-03-14 17:59:18 +02:00
c1ad952c7c fix: fix values and refactor, move yaml to config/ 2025-03-13 18:28:39 +02:00
dc3358d986 WIP: feat!: move university-related info to yaml file 2025-03-13 17:57:46 +02:00
6bf37099b4 refactor: move university name into a variable 2025-03-13 17:31:22 +02:00
bf00b3de5d feat!: add course and semester keys for authors
fix: bring cw-template more in line with pz-lb-template
fix: remove hard-coded values
docs: update a template
2025-03-13 16:52:52 +02:00
c049a9a3ce style: reformat with 120 col width 2025-03-13 13:08:18 +02:00
22fb1de736 docs: fix 2025-03-13 12:56:18 +02:00
1db499dad4 docs(readme): change repo owner 2025-03-13 12:42:14 +02:00
41dcbeb1ec feat!: bump version to 0.1.0
fix: adjust templates
style: reformat lib.typ w/ 120 column width
2025-03-13 12:37:58 +02:00
429f632841 fix!: remove unnecessary gender key in cw_template
fix: add more subjects
docs: unify comments with pz_lb_template
2025-03-13 12:35:12 +02:00
b3214e2150 feat!: rename some parametes to avoid redundancy
fix: avoid hard-coded defaults
docs(readme): add more detail
2025-03-13 12:12:57 +02:00
d60d3a9c89 misc: change .gitignore to ignore all pdf files 2025-03-12 23:21:33 +02:00
63dbd82e4d docs(readme): update structure 2025-03-12 23:15:40 +02:00
0b8ceda4f1 feat!: rename "lab-pz-template" to "pz-lb-template"
feat!: make authors.*.edu_program optional, derive it from edu_program_short instead
docs: minor changes to readme and lab template
2025-03-12 23:02:32 +02:00
cf10e0fbdc style: format in 120 column width 2025-03-12 20:42:17 +02:00
33d067b67e feat!: move department_gen to edu_programs
feat!: rename "shorthand" variables to "short"
WIP: feat!: derive group name from edu_program
docs(template): adjust templates accordingly
style: format with typstyle
2025-03-12 20:24:48 +02:00
0e0dc20e9b fix: remove unnecessary variable 2025-03-12 19:11:06 +02:00
b8a309ad2c feat!: change mentor to mentors for lab-pz
feat: implement plural mentor referral
fix: added subject and edu_program
style: format with typstyle
2025-03-12 19:08:41 +02:00
9 changed files with 493 additions and 387 deletions

4
.gitignore vendored
View File

@ -1 +1,3 @@
template.pdf *.pdf
test
config

View File

@ -1,4 +1,8 @@
> [!CAUTION]
> Experimental fork. Successfully **breaking** stuff each commit. Documentation is **not** up to date.
# Typst Template for NURE Works # Typst Template for NURE Works
![pz-lb title page](assets/pz-lb_title_page.png)
## General Info ## General Info
@ -6,12 +10,12 @@ This project contains two template functions and some utilities for writing NURE
### Templates ### Templates
#### `pz-lb-template` - For Laboratory and Practical Works #### `general` - For general works
This template: This template:
- Sets up document styles; - Sets up document styles;
- Formats the title page according to NURE guidelines. - Formats the title page according to NURE/DSTU guidelines.
#### `cw-template` - For Course Works #### `coursework` - For Course Works
This template: This template:
- Sets up document styles; - Sets up document styles;
- Formats the title, task, calendar plan, and abstract pages; - Formats the title, task, calendar plan, and abstract pages;
@ -29,43 +33,84 @@ This template:
### As a local typst package ### As a local typst package
1. Clone this repository into ~/.local/share/typst/packages/: 1. Clone this repository into ~/.local/share/typst/packages/:
```bash ```bash
git clone https://gitea.linerds.us/pencelheimer/typst_nure_template.git ~/.local/share/typst/packages/local/nure/0.0.0 git clone https://github.com/noatu/typst-nure-template.git ~/.local/share/typst/packages/local/nure/0.2.0
``` ```
2. Init your project with Typst: 2. Init your project with Typst:
```bash ```bash
typst init @local/nure:0.0.0 project-name typst init @local/nure:0.2.0 project-name
``` ```
### As a file in your project ### As a standalone file
Include lib.typ in your project and utilize the provided functions: Copy `lib.typ` to your project's root directory.
### In your project
```typst ```typst
// Import the template // Import the template either from a local package...
#import "lib.typ": * #import "@local/nure:0.2.0": *
// ...or by importing a lib.typ directly
// #import "/lib.typ": *
// Setup the document // 1. Setup the document
#show: lab-pz-template.with( // by setting values directly...
title: "Some title", #show: general.with(
title: "Some title",
// etc: "and so on",
// ...
) )
// ...or using a doc.yaml file
#show: general.with(..yaml("doc.yaml"))
// this template automatically inserts a `=title` // this template automatically inserts a `=title`
// Write your content // Write your content
#v(-spacing) // remove spacing between headings #v(-spacing) // remove spacing between headings
== Purpose == Purpose
Some text Some text
// ...or include your modules
#include "src/intro.typ"
#include "src/chapter1.typ"
#include "src/chapter2.typ"
// NOTE: if you want to use variables or utils provided by the package,
// you have to import the package or a lib.typ inside a module.
// If you ever need appendices in general template use the show rule
// WARNING: when using coursework template use its own argument,
// so it can put bibliography before appendices
#show: appendices-style
= Quote
#link("https://youtu.be/bJQj1uKtnus")[
The art isn't the art, the art is never the art,
the art is the thing that happens inside you when you make it and the feeling in the heart of the beholder.
]
``` ```
### Notes: ### Notes:
1. Use `#v(-spacing)` to remove vertical spacing between titles (this cannot be automatically handled by the template). Variable `spacing` used here is imported from the template. 1. Use `#v(-spacing)` to remove vertical spacing between titles (this cannot be automatically handled by the template). Variable `spacing` used here is imported from the template.
2. When importing `@local/nure:0.2.0` and specifying file paths in functions handled by the package, the path will relative to package's root directory, e.g. setting `#show: coursework.with(bib_path: "bibl.yml")` will evaluate to `~/.local/share/typst/packages/local/nure/0.2.0/bibl.yml`, the same is for `#img` function, which makes it quite annoying and forces one to import `lib.typ` file. Please open an issue or contact us in any other way if you have any advice.
### Example Project Structure ### Example Project Structure
``` ```
project-folder/ project/
├── main.typ ├── main.typ -- for boilerplate code and importing everything
├── template.typ ├── src/
├── images/ ├── intro.typ
│ ├── figure1.png │ ├── chapter1.typ
│ ├── figure2.png │ ├── chapter2.typ
── ... ── ...
├── ... ├── figures/
│ ├── chapter1/
│ │ ├── figure1.png
│ │ ├── figure2.png
│ │ ├── figure3.png
│ │ └── ...
│ ├── chapter2/
│ │ ├── figure1.png
│ │ ├── figure2.png
│ │ ├── figure3.png
│ │ └── ...
│ └── ...
└── ...
``` ```

BIN
assets/pz-lb_title_page.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

393
lib.typ
View File

@ -1,31 +1,23 @@
// SPDX-License-Identifier: GPL-3.0
/*
* typst-nure-template/lib.typ
*
* Typst library for NURE (Kharkiv National University of Radio Electronics) works
*/
// Academic aliases {{{1 #import "style.typ": spacing, dstu-style, appendices-style
#import "template.typ": *
/// subject abbreviations to full names // TODO: Template formatting functions {{{
#let subjects = (
"БД": "Бази даних",
"ОПНJ": "Основи програмування на Java",
"ОС": "Операційні системи",
"ПП": "Проектний практикум",
"СПМ": "Скриптові мови програмування",
"Ф": "Філософія",
)
/// education program abbreviations to name & number
#let edu_programs = (
"ПЗПІ": (
name: "Інженерія програмного забезпечення",
number: 121, // TODO: ПЗПІ is "F2" now
),
)
// Template formatting functions {{{1
/// numberless heading /// numberless heading
#let nheading(title) = heading(depth: 1, numbering: none, title) #let nheading(title) = heading(depth: 1, numbering: none, title)
/// fill horizontal space with a box and not an empty space /// fill horizontal space with a box and not an empty space
#let hfill(width) = box(width: width, repeat("")) // NOTE: This is a HAIR SPACE (U+200A), not a regular space #let hfill(width) = box(
width: width,
repeat(""),
) // NOTE: This is a HAIR SPACE (U+200A), not a regular space
/// make underlined cell with filled value /// make underlined cell with filled value
#let uline(align: center, content) = underline[ #let uline(align: center, content) = underline[
@ -53,7 +45,11 @@
"грудня", "грудня",
).at(month - 1) ).at(month - 1)
// Helper functions {{{1 // }}}
// TODO: Helper functions {{{
// TODO: those are dependent on path, move to separate file as a separate sublib for local usage.
/// captioned image with label derived from path: /// captioned image with label derived from path:
/// - "image.png" = @image /// - "image.png" = @image
@ -68,7 +64,9 @@
#let img(path, caption, ..sink) = { #let img(path, caption, ..sink) = {
let parts = path.split(".").first().split("/") let parts = path.split(".").first().split("/")
let label_string = if parts.len() <= 2 or parts.at(-1).starts-with(parts.at(-2)) { let label_string = if (
parts.len() <= 2 or parts.at(-1).starts-with(parts.at(-2))
) {
// ("image",), (_, "image") and (.., "img", "img_image") // ("image",), (_, "image") and (.., "img", "img_image")
parts.last() parts.last()
} else { } else {
@ -77,189 +75,53 @@
}.replace(" ", "_") }.replace(" ", "_")
let caption = if sink.pos().len() == 0 { let caption = if sink.pos().len() == 0 {
caption + " (рисунок виконано самостійно)"
} else if sink.pos().first() == none {
caption caption
} else if sink.pos().first() == none {
caption + " (рисунок виконано самостійно)"
} else { } else {
[#caption (за даними #sink.pos().first())] [#caption (за даними #sink.pos().first())]
} }
[#figure(image(path, ..sink.named()), caption: caption) #label(label_string)] [#figure(
image(path, ..sink.named()),
caption: caption,
) #label(label_string)]
} }
// Styling {{{1 // }}}
/// NOTE: may be wrong
#let ua_alpha_numbering = "абвгдежиклмнпрстуфхцшщюя".split("") // 0 = "", 1 = "а"
// general outlook {{{2 // TODO: Coursework template {{{
// spacing between lines
#let spacing = 0.95em
#let style(it) = {
set page(
paper: "a4",
margin: (top: 20mm, right: 10mm, bottom: 20mm, left: 25mm),
number-align: top + right,
numbering: (..numbers) => {
if numbers.pos().at(0) != 1 {
numbering("1", numbers.pos().at(0))
}
},
)
set text(font: ("Times New Roman", "Liberation Serif"), size: 14pt, hyphenate: false, lang: "uk")
set par(justify: true, first-line-indent: (amount: 1.25cm, all: true))
set underline(evade: false)
// set 1.5 line spacing
set block(spacing: spacing)
set par(spacing: spacing)
set par(leading: spacing)
// enums and lists {{{2
set enum(numbering: i => { ua_alpha_numbering.at(i) + ")" }, indent: 1.25cm, body-indent: 0.5cm)
show enum: it => {
set enum(indent: 0em, numbering: "1)")
it
}
set list(indent: 1.35cm, body-indent: 0.5cm, marker: [--])
// figures {{{2
show figure: it => {
v(spacing * 2, weak: true)
it
v(spacing * 2, weak: true)
}
set figure.caption(separator: [ -- ])
show figure.where(kind: table): set figure.caption(position: top)
show figure.caption.where(kind: table): set align(left)
// figure numbering
show heading.where(level: 1): it => {
counter(math.equation).update(0)
counter(figure.where(kind: image)).update(0)
counter(figure.where(kind: table)).update(0)
counter(figure.where(kind: raw)).update(0)
it
}
set math.equation(numbering: (..num) => numbering("(1.1)", counter(heading).get().at(0), num.pos().first()))
set figure(numbering: (..num) => numbering("1.1", counter(heading).get().at(0), num.pos().first()))
// appearance of references to images and tables {{{2
set ref(
supplement: it => {
if it == none or not it.has("kind") {
it
} else if it.kind == image {
"див. рис."
} else if it.kind == table {
"див. таблицю"
} else {
it
}
},
)
show ref: it => {
let el = it.element
if el == none or not el.has("kind") {
return it
}
if el.kind != image and el.kind != table {
return it
}
[(#it)]
}
// headings {{{2
set heading(numbering: "1.1")
show heading.where(level: 1): it => {
set align(center)
set text(size: 14pt, weight: "semibold")
pagebreak(weak: true)
upper(it)
v(spacing * 2, weak: true)
}
show heading.where(level: 2): it => {
set text(size: 14pt, weight: "regular")
v(spacing * 2, weak: true)
block(width: 100%, spacing: 0em)[
#h(1.25cm)
#counter(heading).display(it.numbering)
#it.body
]
v(spacing * 2, weak: true)
}
show heading.where(level: 3): it => {
set text(size: 14pt, weight: "regular")
v(spacing * 2, weak: true)
block(width: 100%, spacing: 0em)[
#h(1.25cm)
#counter(heading).display(it.numbering)
#it.body
]
v(spacing * 2, weak: true)
}
// listings {{{2
show raw: it => {
let new_spacing = 0.5em
set block(spacing: new_spacing)
set par(
spacing: new_spacing,
leading: new_spacing,
)
set text(size: 11pt, font: "Courier New", weight: "semibold")
v(spacing * 2.5, weak: true)
pad(it, left: 1.25cm)
v(spacing * 2.5, weak: true)
}
it
}
// Coursework template {{{1
/// DSTU 3008:2015 Template for NURE /// DSTU 3008:2015 Template for NURE
/// -> content /// -> content
/// - doc (content): Content to apply the template to. /// - doc (content): Content to apply the template to.
/// - title (str): Title of the document. /// - title (str): Title of the document.
/// - subject_shorthand (str): Subject short name. /// - subject (str): Subject short name.
/// - department_gen (str): Department name in genitive form. /// - authors ((name: str, full_name_gen: str, variant: int, course: int, semester: int, group: str, gender: str),): List of authors.
/// - authors ((name: str, full_name_gen: str, variant: int, group: str, gender: str),): List of Authors dicts. /// - mentors ((name: str, degree: str),): List of mentors.
/// - mentors ((name: str, gender: str, degree: str),): List of mentors dicts. /// - edu_program (str): Education program shorthand.
/// - edu_program_shorthand (str): Education program shorthand.
/// - task_list (done_date: datetime, initial_date: datetime, source: (content | str), content: (content | str), graphics: (content | str)): Task list object. /// - task_list (done_date: datetime, initial_date: datetime, source: (content | str), content: (content | str), graphics: (content | str)): Task list object.
/// - calendar_plan ( plan_table: (content | str), approval_date: datetime): Calendar plan object. /// - calendar_plan ( plan_table: (content | str), approval_date: datetime): Calendar plan object.
/// - abstract (keywords: (str, ), text: (content | str)): Abstract object. /// - abstract (keywords: (str, ), text: (content | str)): Abstract object.
/// - bib_path path: Path to the bibliography yaml file. /// - bib_path path: Path to the bibliography yaml file.
/// - appendices (content): Content with appendices. /// - appendices (content): Content with appendices.
#let cw-template( #let coursework(
doc, doc,
title: "NONE", title: none,
subject_shorthand: "NONE", subject: none,
department_gen: "Програмної інженерії", university: "ХНУРЕ",
author: (), author: (),
mentors: (), mentors: (),
edu_program_shorthand: "ПЗПІ", edu_program: none,
task_list: (), task_list: (),
calendar_plan: (), calendar_plan: (),
abstract: (), abstract: (),
bib_path: "bibl.yml", bib_path: none,
appendices: (), appendices: (),
) = { ) = {
set document(title: title, author: author.name) set document(title: title, author: author.name)
show: style show: dstu-style.with(skip: 1)
let bib-count = state("citation-counter", ()) let bib-count = state("citation-counter", ())
show cite: it => { show cite: it => {
@ -273,27 +135,24 @@
let head_mentor = mentors.at(0) let head_mentor = mentors.at(0)
let edu_program = edu_programs.at(edu_program_shorthand) let uni = universities.at(university)
let edu_prog = uni.edu_programs.at(edu_program)
// page 1 {{{2 // page 1 {{{2
[ [
#set align(center) #set align(center)
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ\
#upper(uni.name)
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
\ \
Кафедра Програмної інженерії Кафедра #edu_prog.department_gen
\ \
ПОЯСНЮВАЛЬНА ЗАПИСКА ПОЯСНЮВАЛЬНА ЗАПИСКА\
ДО КУРСОВОЇ РОБОТИ\
ДО КУРСОВОЇ РОБОТИ з дисципліни: "#uni.subjects.at(subject, default: "NONE")"\
з дисципліни: "#subjects.at(subject_shorthand, default: "NONE")"
Тема роботи: "#title" Тема роботи: "#title"
\ \ \ \ \ \
@ -301,7 +160,7 @@
#columns(2, gutter: 4cm)[ #columns(2, gutter: 4cm)[
#set align(left) #set align(left)
#if author.gender == "m" { [Виконав\ ] } else { [Виконала\ ] } ст. гр. #author.group #if author.gender == "m" { [Виконав\ ] } else { [Виконала\ ] } ст. гр. #edu_program\-#author.group
\ \
Керівник:\ Керівник:\
@ -345,7 +204,7 @@
// page 2 {{{2 // page 2 {{{2
{ {
uline[Харківський національний університет радіоелектроніки] uline[#uni.name]
linebreak() linebreak()
linebreak() linebreak()
@ -358,17 +217,19 @@
Спеціальність Спеціальність
], ],
{ {
uline(align: left, department_gen) uline(align: left, edu_prog.department_gen)
linebreak() linebreak()
uline(align: left, subjects.at(subject_shorthand)) uline(align: left, uni.subjects.at(subject))
linebreak() linebreak()
uline(align: left, [#edu_program.number #edu_program.name]) uline(align: left, [#edu_prog.code #edu_prog.name_long])
}, },
) )
grid( grid(
columns: (1fr, 1fr, 1fr), columns: (1fr, 1fr, 1fr),
gutter: 0.3fr, gutter: 0.3fr,
[#bold[Курс] #uline(2)], [#bold[Група] #uline(author.group)], [#bold[Семестр] #uline(3)], [#bold[Курс] #uline(author.course)],
[#bold[Група] #uline([#edu_program\-#author.group])],
[#bold[Семестр] #uline(author.semester)],
) )
linebreak() linebreak()
@ -495,12 +356,18 @@
for i in range(n) { for i in range(n) {
for j in range(0, n - i - 1) { for j in range(0, n - i - 1) {
if ( if (
(not is_cyrillic(keywords.at(j)) and is_cyrillic(keywords.at(j + 1))) (
not is_cyrillic(keywords.at(j)) and is_cyrillic(keywords.at(j + 1))
)
or ( or (
is_cyrillic(keywords.at(j)) == is_cyrillic(keywords.at(j + 1)) and keywords.at(j) > keywords.at(j + 1) is_cyrillic(keywords.at(j)) == is_cyrillic(keywords.at(j + 1))
and keywords.at(j) > keywords.at(j + 1)
) )
) { ) {
(keywords.at(j), keywords.at(j + 1)) = (keywords.at(j + 1), keywords.at(j)) (keywords.at(j), keywords.at(j + 1)) = (
keywords.at(j + 1),
keywords.at(j),
)
} }
} }
} }
@ -571,7 +438,10 @@
} }
context { context {
for (i, citation) in query(ref.where(element: none)).map(r => str(r.target)).dedup().enumerate() { for (i, citation) in query(ref.where(element: none))
.map(r => str(r.target))
.dedup()
.enumerate() {
enum.item( enum.item(
i + 1, i + 1,
format-entry(bib_data.at(citation)), format-entry(bib_data.at(citation)),
@ -580,128 +450,7 @@
} }
} }
// appendices {{{2 appendices-style(appendices)
{ } // }}}
counter(heading).update(0)
set heading(
numbering: (i, ..nums) => {
let char = upper(ua_alpha_numbering.at(i))
if nums.pos().len() == 0 { char } else {
char + "." + nums.pos().map(str).join(".")
}
},
)
show heading.where(level: 1): it => {
set align(center)
set text(size: 14pt, weight: "regular")
pagebreak(weak: true)
bold[ДОДАТОК #counter(heading).display(it.numbering)]
linebreak()
it.body
v(spacing * 2, weak: true)
}
show heading.where(level: 2): it => {
set text(size: 14pt, weight: "regular")
v(spacing * 2, weak: true)
block(width: 100%, spacing: 0em)[
#h(1.25cm)
#counter(heading).display(it.numbering)
#it.body
]
v(spacing * 2, weak: true)
}
appendices
}
}
// Laboratory work template {{{1
/// DSTU 3008:2015 Template for NURE
/// -> content
/// - doc (content): Content to apply the template to.
/// - doctype ("ЛБ" | "ПЗ"): Document type.
/// - title (str): Title of the document.
/// - subject_shorthand (str): Subject short name.
/// - department_gen (str): Department name in genitive form.
/// - worknumber (int): Number of the work, can be omitted.
/// - authors ((name: str, full_name_gen: str, variant: int, group: str, gender: str),): List of Authors dicts.
/// - mentor (name: str, gender: str, degree: str): Mentors objects.
#let lab-pz-template(
doc,
doctype: "NONE",
title: "NONE",
subject_shorthand: "NONE",
department_gen: "Програмної інженерії",
worknumber: 1,
authors: (),
mentor: (),
) = {
set document(title: title, author: authors.at(0).name)
show: style
context counter(heading).update(worknumber - 1)
// page 1 {{{2
align(center)[
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ \
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
\ \
Кафедра #department_gen
\ \ \
Звіт \
з
#if doctype == "ЛБ" [лабораторної роботи] else [практичної роботи]
#if worknumber != none [ #worknumber]
з дисципліни: "#subjects.at(subject_shorthand, default: "UNLNOWN SUBJECT, PLEASE OPEN AN ISSUE")"
з теми: "#title"
\ \ \ \
#columns(2)[
#set align(left)
#set par(first-line-indent: 0pt)
#if authors.len() == 1 {
let author = authors.at(0)
if author.gender == "m" [Виконав:\ ] else [Виконала:\ ]
[
ст. гр. #author.group\
#author.name\
]
if author.variant != none [Варіант: #author.variant]
} else [
Виконали:\
ст. гр. #authors.at(0).group\
#authors.map(a => [ #a.name\ ])
]
#colbreak()
#set align(right)
#if mentor.gender == "m" { [Перевірив:\ ] } else { [Перевірила:\ ] }
#mentor.degree #if mentor.degree.len() >= 15 [\ ]
#mentor.name\
]
#v(1fr)
Харків -- #datetime.today().display("[year]")
]
pagebreak(weak: true)
heading(title)
doc
}
// vim:sts=2:sw=2:fdl=0:fdm=marker:cms=/*%s*/ // vim:sts=2:sw=2:fdl=0:fdm=marker:cms=/*%s*/

160
style.typ Normal file
View File

@ -0,0 +1,160 @@
// SPDX-License-Identifier: GPL-3.0
/*
* style.typ: Styles beneficial beyond the typst-nure-template
*/
#let spacing = 0.95em // spacing between lines
#let num-to-alpha = "абвгдежиклмнпрстуфхцшщюя".split("") // 0 = "", 1 = "а"
/// DSTU 3008:2015 Style
/// -> content
/// - it (content): Content to apply the style to.
/// - skip (int): Do not show page number for this number of pages.
/// - offset (int): Adjust all page numbers by this amount.
#let dstu-style(
it,
skip: 0,
offset: 0,
) = {
// General Styling {{{1
set page(
paper: "a4",
number-align: top + right,
margin: (top: 20mm, right: 10mm, bottom: 20mm, left: 25mm),
numbering: (i, ..) => if i > skip { numbering("1", i + offset) },
)
set text(
lang: "uk",
size: 14pt,
hyphenate: false,
font: ("Times New Roman", "Liberation Serif"),
)
set par(
justify: true,
spacing: spacing,
leading: spacing,
first-line-indent: (amount: 1.25cm, all: true),
)
set block(spacing: spacing)
set underline(evade: false)
// Enums & Lists {{{1
// First level
set enum(
indent: 1.25cm,
body-indent: 0.5cm,
numbering: i => { num-to-alpha.at(i) + ")" },
)
// Second level and further nesting
show enum: it => {
set enum(indent: 0em, numbering: "1)")
it
}
// Lists are not intended for multiple levels, use `enum`
set list(indent: 1.35cm, body-indent: 0.5cm, marker: [--])
// Figures {{{1
show figure: it => {
v(spacing * 2, weak: true)
it
v(spacing * 2, weak: true)
}
set figure.caption(separator: [ -- ])
show figure.where(kind: table): set figure.caption(position: top)
show figure.caption.where(kind: table): set align(left)
// Numbering {{{1
show heading.where(level: 1): it => {
counter(math.equation).update(0)
counter(figure.where(kind: raw)).update(0)
counter(figure.where(kind: image)).update(0)
counter(figure.where(kind: table)).update(0)
it
}
set figure(numbering: i => numbering("1.1", counter(heading).get().at(0), i))
set math.equation(numbering: i => numbering("(1.1)", counter(heading).get().at(0), i))
// Headings {{{1
set heading(numbering: "1.1")
show heading: it => if it.level == 1 {
set align(center)
set text(size: 14pt, weight: "semibold")
pagebreak(weak: true)
upper(it)
v(spacing * 2, weak: true)
} else {
set text(size: 14pt, weight: "regular")
v(spacing * 2, weak: true)
block(width: 100%, spacing: 0em)[
#h(1.25cm)
#counter(heading).display(auto)
#it.body
]
v(spacing * 2, weak: true)
}
// Listings {{{1
show raw: it => {
let raw-spacing = 0.5em
set block(spacing: raw-spacing)
set par(spacing: raw-spacing, leading: raw-spacing)
set text(
size: 11pt,
weight: "semibold",
font: ("Courier New", "Liberation Mono"),
)
v(spacing * 2.5, weak: true)
pad(it, left: 1.25cm)
v(spacing * 2.5, weak: true)
}
it
// }}}
}
/// DSTU 3008:2015 Appendices Style
/// -> content
/// - it (content): Content to apply the style to.
#let appendices-style(it) = /* {{{ */ {
// Numbering
counter(heading).update(0)
set heading(numbering: (i, ..n) => upper(num-to-alpha.at(i)) + numbering(".1.1", ..n))
set figure(numbering: i => [#upper(num-to-alpha.at(counter(heading).get().at(0))).#i])
set math.equation(numbering: i => [(#upper(num-to-alpha.at(counter(heading).get().at(0))).#i)])
// Headings
show heading: it => if it.level == 1 {
set align(center)
set text(size: 14pt, weight: "regular")
pagebreak(weak: true)
text(weight: "bold")[ДОДАТОК #counter(heading).display(auto)]
linebreak()
it.body
v(spacing * 2, weak: true)
} else {
set text(size: 14pt, weight: "regular")
v(spacing * 2, weak: true)
block(width: 100%, spacing: 0em)[
#h(1.25cm)
#counter(heading).display(auto)
#it.body
]
v(spacing * 2, weak: true)
}
it
} // }}}
// vim:sts=2:sw=2:fdl=0:fdm=marker:cms=/*%s*/

129
template.typ Normal file
View File

@ -0,0 +1,129 @@
// SPDX-License-Identifier: GPL-3.0
/*
* typst-nure-template/template.typ
*
* Typst templates for NURE (Kharkiv National University of Radio Electronics) works
*/
#import "style.typ": spacing, dstu-style, appendices-style
// Practice and Laboratory works template {{{
/// DSTU 3008:2015 Template for NURE
/// -> content
/// - it (content): Content to apply the template to.
/// - department (str): Education program name.
/// - work_type (str): Work type, i.e. "з лабораторної роботи".
/// - number (int | none): Number of the work. Optional.
/// - subject (str): Subject name.
/// - title (str | none): Title of the work and the document. Optional.
/// - variant (int | none): Variant of the work. Optional.
/// - author ((name: str, group: (str | none), gender: ("m" | "f" | none)),):
/// A dictionary of one author or an array of authors. Other types will be just displayed.
/// - mentor ((name: str, degree: (str | none), gender: ("m" | "f" | none)),):
/// A dictionary of one mentor or an array of mentors. Other types will be just displayed.
#let general(
it,
department: none,
work_type: none,
number: none,
subject: none,
title: none,
variant: none,
author: none,
mentor: none,
year: datetime.today().display("[year]"),
) = {
assert.ne(department, none, message: "Missing argument: \"department\"")
assert.ne(work_type, none, message: "Missing argument: \"work_type\"")
assert.ne(subject, none, message: "Missing argument: \"subject\"")
if type(author) == array and author.len() == 1 { author = author.at(0) }
if type(mentor) == array and mentor.len() == 1 { mentor = mentor.at(0) }
set document(
title: title,
author: if type(author) == array {
author.map(a => a.name)
} else if type(author) == dictionary { author.name } else { "" },
)
show: dstu-style.with(skip: 1)
align(center)[
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
\ \ \
Кафедра #department
\ \ \ \
Звіт
#work_type #if number != none [
#number
#counter(heading).update(number - if title != none { 1 } else { 0 })
]
з дисципліни: "#subject"
#if title != none [з теми: "#title"]
\ \ \ \
#columns(2)[
#set par(first-line-indent: 0pt)
//
#set align(left)
//
#if type(author) == dictionary [
#if "gender" in author and author.gender != none {
if author.gender == "m" [Виконав:] else [Виконала:]
} else [Виконали:]
#if "group" in author [ст. гр. #author.group\ ]
#author.name\
#if variant != none [Варіант: #variant]
] else if type(author) == array [
Виконали:
#for a in author [
#if "group" in a [ст. гр. #a.group\ ]
#a.name\
]
#if variant != none [Варіант: #variant]
] else { author } // custom formatting
//
#colbreak()
//
#set align(right)
//
#if type(mentor) == dictionary [
#if "gender" in mentor and mentor.gender != none {
if mentor.gender == "m" [Перевірив:] else [Перевірила:]
} else [Перевірили:]
#if "degree" in mentor and mentor.degree != none [#mentor.degree\ ]
#mentor.name
] else if type(mentor) == array [
Перевірили:
#for m in mentor [
#if "degree" in m [#m.degree\ ]
#m.name\
]
] else { mentor } // custom formatting
]
#v(1fr)
Харків -- #year
]
pagebreak(weak: true)
if title != none { heading(title) }
it
} // }}}
// vim:sts=2:sw=2:fdl=0:fdm=marker:cms=/*%s*/

View File

@ -1,29 +1,19 @@
#import "@local/nure:0.0.0": * #import "@local/nure:0.2.0": *
#let author = ( #let author = (
name: "Ситник Є. С.", name: "Ситник Є. С.",
full_name_gen: "Ситника Єгора Сергійовича", full_name_gen: "Ситника Єгора Сергійовича",
course: 2,
semester: 3,
variant: 13, variant: 13,
group: "ПЗПІ-23-2", group: "23-2",
gender: "m", gender: "m",
) )
#let mentors = ( #let mentors = (
( (name: "Черепанова Ю. Ю.", degree: "Ст. викл. каф. ПІ"),
name: "Черепанова Ю. Ю.", (name: "Русакова Н. Є.", degree: "Доц. каф. ПІ"),
gender: "f", (name: "Широкопетлєва М. С.", degree: "Ст. викл. каф. ПІ"),
degree: "Ст. викл. каф. ПІ",
),
(
name: "Русакова Н. Є.",
gender: "f",
degree: "Доц. каф. ПІ",
),
(
name: "Широкопетлєва М. С.",
gender: "f",
degree: "Ст. викл. каф. ПІ",
),
) )
#let task_list = ( #let task_list = (
@ -69,11 +59,26 @@
"SQL", "SQL",
), ),
text: [ text: [
Мета даної роботи -- проєктування та розробка інформаційної системи «Помічник класного керівника. Керування класом», яка спрямована на автоматизацію процесів управління класом, облік даних про учнів, планування та аналіз навчального процесу. Основна задача інформаційної системи спростити роботу класного керівника, забезпечити ефективну організацію документації та взаємодію з учасниками освітнього процесу. Мета даної роботи -- проєктування та розробка інформаційної системи «Помічник
класного керівника. Керування класом», яка спрямована на автоматизацію процесів
управління класом, облік даних про учнів, планування та аналіз навчального
процесу. Основна задача інформаційної системи спростити роботу класного
керівника, забезпечити ефективну організацію документації та взаємодію з
учасниками освітнього процесу.
Для реалізації системи було використано сучасний стек технологій, а саме: Go -- як основна мова програмування для створення серверної логіки, HTMX -- для динамічного оновлення інтерфейсу без використання складних фреймворків, MySQL -- як СУБД для зберігання даних про учнів, їх оцінки та розклад, Neovim -- як середовище для швидкої та ефективної розробки коду, Go Echo -- веб-фреймворк для створення REST API, Go SQLx -- бібліотека для роботи з базою даних, що забезпечує зручність і гнучкість. Для реалізації системи було використано сучасний стек технологій, а саме: Go --
як основна мова програмування для створення серверної логіки, HTMX -- для
динамічного оновлення інтерфейсу без використання складних фреймворків, MySQL --
як СУБД для зберігання даних про учнів, їх оцінки та розклад, Neovim -- як
середовище для швидкої та ефективної розробки коду, Go Echo -- веб-фреймворк для
створення REST API, Go SQLx -- бібліотека для роботи з базою даних, що
забезпечує зручність і гнучкість.
Результат роботи веб-додаток, який дозволяє обліковувати особисті дані учнів та їхніх опікунів, включаючи інформацію про успішність, відвідуваність та інші показники; планувати розклад занять; генерувати звіти про успішність учнів та переглядати різну статистику. Інтерфейс, створений з використанням HTMX, легко адаптується під потреби користувача. Результат роботи веб-додаток, який дозволяє обліковувати особисті дані учнів
та їхніх опікунів, включаючи інформацію про успішність, відвідуваність та інші
показники; планувати розклад занять; генерувати звіти про успішність учнів та
переглядати різну статистику. Інтерфейс, створений з використанням HTMX, легко
адаптується під потреби користувача.
], ],
) )
@ -92,17 +97,16 @@
#lorem(200) #lorem(200)
] ]
#show: cw-template.with( #show: coursework.with(
title: "Інформаційна система «Помічник класного керівника». Керування класом", title: "Інформаційна система «Помічник класного керівника». Керування класом",
subject_shorthand: "БД", subject: "БД",
department_gen: "Програмної інженерії", edu_program: "ПЗПІ",
edu_program_shorthand: "ПЗПІ",
author: author, author: author,
mentors: mentors, mentors: mentors,
task_list: task_list, task_list: task_list,
calendar_plan: calendar_plan, calendar_plan: calendar_plan,
abstract: abstract, abstract: abstract,
bib_path: "bibl.yml", bib_path: bytes("bibl.yml"), // NOTE: use `bytes` as typst looks in template dir when using just filename
appendices: appendices, appendices: appendices,
) )

View File

@ -1,25 +1,20 @@
#import "@local/nure:0.0.0": * #import "@local/nure:0.2.0": *
#show: lab-pz-template.with( #show: general.with(
doctype: "ЛБ", department: "Програмної інженерії",
title: "Інформаційна система «Помічник класного керівника». Керування класом", work_type: "з лабораторної роботи",
subject_shorthand: "БД", number: 3,
department_gen: "Програмної інженерії", subject: "Операційні системи",
authors: ( title: "Керування зовнішніми пристроями. Нестандартні пристрої",
( author: (
name: "Ситник Є. С.", (name: "Шевчентко Т. Г.", group: "ПЗПІ-23-0"),
full_name_gen: "Ситника Єгора Сергійовича", (name: "Косач Л. П."),
variant: 13,
group: "ПЗПІ-23-2",
gender: "m",
),
), ),
mentor: ( mentor: (
name: "Черепанова Ю. Ю.", gender: "m",
gender: "f", name: "Франко І. Я.",
degree: "Ст. викл. каф. ПІ", degree: "доц. каф. ПІ",
), ),
worknumber: 1,
) )
#v(-spacing) #v(-spacing)
@ -49,3 +44,25 @@
- #lorem(25); - #lorem(25);
- #lorem(42); - #lorem(42);
- #lorem(27). - #lorem(27).
#show: appendices-style
= Quote
#link("https://youtu.be/bJQj1uKtnus")[
The art isn't the art, the art is never the art,
the art is the thing that happens inside you when you make it and the feeling in the heart of the beholder.
]
= Приклад звіту 1
#v(-spacing)
== Частина 1
#lorem(100)
== Частина2
#lorem(200)
= Приклад звіту 2
#lorem(200)
= Приклад звіту 3
#lorem(200)

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nure" name = "nure"
version = "0.0.0" version = "0.2.0"
entrypoint = "lib.typ" entrypoint = "lib.typ"
authors = ["linerds"] authors = ["linerds"]
license = "GPL-3.0" license = "GPL-3.0"