diff --git a/src/csl/dstu-8302-2015.csl b/src/csl/dstu-8302-2015.csl new file mode 100644 index 0000000..c0b4eb8 --- /dev/null +++ b/src/csl/dstu-8302-2015.csl @@ -0,0 +1,420 @@ + + \ No newline at end of file diff --git a/src/lib.typ b/src/lib.typ index 37266ea..1e042bc 100644 --- a/src/lib.typ +++ b/src/lib.typ @@ -65,6 +65,7 @@ /// - title (str): Work title /// - authors (array): List of author dictionaries /// - mentors (array): List of mentor dictionaries +/// - committee-members (array): Optional list of commission member dictionaries for the title page /// - task-list (dict): Task metadata /// - calendar-plan (dict): Calendar plan table /// - abstract (dict): Keywords and abstract text @@ -77,6 +78,7 @@ title: none, authors: (), mentors: (), + committee-members: none, task-list: (), calendar-plan: (), abstract: (), @@ -107,12 +109,14 @@ } else { abstract } + let committee_members = committee-members tp.cw-v2.nure( university, title, authors, mentors, + committee_members, task-list, calendar-plan, abstract, @@ -125,10 +129,12 @@ doc + + { show regex("^\\d+\\."): it => [#it#h(0.5cm)] show block: it => [#it.body#parbreak()] - bibliography(bib-path, title: [Перелік джерел посилання], style: "csl/dstu-3008-2015.csl", full: true) + bibliography(bib-path, title: [Перелік джерел посилання], style: "csl/dstu-8302-2015.csl", full: true) } style.appendices(appendices) diff --git a/src/style.typ b/src/style.typ index 97f4681..3333f75 100644 --- a/src/style.typ +++ b/src/style.typ @@ -186,6 +186,7 @@ counter(figure.where(kind: raw)).update(0) counter(figure.where(kind: image)).update(0) counter(figure.where(kind: table)).update(0) + dstu-table-counter.update(0) it } set figure(numbering: i => context numbering("1.1", counter(heading).get().at(0), i)) @@ -218,6 +219,15 @@ v(double-half-spacing, weak: true) } + // blocks `like this` aren't welcome, so ` is replaced with " + show raw.where(block: false): it => text( + lang: "uk", + size: 14pt, + hyphenate: false, + weight: "regular", + font: ("Times New Roman", "Liberation Serif"), + )["#it.text"] + it } diff --git a/src/title-pages/coursework-v2/nure.typ b/src/title-pages/coursework-v2/nure.typ index b6ae474..cada300 100644 --- a/src/title-pages/coursework-v2/nure.typ +++ b/src/title-pages/coursework-v2/nure.typ @@ -1,7 +1,7 @@ #import "../../shared.typ": universities #import "../../helpers.typ": * #import "../../style.typ": spacing -#import "../../utils.typ": bold, uline, filled-lines +#import "../../utils.typ": bold, uline, filled-lines, hfill #let note(content) = block(width: 100%, above: 5pt, below: 0pt)[ #set text(size: 10pt) @@ -69,16 +69,37 @@ #let task-num(n) = box(str(n) + ".") #let title-field(value) = { - uline(align: center, filled-lines(value)) + uline(align: center, value.join()) uline(align: center, []) note[(тема)] } +#let commission-lines(members) = { + if members.len() > 0 { + for (i, member) in members.enumerate() { + if i > 0 { + linebreak() + } + let member-display-name = member.at("display-name", default: member.name) + let member-degree = member.at("degree", default: "") + uline(align: left, [#member-degree #member-display-name]) + } + } else { + v(0.55em) + line(length: 100%, stroke: 0.5pt) + v(0.55em) + line(length: 100%, stroke: 0.5pt) + v(0.55em) + line(length: 100%, stroke: 0.5pt) + } +} + #let nure( university, title, authors, mentors, + committee_members, task-list, calendar-plan, abstract, @@ -90,6 +111,11 @@ ) = { let author = authors.first() let head-mentor = mentors.first() + let commission-members = if committee_members == none { + mentors.slice(1) + } else { + committee_members + } let uni = universities.at(university) let edu-prog = uni.edu-programs.at(author.edu-program) @@ -177,12 +203,8 @@ #pad(left: 75pt)[ #set par(first-line-indent: 0pt) Члени комісії (#text(size: 10pt)[Власне ім'я, ПРІЗВИЩЕ, підпис]) - #v(0.55em) - #line(length: 100%, stroke: 0.5pt) - #v(0.55em) - #line(length: 100%, stroke: 0.5pt) - #v(0.55em) - #line(length: 100%, stroke: 0.5pt) + #v(0.15em) + #commission-lines(commission-members) ] ], ) @@ -266,12 +288,12 @@ #v(5.0em) - Дата видачі завдання “#underline(task-list.initial-date.display("[day]"))” #underline(month-gen(task-list.initial-date.month())) #task-list.initial-date.display("[year]")р. + Дата видачі завдання “#underline(task-list.initial-date.display("[day]"))” #underline(month-gen(task-list.initial-date.month())) #task-list.initial-date.display("[year]") р. #v(1.4em) - Здобувач #uline(align: center, []) - #note[(підпис)] + Здобувач #underline([#hfill(6cm)]) + #note[(підпис) #h(8cm)] #v(1.4em) @@ -292,7 +314,8 @@ #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 dstu-tables = query(metadata).filter(it => type(it.value) == str and it.value.starts-with("start-dstu-table-")).len() + #let tables = query(figure.where(kind: table)).len() + dstu-tables #let bibs = bib-count.final().dedup().len() #let counters = () @@ -306,23 +329,33 @@ \ - #( - abstract - .keywords - .map(upper) - .sorted(by: (a, b) => { - if is-cyr(a) != is-cyr(b) { is-cyr(a) } else { a < b } - }) - .join(", ") - ) + #let keyword-pairs = if abstract.keywords.len() > 0 and type(abstract.keywords.first()) == array { + abstract.keywords.map(pair => ( + uk: pair.at(0), + en: pair.at(1), + )) + } else if abstract.at("en", default: none) != none and abstract.en.at("keywords", default: none) != none { + abstract.keywords.enumerate().map(((i, uk)) => ( + uk: uk, + en: abstract.en.keywords.at(i), + )) + } else { + abstract.keywords.map(uk => (uk: uk)) + } + #let sorted-keyword-pairs = keyword-pairs.sorted(by: (a, b) => { + if is-cyr(a.uk) != is-cyr(b.uk) { is-cyr(a.uk) } else { a.uk < b.uk } + }) + + #(sorted-keyword-pairs.map(pair => upper(pair.uk)).join(", ")) \ #abstract.text - #if abstract.at("en", default: none) != none [ + #if abstract.at("en", default: none) != none or (keyword-pairs.len() > 0 and keyword-pairs.first().at("en", default: none) != none) [ \ - #(abstract.en.keywords.map(upper).join(", ")) + + #(sorted-keyword-pairs.map(pair => upper(pair.en)).join(", ")) \ @@ -340,7 +373,7 @@ } else { block(width: 100%)[ #link(el.location())[ - ДОДАТОК #it.prefix()#h(0.5em)#it.inner() + Додаток #it.prefix()#h(0.5em)#it.inner() ] ] } diff --git a/src/title-pages/coursework/nure.typ b/src/title-pages/coursework/nure.typ index ebce727..3e44507 100644 --- a/src/title-pages/coursework/nure.typ +++ b/src/title-pages/coursework/nure.typ @@ -210,7 +210,8 @@ #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 dstu-tables = query(metadata).filter(it => type(it.value) == str and it.value.starts-with("start-dstu-table-")).len() + #let tables = query(figure.where(kind: table)).len() + dstu-tables #let bibs = bib-count.final().dedup().len() /* TODO: why this stopped working? #let tables = counter(figure.where(kind: table)).final().at(0) diff --git a/template/default/coursework-v2.typ b/template/default/coursework-v2.typ index 0df3874..f9a06f3 100644 --- a/template/default/coursework-v2.typ +++ b/template/default/coursework-v2.typ @@ -20,6 +20,12 @@ (name: "Сокорчук І. П.", display-name: "Ігор СОКОРЧУК", degree: "ст.викл. кафедри ПІ"), ) +#let committee_members = ( + (name: "Груздо І.В.", degree: "Доц."), + (name: "Зибіна К.В.", degree: "Ст. викл."), + (name: "Гребенюк В.О.", degree: "Ст. викл."), +) + #let task-list = ( done-date: datetime(year: 2026, month: 12, day: 27), initial-date: datetime(year: 2026, month: 9, day: 15), @@ -53,11 +59,11 @@ #let abstract = ( keywords: ( - "веб-застосунок", - "інформаційна система", - "курсова робота", - "програмна інженерія", - "тестовий приклад", + ("веб-застосунок", "WEB APPLICATION"), + ("інформаційна система", "INFORMATION SYSTEM"), + ("курсова робота", "COURSEWORK"), + ("програмна інженерія", "SOFTWARE ENGINEERING"), + ("тестовий приклад", "DEMO SAMPLE"), ), text: [ Мета даної роботи -- продемонструвати оформлення пояснювальної записки @@ -74,15 +80,7 @@ шаблону без прив'язки до реального студента, викладача або завершеної роботи. ], ) - #let abstract_en = ( - keywords: ( - "WEB APPLICATION", - "INFORMATION SYSTEM", - "COURSEWORK", - "SOFTWARE ENGINEERING", - "DEMO SAMPLE", - ), text: [ The purpose of this work is to demonstrate the formatting of a coursework explanatory note using the new template variant. @@ -122,6 +120,7 @@ ), authors: authors, mentors: mentors, + committee-members: committee_members, task-list: task-list, calendar-plan: calendar-plan, abstract: abstract,