diff --git a/erv/lb2/flake.lock b/erv/lb2/flake.lock new file mode 100644 index 0000000..7027761 --- /dev/null +++ b/erv/lb2/flake.lock @@ -0,0 +1,113 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "local-nure": { + "flake": false, + "locked": { + "lastModified": 1769126611, + "narHash": "sha256-4qmXN7kx87pEpZHFJpyRbLfZ5GanF5Jbi1Bmfx6ZXss=", + "path": "/storage/git/typst_nure_template", + "type": "path" + }, + "original": { + "path": "/storage/git/typst_nure_template", + "type": "path" + } + }, + "local-nure-upstream": { + "flake": false, + "locked": { + "lastModified": 1768301144, + "narHash": "sha256-VHZXALfaAw5f32mClZTS7MeTSaDSQtErAjI+lgpYIZk=", + "ref": "refs/heads/0.1.0", + "rev": "549d7f060f81a6356c43b2c231e6453ddae19fca", + "revCount": 111, + "type": "git", + "url": "ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template" + }, + "original": { + "type": "git", + "url": "ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1763421233, + "narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "local-nure": "local-nure", + "local-nure-upstream": "local-nure-upstream", + "nixpkgs": "nixpkgs", + "typix": "typix" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "typix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769071922, + "narHash": "sha256-WD8cMrUlqWJWDAD8+B6MUyEuWvi/fgGgv5Wg0xF/Zkc=", + "owner": "loqusion", + "repo": "typix", + "rev": "5d334996b24af342b0992f7f432fcb301ed67314", + "type": "github" + }, + "original": { + "owner": "loqusion", + "repo": "typix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/erv/lb2/flake.nix b/erv/lb2/flake.nix new file mode 100644 index 0000000..e044c10 --- /dev/null +++ b/erv/lb2/flake.nix @@ -0,0 +1,176 @@ +{ + description = "A Nix flake for compiling NURE works"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + typix.url = "github:loqusion/typix"; + typix.inputs.nixpkgs.follows = "nixpkgs"; + + flake-utils.url = "github:numtide/flake-utils"; + + # local-nure.url = "git+ssh://gitea@gitea.linerds.us/unexplrd/typst_nure_template"; + local-nure-upstream.url = "git+ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template"; + local-nure-upstream.flake = false; + + local-nure.url = "path:/storage/git/typst_nure_template"; + local-nure.flake = false; + + # Example of downloading icons from a non-flake source + # font-awesome = { + # url = "github:FortAwesome/Font-Awesome"; + # flake = false; + # }; + }; + + outputs = inputs @ { + nixpkgs, + typix, + flake-utils, + ... + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages.${system}; + inherit (pkgs) lib; + inherit (lib.strings) escapeShellArg; + + typixLib = typix.lib.${system}; + + src = lib.fileset.toSource { + root = ./.; + fileset = lib.fileset.unions [ + # lib/ gets imported, which is unwanted + # (lib.fileset.fromSource (typixLib.cleanTypstSource ./.)) + # ./main.typ + # (lib.fileset.maybeMissing ./doc.toml) + # (lib.fileset.maybeMissing ./utils.typ) + # (lib.fileset.maybeMissing ./chapters) + # (lib.fileset.maybeMissing ./assets) + # (lib.fileset.maybeMissing ./figures) + ./src + ]; + }; + commonArgs = { + typstSource = "src/main.typ"; + + fontPaths = [ + "${pkgs.liberation_ttf}/share/fonts/truetype" + ]; + + # Make sure to override outdated files/links (in case of updated flake.lock) + # (may be undesirable with config/universities.yaml in case of custom subjects) + forceVirtualPaths = true; + + virtualPaths = [ + # Add paths that must be locally accessible to typst here + # { + # dest = "src/lib"; + # src = "${inputs.local-nure}/src"; + # } + # { + # dest = "config/universities.yaml"; + # src = "${inputs.local-nure}/src/config/universities.yaml"; + # } + ]; + }; + + mkTypstPackagesDrv = name: entries: let + linkFarmEntries = + lib.foldl (set: { + name, + version, + namespace, + input, + }: + set + // { + "${namespace}/${name}/${version}" = input; + }) + {} + entries; + in + pkgs.linkFarm name linkFarmEntries; + + unpublishedTypstPackages = mkTypstPackagesDrv "unpublished-packages" [ + { + namespace = "unexplrd"; + name = "test-multifile"; + version = "0.1.0"; + input = inputs.local-nure; + } + { + namespace = "local"; + name = "nure"; + version = "0.1.0"; + input = inputs.local-nure-upstream; + } + ]; + + # Any transitive dependencies must be added here + # See https://loqusion.github.io/typix/recipes/using-typst-packages.html#the-typstpackages-attribute + # unstable_typstPackages = [ + # { + # name = "oxifmt"; + # version = "0.2.1"; + # hash = "sha256-8PNPa9TGFybMZ1uuJwb5ET0WGIInmIgg8h24BmdfxlU="; + # } + # ]; + + # Compile a Typst project, *without* copying the result + # to the current directory + build-drv = typixLib.buildTypstProject (commonArgs + // { + inherit src; + # inherit unstable_typstPackages; + TYPST_PACKAGE_PATH = unpublishedTypstPackages; + }); + + # Compile a Typst project, and then copy the result + # to the current directory + build-script = typixLib.buildTypstProjectLocal (commonArgs + // { + inherit src; + # inherit unstable_typstPackages; + TYPST_PACKAGE_PATH = unpublishedTypstPackages; + }); + + # Watch a project and recompile on changes + watch-script = typixLib.watchTypstProject (lib.recursiveUpdate commonArgs + { + typstWatchCommand = "TYPST_PACKAGE_PATH=${escapeShellArg unpublishedTypstPackages} typst watch"; + }); + in { + checks = {inherit build-drv build-script watch-script;}; + + packages.default = build-drv; + packages.watch = watch-script; + + apps = rec { + default = watch; + build = flake-utils.lib.mkApp { + drv = build-script; + }; + watch = flake-utils.lib.mkApp { + drv = watch-script; + }; + }; + + devShells.default = typixLib.devShell { + inherit (commonArgs) fontPaths virtualPaths; + + env = { + TYPST_PACKAGE_PATH = escapeShellArg unpublishedTypstPackages; + }; + packages = with pkgs; [ + # WARNING: Don't run `typst-build` directly, instead use `nix run .#build` + # See https://github.com/loqusion/typix/issues/2 + # build-script + watch-script + + just + typstyle + yq + ]; + }; + }); +} diff --git a/erv/lb2/justfile b/erv/lb2/justfile new file mode 100644 index 0000000..43fd58e --- /dev/null +++ b/erv/lb2/justfile @@ -0,0 +1,79 @@ +# File aliases for common commands +alias w := watch +alias c := compile +alias nw := nix-watch +alias nb := nix-build +alias nd := nix-develop + + +# Configuration +set shell := ["fish", "-ic"] + +file := "src/main.typ" +doc_config := "src/doc.toml" +# out := `cat {{doc_config}} | tomlq '.doctype + (.worknumber | tostring) + "_" + (.authors[0].name | split(" ")[0]) + "_" + (.authors[0].edu + "-" + .authors[0].group) + "_" + .subject + ".pdf"'` +# out := 'bla' + +# Default target - show available recipes +default: + @just --list + +# Validate required files exist +_check-files: + #!/usr/bin/env bash + set -euo pipefail + if [[ ! -f "{{file}}" ]]; then + echo "Error: Source file {{file}} not found" + exit 1 + fi + if [[ ! -f "{{doc_config}}" ]]; then + echo "Error: Config file {{doc_config}} not found" + exit 1 + fi + +# Watch file for changes and recompile automatically +[group('typst')] +watch: _check-files + typst w {{file}} + +# Compile the document once +[group('typst')] +compile: _check-files + typst c {{file}} + +# Compile and copy to parent directory +[group('typst')] +copy: compile + #!/usr/bin/env bash + # set -euo pipefail + # if [[ ! -f "{{out}}" ]]; then + # echo "Error: Output file {{out}} not found after compilation" + # exit 1 + # fi + local final_name = $(cat {{doc_config}} | tomlq '.doctype + (.worknumber | tostring) + "_" + (.authors[0].name | split(" ")[0]) + "_" + (.authors[0].edu + "-" + .authors[0].group) + "_" + .subject + ".pdf"') + cp "main.typ" "$final_name" + +# Enter nix development environment +[group('nix')] +nix-develop: + nix develop . + +# Watch using nix environment +[group('nix')] +nix-watch: + nix run .#watch + +# Build using nix environment +[group('nix')] +nix-build: + nix run .#build + +# Clean generated PDFs +[group('utils'), confirm] +clean: + @rm -rvf *.pdf + +# Show generated filename +# [group('utils')] +# show-output: +# @echo "{{out}}" \ No newline at end of file diff --git a/erv/lb2/src/assets/sample.c b/erv/lb2/src/assets/sample.c new file mode 100644 index 0000000..9ad18c4 --- /dev/null +++ b/erv/lb2/src/assets/sample.c @@ -0,0 +1,30 @@ +#include +int main() { + int i, j; + + // Number of rows + int rows = 3; + + // Taking first character of alphabet + // which is useful to print pattern + char character = 'A'; + + // This loop is used to identify + // number rows + for (i = 0; i < rows; i++) { + // This for loop is used to + // identify number of columns + // based on the rows + for (j = 0; j <= i; j++) { + // Printing character to get + // the required pattern + printf("%c ", character); + + // Incrementing character value so + // that it will print the next character + character++; + } + printf("\n"); + } + return 0; +} diff --git a/erv/lb2/src/assets/table.csv b/erv/lb2/src/assets/table.csv new file mode 100644 index 0000000..2ec748f --- /dev/null +++ b/erv/lb2/src/assets/table.csv @@ -0,0 +1,2 @@ +1,2,3,4 +5,6,7,8 diff --git a/erv/lb2/src/chapters/appendices.typ b/erv/lb2/src/chapters/appendices.typ new file mode 100644 index 0000000..b221b49 --- /dev/null +++ b/erv/lb2/src/chapters/appendices.typ @@ -0,0 +1,4 @@ +#import "/utils.typ": code + += Код програми sample.c +#code(read("/assets/sample.c")) diff --git a/erv/lb2/src/doc.toml b/erv/lb2/src/doc.toml new file mode 100644 index 0000000..293e2a1 --- /dev/null +++ b/erv/lb2/src/doc.toml @@ -0,0 +1,24 @@ +university = "ХНУРЕ" +subject = "ЕРВ" +type = "ЛБ" +number = 2 + +[[mentors]] +name = "Шевченко Т. Г." +degree = "Доцент кафедри ПІ" +gender = "m" + +[[mentors]] +name = "Франко І. Я." +degree = "Асистент кафедри ПІ" +gender = "m" + +[[authors]] +name = "Косач Л. П." +edu_program = "КУІБ" +group = "23-2" +gender = "f" +variant = 8 +full_name_gen = "Косач Лариси Петрівни" +course = 2 +semester = 4 diff --git a/erv/lb2/src/figures/Google-Logo-700x394.png b/erv/lb2/src/figures/Google-Logo-700x394.png new file mode 100644 index 0000000..9967a3c Binary files /dev/null and b/erv/lb2/src/figures/Google-Logo-700x394.png differ diff --git a/erv/lb2/src/main.typ b/erv/lb2/src/main.typ new file mode 100644 index 0000000..a3d4e65 --- /dev/null +++ b/erv/lb2/src/main.typ @@ -0,0 +1,54 @@ +#import "@unexplrd/test-multifile:0.1.0": * +// #import "/lib/lib.typ": * +#import "utils.typ": * + +#import style: spacing + +// #show: correctly-indent-list-and-enum-items + +// #show: style.dstu +#show: pz-lb.with( + ..toml("doc.toml"), + title: lorem(2), +) + +== #lorem(3) +#v(-spacing) +=== #lorem(5) + +#lorem(20) + ++ #lorem(10) + + #lorem(10) ++ #lorem(10) + + #lorem(10) + $ 1/2 dot 3 = 3/2 $ + + #lorem(10) +$ 1/2 dot 3 = 3/2 $ ++ #lorem(10) + + #lorem(10) + + #lorem(10) + +#lorem(20) + +// #img("/figures/Google-Logo-700x394.png", [Корпорація зла], width: 60%) + + +#lorem(50) + +#figure(caption: "Приклад коду на C", code(read("assets/sample.c"))) + +#lorem(20) + +#figure( + caption: [Цифри], + table( + columns: 4, + table.header([Один], [Два], [Три], [Чотири]), + ..csv("assets/table.csv").flatten(), + ), +) + +#lorem(20) + +#style.appendices(include "chapters/appendices.typ") diff --git a/erv/lb2/src/utils.typ b/erv/lb2/src/utils.typ new file mode 100644 index 0000000..7e1ba9b --- /dev/null +++ b/erv/lb2/src/utils.typ @@ -0,0 +1,109 @@ +/// takes in a string of code, e.g. #code(read("foo.c")) +#let code(content) = raw(block: true, theme: none, content) + +/// read file as bytes +#let p(path) = bytes(read(path, encoding: none)) + +/// include chapters by file names from /chapters +#let chapters(ch) = ( + array(ch).map(chapter => include str(chapter) + ".typ").join() +) + +#let pz-header(worknumber, name) = columns[#text(weight: "bold", [ + #align(left)[Практичне заняття №#worknumber] + #colbreak() + #align(right)[#name] +])] + +/// https://forum.typst.app/t/how-to-make-bullet-list-item-bodies-flow-like-paragraphs/3756/3?u=andrew +/// Spacing doesn't work the same way as native solution if par leading and +/// spacing are different. +#let correctly-indent-list-and-enum-items(doc) = { + let first-line-indent() = if type(par.first-line-indent) == dictionary { + par.first-line-indent.amount + } else { + par.first-line-indent + } + + show list: li => { + for (i, it) in li.children.enumerate() { + let nesting = state("list-nesting", 0) + let indent = context h((nesting.get() + 1) * li.indent) + let get-nesting() = calc.div-euclid(nesting.get(), 10) + let marker = context { + let n = get-nesting() + if type(li.marker) == array { + li.marker.at(calc.rem-euclid(n, li.marker.len())) + } else if type(li.marker) == content { + li.marker + } else { + li.marker(n) + } + } + let parents = state("enum-parents", ()) // Support enum nesting. + let body = { + parents.update(arr => arr + (-1,)) + nesting.update(x => x + 10) + it.body + parbreak() + nesting.update(x => x - 10) + parents.update(arr => arr.slice(0, -1)) + } + let content = { + marker + h(li.body-indent) + body + } + context pad(left: int(nesting.get() != 0) * li.indent, content) + } + } + + show enum: en => { + let start = if en.start == auto { + if en.children.first().has("number") { + if en.reversed { en.children.first().number } else { 1 } + } else { + if en.reversed { en.children.len() } else { 1 } + } + } else { + en.start + } + let number = start + for (i, it) in en.children.enumerate() { + number = if it.number != auto { it.number } else { number } + if en.reversed { number = start - i } + let parents = state("enum-parents", ()) + let get-parents() = parents.get().filter(x => x >= 0) + let indent = context h((get-parents().len() + 1) * en.indent) + let num = if en.full { + context numbering(en.numbering, ..get-parents(), number) + } else { + numbering(en.numbering, number) + } + let max-num = if en.full { + context numbering(en.numbering, ..get-parents(), en.children.len()) + } else { + numbering(en.numbering, en.children.len()) + } + num = context box( + width: measure(max-num).width, + align(right, text(overhang: false, num)), + ) + let list-nesting = state("list-nesting", 0) // Support list nesting. + let body = { + parents.update(arr => arr + (number,)) + list-nesting.update(x => x + 1) + it.body + parbreak() + list-nesting.update(x => x - 1) + parents.update(arr => arr.slice(0, -1)) + } + if not en.reversed { number += 1 } + let content = { + num + h(en.body-indent) + body + } + context pad(left: int(parents.get().len() != 0) * en.indent, content) + } + } + doc +} diff --git a/erv/lb4/flake.lock b/erv/lb4/flake.lock new file mode 100644 index 0000000..7027761 --- /dev/null +++ b/erv/lb4/flake.lock @@ -0,0 +1,113 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "local-nure": { + "flake": false, + "locked": { + "lastModified": 1769126611, + "narHash": "sha256-4qmXN7kx87pEpZHFJpyRbLfZ5GanF5Jbi1Bmfx6ZXss=", + "path": "/storage/git/typst_nure_template", + "type": "path" + }, + "original": { + "path": "/storage/git/typst_nure_template", + "type": "path" + } + }, + "local-nure-upstream": { + "flake": false, + "locked": { + "lastModified": 1768301144, + "narHash": "sha256-VHZXALfaAw5f32mClZTS7MeTSaDSQtErAjI+lgpYIZk=", + "ref": "refs/heads/0.1.0", + "rev": "549d7f060f81a6356c43b2c231e6453ddae19fca", + "revCount": 111, + "type": "git", + "url": "ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template" + }, + "original": { + "type": "git", + "url": "ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1763421233, + "narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "local-nure": "local-nure", + "local-nure-upstream": "local-nure-upstream", + "nixpkgs": "nixpkgs", + "typix": "typix" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "typix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769071922, + "narHash": "sha256-WD8cMrUlqWJWDAD8+B6MUyEuWvi/fgGgv5Wg0xF/Zkc=", + "owner": "loqusion", + "repo": "typix", + "rev": "5d334996b24af342b0992f7f432fcb301ed67314", + "type": "github" + }, + "original": { + "owner": "loqusion", + "repo": "typix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/erv/lb4/flake.nix b/erv/lb4/flake.nix new file mode 100644 index 0000000..e044c10 --- /dev/null +++ b/erv/lb4/flake.nix @@ -0,0 +1,176 @@ +{ + description = "A Nix flake for compiling NURE works"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + typix.url = "github:loqusion/typix"; + typix.inputs.nixpkgs.follows = "nixpkgs"; + + flake-utils.url = "github:numtide/flake-utils"; + + # local-nure.url = "git+ssh://gitea@gitea.linerds.us/unexplrd/typst_nure_template"; + local-nure-upstream.url = "git+ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template"; + local-nure-upstream.flake = false; + + local-nure.url = "path:/storage/git/typst_nure_template"; + local-nure.flake = false; + + # Example of downloading icons from a non-flake source + # font-awesome = { + # url = "github:FortAwesome/Font-Awesome"; + # flake = false; + # }; + }; + + outputs = inputs @ { + nixpkgs, + typix, + flake-utils, + ... + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages.${system}; + inherit (pkgs) lib; + inherit (lib.strings) escapeShellArg; + + typixLib = typix.lib.${system}; + + src = lib.fileset.toSource { + root = ./.; + fileset = lib.fileset.unions [ + # lib/ gets imported, which is unwanted + # (lib.fileset.fromSource (typixLib.cleanTypstSource ./.)) + # ./main.typ + # (lib.fileset.maybeMissing ./doc.toml) + # (lib.fileset.maybeMissing ./utils.typ) + # (lib.fileset.maybeMissing ./chapters) + # (lib.fileset.maybeMissing ./assets) + # (lib.fileset.maybeMissing ./figures) + ./src + ]; + }; + commonArgs = { + typstSource = "src/main.typ"; + + fontPaths = [ + "${pkgs.liberation_ttf}/share/fonts/truetype" + ]; + + # Make sure to override outdated files/links (in case of updated flake.lock) + # (may be undesirable with config/universities.yaml in case of custom subjects) + forceVirtualPaths = true; + + virtualPaths = [ + # Add paths that must be locally accessible to typst here + # { + # dest = "src/lib"; + # src = "${inputs.local-nure}/src"; + # } + # { + # dest = "config/universities.yaml"; + # src = "${inputs.local-nure}/src/config/universities.yaml"; + # } + ]; + }; + + mkTypstPackagesDrv = name: entries: let + linkFarmEntries = + lib.foldl (set: { + name, + version, + namespace, + input, + }: + set + // { + "${namespace}/${name}/${version}" = input; + }) + {} + entries; + in + pkgs.linkFarm name linkFarmEntries; + + unpublishedTypstPackages = mkTypstPackagesDrv "unpublished-packages" [ + { + namespace = "unexplrd"; + name = "test-multifile"; + version = "0.1.0"; + input = inputs.local-nure; + } + { + namespace = "local"; + name = "nure"; + version = "0.1.0"; + input = inputs.local-nure-upstream; + } + ]; + + # Any transitive dependencies must be added here + # See https://loqusion.github.io/typix/recipes/using-typst-packages.html#the-typstpackages-attribute + # unstable_typstPackages = [ + # { + # name = "oxifmt"; + # version = "0.2.1"; + # hash = "sha256-8PNPa9TGFybMZ1uuJwb5ET0WGIInmIgg8h24BmdfxlU="; + # } + # ]; + + # Compile a Typst project, *without* copying the result + # to the current directory + build-drv = typixLib.buildTypstProject (commonArgs + // { + inherit src; + # inherit unstable_typstPackages; + TYPST_PACKAGE_PATH = unpublishedTypstPackages; + }); + + # Compile a Typst project, and then copy the result + # to the current directory + build-script = typixLib.buildTypstProjectLocal (commonArgs + // { + inherit src; + # inherit unstable_typstPackages; + TYPST_PACKAGE_PATH = unpublishedTypstPackages; + }); + + # Watch a project and recompile on changes + watch-script = typixLib.watchTypstProject (lib.recursiveUpdate commonArgs + { + typstWatchCommand = "TYPST_PACKAGE_PATH=${escapeShellArg unpublishedTypstPackages} typst watch"; + }); + in { + checks = {inherit build-drv build-script watch-script;}; + + packages.default = build-drv; + packages.watch = watch-script; + + apps = rec { + default = watch; + build = flake-utils.lib.mkApp { + drv = build-script; + }; + watch = flake-utils.lib.mkApp { + drv = watch-script; + }; + }; + + devShells.default = typixLib.devShell { + inherit (commonArgs) fontPaths virtualPaths; + + env = { + TYPST_PACKAGE_PATH = escapeShellArg unpublishedTypstPackages; + }; + packages = with pkgs; [ + # WARNING: Don't run `typst-build` directly, instead use `nix run .#build` + # See https://github.com/loqusion/typix/issues/2 + # build-script + watch-script + + just + typstyle + yq + ]; + }; + }); +} diff --git a/erv/lb4/justfile b/erv/lb4/justfile new file mode 100644 index 0000000..43fd58e --- /dev/null +++ b/erv/lb4/justfile @@ -0,0 +1,79 @@ +# File aliases for common commands +alias w := watch +alias c := compile +alias nw := nix-watch +alias nb := nix-build +alias nd := nix-develop + + +# Configuration +set shell := ["fish", "-ic"] + +file := "src/main.typ" +doc_config := "src/doc.toml" +# out := `cat {{doc_config}} | tomlq '.doctype + (.worknumber | tostring) + "_" + (.authors[0].name | split(" ")[0]) + "_" + (.authors[0].edu + "-" + .authors[0].group) + "_" + .subject + ".pdf"'` +# out := 'bla' + +# Default target - show available recipes +default: + @just --list + +# Validate required files exist +_check-files: + #!/usr/bin/env bash + set -euo pipefail + if [[ ! -f "{{file}}" ]]; then + echo "Error: Source file {{file}} not found" + exit 1 + fi + if [[ ! -f "{{doc_config}}" ]]; then + echo "Error: Config file {{doc_config}} not found" + exit 1 + fi + +# Watch file for changes and recompile automatically +[group('typst')] +watch: _check-files + typst w {{file}} + +# Compile the document once +[group('typst')] +compile: _check-files + typst c {{file}} + +# Compile and copy to parent directory +[group('typst')] +copy: compile + #!/usr/bin/env bash + # set -euo pipefail + # if [[ ! -f "{{out}}" ]]; then + # echo "Error: Output file {{out}} not found after compilation" + # exit 1 + # fi + local final_name = $(cat {{doc_config}} | tomlq '.doctype + (.worknumber | tostring) + "_" + (.authors[0].name | split(" ")[0]) + "_" + (.authors[0].edu + "-" + .authors[0].group) + "_" + .subject + ".pdf"') + cp "main.typ" "$final_name" + +# Enter nix development environment +[group('nix')] +nix-develop: + nix develop . + +# Watch using nix environment +[group('nix')] +nix-watch: + nix run .#watch + +# Build using nix environment +[group('nix')] +nix-build: + nix run .#build + +# Clean generated PDFs +[group('utils'), confirm] +clean: + @rm -rvf *.pdf + +# Show generated filename +# [group('utils')] +# show-output: +# @echo "{{out}}" \ No newline at end of file diff --git a/erv/lb4/src/assets/sample.c b/erv/lb4/src/assets/sample.c new file mode 100644 index 0000000..9ad18c4 --- /dev/null +++ b/erv/lb4/src/assets/sample.c @@ -0,0 +1,30 @@ +#include +int main() { + int i, j; + + // Number of rows + int rows = 3; + + // Taking first character of alphabet + // which is useful to print pattern + char character = 'A'; + + // This loop is used to identify + // number rows + for (i = 0; i < rows; i++) { + // This for loop is used to + // identify number of columns + // based on the rows + for (j = 0; j <= i; j++) { + // Printing character to get + // the required pattern + printf("%c ", character); + + // Incrementing character value so + // that it will print the next character + character++; + } + printf("\n"); + } + return 0; +} diff --git a/erv/lb4/src/assets/table.csv b/erv/lb4/src/assets/table.csv new file mode 100644 index 0000000..2ec748f --- /dev/null +++ b/erv/lb4/src/assets/table.csv @@ -0,0 +1,2 @@ +1,2,3,4 +5,6,7,8 diff --git a/erv/lb4/src/chapters/appendices.typ b/erv/lb4/src/chapters/appendices.typ new file mode 100644 index 0000000..b221b49 --- /dev/null +++ b/erv/lb4/src/chapters/appendices.typ @@ -0,0 +1,4 @@ +#import "/utils.typ": code + += Код програми sample.c +#code(read("/assets/sample.c")) diff --git a/erv/lb4/src/doc.toml b/erv/lb4/src/doc.toml new file mode 100644 index 0000000..e5c5103 --- /dev/null +++ b/erv/lb4/src/doc.toml @@ -0,0 +1,24 @@ +university = "ХНУРЕ" +subject = "ЕРВ" +type = "ЛБ" +number = 4 + +[[mentors]] +name = "Шевченко Т. Г." +degree = "Доцент кафедри ПІ" +gender = "m" + +[[mentors]] +name = "Франко І. Я." +degree = "Асистент кафедри ПІ" +gender = "m" + +[[authors]] +name = "Косач Л. П." +edu_program = "КУІБ" +group = "23-2" +gender = "f" +variant = 8 +full_name_gen = "Косач Лариси Петрівни" +course = 2 +semester = 4 diff --git a/erv/lb4/src/figures/Google-Logo-700x394.png b/erv/lb4/src/figures/Google-Logo-700x394.png new file mode 100644 index 0000000..9967a3c Binary files /dev/null and b/erv/lb4/src/figures/Google-Logo-700x394.png differ diff --git a/erv/lb4/src/main.typ b/erv/lb4/src/main.typ new file mode 100644 index 0000000..a3d4e65 --- /dev/null +++ b/erv/lb4/src/main.typ @@ -0,0 +1,54 @@ +#import "@unexplrd/test-multifile:0.1.0": * +// #import "/lib/lib.typ": * +#import "utils.typ": * + +#import style: spacing + +// #show: correctly-indent-list-and-enum-items + +// #show: style.dstu +#show: pz-lb.with( + ..toml("doc.toml"), + title: lorem(2), +) + +== #lorem(3) +#v(-spacing) +=== #lorem(5) + +#lorem(20) + ++ #lorem(10) + + #lorem(10) ++ #lorem(10) + + #lorem(10) + $ 1/2 dot 3 = 3/2 $ + + #lorem(10) +$ 1/2 dot 3 = 3/2 $ ++ #lorem(10) + + #lorem(10) + + #lorem(10) + +#lorem(20) + +// #img("/figures/Google-Logo-700x394.png", [Корпорація зла], width: 60%) + + +#lorem(50) + +#figure(caption: "Приклад коду на C", code(read("assets/sample.c"))) + +#lorem(20) + +#figure( + caption: [Цифри], + table( + columns: 4, + table.header([Один], [Два], [Три], [Чотири]), + ..csv("assets/table.csv").flatten(), + ), +) + +#lorem(20) + +#style.appendices(include "chapters/appendices.typ") diff --git a/erv/lb4/src/utils.typ b/erv/lb4/src/utils.typ new file mode 100644 index 0000000..7e1ba9b --- /dev/null +++ b/erv/lb4/src/utils.typ @@ -0,0 +1,109 @@ +/// takes in a string of code, e.g. #code(read("foo.c")) +#let code(content) = raw(block: true, theme: none, content) + +/// read file as bytes +#let p(path) = bytes(read(path, encoding: none)) + +/// include chapters by file names from /chapters +#let chapters(ch) = ( + array(ch).map(chapter => include str(chapter) + ".typ").join() +) + +#let pz-header(worknumber, name) = columns[#text(weight: "bold", [ + #align(left)[Практичне заняття №#worknumber] + #colbreak() + #align(right)[#name] +])] + +/// https://forum.typst.app/t/how-to-make-bullet-list-item-bodies-flow-like-paragraphs/3756/3?u=andrew +/// Spacing doesn't work the same way as native solution if par leading and +/// spacing are different. +#let correctly-indent-list-and-enum-items(doc) = { + let first-line-indent() = if type(par.first-line-indent) == dictionary { + par.first-line-indent.amount + } else { + par.first-line-indent + } + + show list: li => { + for (i, it) in li.children.enumerate() { + let nesting = state("list-nesting", 0) + let indent = context h((nesting.get() + 1) * li.indent) + let get-nesting() = calc.div-euclid(nesting.get(), 10) + let marker = context { + let n = get-nesting() + if type(li.marker) == array { + li.marker.at(calc.rem-euclid(n, li.marker.len())) + } else if type(li.marker) == content { + li.marker + } else { + li.marker(n) + } + } + let parents = state("enum-parents", ()) // Support enum nesting. + let body = { + parents.update(arr => arr + (-1,)) + nesting.update(x => x + 10) + it.body + parbreak() + nesting.update(x => x - 10) + parents.update(arr => arr.slice(0, -1)) + } + let content = { + marker + h(li.body-indent) + body + } + context pad(left: int(nesting.get() != 0) * li.indent, content) + } + } + + show enum: en => { + let start = if en.start == auto { + if en.children.first().has("number") { + if en.reversed { en.children.first().number } else { 1 } + } else { + if en.reversed { en.children.len() } else { 1 } + } + } else { + en.start + } + let number = start + for (i, it) in en.children.enumerate() { + number = if it.number != auto { it.number } else { number } + if en.reversed { number = start - i } + let parents = state("enum-parents", ()) + let get-parents() = parents.get().filter(x => x >= 0) + let indent = context h((get-parents().len() + 1) * en.indent) + let num = if en.full { + context numbering(en.numbering, ..get-parents(), number) + } else { + numbering(en.numbering, number) + } + let max-num = if en.full { + context numbering(en.numbering, ..get-parents(), en.children.len()) + } else { + numbering(en.numbering, en.children.len()) + } + num = context box( + width: measure(max-num).width, + align(right, text(overhang: false, num)), + ) + let list-nesting = state("list-nesting", 0) // Support list nesting. + let body = { + parents.update(arr => arr + (number,)) + list-nesting.update(x => x + 1) + it.body + parbreak() + list-nesting.update(x => x - 1) + parents.update(arr => arr.slice(0, -1)) + } + if not en.reversed { number += 1 } + let content = { + num + h(en.body-indent) + body + } + context pad(left: int(parents.get().len() != 0) * en.indent, content) + } + } + doc +} diff --git a/erv/lb5/flake.lock b/erv/lb5/flake.lock new file mode 100644 index 0000000..7027761 --- /dev/null +++ b/erv/lb5/flake.lock @@ -0,0 +1,113 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "local-nure": { + "flake": false, + "locked": { + "lastModified": 1769126611, + "narHash": "sha256-4qmXN7kx87pEpZHFJpyRbLfZ5GanF5Jbi1Bmfx6ZXss=", + "path": "/storage/git/typst_nure_template", + "type": "path" + }, + "original": { + "path": "/storage/git/typst_nure_template", + "type": "path" + } + }, + "local-nure-upstream": { + "flake": false, + "locked": { + "lastModified": 1768301144, + "narHash": "sha256-VHZXALfaAw5f32mClZTS7MeTSaDSQtErAjI+lgpYIZk=", + "ref": "refs/heads/0.1.0", + "rev": "549d7f060f81a6356c43b2c231e6453ddae19fca", + "revCount": 111, + "type": "git", + "url": "ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template" + }, + "original": { + "type": "git", + "url": "ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1763421233, + "narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "local-nure": "local-nure", + "local-nure-upstream": "local-nure-upstream", + "nixpkgs": "nixpkgs", + "typix": "typix" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "typix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769071922, + "narHash": "sha256-WD8cMrUlqWJWDAD8+B6MUyEuWvi/fgGgv5Wg0xF/Zkc=", + "owner": "loqusion", + "repo": "typix", + "rev": "5d334996b24af342b0992f7f432fcb301ed67314", + "type": "github" + }, + "original": { + "owner": "loqusion", + "repo": "typix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/erv/lb5/flake.nix b/erv/lb5/flake.nix new file mode 100644 index 0000000..e044c10 --- /dev/null +++ b/erv/lb5/flake.nix @@ -0,0 +1,176 @@ +{ + description = "A Nix flake for compiling NURE works"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + typix.url = "github:loqusion/typix"; + typix.inputs.nixpkgs.follows = "nixpkgs"; + + flake-utils.url = "github:numtide/flake-utils"; + + # local-nure.url = "git+ssh://gitea@gitea.linerds.us/unexplrd/typst_nure_template"; + local-nure-upstream.url = "git+ssh://gitea@gitea.linerds.us/pencelheimer/typst_nure_template"; + local-nure-upstream.flake = false; + + local-nure.url = "path:/storage/git/typst_nure_template"; + local-nure.flake = false; + + # Example of downloading icons from a non-flake source + # font-awesome = { + # url = "github:FortAwesome/Font-Awesome"; + # flake = false; + # }; + }; + + outputs = inputs @ { + nixpkgs, + typix, + flake-utils, + ... + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages.${system}; + inherit (pkgs) lib; + inherit (lib.strings) escapeShellArg; + + typixLib = typix.lib.${system}; + + src = lib.fileset.toSource { + root = ./.; + fileset = lib.fileset.unions [ + # lib/ gets imported, which is unwanted + # (lib.fileset.fromSource (typixLib.cleanTypstSource ./.)) + # ./main.typ + # (lib.fileset.maybeMissing ./doc.toml) + # (lib.fileset.maybeMissing ./utils.typ) + # (lib.fileset.maybeMissing ./chapters) + # (lib.fileset.maybeMissing ./assets) + # (lib.fileset.maybeMissing ./figures) + ./src + ]; + }; + commonArgs = { + typstSource = "src/main.typ"; + + fontPaths = [ + "${pkgs.liberation_ttf}/share/fonts/truetype" + ]; + + # Make sure to override outdated files/links (in case of updated flake.lock) + # (may be undesirable with config/universities.yaml in case of custom subjects) + forceVirtualPaths = true; + + virtualPaths = [ + # Add paths that must be locally accessible to typst here + # { + # dest = "src/lib"; + # src = "${inputs.local-nure}/src"; + # } + # { + # dest = "config/universities.yaml"; + # src = "${inputs.local-nure}/src/config/universities.yaml"; + # } + ]; + }; + + mkTypstPackagesDrv = name: entries: let + linkFarmEntries = + lib.foldl (set: { + name, + version, + namespace, + input, + }: + set + // { + "${namespace}/${name}/${version}" = input; + }) + {} + entries; + in + pkgs.linkFarm name linkFarmEntries; + + unpublishedTypstPackages = mkTypstPackagesDrv "unpublished-packages" [ + { + namespace = "unexplrd"; + name = "test-multifile"; + version = "0.1.0"; + input = inputs.local-nure; + } + { + namespace = "local"; + name = "nure"; + version = "0.1.0"; + input = inputs.local-nure-upstream; + } + ]; + + # Any transitive dependencies must be added here + # See https://loqusion.github.io/typix/recipes/using-typst-packages.html#the-typstpackages-attribute + # unstable_typstPackages = [ + # { + # name = "oxifmt"; + # version = "0.2.1"; + # hash = "sha256-8PNPa9TGFybMZ1uuJwb5ET0WGIInmIgg8h24BmdfxlU="; + # } + # ]; + + # Compile a Typst project, *without* copying the result + # to the current directory + build-drv = typixLib.buildTypstProject (commonArgs + // { + inherit src; + # inherit unstable_typstPackages; + TYPST_PACKAGE_PATH = unpublishedTypstPackages; + }); + + # Compile a Typst project, and then copy the result + # to the current directory + build-script = typixLib.buildTypstProjectLocal (commonArgs + // { + inherit src; + # inherit unstable_typstPackages; + TYPST_PACKAGE_PATH = unpublishedTypstPackages; + }); + + # Watch a project and recompile on changes + watch-script = typixLib.watchTypstProject (lib.recursiveUpdate commonArgs + { + typstWatchCommand = "TYPST_PACKAGE_PATH=${escapeShellArg unpublishedTypstPackages} typst watch"; + }); + in { + checks = {inherit build-drv build-script watch-script;}; + + packages.default = build-drv; + packages.watch = watch-script; + + apps = rec { + default = watch; + build = flake-utils.lib.mkApp { + drv = build-script; + }; + watch = flake-utils.lib.mkApp { + drv = watch-script; + }; + }; + + devShells.default = typixLib.devShell { + inherit (commonArgs) fontPaths virtualPaths; + + env = { + TYPST_PACKAGE_PATH = escapeShellArg unpublishedTypstPackages; + }; + packages = with pkgs; [ + # WARNING: Don't run `typst-build` directly, instead use `nix run .#build` + # See https://github.com/loqusion/typix/issues/2 + # build-script + watch-script + + just + typstyle + yq + ]; + }; + }); +} diff --git a/erv/lb5/justfile b/erv/lb5/justfile new file mode 100644 index 0000000..43fd58e --- /dev/null +++ b/erv/lb5/justfile @@ -0,0 +1,79 @@ +# File aliases for common commands +alias w := watch +alias c := compile +alias nw := nix-watch +alias nb := nix-build +alias nd := nix-develop + + +# Configuration +set shell := ["fish", "-ic"] + +file := "src/main.typ" +doc_config := "src/doc.toml" +# out := `cat {{doc_config}} | tomlq '.doctype + (.worknumber | tostring) + "_" + (.authors[0].name | split(" ")[0]) + "_" + (.authors[0].edu + "-" + .authors[0].group) + "_" + .subject + ".pdf"'` +# out := 'bla' + +# Default target - show available recipes +default: + @just --list + +# Validate required files exist +_check-files: + #!/usr/bin/env bash + set -euo pipefail + if [[ ! -f "{{file}}" ]]; then + echo "Error: Source file {{file}} not found" + exit 1 + fi + if [[ ! -f "{{doc_config}}" ]]; then + echo "Error: Config file {{doc_config}} not found" + exit 1 + fi + +# Watch file for changes and recompile automatically +[group('typst')] +watch: _check-files + typst w {{file}} + +# Compile the document once +[group('typst')] +compile: _check-files + typst c {{file}} + +# Compile and copy to parent directory +[group('typst')] +copy: compile + #!/usr/bin/env bash + # set -euo pipefail + # if [[ ! -f "{{out}}" ]]; then + # echo "Error: Output file {{out}} not found after compilation" + # exit 1 + # fi + local final_name = $(cat {{doc_config}} | tomlq '.doctype + (.worknumber | tostring) + "_" + (.authors[0].name | split(" ")[0]) + "_" + (.authors[0].edu + "-" + .authors[0].group) + "_" + .subject + ".pdf"') + cp "main.typ" "$final_name" + +# Enter nix development environment +[group('nix')] +nix-develop: + nix develop . + +# Watch using nix environment +[group('nix')] +nix-watch: + nix run .#watch + +# Build using nix environment +[group('nix')] +nix-build: + nix run .#build + +# Clean generated PDFs +[group('utils'), confirm] +clean: + @rm -rvf *.pdf + +# Show generated filename +# [group('utils')] +# show-output: +# @echo "{{out}}" \ No newline at end of file diff --git a/erv/lb5/src/assets/sample.c b/erv/lb5/src/assets/sample.c new file mode 100644 index 0000000..9ad18c4 --- /dev/null +++ b/erv/lb5/src/assets/sample.c @@ -0,0 +1,30 @@ +#include +int main() { + int i, j; + + // Number of rows + int rows = 3; + + // Taking first character of alphabet + // which is useful to print pattern + char character = 'A'; + + // This loop is used to identify + // number rows + for (i = 0; i < rows; i++) { + // This for loop is used to + // identify number of columns + // based on the rows + for (j = 0; j <= i; j++) { + // Printing character to get + // the required pattern + printf("%c ", character); + + // Incrementing character value so + // that it will print the next character + character++; + } + printf("\n"); + } + return 0; +} diff --git a/erv/lb5/src/assets/table.csv b/erv/lb5/src/assets/table.csv new file mode 100644 index 0000000..2ec748f --- /dev/null +++ b/erv/lb5/src/assets/table.csv @@ -0,0 +1,2 @@ +1,2,3,4 +5,6,7,8 diff --git a/erv/lb5/src/chapters/appendices.typ b/erv/lb5/src/chapters/appendices.typ new file mode 100644 index 0000000..b221b49 --- /dev/null +++ b/erv/lb5/src/chapters/appendices.typ @@ -0,0 +1,4 @@ +#import "/utils.typ": code + += Код програми sample.c +#code(read("/assets/sample.c")) diff --git a/erv/lb5/src/doc.toml b/erv/lb5/src/doc.toml new file mode 100644 index 0000000..d66e41a --- /dev/null +++ b/erv/lb5/src/doc.toml @@ -0,0 +1,24 @@ +university = "ХНУРЕ" +subject = "ЕРВ" +type = "ЛБ" +number = 5 + +[[mentors]] +name = "Шевченко Т. Г." +degree = "Доцент кафедри ПІ" +gender = "m" + +[[mentors]] +name = "Франко І. Я." +degree = "Асистент кафедри ПІ" +gender = "m" + +[[authors]] +name = "Косач Л. П." +edu_program = "КУІБ" +group = "23-2" +gender = "f" +variant = 8 +full_name_gen = "Косач Лариси Петрівни" +course = 2 +semester = 4 diff --git a/erv/lb5/src/figures/Google-Logo-700x394.png b/erv/lb5/src/figures/Google-Logo-700x394.png new file mode 100644 index 0000000..9967a3c Binary files /dev/null and b/erv/lb5/src/figures/Google-Logo-700x394.png differ diff --git a/erv/lb5/src/main.typ b/erv/lb5/src/main.typ new file mode 100644 index 0000000..a3d4e65 --- /dev/null +++ b/erv/lb5/src/main.typ @@ -0,0 +1,54 @@ +#import "@unexplrd/test-multifile:0.1.0": * +// #import "/lib/lib.typ": * +#import "utils.typ": * + +#import style: spacing + +// #show: correctly-indent-list-and-enum-items + +// #show: style.dstu +#show: pz-lb.with( + ..toml("doc.toml"), + title: lorem(2), +) + +== #lorem(3) +#v(-spacing) +=== #lorem(5) + +#lorem(20) + ++ #lorem(10) + + #lorem(10) ++ #lorem(10) + + #lorem(10) + $ 1/2 dot 3 = 3/2 $ + + #lorem(10) +$ 1/2 dot 3 = 3/2 $ ++ #lorem(10) + + #lorem(10) + + #lorem(10) + +#lorem(20) + +// #img("/figures/Google-Logo-700x394.png", [Корпорація зла], width: 60%) + + +#lorem(50) + +#figure(caption: "Приклад коду на C", code(read("assets/sample.c"))) + +#lorem(20) + +#figure( + caption: [Цифри], + table( + columns: 4, + table.header([Один], [Два], [Три], [Чотири]), + ..csv("assets/table.csv").flatten(), + ), +) + +#lorem(20) + +#style.appendices(include "chapters/appendices.typ") diff --git a/erv/lb5/src/utils.typ b/erv/lb5/src/utils.typ new file mode 100644 index 0000000..7e1ba9b --- /dev/null +++ b/erv/lb5/src/utils.typ @@ -0,0 +1,109 @@ +/// takes in a string of code, e.g. #code(read("foo.c")) +#let code(content) = raw(block: true, theme: none, content) + +/// read file as bytes +#let p(path) = bytes(read(path, encoding: none)) + +/// include chapters by file names from /chapters +#let chapters(ch) = ( + array(ch).map(chapter => include str(chapter) + ".typ").join() +) + +#let pz-header(worknumber, name) = columns[#text(weight: "bold", [ + #align(left)[Практичне заняття №#worknumber] + #colbreak() + #align(right)[#name] +])] + +/// https://forum.typst.app/t/how-to-make-bullet-list-item-bodies-flow-like-paragraphs/3756/3?u=andrew +/// Spacing doesn't work the same way as native solution if par leading and +/// spacing are different. +#let correctly-indent-list-and-enum-items(doc) = { + let first-line-indent() = if type(par.first-line-indent) == dictionary { + par.first-line-indent.amount + } else { + par.first-line-indent + } + + show list: li => { + for (i, it) in li.children.enumerate() { + let nesting = state("list-nesting", 0) + let indent = context h((nesting.get() + 1) * li.indent) + let get-nesting() = calc.div-euclid(nesting.get(), 10) + let marker = context { + let n = get-nesting() + if type(li.marker) == array { + li.marker.at(calc.rem-euclid(n, li.marker.len())) + } else if type(li.marker) == content { + li.marker + } else { + li.marker(n) + } + } + let parents = state("enum-parents", ()) // Support enum nesting. + let body = { + parents.update(arr => arr + (-1,)) + nesting.update(x => x + 10) + it.body + parbreak() + nesting.update(x => x - 10) + parents.update(arr => arr.slice(0, -1)) + } + let content = { + marker + h(li.body-indent) + body + } + context pad(left: int(nesting.get() != 0) * li.indent, content) + } + } + + show enum: en => { + let start = if en.start == auto { + if en.children.first().has("number") { + if en.reversed { en.children.first().number } else { 1 } + } else { + if en.reversed { en.children.len() } else { 1 } + } + } else { + en.start + } + let number = start + for (i, it) in en.children.enumerate() { + number = if it.number != auto { it.number } else { number } + if en.reversed { number = start - i } + let parents = state("enum-parents", ()) + let get-parents() = parents.get().filter(x => x >= 0) + let indent = context h((get-parents().len() + 1) * en.indent) + let num = if en.full { + context numbering(en.numbering, ..get-parents(), number) + } else { + numbering(en.numbering, number) + } + let max-num = if en.full { + context numbering(en.numbering, ..get-parents(), en.children.len()) + } else { + numbering(en.numbering, en.children.len()) + } + num = context box( + width: measure(max-num).width, + align(right, text(overhang: false, num)), + ) + let list-nesting = state("list-nesting", 0) // Support list nesting. + let body = { + parents.update(arr => arr + (number,)) + list-nesting.update(x => x + 1) + it.body + parbreak() + list-nesting.update(x => x - 1) + parents.update(arr => arr.slice(0, -1)) + } + if not en.reversed { number += 1 } + let content = { + num + h(en.body-indent) + body + } + context pad(left: int(parents.get().len() != 0) * en.indent, content) + } + } + doc +}