Merge branch 'feature/typstyle'
Gitea Action for checking typst compilation / run-ci-linux (push) Successful in 2m48s
Details
Gitea Action for checking typst compilation / run-ci-linux (push) Successful in 2m48s
Details
This commit is contained in:
commit
255cdfeae1
|
@ -5,15 +5,16 @@ on: [push]
|
|||
jobs:
|
||||
run-ci-linux:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TYPST_INSTALL: /usr/local
|
||||
TYPST_VERSION: 0.11.1
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- name: Install Typst CLI
|
||||
run: curl -fsSL https://typst.community/typst-install/install.sh | sh -s "$TYPST_VERSION"
|
||||
- name: Set up Python 3
|
||||
run: apt update -y && apt install python3-pip -y
|
||||
- name: Install dependencies for Nix setup action
|
||||
run: |
|
||||
apt update -y
|
||||
apt install sudo -y
|
||||
- name: Setup Nix
|
||||
uses: cachix/install-nix-action@v27
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- name: Run CI
|
||||
run: bash -c ./run-ci.sh
|
||||
run: nix-shell --run ./run-ci.sh
|
||||
|
|
|
@ -3,21 +3,24 @@ name: release
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
- 'v*.*.*'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- name: Install dependencies for Nix setup action
|
||||
run: |
|
||||
apt update -y
|
||||
apt install sudo -y
|
||||
- name: Setup Nix
|
||||
uses: cachix/install-nix-action@v27
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Typst CLI
|
||||
run: curl -fsSL https://typst.community/typst-install/install.sh | sh -s "$TYPST_VERSION"
|
||||
- name: Set up Python 3
|
||||
run: apt update -y && apt install python3-pip -y
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- name: Run CI
|
||||
run: bash -c ./run-ci.sh
|
||||
run: nix-shell --run ./run-ci.sh
|
||||
- name: Setup go
|
||||
uses: https://github.com/actions/setup-go@v4
|
||||
with:
|
||||
|
|
26
run-ci.sh
26
run-ci.sh
|
@ -25,19 +25,29 @@ function enter-section() {
|
|||
printf "\\n"
|
||||
|
||||
eval "$2"
|
||||
if [ $? -neq $3 ]; then
|
||||
abort "command: $2 failed in section: $1"
|
||||
exit_status=$?
|
||||
|
||||
if [ "$3" == "should fail" ]; then
|
||||
log "INFO" "expected to fail..."
|
||||
if [ $exit_status -eq 0 ]; then
|
||||
abort "command: $2 failed in section: $1 with: $exit_status"
|
||||
fi
|
||||
else
|
||||
log "INFO" "expected to pass..."
|
||||
if [ ! $exit_status -eq 0 ]; then
|
||||
abort "command: $2 failed in section: $1 with: $exit_status"
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "\\n"
|
||||
log "INFO" "section $1 completed successfully"
|
||||
}
|
||||
|
||||
enter-section "BUILD: ABB code theme" "./generate-theme.sh" 0
|
||||
enter-section "Compiling template..." "typst compile template/main.typ --root . example.pdf" 0
|
||||
enter-section "TEST: local template import" "typst compile tests/local-import/main.typ --root ." 0
|
||||
enter-section "TEST: invalid config case 1" "typst compile tests/invalid-config/test-case-1.typ --root ." 1
|
||||
enter-section "TEST: invalid config case 2" "compile tests/invalid-config/test-case-2.typ" 0
|
||||
enter-section "TEST: invalid config case 3" "typst compile tests/invalid-config/test-case-3.typ --root ." 1
|
||||
enter-section "Typstyle checking" "./run-fmt.sh --check src/lib.typ" 0
|
||||
enter-section "Compiling template..." "typst compile template/main.typ --root . example.pdf"
|
||||
enter-section "TEST: local template import" "typst compile tests/local-import/main.typ --root ."
|
||||
enter-section "TEST: invalid config case 1" "typst compile tests/invalid-config/test-case-1.typ --root ." "should fail"
|
||||
enter-section "TEST: invalid config case 2" "typst compile tests/invalid-config/test-case-2.typ --root ."
|
||||
enter-section "TEST: invalid config case 3" "typst compile tests/invalid-config/test-case-3.typ --root ." "should fail"
|
||||
|
||||
log "INFO" "CI completed successfully"
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash
|
||||
|
||||
function format() {
|
||||
# format file
|
||||
# typstyle --format $1
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local wd=$(dirname $(realpath "$1"))
|
||||
|
||||
echo "processing file $1..."
|
||||
typstyle "$2" "$1" > /dev/null
|
||||
if [ $? -eq 1 ]; then
|
||||
echo "failed format validation: $1"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local imports=$(rg "#import \"([a-z0-9/\-]+\.typ)\"" -Nor '$1' "$1")
|
||||
|
||||
# format all included files
|
||||
while IFS= read -r line; do
|
||||
if [ -z "$line" ]; then
|
||||
continue
|
||||
fi
|
||||
format "$wd/$line" "$2"
|
||||
done <<< "$imports"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
"--format")
|
||||
format "$2" "--inplace"
|
||||
;;
|
||||
"--check")
|
||||
format "$2" "--check"
|
||||
;;
|
||||
*)
|
||||
echo "unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
|
@ -0,0 +1,13 @@
|
|||
let
|
||||
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-unstable";
|
||||
pkgs = import nixpkgs { config = {}; overlays = []; };
|
||||
in
|
||||
|
||||
pkgs.mkShellNoCC {
|
||||
packages = with pkgs; [
|
||||
python312
|
||||
python312Packages.pyyaml
|
||||
typst
|
||||
typstyle
|
||||
];
|
||||
}
|
|
@ -30,7 +30,10 @@ SOFTWARE.*/
|
|||
#let __query_labels_with_key(loc, key, before: false) = {
|
||||
if before {
|
||||
query(
|
||||
selector(label(__glossary_label_prefix + key)).before(loc, inclusive: false),
|
||||
selector(label(__glossary_label_prefix + key)).before(
|
||||
loc,
|
||||
inclusive: false,
|
||||
),
|
||||
loc,
|
||||
)
|
||||
} else {
|
||||
|
@ -56,13 +59,18 @@ SOFTWARE.*/
|
|||
let entlong = entry.at("long", default: "")
|
||||
let textLink = if display != none {
|
||||
[#display]
|
||||
} else if (is_first or long == true) and entlong != [] and entlong != "" and long != false {
|
||||
} else if (
|
||||
is_first or long == true
|
||||
) and entlong != [] and entlong != "" and long != false {
|
||||
[#entlong (#entry.short#suffix)]
|
||||
} else {
|
||||
[#entry.short#suffix]
|
||||
}
|
||||
|
||||
[#link(label(entry.key), textLink)#label(__glossary_label_prefix + entry.key)]
|
||||
[#link(
|
||||
label(entry.key),
|
||||
textLink,
|
||||
)#label(__glossary_label_prefix + entry.key)]
|
||||
} else {
|
||||
panic(__not-found-panic-error-msg(key))
|
||||
}
|
||||
|
@ -100,13 +108,18 @@ SOFTWARE.*/
|
|||
[#entplural]
|
||||
}
|
||||
|
||||
let textLink = if (is_first or long == true) and entlong != [] and entlong != "" and long != false {
|
||||
let textLink = if (
|
||||
is_first or long == true
|
||||
) and entlong != [] and entlong != "" and long != false {
|
||||
[#entlong (#short)]
|
||||
} else {
|
||||
[#short]
|
||||
}
|
||||
|
||||
[#link(label(entry.key), textLink)#label(__glossary_label_prefix + entry.key)]
|
||||
[#link(
|
||||
label(entry.key),
|
||||
textLink,
|
||||
)#label(__glossary_label_prefix + entry.key)]
|
||||
} else {
|
||||
panic(__not-found-panic-error-msg(key))
|
||||
}
|
||||
|
@ -116,7 +129,9 @@ SOFTWARE.*/
|
|||
// show rule to make the references for glossarium
|
||||
#let make-glossary(body) = {
|
||||
show ref: r => {
|
||||
if r.element != none and r.element.func() == figure and r.element.kind == __glossarium_figure {
|
||||
if r.element != none and r.element.func() == figure and r
|
||||
.element
|
||||
.kind == __glossarium_figure {
|
||||
// call to the general citing function
|
||||
gls(str(r.target), suffix: r.citation.supplement)
|
||||
} else {
|
||||
|
@ -200,7 +215,9 @@ SOFTWARE.*/
|
|||
.sorted(key: x => x.page())
|
||||
.fold(
|
||||
(values: (), pages: ()),
|
||||
((values, pages), x) => if pages.contains(x.page()) {
|
||||
((values, pages), x) => if pages.contains(
|
||||
x.page(),
|
||||
) {
|
||||
(values: values, pages: pages)
|
||||
} else {
|
||||
values.push(x)
|
||||
|
@ -214,7 +231,10 @@ SOFTWARE.*/
|
|||
if page-numbering == none {
|
||||
page-numbering = "1"
|
||||
}
|
||||
link(x)[#numbering(page-numbering, ..counter(page).at(x))]
|
||||
link(x)[#numbering(
|
||||
page-numbering,
|
||||
..counter(page).at(x),
|
||||
)]
|
||||
}
|
||||
)
|
||||
.join(", ")
|
||||
|
|
|
@ -75,8 +75,14 @@
|
|||
// create dedicated entries for
|
||||
// acronym and glossary
|
||||
if "long" in v and "desc" in v {
|
||||
processed_glossary.insert(k, (short: v.short, long: v.long, group: acronym_group))
|
||||
processed_glossary.insert(k + "__glossary_entry", (short: v.short, desc: v.desc, long: v.long, group: glossary_group))
|
||||
processed_glossary.insert(
|
||||
k,
|
||||
(short: v.short, long: v.long, group: acronym_group),
|
||||
)
|
||||
processed_glossary.insert(
|
||||
k + "__glossary_entry",
|
||||
(short: v.short, desc: v.desc, long: v.long, group: glossary_group),
|
||||
)
|
||||
} else {
|
||||
processed_glossary.insert(k, v)
|
||||
processed_glossary.at(k).group = group
|
||||
|
|
16
src/lib.typ
16
src/lib.typ
|
@ -31,7 +31,13 @@
|
|||
inset: (left: 2pt, right: 2pt),
|
||||
outset: (top: 4pt, bottom: 4pt),
|
||||
fill: ABB-GRAY-06,
|
||||
[#box(fill: rgb(color), radius: 2pt, inset: 0pt, width: 0.75em, height: 0.75em) #text(
|
||||
[#box(
|
||||
fill: rgb(color),
|
||||
radius: 2pt,
|
||||
inset: 0pt,
|
||||
width: 0.75em,
|
||||
height: 0.75em,
|
||||
) #text(
|
||||
font: default-config.style.code.font,
|
||||
size: default-config.style.code.size,
|
||||
content,
|
||||
|
@ -40,13 +46,17 @@
|
|||
}
|
||||
|
||||
#let url(label, content) = {
|
||||
link(label)[#underline(offset: 2pt, stroke: 0.5pt + blue, text(fill: blue)[
|
||||
link(label)[#underline(
|
||||
offset: 2pt,
|
||||
stroke: 0.5pt + blue,
|
||||
text(fill: blue)[
|
||||
#content
|
||||
#let domain = label.find(regex("\w+\.\w+(?:\.\w+)*"))
|
||||
#if domain.len() > 0 [
|
||||
(#domain)
|
||||
]
|
||||
])]
|
||||
],
|
||||
)]
|
||||
}
|
||||
|
||||
// start of template pages and styles
|
||||
|
|
|
@ -64,7 +64,9 @@
|
|||
stroke: none,
|
||||
[*Verfasser:*], author.name,
|
||||
[*Bearbeitungszeitraum:*], thesis.timeframe,
|
||||
[*Matrikelnummer, Kurs:*], str(author.matriculation-number) + ", " + author.course,
|
||||
[*Matrikelnummer, Kurs:*],
|
||||
str(author.matriculation-number) + ", " + author.course,
|
||||
|
||||
[*Ausbildungsbetrieb:*], author.company,
|
||||
[*Betrieblicher Betreuer:*], author.supervisor,
|
||||
[*Abgabedatum:*], thesis.submission-date,
|
||||
|
@ -77,7 +79,9 @@
|
|||
stroke: none,
|
||||
[*Author:*], author.name,
|
||||
[*Editing period:*], thesis.timeframe,
|
||||
[*Matriculation number, course:*], str(author.matriculation-number) + ", " + author.course,
|
||||
[*Matriculation number, course:*],
|
||||
str(author.matriculation-number) + ", " + author.course,
|
||||
|
||||
[*Training company:*], author.company,
|
||||
[*Company supervisor:*], author.supervisor,
|
||||
[*Submission date:*], thesis.submission-date,
|
||||
|
|
|
@ -12,7 +12,13 @@
|
|||
#let watermark-color = luma(50%).transparentize(70%)
|
||||
|
||||
#let watermark-pattern = pattern(size: (5pt, 5pt))[
|
||||
#place(line(start: (50%, 0%), end: (50%, 100%), stroke: (paint: watermark-color, thickness: 3pt)))
|
||||
#place(
|
||||
line(
|
||||
start: (50%, 0%),
|
||||
end: (50%, 100%),
|
||||
stroke: (paint: watermark-color, thickness: 3pt),
|
||||
),
|
||||
)
|
||||
]
|
||||
|
||||
#let watermark(config) = if config.draft {
|
||||
|
@ -29,7 +35,10 @@
|
|||
#linebreak()
|
||||
document version.
|
||||
#linebreak()
|
||||
#text(size: 0.75em, "Further usage without the authors consent is not permitted.")]]]
|
||||
#text(
|
||||
size: 0.75em,
|
||||
"Further usage without the authors consent is not permitted.",
|
||||
)]]]
|
||||
}
|
||||
|
||||
#let numberingH(c) = {
|
||||
|
@ -117,17 +126,27 @@
|
|||
e => {
|
||||
let (i, l) = e
|
||||
let n = i + 1
|
||||
let n_str = if (calc.rem(n, 1) == 0) or (true and i == 0) { text(font: style.code.font, size: style.code.size, fill: ABB-BLACK, str(n)) } else { none }
|
||||
(n_str + h(0.5em), raw(block: true, lang: lang, l))
|
||||
})
|
||||
let n_str = if (calc.rem(n, 1) == 0) or (true and i == 0) {
|
||||
text(
|
||||
font: style.code.font,
|
||||
size: style.code.size,
|
||||
fill: ABB-BLACK,
|
||||
str(n),
|
||||
)
|
||||
} else {
|
||||
none
|
||||
}
|
||||
else {
|
||||
( ( 1fr, ),
|
||||
(n_str + h(0.5em), raw(block: true, lang: lang, l))
|
||||
},
|
||||
)
|
||||
} else {
|
||||
(
|
||||
(1fr,),
|
||||
(left,),
|
||||
e => {
|
||||
let (i, l) = e
|
||||
raw(block: true, lang: lang, l)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -145,9 +164,13 @@
|
|||
.enumerate()
|
||||
.map(make_row)
|
||||
.flatten()
|
||||
.map(c => if c.has("text") and c.text == "" { v(1em) } else { c })
|
||||
.map(c => if c.has("text") and c.text == "" {
|
||||
v(1em)
|
||||
} else {
|
||||
c
|
||||
})
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
#v(-1em)
|
||||
#align(center + top, it.caption)
|
||||
|
@ -184,8 +207,20 @@
|
|||
stroke: (x, y) => (
|
||||
left: none,
|
||||
right: none,
|
||||
top: if y == 0 { 1.5pt } else if y < 2 { 1pt } else { 0.5pt },
|
||||
bottom: if y == 0 { 1pt } else { 1.5pt } ))
|
||||
top: if y == 0 {
|
||||
1.5pt
|
||||
} else if y < 2 {
|
||||
1pt
|
||||
} else {
|
||||
0.5pt
|
||||
},
|
||||
bottom: if y == 0 {
|
||||
1pt
|
||||
} else {
|
||||
1.5pt
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
// make table header bold
|
||||
show table.cell.where(y: 0): set text(weight: "bold")
|
||||
|
@ -194,7 +229,8 @@
|
|||
set par(
|
||||
justify: true,
|
||||
first-line-indent: 1em,
|
||||
leading: 1em)
|
||||
leading: 1em,
|
||||
)
|
||||
|
||||
// give links a color
|
||||
show link: set text(fill: style.link.color)
|
||||
|
@ -207,17 +243,26 @@
|
|||
header-ascent: style.header.content-padding,
|
||||
footer-descent: style.header.content-padding,
|
||||
margin: (
|
||||
top: style.page.margin.top + style.header.underline-top-padding + style.header.content-padding,
|
||||
top: style.page.margin.top + style.header.underline-top-padding + style
|
||||
.header
|
||||
.content-padding,
|
||||
bottom: style.page.margin.bottom + style.footer.content-padding,
|
||||
left: style.page.margin.left,
|
||||
right: style.page.margin.right),
|
||||
right: style.page.margin.right,
|
||||
),
|
||||
numbering: (..nums) => {
|
||||
let current-page = here().page()
|
||||
if current-page == 1 {
|
||||
[]
|
||||
} else if query(<end-of-prelude>).first().location().page() > current-page {
|
||||
} else if query(<end-of-prelude>)
|
||||
.first()
|
||||
.location()
|
||||
.page() > current-page {
|
||||
numbering("I", nums.pos().first())
|
||||
} else if query(<end-of-content>).first().location().page() >= current-page {
|
||||
} else if query(<end-of-content>)
|
||||
.first()
|
||||
.location()
|
||||
.page() >= current-page {
|
||||
numbering("1", nums.pos().first())
|
||||
} else {
|
||||
numbering("a", nums.pos().first())
|
||||
|
@ -234,7 +279,11 @@
|
|||
set align(center)
|
||||
numbering("I", page-counter)
|
||||
} else if query(<end-of-content>).first().location().page() >= page-number {
|
||||
numbering("1 / 1", page-counter, counter(page).at(<end-of-content>).last())
|
||||
numbering(
|
||||
"1 / 1",
|
||||
page-counter,
|
||||
counter(page).at(<end-of-content>).last(),
|
||||
)
|
||||
} else {
|
||||
numbering("a", page-counter)
|
||||
}
|
||||
|
@ -254,7 +303,13 @@
|
|||
// right align logo of DHBW
|
||||
align(right, image("res/DHBW.svg", height: style.header.logo-height)))
|
||||
|
||||
} else if query(<end-of-content>).first().location().page() >= current-page and query(<end-of-prelude>).first().location().page() < current-page + 1 {
|
||||
} else if query(<end-of-content>)
|
||||
.first()
|
||||
.location()
|
||||
.page() >= current-page and query(<end-of-prelude>)
|
||||
.first()
|
||||
.location()
|
||||
.page() < current-page + 1 {
|
||||
let heading = currentH()
|
||||
|
||||
heading.at(0)
|
||||
|
@ -267,7 +322,8 @@
|
|||
v(style.header.underline-top-padding - 1em)
|
||||
line(length: 100%)
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
body
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
#import "../../src/lib.typ": dhbw-template
|
||||
|
||||
#show: dhbw-template.with(
|
||||
config: (
|
||||
#show: dhbw-template.with((
|
||||
lang: none,
|
||||
region: "en",
|
||||
author: (
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
#import "../../src/lib.typ": dhbw-template
|
||||
|
||||
#show: dhbw-template.with(
|
||||
config: (
|
||||
#show: dhbw-template.with((
|
||||
lang: "en",
|
||||
this-key-is-not-in-config: "Ha Ha",
|
||||
region: "en",
|
||||
|
@ -15,7 +14,8 @@
|
|||
university: "DHBW Mannheim",
|
||||
company: "ABB AG",
|
||||
supervisor: "Benny Goodman",
|
||||
matriculation-number: 123456789),
|
||||
matriculation-number: 123456789,
|
||||
),
|
||||
thesis: (
|
||||
title: "Unofficial ABB/DHBW Typst template",
|
||||
subtitle: "for reports and thesises",
|
||||
|
@ -27,4 +27,8 @@
|
|||
keywords: ("IT", "other stuff"),
|
||||
bibliography: none,
|
||||
glossary: none,
|
||||
appendices: none)))
|
||||
appendices: none,
|
||||
),
|
||||
))
|
||||
|
||||
= Heading
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
|
||||
#import "../../src/lib.typ": dhbw-template
|
||||
|
||||
#show: dhbw-template.with(
|
||||
config: (
|
||||
#show: dhbw-template.with((
|
||||
lang: "en",
|
||||
region: "en",
|
||||
author: (
|
||||
university: "DHBW Mannheim",
|
||||
company: "ABB AG",
|
||||
supervisor: none,
|
||||
matriculation-number: 123456789),
|
||||
matriculation-number: 123456789,
|
||||
),
|
||||
thesis: (
|
||||
title: "Unofficial ABB/DHBW Typst template",
|
||||
subtitle: "for reports and thesises",
|
||||
|
@ -21,4 +21,6 @@
|
|||
keywords: ("IT", "other stuff"),
|
||||
bibliography: none,
|
||||
glossary: none,
|
||||
appendices: none)))
|
||||
appendices: none,
|
||||
),
|
||||
))
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
#import "../../src/lib.typ": dhbw-template
|
||||
|
||||
#show: dhbw-template.with(
|
||||
config: (
|
||||
#show: dhbw-template.with((
|
||||
lang: "en",
|
||||
region: "en",
|
||||
author: (
|
||||
|
@ -27,3 +26,5 @@
|
|||
bibliography: none,
|
||||
glossary: none,
|
||||
appendices: none)))
|
||||
|
||||
= Heading
|
||||
|
|
Loading…
Reference in New Issue