From 3fff9f0f75da6bab05d5182f8ca6bffea434671f Mon Sep 17 00:00:00 2001 From: JustAnyone Date: Sun, 10 May 2026 14:19:59 +0300 Subject: [PATCH] Move the library over from dotfiles --- src/assets/iso690-numeric-lt.csl | 271 +++++++++++++++ src/assets/ktu-logo.png | Bin 0 -> 2751 bytes src/config.typ | 9 + src/fragments.typ | 204 +++++++++++ src/lib.typ | 580 +++++++++++++++++++++++++++++++ typst.toml | 13 + 6 files changed, 1077 insertions(+) create mode 100644 src/assets/iso690-numeric-lt.csl create mode 100644 src/assets/ktu-logo.png create mode 100644 src/config.typ create mode 100644 src/fragments.typ create mode 100644 src/lib.typ create mode 100644 typst.toml diff --git a/src/assets/iso690-numeric-lt.csl b/src/assets/iso690-numeric-lt.csl new file mode 100644 index 0000000..f9cd942 --- /dev/null +++ b/src/assets/iso690-numeric-lt.csl @@ -0,0 +1,271 @@ + + diff --git a/src/assets/ktu-logo.png b/src/assets/ktu-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3131335830a617c5d5e3bf89de8fa464cc9e8cbd GIT binary patch literal 2751 zcmeHJXEYlO7f!^e5Y>oLVhgcKi?+sV#P+I+Sw-!Z4!c96HnD1zY6(gZYBjY>Q@a{O zVzou9F%x@LDQ!RR`F?-Dzd!Fi&vWj1?w@<^bM8IoCRtmVLcqdc0000nH#4$1&Y8z7 zIspOzfUR7IKaK@3#Ksf_sHMP}$Aa~S!6gF#fSAs8y5jVG!_2#O1_S^W=f^EeE`d=&VuQ8lm+(wkZ>Af2hP>31rSHovI!F z7Wv!nCI5;;F3TswIMtxnqC3}$z~BB(9l99y261?u0A<+fM|Uav*9mVr<2b$~ku~l$ zOYM7=o?OTriBPyzEx2~&IqRfxg7|lL?%7Le!&;d3U%r(v`=`K(4TmB6Ya=(ACLUvRzH z?h7uu*fmqNiqmf;@g?3}W){SI)a6x)a@Y9Jfypb%f-=c~fEgJe(k z@idW`)EjHPK_T5Q99U2OQdd-f8E(B1afEBFuh&*ntghc=3y3IpkyUoJ#QVerM-7>P z+d~{J>VuNJ3gPS`ze4s^##NT$(f;5@;aZpI-7ZF*$ciCi0oUCYU7VfE<;eTnE|s^c zawDe;lFwbzt=RZO&E;qLvX7MUd{~*f=hi}QR*Q}6U;JZ+E|p5H=^CMq^FtJCg;nnu z-AP=A_s^E^#lv<6r`SlW4s`G6klw(HMQIjR><+YbR-G0ff*}F?)2T8ml4#*Q0G(zy z$2zk0n%mR5q^%($EM!q%=3M2QQTm1E7lEAq8lV=|6w<5}K>j6?Y&>be#73f7-s?7Y zCI=GIW0E*3cxCBQX0#wnpKgv1S82K~tnx8Nk~b^$Nil*nZZ$M+v z)Wa&!1LyqR&g5yOCn@U7%YtEiwIvtNUhPR)!v)Sc?;eJj8mA!XaUwG%z44b(s6hrEJt+!s}ED9s0LL6?jgDuoz%{pGYoloSaOS|7xv)nUe8P>U7Fg;w$}hx2_nkBE zo?#PQ{#JW;LSE7~J44f=ACB-&gPxPKK^<;}_PX*}#^oKwZErgS4U6Za0KnXy(-@Q* zpaHAJLPUl-H8ErFg9iJDFAL@a8MG*T;XAKO$jrQmmTVmFdjJpFqYdTP(zCG%nelAX z(hSS@DnGq9D?w_|Rxjr4 zO;!Qy*)k9fCQW;BuTFDhs2HY_GVkzk^-S?+sX0eT&v2>ARI(DFeU+Ej51=9#)T~U0 z|Lys4&M2^CpA9ynJ25Ha@G)dc`BQanRk;_oHft!$Pxw4P*!y|=HQ6l;wXZ2d%%UGh zLX0V0C0qap5xEGv;lgM2-H>YnCoX~zj@J@!gGtoE*oO=*{`JgsLe4}Dv@*aU5wj5F z5l4%JZ2HbzRhrz16T(?YvkP%O77%R>&{6C;C{TBgBT~B`1kM3TAh#{`()7#>ih`;{(38=kD+C8Rg3%J2b|3>l1yx>f|*gsogM{n`uWmj zk0kiHx66#llQ42o0gE=Sko#CJp)DR1;6}MA;%VfxbZI}r!-r>WZr8M9(+995<5-5i_xe{hYgrtVr zBk|kG<E1AM$*&*35Kv#Ckv0H&9ocDmAl_N6!pD8hxa9WNw=< z^ReQqCQmcX=9$7ommFUqBf*nf@E1rUcq)53YP@*;3O0>h9~j~Hh&dRyVlAg27Bd>@ z^_n1R0vYKu>?p=-h3-nHDq&zyfg!9UWWdYw+#awxAUSCZcdvj>MGvMun0ADKX7Xf= zX4@$g%C_1Q_8c$5Q6_S&QFY{_C;~R~NON$WbaMbb&qzs|7|J{HU_H2NR3RsQyrEc$ ap2$C!$L6{6hiU(O8Ro`TMztvSnEwFeQ2LJm literal 0 HcmV?d00001 diff --git a/src/config.typ b/src/config.typ new file mode 100644 index 0000000..d8388b6 --- /dev/null +++ b/src/config.typ @@ -0,0 +1,9 @@ +#let __DEBUG_AUTHOR_TABLE = state("$ktu-template-DEBUG_AUTHOR_TABLE", false) +#let debug-author-table() = { + __DEBUG_AUTHOR_TABLE.update(true) +} + +#let __HEADING_EXPERIMENT = state("$ktu-template-HEADING_EXPERIMENT", false) +#let enable-heading-experiment() = { + __HEADING_EXPERIMENT.update(true) +} diff --git a/src/fragments.typ b/src/fragments.typ new file mode 100644 index 0000000..3d8d4a6 --- /dev/null +++ b/src/fragments.typ @@ -0,0 +1,204 @@ +#import "config.typ": __DEBUG_AUTHOR_TABLE + +/// Wrapper around the table function that returns a KTU style conformant table. +/// This includes setting text size to 10 pt. +#let ktu-table(..args) = { + show table: it => { + set text(size: 10pt) + // TODO: FIXME line spacing is defined differently + set par(leading: 1em - 0.75em) // intervalas tarp eilučių -- 1 + it + } + table( + ..args + ) +} + +#let ktu-author-table( + authors: (), + alignment: right, +) = context { + // The layout should be a list of lists whose elements are (name, role) pairs. + assert(authors.len() > 0, message: "author table must have at least one author") + assert(authors.all(it => it.len() == 2), message: "each author entry must be a pair of name and role") + + let frame(color) = (x, y) => ( + left: 0pt, + right: 0pt, + top: if y == 0 { 0.5pt + color } else { 0pt }, + bottom: 0.5pt + color, + ) + set table( + inset: 5.4pt, + stroke: if __DEBUG_AUTHOR_TABLE.get() { + 0.5pt + rgb("D4AF37") + } else { + frame(rgb("D4AF37")) + }, + ) + show table.cell: it => context { + [#it] + if it.body == [] { + v(10pt) + } else { + v(0pt) + } + } + + if alignment == center { + align(center, table( + columns: (198.5pt + 56.7pt), + table.header([]), + ..for author in authors { + let (name, role) = author + (align(center)[ + #set block(below: 8pt) + #block[*#name*] + #block[#role] + + ], []) + } + )) + } else { + align(alignment, table( + columns: (198.5pt, 56.7pt), + table.header( + [], [], + ), + ..for author in authors { + let (name, role) = author + (align(left)[ + #set block(below: 8pt) + #block[*#name*] + #block[#role] + + ], [], [], []) + } + )) + } +} + +/// This function constructs the title page header block for KTU reports. It includes the university logo, name, subheaders, the main and sub titles of the report. +/// +/// - bigTitle (content): The main title of the report, usually the name of the work. Displayed in 18 pt font. +/// - subTitles (): Additional titles or information to be displayed under the main title, such as the type of work. Displayed in 14 pt font. If not provided, defaults to "Rašto darbo tipas". +/// - subHeaders (): Additional header information to be displayed under the university name, such as the faculty. If not provided, defaults to "Fakulteto pavadinimas". +/// -> +#let ktu-title-header-block( + bigTitle: highlight[Didelis pavadinimas], + subTitles: (), + subHeaders: (), +) = { + let parsedSubtext = if subHeaders.len() > 0 { + subHeaders + } else { + ( + highlight[Fakulteto pavadinimas], + ) + } + + let subTitles = if subTitles.len() > 0 { + subTitles + } else { + ( + highlight[Rašto darbo tipas], + ) + } + + // Top of the title page + v(20pt) + align(center)[ + #image("assets/ktu-logo.png", width: 2.46cm, height: 2.69cm) + #v(25pt) + #block[*Kauno technologijos universitetas*] + #for value in parsedSubtext { + block[#value] + } + ] + + // The title page information + v(91pt) + align(center)[ + #set par(justify: false) + #set linebreak(justify: false) + #block(text(size: 18pt, hyphenate: false)[*#bigTitle*]) + #for value in subTitles { + block(text(size: 14pt)[#value]) + } + ] +} + +#let ktu-heading-page-centered( + faculty: highlight[Fakulteto pavadinimas], + title: highlight[Rašto darbo pavadinimas], + subtitles: highlight[Praktikos ataskaita / referatas ir pan. (įrašyti rašto darbo tipą)], + authors: ( + (highlight[Vardenis Pavardenis], highlight[Projekto autorius]), + (highlight[Vardenis Pavardenis], highlight[Vadovas]), + ), + place: highlight[Kaunas], + year: highlight[#datetime.today().year()], +) = { + let isArr = type(subtitles) == array + if not isArr { + subtitles = (subtitles,) + } + ktu-title-header-block( + subHeaders: (faculty,), + bigTitle: title, + subTitles: subtitles, + ) + v(94pt) + ktu-author-table(authors: authors, alignment: center) + align(center+bottom, block([*#place, #year*])) +} + +#let ktu-heading-page-normal( + faculty: highlight[Fakulteto pavadinimas], + title: highlight[Rašto darbo pavadinimas], + subtitles: highlight[Praktikos ataskaita / referatas ir pan. (įrašyti rašto darbo tipą)], + authors: ( + (highlight[Vardenis Pavardenis], highlight[Projekto autorius]), + (highlight[Vardenis Pavardenis], highlight[Vadovas]), + ), + place: highlight[Kaunas], + year: highlight[#datetime.today().year()], +) = { + let isArr = type(subtitles) == array + if not isArr { + subtitles = (subtitles,) + } + ktu-title-header-block( + subHeaders: (faculty,), + bigTitle: title, + subTitles: subtitles, + ) + v(94pt) + ktu-author-table(authors: authors) + align(center+bottom, block([*#place, #year*])) +} + +#let ktu-academic-honestly-declaration-page( + faculty: highlight[Informatikos fakultetas], + author: highlight[Vardenis Pavardenis], + projectTitle: highlight[Projekto pavadinimas], +) = { + ktu-title-header-block( + subHeaders: (faculty, author), + bigTitle: projectTitle, + subTitles: ("Akademinio sąžiningumo deklaracija",) + ) + v(20pt) + [ + Patvirtinu, kad: + + baigiamąjį projektą parengiau savarankiškai ir sąžiningai, nepažeisdama(s) kitų asmenų autoriaus ar kitų teisių, laikydamasi(s) Lietuvos Respublikos autorių teisių ir gretutinių teisių įstatymo nuostatų, Kauno technologijos universiteto (toliau -- Universitetas) intelektinės nuosavybės valdymo ir perdavimo nuostatų bei Universiteto akademinės etikos kodekse nustatytų etikos reikalavimų; + + baigiamajame projekte visi pateikti duomenys ir tyrimų rezultatai yra teisingi ir gauti teisėtai, nei viena šio projekto dalis nėra plagijuota nuo jokių spausdintinių ar elektroninių šaltinių, visos baigiamojo projekto tekste pateiktos citatos ir nuorodos yra nurodytos literatūros sąraše; + + įstatymų nenumatytų piniginių sumų už baigiamąjį projektą ar jo dalis niekam nesu mokėjęs (-usi); + + suprantu, kad išaiškėjus nesąžiningumo ar kitų asmenų teisių pažeidimo faktui, man bus taikomos akademinės nuobaudos pagal Universitete galiojančią tvarką ir būsiu pašalinta(s) iš Universiteto, o baigiamasis projektas gali būti pateiktas Akademinės etikos ir procedūrų kontrolieriaus tarnybai nagrinėjant galimą akademinės etikos pažeidimą. + + #v(10pt) + #h(58%) #author + + #h(58%) _Patvirtinta elektroniniu būdu_ + ] +} \ No newline at end of file diff --git a/src/lib.typ b/src/lib.typ new file mode 100644 index 0000000..85046fd --- /dev/null +++ b/src/lib.typ @@ -0,0 +1,580 @@ +#import "@preview/codly:1.3.0": codly, codly-init +#import "config.typ": debug-author-table, enable-heading-experiment, __HEADING_EXPERIMENT +#import "fragments.typ": ( + ktu-table, + ktu-heading-page-centered, ktu-heading-page-normal, ktu-academic-honestly-declaration-page +) + +/** + * Paruošta pagal "Rašto ..." +*/ + +/* + * Further reading required: + * - Double line spacing | https://github.com/typst/typst/issues/106 + * - Proposal: change `leading` option to `line-height` | https://github.com/typst/typst/issues/4224 +*/ + +/// +/// Insert a heading without a number. +/// +/// Usually used for introductory or summary sections at the start and end. +/// - text (str): The heading's title. +/// -> +#let unnumbered-heading(text) = { + set heading(numbering: none) + [#text] +} + +#let figureDefinitions = ( + table: ( + outlineFormat: (number) => [*#number lentelė.*], + captionFormat: (number) => [*#number lentelė.*], + ), +) + +#let custom-figure( + kind, + caption: none, + body +) = { + figure( + body, + kind: kind, + caption: caption, + supplement: "CUSTOM-FIGURE" + ) +} + +#let appendix-item(body) = { + heading( + metadata("appendix-heading") + "priedas. " + body, + level: 2, + numbering: (..any) => {str(any.at(1))} + ) +} + +// Stores localized names for various figure types +#let figureNames = ( + table: ("lentelė"), + image: ("pav"), + code: ("kodo frag"), + equation: ("lygtis"), +) + +// Utility function to round numbers with padded zeros +#let round-and-pad(number, decimals) = { + let rounded = calc.round(number, digits: decimals) + let s = str(rounded) + let parts = s.split(".") + let integer-part = parts.at(0) + let decimal-part = if parts.len() == 2 { parts.at(1) } else { ""} + + + let padded-decimal = if decimals > 0 { + let current-decimal-length = decimal-part.len() + let padding-needed = decimals - current-decimal-length + let trailing-zeros = "" + for _ in range(padding-needed) { + trailing-zeros = trailing-zeros + "0" + } + if decimal-part == "" { + "." + trailing-zeros + } else { + "." + decimal-part + trailing-zeros + }.slice(0, decimals + 1) + } else { + "" + } + integer-part + padded-decimal +} + + +/// Returns a number for the given reference target. +/// - target (label): Label to get the reference number for. +#let ref-no(target) = context { + let loc = locate(target) + let elem = query(target) + let item = elem.at(0) + + // If it's a figure, return the figure number + if item.func() == figure { + link(loc, [#counter(figure.where(kind: item.kind)).at(loc).at(0)]) + } else if item.func() == heading { + let fullValue = counter(heading).at(loc) + + // If the heading has the "appendix-heading" metadata attached, + // it means that it's an appendix heading and should be numbered differently + if item.body.has("children") and item.body.children.at(0) == metadata("appendix-heading") { + link(loc, [#fullValue.at(1)]) + // Otherwise, show the fully qualified heading numbering + } else { + link(loc, [#fullValue.map((x) => str(x)).join(".")]) + } + } else { + panic("referencing unknown type: ", item.func()) + } +} + +#let __ref-no-element(element) = context { + // Ensure that we pass an element + if type(element) != content { + panic("can only reference elements of type content") + } + let loc = element.location() + let elem = query(loc) + let fig = elem.at(0) + if fig.func() != figure { + panic("referencing unknown type: " + fig.func()) + } + fig.caption.counter.at(loc).at(0) +} + +// Constructs a reference from multiple targets +#let custom-ref(..targets) = context { + let collected = (:) + + for target in targets.pos() { + let loc = locate(target) + let elem = query(target) + + let fig = elem.at(0) + if fig.func() != figure { + panic("referencing unknown type") + } + + // determine what we... + let element = fig.body; + let elementName = "unknown"; + let found = false; + while not found { + + // If it's a grid + if (element.func() == grid) { + for cell in element.children { + if cell.body.func() == image { + elementName = "pav." + found = true + break + } + } + break + } + + if (element.func() == table) { + elementName = "lentelė" + found = true + break + } + + if (element.func() == raw) { + elementName = "kodo frag." + found = true + break + } + + if (element.func() == image) { + elementName = "pav." + found = true + break + } + + panic("unknown element", element.func()) + } + + if elementName not in collected { + collected.insert(elementName, ()) + } + + collected.at(elementName).push( + (loc, fig.caption.counter.at(loc).at(0)) + ) + } + + if collected.len() > 1 { + panic("multiple types detected") + } + + for type in collected { + let name = type.at(0) + let arr = type.at(1).sorted(key: k => k.at(1)) + + [(žr. #arr.map(x =>link(x.at(0), [#x.at(1)])).join(", ") #name)] + } +} + + +/// Returns a KTU template-conformant outline. +/// - depth (int | none): Same as outline depth. +/// - indent (auto | function | relative): Same as outline indent. +/// - target (function | label | location | selector): Same as outline target. +/// - title (auto | content | none): Same as outline title. +/// -> outline +#let __ktu_outline( + depth: none, + indent: 0em, // Disable the default outline indenting + target: heading, + title: auto +) = { + // TODO: įtrauka + set block(spacing: 0em) + // genius solution by @two_horus on Discord (364397430059302912) + show outline: o => context { + // If it's a heading, show the default outline with bold text + if (o.target == selector(heading)) { + // Define known target widths based on KTU template + let targets = (0.64cm, 0.96cm, 1.28cm, 1.6cm, 1.92cm) + + // Apply custom outline entry formatting + show outline.entry: it => { + // Recompute the gap based on the prefix content, so that the outline entry is indented + // from the left regardless of the length of the prefix (based on the requirement) + let prefixContent = it.prefix() + let measurement = measure(prefixContent) + let target = targets.at(it.level - 1, default: 0.64cm) + let newGap = target - measurement.width + if it.element.body.has("children") and it.element.body.children.at(0) == metadata("appendix-heading") { + target = 0.64cm + } + let newGap = target - measurement.width + link( + it.element.location(), + it.indented(prefixContent, it.inner(), gap: newGap), + ) + } + + show outline.entry.where(level: 1): e => { + strong(e) + } + o + + // If it's an image + } else if (o.target == figure.where(kind: image)) { + show outline.entry: it => link( + it.element.location(), + it.indented([*#__ref-no-element(it.element) #figureNames.image.*], [ #it.inner()], gap: 0pt), + ) + o + + // If it is a table, show table formatting + } else if (o.target == figure.where(kind: table)) { + show outline.entry: it => link( + it.element.location(), + it.indented([*#__ref-no-element(it.element) #figureNames.table.*], [ #it.inner()], gap: 0pt), + ) + o + + // If it is a table, show table formatting + } else if (o.target == figure.where(kind: raw)) { + show outline.entry: it => link( + it.element.location(), + it.indented([*#__ref-no-element(it.element) #figureNames.code.*], [ #it.inner()], gap: 0pt), + ) + o + + // Otherwise, try to determine what kind of outline it is + } else { + + /*[ + #o.target #type(o.target), + #(o.target == "heading") + #(o.target == heading) + #(o.target == figure.where(kind: heading)) + #(o.target == heading.where()) + #(o.target == selector(heading)) + ]*/ + + show outline.entry: it => link( + it.element.location(), + it.indented([*#__ref-no-element(it.element) unknown.*], it.inner(), gap: 0pt), + ) + o + } + } + outline(depth: depth, indent: indent, target: target, title: title) +} + +#let func-to-name(func) = { + if func == table { + return "lentelė" + } + if func == image { + return "pav." + } + if func == grid { + return "pav." + } + return func +} + +// Doesn't work in Typst 0.12.0 due to relative paths +#let bibliography-list(path) = { + bibliography(path, title: "Literatūros sąrašas", full: true) +} + +/// Returns a KTU style conformant outline. +/// - depth (int | none): Same as outline depth. +/// - indent (auto | function | relative): Same as outline indent. +/// - target (function | label | location | selector): Same as outline target. +/// - title (auto | content | none): Same as outline title. +/// -> outline +#let ktu-outline( + depth: none, + indent: 0em, // Disable the default outline indenting + target: heading, + title: auto +) = { + __ktu_outline(depth: depth, indent: indent, target: target, title: title) +} + +#let ktu-table-of-contents(depth: 3) = { + ktu-outline(target: heading, title: "Turinys", depth: depth) +} + +#let ktu-table-list() = { + ktu-outline(title: heading("Lentelių sąrašas", outlined: true), target: figure.where(kind: table)) +} + +#let ktu-picture-list() = { + ktu-outline(title: heading("Paveikslų sąrašas", outlined: true), target: figure.where(kind: image)) +} + +/// Define a custom outline for a specific figure type. +/// This function creates an outline entry with a specified title and figure type. +/// The outline entry will link to the figure of the specified type. +/// - title (str): Title of the outline +/// - kind (str): Type of the figure +#let custom-list(title, kind) = { + __ktu_outline(title: heading(title, outlined: true), target: figure.where(kind: kind)) +} + +#let setup-code(body) = { + show: codly-init.with() + codly( + fill: white, + zebra-fill: none, + stroke: none, + display-name: false, + display-icon: false, + ) + show raw: set text(font: "Hack", spacing: 80%) + body +} + +#let __page_rules(body) = { + // Page size and margins + set page( + paper: "a4", + width: 210mm, + height: 297mm, + margin: ( + left: 30mm, + right: 10mm, + bottom: 20mm, + top: 20mm + ) + ) + set page(width: 595pt, height: 842pt) + + // Numbering rules + set page(numbering: none, number-align: right) + + // Use Lithuanian quotes + set smartquote(quotes: "„“") + + // Heading numbering + set heading(numbering: "1.") + + // Number equations + set math.equation(numbering: "(1)") + + // Set text font + set text( + font: "Arial", + size: 12pt, + lang: "lt", + // Change where the bounding box is drawn for the text + top-edge: "ascender", + bottom-edge: "descender", + kerning: false, // Disable kerning + ) + + // Text line interval, defined differently in Typst + let leading = 1.15em // Your line spacing (1, 1.5, 2, etc.) + let leading = leading - 0.75em // "Normalization" + set par(leading: leading) + + // Indentation for lists and enumerations + set enum(indent: 12pt) + set list(indent: 12pt) + + body +} + +#let setup-page(body) = { + show: __page_rules.with() + + // Pagal formaliuosius rašto darbų reikalavimus + + // Tarpas tarp teksto pastraipų + set par(spacing: 10pt) + set block(below: 10pt) + + // Teksto lygiuotė, abipusė + set par(justify: true) + set linebreak(justify: true) + + // Antraštės + // Force them into blocks so they don't count as paragraphs + show heading: it => { + // Align everything left + set align(left) + + // Visų antraščių teksto dydis vienodas + // Visų antraščių teksto šifras paryškintas + set text(size: 12pt) + set block(below: 10pt) + + let useExperiment = __HEADING_EXPERIMENT.get() + + // TODO: intervalas tarp eilučių – 1,15 kiekvienai antraštei + + // Antraštė be nr. + if it.numbering == none { + // Centruota lygiuotė + set align(center) + + // atstumas prieš ir po antraštės - 10 pt + block[#it.body] + if useExperiment { + v(10pt) + } + } + + + // Skyrius + if it.numbering != none and it.level == 1 { + // abipusė lygiuotė + set par(justify: true) + //set align + + // po antraštės - 10 pt + block[#counter(heading).display() #it.body] + if useExperiment { + v(10pt) + } + } + + // Determine whether the heading has appending metadata attached and adjust its display accordingly + let isAppendixHeading = it.body.has("children") and it.body.children.at(0) == metadata("appendix-heading") + if isAppendixHeading { + block[#counter(heading).display(it.numbering) #it.body] + } + + // Poskyris ir skyrelis + if not isAppendixHeading and it.numbering != none and it.level != 1 { + // abipusė lygiuotė + set par(justify: true) + + // prieš ir po antraštės - 10 pt + if useExperiment { + v(10pt) + } + block[#counter(heading).display() #it.body] + if useExperiment { + v(10pt) + } + } + } + + // Override references for equations + show ref: it => { + let el = it.element + + if el == none { + return it + } + + // Override equation references + if el.func() == math.equation { + link( + el.location(), + numbering(el.numbering, ..counter(math.equation).at(el.location())) + ) + // Override references to figures + } else if el.func() == figure { + let fig = el.body + let figType = fig.func() + link(el.location(), [ + (žr. #numbering(el.numbering, ..counter(figure.where(kind: figType)).at(el.location())) #func-to-name(figType)) + ]) + } else { + it + } + } + + // Change captions for figures + show figure: it => { + let separator = [.] + let caption = it.caption + + // If caption is not provided, just show the figure body + if caption == none { + it.body + return + } + + let counter = caption.counter + let supplement = caption.supplement + + if it.body.func() == math.equation { + supplement = figureNames.equation + } else if it.kind == image { + supplement = figureNames.image + } else if it.kind == table { + supplement = figureNames.table + } else if it.kind == raw { + supplement = figureNames.code + } + + + // Tables have captions at the top + set text(size: 11pt) + if it.kind == table { + {set align(left) + [*#context counter.display(caption.numbering) #supplement#separator* #caption.body]} + it.body + } else { + it.body + [*#context counter.display(caption.numbering) #supplement#separator* #caption.body] + } + } + + // Lentelės pirma eilutė + /* + show table.cell.where(y: 0): it => context { + set align(left) + set par(justify: false) + set text(size: TableHeadSize.get()) // Šrifto dydis + v(3pt) + // Paryškintas + [*#it*] + v(3pt) + } + + show table.cell: it => context { + set align(left) + set par(justify: false) + set text(size: TableCellSize.get()) + v(3pt) + [#it] + v(3pt) + }*/ + + // Set bibliography and citing style + set bibliography(style: "assets/iso690-numeric-lt.csl") + + // Return the body + body +} + diff --git a/typst.toml b/typst.toml new file mode 100644 index 0000000..92a3bfa --- /dev/null +++ b/typst.toml @@ -0,0 +1,13 @@ +[package] +name = "ktu-paper" +version = "0.1.0" +compiler = "0.12.0" +entrypoint = "src/lib.typ" +repository = "https://git.svetikas.lt/JustAnyone/dotfiles" +authors = ["Dominykas Svetikas "] +license = "MIT" +description = "KTU report template to use for writing lab reports or final thesis." + +[template] +path = "template" +entrypoint = "main.typ"