Compare commits

69 Commits

Author SHA1 Message Date
2e65baae70 refactor: backport changes from noatu's fork
feat(style)!: remove reference styling & fix figure numbering for appendices
feat!: swap appending on 'none' being the first position in ..sink
feat: add chapters to pz-lb()
feat: add asserts
fix: better control flow

img() function now requires `none` to be the first position in ..sink,
e.g. `#img("/fig/1.png", "Caption", none)` to get "Caption (рисунок виконано самостійно)" caption.

Use `@some_label[див. рис.]` to get a "див. рис. 42" link.

Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-07-09 17:17:53 +03:00
d338c21965 Merge pull request 'add name of educational program && names of subjects for this semester' (#14) from add-program-and-subject-names into 0.1.0
Reviewed-on: #14
LGTM
2025-05-25 04:11:28 +03:00
7e15ea09d4 add name of educational program && names of subjects for this semester 2025-05-25 04:08:53 +03:00
3b3d62fd9b lib.typ: too lazy to name it
Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-05-20 20:46:32 +03:00
04c5b283e7 lib.typ: better code branching
Signed-off-by: unexplrd <unexplrd@linerds.us>
2025-05-20 20:31:41 +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: #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: #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
f36b513a2d docs(README): fix installation instructions 2025-03-01 10:53:53 +02:00
d7c26debfd fix: package entry point 2025-03-01 01:26:50 +02:00
f940d16e06 fix: imports 2025-03-01 01:26:38 +02:00
09b4d3aa44 feat(README): added instructions for local typst package setup 2025-03-01 01:15:13 +02:00
0d526d4f58 feat: restructured files accrording to typst package format
- added typst.toml
- moved templates to "template" folder
- renamed files according to convention
2025-03-01 01:10:05 +02:00
efa56f1fec feat(style func): added show rules for heading(level: 3) 2025-02-27 11:54:31 +02:00
0e6f2ce25e docs: improve code examples 2025-02-27 08:49:47 +02:00
394d4b1fcf minor syntactic changes 2025-02-25 10:20:20 +02:00
09fc15a8c9 reimplement appendices 2025-02-21 15:06:28 +02:00
a761f36a02 removed typst-13 warning from readme 2025-02-20 00:19:23 +02:00
b12627d888 fixed calendar plan signature indent 2025-02-19 16:08:24 +02:00
2d67b11f48 pass named arguments for img to image 2025-02-17 18:23:36 +02:00
c2fd8f6ad0 fix image and table count 2025-02-16 21:43:16 +02:00
63720d0068 remove italics from bibliography 2025-02-15 12:06:01 +02:00
8cabd1c779 fix bibliography indent 2025-02-15 10:02:04 +02:00
a6ec38abee reorganize a bit 2025-02-15 09:26:27 +02:00
bc78371fce add fold-markers 2025-02-15 00:30:50 +02:00
612e70a897 fixed authors list 2025-02-14 23:48:59 +02:00
67dc761845 updated readme and lab template to 0.13 2025-02-14 23:48:47 +02:00
b3c0a466f7 make img func source arg optional 2025-02-14 15:53:22 +02:00
e1354921f3 update README.md 2025-02-14 11:44:18 +02:00
84e83c6f39 change text.font.lang from ua to uk
May also need to rework bibliography handling.
2025-02-14 09:37:11 +02:00
9758b54735 fixed par indent 2025-02-14 01:48:47 +02:00
f2833b62c6 added general info and removed unnecessary code 2025-02-14 01:48:34 +02:00
003f327c71 fix image & reference numbering 2025-02-13 22:20:05 +02:00
c9e56a75b1 add source to img function 2025-02-13 19:32:38 +02:00
eab40dfbfb make Times New Roman the default font 2025-02-13 12:40:11 +02:00
36208ab7a8 Merge pull request 'fix initial_date' (#6) from 0x1D8/typst_nure_template:main into main
Reviewed-on: #6
2025-02-13 11:41:01 +02:00
ab418ea1ec fix intial_date 2025-02-13 08:24:40 +02:00
14 changed files with 1000 additions and 777 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
template.pdf *.pdf

106
README.md
View File

@ -1,23 +1,18 @@
# Typst Template for NURE Works # Typst Template for NURE Works
![pz-lb title page](assets/pz-lb_title_page.png)
> [!INFO]
> Needs more work, but it is functional and ready for use.
## TODO
- Add more information about the template.
## General Info ## General Info
This project contains two template functions and some utilities for writing NURE works. All functions include documentation comments inside them, so you can explore all possibilities using LSP/IntelliSense. This project contains two template functions and some utilities for writing NURE works. All functions include documentation comments inside them, so you can explore all possibilities using LSP.
### Templates ### Templates
#### `pz-lb-template` - For Laboratory and Practical Works #### `pz-lb` - For Practice and Laboratory 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;
@ -32,36 +27,91 @@ This template:
## Usage ## Usage
To use the template, include it in your project and utilize the provided functions: ### As a local typst package
1. Clone this repository into ~/.local/share/typst/packages/:
```bash
git clone -b 0.1.0 https://gitea.linerds.us/pencelheimer/typst_nure_template.git ~/.local/share/typst/packages/local/nure/0.1.0
```
2. Init your project with Typst:
```bash
typst init @local/nure:0.1.0 project-name
```
### As a standalone file
Copy `lib.typ` to your project's root directory.
### In your project
```typst ```typst
#import "path/to/template.typ": * // Import the template // Import the template either from a local package...
#import "@preview/indenta:0.0.3": fix-indent // Import indentation fix utility #import "@local/nure:0.1.0": *
// ...or by importing a lib.typ directly
// #import "/lib.typ": *
#show: pz-lb-template.with( // 1. Setup the document
title: "Some title", // by setting values directly...
#show: pz-lb.with(
title: "Some title",
// etc: "and so on",
// ...
) )
// ...or using a config/doc.yaml file
#show: pz-lb.with(..yaml("config/doc.yaml"))
#show: fix-indent() // this template automatically inserts a `=title`
#v(-spacing) // Write your content
#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 pz-lb 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. You must use the `fix-indent` function from `@preview/indenta` to correct indentation after the title. 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. Use `#v(-spacing)` to remove vertical spacing between titles (this cannot be automatically handled by the template). Notice that the `spacing` variable used here is imported from the template. 2. When importing `@local/nure:0.1.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.1.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 ├── config/
├── images/ │ ├── doc.yaml -- for things that don't change across works, i.e. author and mentor metadata
│ ├── figure1.png │ ├── universities.yaml -- for user-specific configuration, i.e. education programs and disciplines
── figure2.png ── ...
│ ├── ... ├── src/
├── ... │ ├── intro.typ
│ ├── chapter1.typ
│ ├── chapter2.typ
│ └── ...
├── figures/
│ ├── chapter1/
│ │ ├── figure1.png
│ │ ├── figure2.png
│ │ ├── figure3.png
│ │ └── ...
│ ├── chapter2/
│ │ ├── figure1.png
│ │ ├── figure2.png
│ │ ├── figure3.png
│ │ └── ...
│ └── ...
└── ...
``` ```
This setup ensures that `main.typ` includes and applies the template correctly.

BIN
assets/pz-lb_title_page.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

58
config/universities.yaml Normal file
View File

@ -0,0 +1,58 @@
ХНУРЕ:
name: Харківський національний університет радіоелектроніки
edu_programs:
ПЗПІ:
name_long: Інженерія програмного забезпечення
department_gen: Програмної інженерії
code: 121 # TODO: change to F2?
КУІБ:
name_long: Управління інформаційною безпекою
department_gen: Інфокомунікаційної інженерії ім. В. В. Поповського
code: 125
КНТ:
name_long: Комп'ютерні науки та технології
department_gen: Системотехніки
code: 122
subjects:
ODS: Основи Dаtа Sсіеnсе # NOTE: Eng O here
ІМ: Іноземна мова
АКтаК: Архітектура комп'ютера та комп'ютерних мереж
АТСД: Алгоритми та структури даних
БД: Бази даних
БЖД: Безпека життєдіяльності
ВДІТБ: Введення до ІТ-бізнесу # NOTE: all in UA
ВМ: Вища математика
ГТГ: Гіпертекст та гіпермедіа
ДМ: Дискретна математика
КДМА: Комп'ютерна дискретна математика
КМ: Комп`ютерні мережі
КЗВШ: Креативність з використанням штучного інтелекту
ЛМВ: Людино-машинна взаємодія
МОТДО: Методи оптимізаціі та дослідження операцій
МС: Моделювання систем
ОІМ: Основи IP-мереж
ООП: Об'єктно-орієнтоване програмування
ОП: Основи права
ОПІ: Основи програмноі інженеріі
ОПНJ: Основи програмування на Java
ОПр: Основи програмування
ОС: Операційні системи
ОТК: Основи теорії кіл
ПНП: Програмування на платформі .NЕТ
ПП: Проектний практикум
ПРОГ: Програмування
СМП: Скриптові мови програмування
ТЙтаМ: Теорія ймовірностей та математична # TODO: what?
ТКП: Технології комп`ютерного проєктування
УФМ: Українське фахове мовлення
ФІЗ: Фізика
ФІЛ: Філософія
ФВС: Фізичне виховання та спорт
# Oleksii 6th semester
ХТ: Хмарні технології
ООАПС: Об'єктно-орієнтований аналіз в проектуванні систем
СА: Системний аналіз
МППС: Методології проектування програмних систем
ТЗІ: Технології захисту інформації
АДан: Аналітика даних
DMT: Decision making theory

Binary file not shown.

Binary file not shown.

View File

@ -1,39 +0,0 @@
#import "template.typ": *
#import "@preview/indenta:0.0.3": fix-indent
#show: lab-pz-template.with(
doctype: "ЛБ",
title: "Інформаційна система «Помічник класного керівника». Керування класом",
subject_shorthand: "БД",
department_gen: "Програмної інженерії",
authors: (
(
name: "Ситник Є. С.",
full_name_gen: "Ситника Єгора Сергійовича",
variant: 13,
group: "ПЗПІ-23-2",
gender: "m",
),
),
mentor: (
name: "Черепанова Ю. Ю.",
gender: "f",
degree: "Ст. викл. каф. ПІ",
),
worknumber: 1,
)
#show: fix-indent()
#v(-spacing)
== Мета роботи
Супер важлива мета
== Висновки
Супер важливий висновок
== Хід роботи
== Контрольні запитання
Супер важливі контрольні запитання

721
lib.typ Normal file
View File

@ -0,0 +1,721 @@
// Academic aliases {{{1
#let universities = yaml("config/universities.yaml")
// Template formatting functions {{{1
/// numberless heading
#let nheading(title) = heading(depth: 1, numbering: none, title)
/// 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
/// make underlined cell with filled value
#let uline(align: center, content) = underline[
#if align != left { hfill(1fr) }
#content
#if align != right { hfill(1fr) }
]
/// bold text
#let bold(content) = text(weight: "bold")[#content]
/// month name from its number
#let month_gen(month) = (
"січня",
"лютого",
"березня",
"квітня",
"травня",
"червня",
"липня",
"серпня",
"вересня",
"жовтня",
"листопада",
"грудня",
).at(month - 1)
// Helper functions {{{1
/// captioned image with label derived from path:
/// - "image.png" = @image
/// - "img/image.png" = @image
/// - "img/foo/image.png" = @foo_image
/// - "img/foo/foo_image.png" = @foo_image
/// the caption will be modified based on a conditional positional value:
/// - `none`: no change
/// - some value: "`caption` (за даними `value`)"
/// - no value: "`caption` (рисунок виконано самостійно)"
/// additional named arguments will be passed to original `image` function
#let img(path, caption, ..sink) = {
let parts = path.split(".").first().split("/")
let label_string = if (
parts.len() <= 2 or parts.at(-1).starts-with(parts.at(-2))
) {
// ("image",), (_, "image") and (.., "img", "img_image")
parts.last()
} else {
// (.., "img", "image") = "img_image"
parts.at(-2) + "_" + parts.at(-1)
}.replace(" ", "_")
let caption = if sink.pos().len() == 0 {
caption
} else if sink.pos().first() == none {
caption + " (рисунок виконано самостійно)"
} else {
[#caption (за даними #sink.pos().first())]
}
[#figure(
image(path, ..sink.named()),
caption: caption,
) #label(label_string)]
}
#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
} // }}}
// Coursework template {{{1
/// DSTU 3008:2015 Template for NURE
/// -> content
/// - doc (content): Content to apply the template to.
/// - title (str): Title of the document.
/// - subject (str): Subject short name.
/// - authors ((name: str, full_name_gen: str, variant: int, course: int, semester: int, group: str, gender: str),): List of authors.
/// - mentors ((name: str, degree: str),): List of mentors.
/// - edu_program (str): Education program shorthand.
/// - 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.
/// - abstract (keywords: (str, ), text: (content | str)): Abstract object.
/// - bib_path path: Path to the bibliography yaml file.
/// - appendices (content): Content with appendices.
#let coursework(
doc,
title: none,
subject: none,
university: "ХНУРЕ",
author: (),
mentors: (),
edu_program: none,
task_list: (),
calendar_plan: (),
abstract: (),
bib_path: none,
appendices: (),
) = {
set document(title: title, author: author.name)
show: dstu-style.with(skip: 1)
let bib-count = state("citation-counter", ())
show cite: it => {
it
bib-count.update(((..c)) => (..c, it.key))
}
show bibliography: it => {
set text(size: 0pt)
it
}
let head_mentor = mentors.at(0)
let uni = universities.at(university)
let edu_prog = uni.edu_programs.at(edu_program)
// page 1 {{{2
[
#set align(center)
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ\
#upper(uni.name)
\
Кафедра #edu_prog.department_gen
\
ПОЯСНЮВАЛЬНА ЗАПИСКА\
ДО КУРСОВОЇ РОБОТИ\
з дисципліни: "#uni.subjects.at(subject, default: "NONE")"\
Тема роботи: "#title"
\ \ \
#columns(2, gutter: 4cm)[
#set align(left)
#if author.gender == "m" { [Виконав\ ] } else { [Виконала\ ] } ст. гр. #edu_program\-#author.group
\
Керівник:\
#head_mentor.degree
\
Робота захищена на оцінку
\
Комісія:\
#for mentor in mentors {
[#mentor.degree\
]
}
#colbreak()
#set align(left)
\
#author.name
\ \
#head_mentor.name
\
#underline(" " * 35)
\ \
#for mentor in mentors {
[#mentor.name\
]
}
]
#v(1fr)
Харків -- #task_list.done_date.display("[year]")
#pagebreak()
]
// page 2 {{{2
{
uline[#uni.name]
linebreak()
linebreak()
grid(
columns: (100pt, 1fr),
bold[
Кафедра
Дисципліна
Спеціальність
],
{
uline(align: left, edu_prog.department_gen)
linebreak()
uline(align: left, uni.subjects.at(subject))
linebreak()
uline(align: left, [#edu_prog.code #edu_prog.name_long])
},
)
grid(
columns: (1fr, 1fr, 1fr),
gutter: 0.3fr,
[#bold[Курс] #uline(author.course)], [#bold[Група] #uline([#edu_program\-#author.group])], [#bold[Семестр] #uline(author.semester)],
)
linebreak()
linebreak()
linebreak()
align(center, bold[ЗАВДАННЯ \ на курсову роботу студента])
linebreak()
uline(align: left)[_#author.full_name_gen _]
linebreak()
linebreak()
bold[\1. Тема роботи:]
uline[#title.]
linebreak()
{
bold[\2. Строк здачі закінченої роботи:]
uline(task_list.done_date.display("[day].[month].[year]"))
hfill(10fr)
}
linebreak()
bold[\3. Вихідні дані для роботи:]
uline(task_list.source)
linebreak()
bold[\4. Зміст розрахунково-пояснювальної записки:]
uline(task_list.content)
linebreak()
bold[\5. Перелік графічного матеріалу:]
uline(task_list.graphics)
linebreak()
{
bold[\6. Дата видачі завдання:]
uline(task_list.initial_date.display("[day].[month].[year]"))
hfill(10fr)
}
pagebreak()
}
// page 3 {{{2
{
align(center, bold[КАЛЕНДАРНИЙ ПЛАН])
set par(first-line-indent: 0pt)
linebreak()
calendar_plan.plan_table
linebreak()
grid(
columns: (5fr, 5fr),
grid(
columns: (1fr, 2fr, 1fr),
gutter: 0.2fr,
[
Студент \
Керівник \
#align(center)["#underline[#calendar_plan.approval_date.day()]"]
],
[
#uline(align: center, []) \
#uline(align: center, []) \
#uline(align: center, month_gen(calendar_plan.approval_date.month()))
],
[
\ \
#underline[#calendar_plan.approval_date.year()] р.
],
),
[
#author.name, \
#head_mentor.degree
#head_mentor.name.
],
)
pagebreak()
}
// page 4 {{{2
[
#align(center, bold[РЕФЕРАТ]) \
#context [
#let pages = counter(page).final().at(0)
#let images = query(figure.where(kind: image)).len()
#let tables = query(figure.where(kind: table)).len()
#let bibs = bib-count.final().dedup().len()
/* TODO: why this stopped working?
#let tables = counter(figure.where(kind: table)).final().at(0)
#let images = counter(figure.where(kind: image)).final().at(0)*/
#let counters = ()
#if pages != 0 { counters.push[#pages с.] }
#if tables != 0 { counters.push[#tables табл.] }
#if images != 0 { counters.push[#images рис.] }
#if bibs != 0 { counters.push[#bibs джерел] }
Пояснювальна записка до курсової роботи: #counters.join(", ").
]
\
#{
let keywords = abstract.keywords.map(upper)
let is_cyrillic = word => word.split("").any(char => ("А" <= char and char <= "я"))
let n = keywords.len()
for i in range(n) {
for j in range(0, n - i - 1) {
if (
(
not is_cyrillic(keywords.at(j)) and is_cyrillic(keywords.at(j + 1))
)
or (
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.join(", ")
}
\
#abstract.text
]
// page 5 {{{2
outline(
title: [
ЗМІСТ
#v(spacing * 2, weak: true)
],
depth: 2,
indent: auto,
)
doc
// bibliography {{{2
{
heading(depth: 1, numbering: none)[Перелік джерел посилання]
bibliography(
bib_path,
style: "ieee",
full: true,
title: none,
)
let bib_data = yaml(bib_path)
let format-entry(citation) = {
if (citation.type == "Web") {
let date_array = citation.url.date.split("-")
let date = datetime(
year: int(date_array.at(0)),
month: int(date_array.at(1)),
day: int(date_array.at(2)),
)
[
#citation.title.
#citation.author.
URL: #citation.url.value (дата звернення: #date.display("[day].[month].[year]")).
]
} else if citation.type == "Book" [
#citation.author
#citation.title.
#citation.publisher,
#citation.date.
#citation.page-total c.
] else [
UNSUPPORTED BIBLIOGRAPHY ENTRY TYPE, PLEASE OPEN AN ISSUE
]
}
show enum.item: it => {
set par(first-line-indent: 0pt)
box(width: 1.25cm)
box(width: 1em + 0.5cm)[#it.number.]
it.body
linebreak()
}
context {
for (i, citation) in query(ref.where(element: none)).map(r => str(r.target)).dedup().enumerate() {
enum.item(
i + 1,
format-entry(bib_data.at(citation)),
)
}
}
}
appendices-style(appendices)
}
// Practice and Laboratory works template {{{1
/// DSTU 3008:2015 Template for NURE
/// -> content
/// - doc (content): Content to apply the template to.
/// - edu_program (str): Education program shorthand.
/// - doctype ("ЛБ" | "ПЗ" | str): Document type.
/// - title (str or none): Title of the document. Optional.
/// - subject (str): Subject shorthand.
/// - worknumber (int or none): Number of the work. Optional.
/// - authors ((name: str, full_name_gen: str, group: str, gender: str, variant: int or none),): List of authors.
/// - mentors ((name: str, degree: str, gender: str or none),): List of mentors. Optional.
/// - chapters (): List of file names in chapters/ subdirectory. Optional.
#let pz-lb(
doc,
university: "ХНУРЕ",
edu_program: none,
doctype: none,
title: none,
subject: none,
worknumber: none,
authors: (),
mentors: (),
chapters: (),
) = {
assert.ne(edu_program, none, message: "Missing argument: \"edu_program\"")
assert.ne(doctype, none, message: "Missing argument: \"doctype\"")
assert.ne(subject, none, message: "Missing argument: \"subject\"")
set document(title: title, author: authors.at(0).name)
show: dstu-style.with(skip: 1)
let uni = universities.at(university)
let edu_prog = uni.edu_programs.at(edu_program)
// page 1 {{{2
align(center)[
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ \
#upper(uni.name)
\ \
Кафедра #edu_prog.department_gen
\ \ \
#if doctype == "ЛБ" [Звіт \ з лабораторної роботи] else if (
doctype == "ПЗ"
) [Звіт \ з практичної роботи] else [#doctype]
#if worknumber != none {
context counter(heading).update(
worknumber - if title == none { 0 } else { 1 },
)
[№#worknumber]
} else if title != none and worknumber != none {
context counter(heading).update(1)
}
з дисципліни: "#uni.subjects.at(subject)"
#if title != none [з теми: "#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 [Виконала:\ ]
[
ст. гр. #edu_program\-#author.group\
#author.name\
]
if (
"variant" in author.keys() and author.variant != none
) [Варіант: #author.variant]
} else if authors.len() > 1 [
Виконали:\
ст. гр. #edu_program\-#authors.at(0).group\
#for author in authors [#author.name\ ]
]
#colbreak()
#set align(right)
#if type(mentors) == array {
if mentors.len() == 1 {
let mentor = mentors.at(0)
if "gender" in mentor.keys() {
if mentor.gender == "m" [Перевірив:\ ] else if (
mentor.gender == "f"
) [Перевірила:\ ]
} else [Перевірили:\ ]
if (
"degree" in mentor.keys() and mentor.degree != none
) [#mentor.degree\ ]
[#mentor.name\ ]
} else if mentors.len() > 1 [
Перевірили:\
#for mentor in mentors {
[
#mentor.degree\
#mentor.name\
]
}
]
}
]
#v(1fr)
Харків -- #datetime.today().display("[year]")
]
pagebreak(weak: true)
if title != none [#heading(title)]
doc
chapters.map(chapter => include "/chapters/" + str(chapter) + ".typ").join()
}
// vim:sts=2:sw=2:fdl=0:fdm=marker:cms=/*%s*/

View File

@ -1,667 +0,0 @@
/// numberless heading
#let nheading(title) = heading(depth: 1, numbering: none, title)
/// 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
/// make underlined cell with filled value
#let uline(align: center, content) = underline[
#if align != left { hfill(1fr) }
#content
#if align != right { hfill(1fr) }
]
/// bold text
#let bold(content) = text(weight: "bold")[#content]
/// captioned image with label derived from path:
/// - `image.png` = @image
/// - `img/image.png` = @image
/// - `img/foo/image.png` = @foo_image
/// - `img/foo/foo_image.png` = @foo_image
#let img(path, caption) = [
#let parts = path.split(".").first().split("/")
#figure(
image(path),
caption: caption,
)
#label(
if parts.len() <= 2 or parts.at(-1).starts-with(parts.at(-2)) {
// ("image",), (_, "image") and (.., "img", "img_image")
parts.last()
} else {
// (.., "img", "image") = "img_image"
parts.at(-2) + "_" + parts.at(-1)
}.replace(" ", "_"),
)
]
/// subjects list
#let subjects = (
"БД": "Бази даних",
"ОПНJ": "Основи програмування на Java",
"ОС": "Операційні системи",
"ПП": "Проектний практикум",
"СПМ": "Скриптові мови програмування",
"Ф": "Філософія",
)
/// education programs list
#let edu_programs = (
"ПЗПІ": (
name: "Інженерія програмного забезпечення",
number: 121,
),
)
#let month_gen(month) = (
"січня",
"лютого",
"березня",
"квітня",
"травня",
"червня",
"липня",
"серпня",
"вересня",
"жовтня",
"листопада",
"грудня",
).at(month - 1)
/// 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: "Liberation Serif", size: 14pt, hyphenate: false, lang: "ua")
set par(justify: true, first-line-indent: 1.25cm)
set underline(evade: false)
// set 1.5 line spacing
set block(spacing: spacing)
set par(spacing: spacing)
set par(leading: spacing)
// enums and lists
let ua_alph_numbering() = {
// INFO: This alphabet is not full, maybe it should be extended or maybe not.
// I cant remember nor find proper formatting rules.
// "абвгґдеєжзиіїйклмнопрстуфхцчшщьюя" (full alphabet)
let alphabet = "абвгдежиклмнпрстуфхцшщюя".split("")
i => { alphabet.at(i) + ")" }
}
set enum(numbering: ua_alph_numbering(), 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
set figure.caption(separator: [ -- ])
show figure.where(kind: table): set figure.caption(position: top)
show figure.caption.where(kind: table): set align(left)
let img = counter("image")
let tab = counter("table")
show figure.where(kind: image): set figure(
numbering: (..) => {
img.step()
context str(counter(heading).get().at(0)) + "." + context img.display()
},
)
show figure.where(kind: table): set figure(
numbering: (..) => {
tab.step()
context str(counter(heading).get().at(0)) + "." + context tab.display()
},
)
// appearance of references to images and tables
show ref: it => {
let el = it.element
if el == none or not el.has("kind") {
return it
}
let el_name = if el.kind == image {
"рис."
} else if el.kind == table {
"таблицю"
} else {
return it
}
link(
el.location(),
[(див. #el_name #numbering(el.numbering))],
)
}
// TODO: Maybe this will be better. Must be investigated.
//
// set math.equation(numbering: (..num) =>
// numbering("(1.1)", counter(heading).get().first(), num.pos().first())
// )
// set figure(numbering: (..num) =>
// numbering("1.1", counter(heading).get().first(), num.pos().first())
// )
show figure: it => {
v(spacing * 2, weak: true)
it
v(spacing * 2, weak: true)
}
// headings
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)
}
// listings
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
}
/// DSTU 3008:2015 Template for NURE
/// -> content
/// - doc (content): Content to apply the template to.
/// - title (str): Title of the document.
/// - subject_shorthand (str): Subject short name.
/// - department_gen (str): Department name in genitive form.
/// - authors ((name: str, full_name_gen: str, variant: int, group: str, gender: str),): List of Authors dicts.
/// - mentors ((name: str, gender: str, degree: str),): List of mentors dicts.
/// - edu_program_shorthand (str): Education program shorthand.
/// - task_list (done_date: datetime, initial_data: 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.
/// - abstract (keywords: (str, ), text: (content | str)): Abstract object.
/// - bib_path path: Path to the bibliography yaml file.
/// - appendices ((title: str, content: content, ): List of appendices objects.
#let cw-template(
doc,
title: "NONE",
subject_shorthand: "NONE",
department_gen: "Програмної інженерії",
author: (),
mentors: (),
edu_program_shorthand: "ПЗПІ",
task_list: (),
calendar_plan: (),
abstract: (),
bib_path: "bibl.yml",
appendices: (),
) = {
set document(title: title, author: author.name)
show: style
let bib-count = state("citation-counter", ())
show cite: it => {
it
bib-count.update(((..c)) => (..c, it.key))
}
show bibliography: it => {
set text(size: 0pt)
it
}
let head_mentor = mentors.at(0)
let edu_program = edu_programs.at(edu_program_shorthand)
// page 1
[
#set align(center)
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
\
Кафедра Програмної інженерії
\
ПОЯСНЮВАЛЬНА ЗАПИСКА
ДО КУРСОВОЇ РОБОТИ
з дисципліни: "#subjects.at(subject_shorthand, default: "NONE")"
Тема роботи: "#title"
\ \ \
#columns(2, gutter: 4cm)[
#set align(left)
#if author.gender == "m" { [Виконав\ ] } else { [Виконала\ ] } ст. гр. #author.group
\
Керівник:\
#head_mentor.degree
\
Робота захищена на оцінку
\
Комісія:\
#for mentor in mentors {
[#mentor.degree\
]
}
#colbreak()
#set align(left)
\
#author.name
\ \
#head_mentor.name
\
#underline(" " * 35)
\ \
#for mentor in mentors {
[#mentor.name\
]
}
]
#v(1fr)
Харків -- #task_list.done_date.display("[year]")
#pagebreak()
]
//
// page 2
{
uline([Харківський національний університет радіоелектроніки])
linebreak()
linebreak()
grid(
columns: (100pt, 1fr),
bold([
Кафедра
Дисципліна
Спеціальність
]),
{
uline(align: left, department_gen)
linebreak()
uline(align: left, subjects.at(subject_shorthand))
linebreak()
uline(align: left, [#edu_program.number #edu_program.name])
},
)
grid(
columns: (1fr, 1fr, 1fr),
gutter: 0.3fr,
[#bold("Курс") #uline(2)], [#bold("Група") #uline(author.group)], [#bold("Семестр") #uline(3)],
)
linebreak()
linebreak()
linebreak()
align(center, bold[ЗАВДАННЯ \ на курсову роботу студента])
linebreak()
uline(align: left)[_#author.full_name_gen _]
linebreak()
linebreak()
bold[\1. Тема роботи:]
uline[#title.]
linebreak()
{
bold[\2. Строк здачі закінченої роботи:]
uline(task_list.done_date.display("[day].[month].[year]"))
hfill(10fr)
}
linebreak()
bold[\3. Вихідні дані для роботи:]
uline(task_list.source)
linebreak()
bold[\4. Зміст розрахунково-пояснювальної записки:]
uline(task_list.content)
linebreak()
bold[\5. Перелік графічного матеріалу:]
uline(task_list.graphics)
linebreak()
{
bold[\6. Строк здачі закінченої роботи:]
uline(task_list.done_date.display("[day].[month].[year]"))
hfill(10fr)
}
pagebreak()
}
// page 3
{
align(center, bold[КАЛЕНДАРНИЙ ПЛАН])
linebreak()
calendar_plan.plan_table
linebreak()
grid(
columns: (5fr, 5fr),
grid(
columns: (1fr, 2fr, 1fr),
gutter: 0.2fr,
[
Студент \
Керівник \
#align(center)["#underline[#calendar_plan.approval_date.day()]"]
],
[
#uline(align: center, []) \
#uline(align: center, []) \
#uline(align: center, month_gen(calendar_plan.approval_date.month()))
],
[
\ \
#underline[#calendar_plan.approval_date.year()] р.
],
),
[
#author.name, \
#head_mentor.degree
#head_mentor.name.
],
)
pagebreak()
}
// page 4 {{{
[
#align(center, bold([РЕФЕРАТ])) \
#context [
#let pages = counter(page).final().at(0)
#let tables = counter("table").final().at(0)
#let images = counter("image").final().at(0)
#let bibs = bib-count.final().dedup().len()
#let counters = ()
#if pages != 0 { counters.push([#pages с.]) }
#if tables != 0 { counters.push([#tables табл.]) }
#if images != 0 { counters.push([#images рис.]) }
#if bibs != 0 { counters.push([#bibs джерел]) }
Пояснювальна записка до курсової роботи: #counters.join(", ").
]
\
#{
let keywords = abstract.keywords.map(upper)
let is_cyrillic = word => word.split("").any(char => ("А" <= char and char <= "я"))
let n = keywords.len()
for i in range(n) {
for j in range(0, n - i - 1) {
if (
(not is_cyrillic(keywords.at(j)) and is_cyrillic(keywords.at(j + 1)))
or (
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.join(", ")
}
\
#abstract.text
]
// }}}
// page 5
outline(
title: [
ЗМІСТ
#v(spacing * 2, weak: true)
],
depth: 2,
indent: auto,
)
doc
// bibliography
{
heading(depth: 1, numbering: none)[Перелік джерел посилання]
bibliography(
bib_path,
style: "ieee",
full: true,
title: none,
)
let bib_data = yaml(bib_path)
let format-entry(citation) = {
if (citation.type == "Web") {
let date_array = citation.url.date.split("-")
let date = datetime(
year: int(date_array.at(0)),
month: int(date_array.at(1)),
day: int(date_array.at(2)),
)
[
#citation.title.
_#{citation.author}_.
URL: #citation.url.value (дата звернення: #date.display("[day].[month].[year]")).
]
} else if citation.type == "Book" [
#citation.author
#citation.title.
#citation.publisher,
#citation.date.
#citation.page-total c.
] else [
UNSUPPORTED BIBLIOGRAPHY ENTRY TYPE, PLEASE OPEN THE ISSUE
]
}
show enum.item: it => {
box(width: 1.25cm)
box(width: 1em + 0.5cm)[#it.number.]
it.body
linebreak()
}
context {
for (i, citation) in query(ref.where(element: none)).map(r => str(r.target)).dedup().enumerate() {
enum.item(
i + 1,
format-entry(bib_data.at(citation)),
)
}
}
}
// appendices
{
counter(heading).update(0)
for (i, appendix) in appendices.enumerate() [
#set heading(
numbering: i => [
Додаток #"АБВГДЕЖИКЛМНПРСТУФХЦШЩЮЯ".split("").at(i)
],
)
#show heading: it => {
set align(center)
set text(size: 14pt, weight: "regular")
pagebreak(weak: true)
bold(upper(counter(heading).display(it.numbering)))
linebreak()
it.body
v(spacing * 2, weak: true)
}
#heading(appendix.title)
#appendix.content
]
}
}
/// 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)
align(center)[
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ \
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
\ \
Кафедра #department_gen
\ \ \
Звіт \
з
#if doctype == "ЛБ" [лабораторної роботи] else [практичної роботи]
#if worknumber != none [ #worknumber]
з дисципліни: "#subjects.at(subject_shorthand, default: "UNLNOWN SUBJECT, PLEASE OPEN THE ISSUE")"
з теми: "#title"
\ \ \ \
#columns(2)[
#set align(left)
#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
}

22
template/config/doc.yaml Normal file
View File

@ -0,0 +1,22 @@
title: Потiк керування та алгоритмічні структури Bash
subject: СМП
doctype: ЛБ
worknumber: 2
mentors:
- name: Шевченко Т. Г.
degree: Доцент кафедри ПІ
gender: m
- name: Франко І. Я.
degree: Асистент кафедри ПІ
gender: m
edu_program: &EDU ПЗПІ
university: ХНУРЕ
authors:
- name: Косач Л. П.
full_name_gen: Косач Лариси Петрівни
course: 2
edu: *EDU
gender: f
group: 23-2
semester: 4
variant: 8

View File

@ -1,35 +1,24 @@
#import "template.typ": * #import "@local/nure:0.1.0": *
#import "@preview/indenta:0.0.3": fix-indent
#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 = (
done_date: datetime(year: 2024, month: 12, day: 27), done_date: datetime(year: 2024, month: 12, day: 27),
initial_data: datetime(year: 2024, month: 9, day: 15), initial_date: datetime(year: 2024, month: 9, day: 15),
source: "методичні вказівки до виконання курсової роботи, вимоги до інформаційної системи, предметна область, що пов’язана з управлінням класом та класним керівництвом.", source: "методичні вказівки до виконання курсової роботи, вимоги до інформаційної системи, предметна область, що пов’язана з управлінням класом та класним керівництвом.",
content: "вступ, аналіз предметної області; постановка задачі; проектування бази даних; опис програми; висновки; перелік джерел посилання.", content: "вступ, аналіз предметної області; постановка задачі; проектування бази даних; опис програми; висновки; перелік джерел посилання.",
graphics: "загальна діаграма класів, ER-діаграма, UML-діаграми, DFD-діаграма, схема БД в 1НФ, 2НФ, 3НФ, копії екранів (“скриншоти”) прикладної програми, приклади звітів прикладної програми.", graphics: "загальна діаграма класів, ER-діаграма, UML-діаграми, DFD-діаграма, схема БД в 1НФ, 2НФ, 3НФ, копії екранів (“скриншоти”) прикладної програми, приклади звітів прикладної програми.",
@ -70,41 +59,66 @@
"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, легко
адаптується під потреби користувача.
], ],
) )
#let appendices = ( #let appendices = [
( = Приклад звіту 1
title: "Приклад звіту 1", #v(-spacing)
content: [test], == Частина 1
), #lorem(100)
( == Частина2
title: "Приклад звіту 2", #lorem(200)
content: [test],
),
(
title: "Приклад звіту 3",
content: [test],
),
)
#show: cw-template.with( = Приклад звіту 2
#lorem(200)
= Приклад звіту 3
#lorem(200)
]
#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,
) )
#show: fix-indent() = Моделювання
#lorem(250)
= Імплементація
#v(-spacing)
== Підоготовка
#lorem(200)
== Процес
#lorem(500)
= Тестування
#lorem(300)

53
template/lab.typ Normal file
View File

@ -0,0 +1,53 @@
#import "@local/nure:0.1.0": *
#show: pz-lb.with(..yaml("config/doc.yaml"))
#v(-spacing)
== Мета роботи
#lorem(100)
== Хід роботи
#v(-spacing)
=== Підготовка
#lorem(150)
=== Виконання дослідження
#lorem(300)
=== Підрахунок результатів
#lorem(250)
== Висновки
#lorem(100)
== Контрольні запитання
#lorem(100):
- #lorem(20);
- #lorem(30);
- #lorem(15);
- #lorem(25);
- #lorem(42);
- #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)

11
typst.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "nure"
version = "0.1.0"
entrypoint = "lib.typ"
authors = ["linerds"]
license = "GPL-3.0"
description = "Typst NURE package"
[template]
path = "template"
entrypoint = "lab.typ"