moved WIP templates here

This commit is contained in:
2025-02-06 14:50:02 +02:00
parent 7f7f69c3ed
commit 1a06e70082
2 changed files with 867 additions and 0 deletions

267
default.typ Normal file
View File

@ -0,0 +1,267 @@
#import "@preview/indenta:0.0.3": fix-indent
#let subjects = (
БД: (
name: "Бази даних",
mentor: (
name: "Черепанова Ю. Ю.",
gender: "f",
degree: "ст. викл. каф. ПІ",
),
),
)
/// DSTU 3008:2015 Template for NURE
/// -> content
/// - doc (content): Content to apply the template to.
/// - title (string): Title of the document.
/// - authors: List of Author dicts.
/// - mentor: Mentor dict.
/// - include_toc: Include table of contents?
/// - doctype ("lb" | "pz" | "ku"): Document type.
/// - worknumber: Number of the work, can be omitted.
/// - subject: Subject name.
#let conf(
doc,
title: [Work Title],
authors: ((name: "Author Name", variant: 1, group: "Group Name", gender: "m"),),
include_toc: false,
doctype: "ЛБ",
worknumber: 1,
subject_shorthand: "NONE",
) = {
// numless header
let numless(it) = {
set heading(numbering: none)
it
}
// LaTeX-like vfill shorthand
let vfill = () => v(1fr)
set document(title: title, author: authors.at(0).name)
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", size: 14pt, hyphenate: false, lang: "ua")
set par(justify: true, first-line-indent: 1.25cm)
// set 1.5 line spacing
let spacing = 0.95em
set block(spacing: spacing)
set par(spacing: spacing)
set par(leading: spacing)
// enums and lists
let ua_alph(pattern: "а)") = {
// 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 => {
let letter = alphabet.at(i)
let str = ""
for char in pattern {
if char == "а" {
str += letter
} else if char == "А" {
str += upper(letter)
} else {
str += char
}
}
str
}
}
set enum(numbering: ua_alph(pattern: "а)"), 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: [ -- ])
let fig = counter("figure")
let tab = counter("table")
show figure.where(kind: image): set figure(
numbering: (..) => {
fig.step()
context str(counter(heading).get().at(0) + worknumber - 1) + "." + context fig.display()
},
)
show figure.where(kind: table): set figure(
numbering: (..) => {
tab.step()
context str(counter(heading).get().at(0) + worknumber - 1) + "." + context tab.display()
},
)
// 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")
// HACK: I can't set initial value for headers counter, so change is only visual. If this style is changed do not forget to fix images and tables numbering as well.
set heading(numbering: (n1, ..x) => numbering("1.1", n1 - 1 + worknumber, ..x))
show heading.where(level: 1): it => {
set align(center)
set text(size: 14pt, weight: "semibold")
pagebreak(weak: true)
block(width: 100%, spacing: 0em)[ #upper(it) ]
}
show heading.where(level: 2): it => {
set text(size: 14pt, weight: "regular")
block(width: 100%, spacing: 0em)[
#h(1.25cm)
#counter(heading).display(it.numbering)
#it.body
]
}
let fix-spacings() = doc => {
if not doc.has("children") { return doc }
let elems = doc.children.filter(x => x != [ ] and x.func() != parbreak)
let is_heading = e => e != none and e.func() == heading
for (i, elem) in elems.enumerate() {
if not is_heading(elem) {
elem
continue
}
let prev_elem = elems.at(i - 1, default: none)
let next_elem = elems.at(i + 1, default: none)
if elem.depth == 2 {
v(spacing * (if not is_heading(prev_elem) { 2 } else { 1 }), weak: true)
}
elem
v(spacing * (if not is_heading(next_elem) { 2 } else { 1 }), weak: true)
}
}
show: fix-spacings()
show: fix-indent()
if doctype in ("ЛБ", "ПЗ") {
let subject = subjects.at(subject_shorthand, default: "NONE")
let mentor = subject.mentor
align(
center,
[
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
#linebreak()
Кафедра Програмної інженерії
#linebreak()
#linebreak()
#linebreak()
Звіт
з
#if doctype == "ЛБ" { [лабораторної роботи] } else { [практичної роботи] }
#if worknumber != none { [ #worknumber] }
з дисципліни: "#subject.name"
з теми: "#title"
#linebreak()
#linebreak()
#linebreak()
#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\
]
#vfill()
Харків -- #datetime.today().display("[year]")
],
)
} else if doctype == "КУ" { }
if include_toc {
outline(
title: [
ЗМІСТ
#v(spacing * 2)
],
depth: 2,
indent: auto,
)
}
doc
}

600
test.typ Normal file
View File

@ -0,0 +1,600 @@
#import "@preview/indenta:0.0.3": fix-indent
#let subjects = (
"БД": (
name: "Бази даних",
mentors: (
(
name: "Черепанова Ю. Ю.",
gender: "f",
degree: "Ст. викл. каф. ПІ",
),
(
name: "Русакова Н. Є.",
gender: "f",
degree: "Доц. каф. ПІ",
),
(
name: "Широкопетлєва М. С.",
gender: "f",
degree: "Ст. викл. каф. ПІ",
),
),
),
)
/// DSTU 3008:2015 Template for NURE
/// -> content
/// - doc (content): Content to apply the template to.
/// - title (string): Title of the document.
/// - authors: List of Author dicts.
/// - mentor: Mentor dict.
/// - include_toc: Include table of contents?
/// - doctype ("lb" | "pz" | "ku"): Document type.
/// - worknumber: Number of the work, can be omitted.
/// - subject: Subject name.
#let conf(
doc,
authors: (
(
name: "Ситник Є. С.",
full_name_gen: "Ситника Єгора Сергійовича",
variant: 14,
group: "ПЗПІ-23-2",
)
),
title: "Інформаційна система «Помічник класного керівника». Керування класом",
worknumber: 1,
doctype: "ЛБ",
subject_shorthand: "БД",
department: "Програмної інженерії",
edu_program: (
name: "Інженерія програмного забезпечення",
number: 121,
),
task_list: (
done_date: datetime(year: 2024, month: 12, day: 27),
initial_data: datetime(year: 2024, month: 9, day: 15),
source: "методичні вказівки до виконання курсової роботи, вимоги до інформаційної системи, предметна область, що пов’язана з управлінням класом та класним керівництвом.",
content: "вступ, аналіз предметної області; постановка задачі; проектування бази даних; опис програми; висновки; перелік джерел посилання.",
graphics: "загальна діаграма класів, ER-діаграма, UML-діаграми, DFD-діаграма, схема БД в 1НФ, 2НФ, 3НФ, копії екранів (“скриншоти”) прикладної програми, приклади звітів прикладної програми.",
),
calendar_plan: (
plan_table: [],
approval_date: datetime(year: 2024, month: 12, day: 27),
),
abstract: (
keywords: (
"БАЗА ДАНИХ",
"АВТОМАТИЗАЦІЯ",
"КЛАСНИЙ КЕРІВНИК",
"КЛАС",
"ШКОЛА",
"GO",
"HTMX",
"MYSQL",
"SQL",
),
text: [
Мета даної роботи проєктування та розробка інформаційної системи «Помічник класного керівника. Керування класом», яка спрямована на автоматизацію процесів управління класом, облік даних про учнів, планування та аналіз навчального процесу. Основна задача інформаційної системи спростити роботу класного керівника, забезпечити ефективну організацію документації та взаємодію з учасниками освітнього процесу.
Для реалізації системи було використано сучасний стек технологій, а саме: Go як основна мова програмування для створення серверної логіки, HTMX для динамічного оновлення інтерфейсу без використання складних фреймворків, MySQL як СУБД для зберігання даних про учнів, їх оцінки та розклад, Neovim як середовище для швидкої та ефективної розробки коду, Go Echo веб-фреймворк для створення REST API, Go SQLx бібліотека для роботи з базою даних, що забезпечує зручність і гнучкість.
Результат роботи веб-додаток, який дозволяє обліковувати особисті дані учнів та їхніх опікунів, включаючи інформацію про успішність, відвідуваність та інші показники; планувати розклад занять; генерувати звіти про успішність учнів та переглядати різну статистику. Інтерфейс, створений з використанням HTMX, легко адаптується під потреби користувача.
],
),
include_toc: true,
) = {
// LaTeX-like vfill/hfill shorthands
let vfill = () => v(1fr)
let hfill(width) = box(width: width, repeat("")) // NOTE: This is a HAIR SPACE (U+200A ), not a regular space
set underline(evade: false)
let uline(align: center, content) = {
underline([
#if align != left { hfill(1fr) }
#content
#if align != right { hfill(1fr) }
])
}
// other shorthands
let bold(it) = text(weight: "bold")[#it]
let month_gen(month) = (
"січня",
"лютого",
"березня",
"квітня",
"травня",
"червня",
"липня",
"серпня",
"вересня",
"жовтня",
"листопада",
"грудня",
).at(month - 1)
set document(title: title, author: authors.at(0).name)
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", size: 14pt, hyphenate: false, lang: "ua")
set par(justify: true, first-line-indent: 1.25cm)
// set 1.5 line spacing
let spacing = 0.95em
set block(spacing: spacing)
set par(spacing: spacing)
set par(leading: spacing)
// enums and lists
let ua_alph(pattern: "а)") = {
// 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 => {
let letter = alphabet.at(i)
let str = ""
for char in pattern {
if char == "а" {
str += letter
} else if char == "А" {
str += upper(letter)
} else {
str += char
}
}
str
}
}
set enum(numbering: ua_alph(pattern: "а)"), 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: [ -- ])
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) + worknumber - 1) + "." + context img.display()
},
)
show figure.where(kind: table): set figure(
numbering: (..) => {
tab.step()
context str(counter(heading).get().at(0) + worknumber - 1) + "." + context tab.display()
},
)
// 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")
// HACK: I can't set initial value for headers counter, so change is only visual. If this style is changed do not forget to fix images and tables numbering as well.
set heading(numbering: (n1, ..x) => numbering("1.1", n1 - 1 + worknumber, ..x))
show heading.where(level: 1): it => {
set align(center)
set text(size: 14pt, weight: "semibold")
pagebreak(weak: true)
block(width: 100%, spacing: 0em)[ #upper(it) ]
}
show heading.where(level: 2): it => {
set text(size: 14pt, weight: "regular")
block(width: 100%, spacing: 0em)[
#h(1.25cm)
#counter(heading).display(it.numbering)
#it.body
]
}
let fix-spacings() = doc => {
if not doc.has("children") { return doc }
let elems = doc.children.filter(x => x != [ ])
let is_heading = e => e != none and e.func() == heading
for (i, elem) in elems.enumerate() {
if not is_heading(elem) {
elem
continue
}
let prev_elem = elems.at(i - 1, default: none)
let next_elem = elems.at(i + 1, default: none)
if elem.depth == 2 {
v(spacing * (if not is_heading(prev_elem) { 2 } else { 1 }), weak: true)
}
elem
v(spacing * (if not is_heading(next_elem) { 2 } else { 1 }), weak: true)
}
}
show: fix-spacings()
show: fix-indent()
let subject = subjects.at(subject_shorthand, default: "NONE")
if doctype in ("ЛБ", "ПЗ") {
let mentor = subject.mentors.at(0)
align(
center,
[
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
#linebreak()
Кафедра Програмної інженерії
#linebreak()
#linebreak()
#linebreak()
Звіт
з
#if doctype == "ЛБ" { [лабораторної роботи] } else { [практичної роботи] }
#if worknumber != none { [ #worknumber] }
з дисципліни: "#subject.name"
з теми: "#title"
#linebreak()
#linebreak()
#linebreak()
#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\
]
#vfill()
Харків -- #datetime.today().display("[year]")
],
)
} else if doctype == "КУ" {
let head_mentor = subject.mentors.at(0)
let author = authors.at(0)
// page 1 {{{
align(center)[
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
#linebreak()
Кафедра Програмної інженерії
#linebreak()
ПОЯСНЮВАЛЬНА ЗАПИСКА
ДО КУРСОВОЇ РОБОТИ
з дисципліни: "#subject.name"
Тема роботи: "#title"
#linebreak()
#linebreak()
#linebreak()
#columns(2, gutter: 4cm)[
#set align(left)
#if authors.len() == 1 [
#if author.gender == "m" { [Виконав\ ] } else { [Виконала\ ] } ст. гр. #author.group
]
#linebreak()
Керівник:\
#head_mentor.degree
#linebreak()
Робота захищена на оцінку
#linebreak()
Комісія:\
#for mentor in subject.mentors {
[#mentor.degree\
]
}
#colbreak()
#set align(left)
#linebreak()
#author.name
#linebreak()
#linebreak()
#head_mentor.name
#linebreak()
#underline(" " * 35)
#linebreak()
#linebreak()
#for mentor in subject.mentors {
[#mentor.name\
]
}
]
#vfill()
Харків -- #datetime.today().display("[year]")
#pagebreak()
]
// }}}
// page 2 {{{
uline([Харківський національний університет радіоелектроніки])
linebreak()
linebreak()
grid(
columns: (100pt, 1fr),
bold([
Кафедра
Дисципліна
Спеціальність
]),
{
uline(align: left, department)
linebreak()
uline(align: left, subject.name)
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)[#emph(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 {{{
heading(numbering: none, depth: 1, [Календарний план])
calendar_plan.plan_table
linebreak()
grid(
columns: (6fr, 5fr),
grid(
columns: (1fr, 3fr, 1fr),
gutter: 0.2fr,
[
Студент
#linebreak()
Керівник
#linebreak()
#align(center, ["#calendar_plan.approval_date.day()"])
],
[
#uline(align: center, [])
#linebreak()
#uline(align: center, [])
#linebreak()
#uline(align: center, month_gen(calendar_plan.approval_date.month()))
],
{
linebreak()
linebreak()
[#calendar_plan.approval_date.year() р.]
},
),
[
#author.name,
#linebreak()
#head_mentor.degree
#head_mentor.name.
],
)
pagebreak()
// }}}
// page 4 {{{
[
#heading(numbering: none, depth: 1, [Реферат])
Пояснювальна записка до курсової роботи:
#context [ #counter(page).final().at(0) ] с.,
#context [ #counter("table").final().at(0) ] табл.,
#context [ #counter("image").final().at(0) ] рис.,
#context [ #counter(bibliography).final().at(0) ] джерел.
#linebreak()
#{
let keywords = abstract.keywords
let is_cyrillic = word => word
.split("")
.any(char => ("А" <= char and char <= "я") or char == "Ё" or 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(", ")
}
#linebreak()
#abstract.text
]
// }}}
}
if include_toc {
outline(
title: [
ЗМІСТ
#v(spacing * 2)
],
depth: 2,
indent: auto,
)
}
doc
}
#show: conf.with(
authors: (
(name: "Ситник Є. С.", full_name_gen: "Ситника Єгора Сергійовича", variant: 15, group: "ПЗПІ-23-2", gender: "m"),
),
title: "Інформаційна система «Помічник класного керівника». Керування класом",
include_toc: true,
doctype: "КУ",
subject_shorthand: "БД",
)