forked from pencelheimer/typst_nure_template
WIP!: break up lib.typ
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
// Template formatting functions {{{1
|
||||
|
||||
/// bold text
|
||||
#let bold(content) = text(weight: "bold")[#content]
|
||||
|
||||
/// 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) }
|
||||
]
|
||||
|
||||
/// month name from its number
|
||||
#let month_gen(month) = (
|
||||
"січня",
|
||||
"лютого",
|
||||
"березня",
|
||||
"квітня",
|
||||
"травня",
|
||||
"червня",
|
||||
"липня",
|
||||
"серпня",
|
||||
"вересня",
|
||||
"жовтня",
|
||||
"листопада",
|
||||
"грудня",
|
||||
).at(month - 1)
|
||||
|
||||
#let is-cyr(c) = regex("[\p{Cyrillic}]") in c
|
||||
|
||||
#let gender-form(verb, gender: "p") = {
|
||||
(
|
||||
"author": ("m": "Виконав", "f": "Виконала", "p": "Виконали"),
|
||||
"mentor": ("m": "Перевірив", "f": "Перевірила", "p": "Перевірили"),
|
||||
)
|
||||
.at(verb)
|
||||
.at(if gender == "m" or gender == "f" { gender } else { "p" }, default: "p")
|
||||
}
|
||||
|
||||
#let gender-get(a) = if "gender" in a.keys() { a.gender } else { "p" }
|
||||
|
||||
#let pz-lb-title(type, number: none) = {
|
||||
let type-title = (
|
||||
"ЛБ": [Звіт \ з лабораторної роботи],
|
||||
"ПЗ": [Звіт \ з практичної роботи],
|
||||
"КР": [Контрольна робота],
|
||||
"РФ": [Реферат], // зрада
|
||||
).at(type, default: type)
|
||||
if number != none { [#type-title №#number] } else { [#type-title] }
|
||||
}
|
||||
|
||||
// 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)]
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#import "/src/helpers.typ": gender-form, gender-get, pz-lb-title
|
||||
|
||||
#let minimal(
|
||||
uni,
|
||||
edu_program,
|
||||
subject,
|
||||
type,
|
||||
number,
|
||||
title,
|
||||
authors,
|
||||
mentors,
|
||||
) = {
|
||||
align(center)[
|
||||
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ \
|
||||
#upper(uni.name)
|
||||
|
||||
\ \
|
||||
Кафедра #uni.edu_programs.at(edu_program).department_gen
|
||||
|
||||
\ \ \
|
||||
#pz-lb-title(type, number: number)
|
||||
|
||||
з дисципліни: "#uni.subjects.at(subject, default: subject)"
|
||||
#if title != none [\ з теми: "#eval(title, mode: "markup")"]
|
||||
|
||||
\ \ \ \
|
||||
#columns(2)[
|
||||
#set align(left)
|
||||
#set par(first-line-indent: 0pt)
|
||||
|
||||
#if authors.len() == 1 {
|
||||
let a = authors.first()
|
||||
[#gender-form("author", gender: gender-get(a)):\ ]
|
||||
[ст. гр. #a.edu_program\-#a.group\ #a.name\ ]
|
||||
if a.variant != none [Варіант: №#a.variant]
|
||||
} else if authors.len() > 1 [
|
||||
#gender-form("author"):\
|
||||
#for a in authors [ст. гр. #a.edu_program\-#a.group\ #a.name\ ]
|
||||
]
|
||||
|
||||
#colbreak()
|
||||
#set align(right)
|
||||
|
||||
#if mentors.len() == 1 {
|
||||
let m = mentors.first()
|
||||
[#gender-form("mentor", gender: gender-get(m)):\ ]
|
||||
if "degree" in m.keys() and m.degree != none [#m.degree\ ]
|
||||
[#m.name\ ]
|
||||
} else if mentors.len() > 1 [
|
||||
#gender-form("mentor"):\
|
||||
#for m in mentors {
|
||||
if "degree" in m.keys() and m.degree != none [#m.degree\ ]
|
||||
[#m.name\ ]
|
||||
}]
|
||||
]
|
||||
|
||||
#v(1fr)
|
||||
|
||||
Харків -- #datetime.today().display("[year]")
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Title page layouts for pz-lb {{{1
|
||||
// This module provides different title page layouts for practice/lab work templates
|
||||
|
||||
#import "/src/helpers.typ": gender-form, gender-get, pz-lb-title
|
||||
|
||||
/// Default DSTU title page layout (ministry + university header, 2-column author/mentor info)
|
||||
/// Returns: content for the title page
|
||||
|
||||
/// Simple title page layout (university header only, single column layout)
|
||||
/// Returns: content for the title page
|
||||
|
||||
#let simple(
|
||||
uni,
|
||||
edu_program,
|
||||
subject,
|
||||
type,
|
||||
number,
|
||||
title,
|
||||
authors,
|
||||
mentors,
|
||||
) = {
|
||||
align(center)[
|
||||
#upper(uni.name)
|
||||
Кафедра #uni.edu_programs.at(edu_program).department_gen
|
||||
|
||||
\ \ \
|
||||
|
||||
#pz-lb-title(type, number: number)
|
||||
|
||||
з дисципліни: "#uni.subjects.at(subject, default: subject)"
|
||||
#if title != none [\ з теми: "#eval(title, mode: "markup")"]
|
||||
|
||||
\ \ \
|
||||
|
||||
#if authors.len() == 1 {
|
||||
let a = authors.first()
|
||||
[#gender-form("author", gender: gender-get(a)):\ #a.name]
|
||||
[ст. гр. #a.edu_program\-#a.group]
|
||||
if a.variant != none [Варіант: №#a.variant]
|
||||
} else if authors.len() > 1 [
|
||||
#gender-form("author"):\
|
||||
#for a in authors [#a.name (ст. гр. #a.edu_program\-#a.group)\ ]
|
||||
]
|
||||
|
||||
\
|
||||
|
||||
#if mentors.len() == 1 {
|
||||
let m = mentors.first()
|
||||
[#gender-form("mentor", gender: gender-get(m)):\ ]
|
||||
if "degree" in m.keys() and m.degree != none [#m.degree ]
|
||||
[#m.name]
|
||||
} else if mentors.len() > 1 [
|
||||
#gender-form("mentor"):\
|
||||
#for m in mentors {
|
||||
if "degree" in m.keys() and m.degree != none [#m.degree\ ]
|
||||
[#m.name\ ]
|
||||
}
|
||||
]
|
||||
|
||||
#v(1fr)
|
||||
|
||||
#datetime.today().display("[year]")
|
||||
]
|
||||
}
|
||||
|
||||
// vim:sts=2:sw=2:fdm=marker:cms=/*%s*/
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
#let spacing = 0.95em // spacing between lines
|
||||
/// symbols used for numbering according to DSTU 3008:2015
|
||||
#let ukr-enum = "абвгдежиклмнпрстуфхцшщюя".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 => { ukr-enum.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)
|
||||
show figure.where(kind: raw): set figure.caption(position: top)
|
||||
show figure.where(kind: raw): 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)
|
||||
}
|
||||
|
||||
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 {{{3
|
||||
show raw.where(block: true): it => {
|
||||
let new_spacing = 0.5em
|
||||
set block(spacing: new_spacing)
|
||||
set par(spacing: new_spacing, leading: new_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(ukr-enum.at(i)) + numbering(".1.1", ..n))
|
||||
set figure(numbering: i => upper(ukr-enum.at(counter(heading).get().at(0))).i)
|
||||
set math.equation(numbering: i => upper(ukr-enum.at(counter(heading).get().at(0))).i)
|
||||
|
||||
// Heading supplement (Heading name shown when citing with @ref)
|
||||
set heading(supplement: [Додаток])
|
||||
|
||||
// Headings
|
||||
show heading: it => if it.level == 1 {
|
||||
set align(center)
|
||||
set text(size: 14pt, weight: "regular")
|
||||
|
||||
pagebreak(weak: true)
|
||||
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
|
||||
} // }}}
|
||||
Reference in New Issue
Block a user