12 Commits
Author SHA1 Message Date
Klagarge 7b34f5a589 feat(cs): add initial lazygit doc
Build site / build (push) Successful in 2m50s
Build site / deploy (push) Skipped
2026-10-12 14:06:04 +02:00
Klagarge 6436f52889 feat(cs): add initial git doc 2026-10-12 14:05:52 +02:00
Klagarge 49e6820eae feat(cs): add tools section 2026-10-12 14:05:28 +02:00
Klagarge f8350ba235 ops: adapt script to work on windows 2026-10-12 13:32:43 +02:00
Klagarge 09f0dc42e4 chore(home): add metadatas
Build site / build (push) Successful in 2m44s
Build site / deploy (push) Successful in 7s
2026-10-11 23:46:05 +02:00
Klagarge 8e2303fcdf refactor: change main categories
Build site / build (push) Successful in 2m48s
Build site / deploy (push) Successful in 6s
2026-10-11 23:32:36 +02:00
Klagarge 4917abe9e6 ops: add toc on side 2026-10-11 23:26:28 +02:00
Klagarge b52629d1f6 feat(home): add gardening with yuca and dracaena 2026-10-11 23:23:48 +02:00
Klagarge b9159581f3 ops: add strip-exif function in justfile 2026-10-11 23:23:14 +02:00
Klagarge 9e9163f01b chore: add IDE in gitignore 2026-10-11 23:22:57 +02:00
Klagarge 54a69b51ae ops: add lib with tag function 2026-10-11 23:22:42 +02:00
Klagarge 975ba4f312 fix: remove act check
Build site / build (push) Successful in 50s
Build site / deploy (push) Successful in 3s
2026-10-11 20:09:47 +02:00
21 changed files with 345 additions and 73 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# Shell scripts and the Justfile must stay LF so they run in Git Bash on Windows.
*.sh text eol=lf
Justfile text eol=lf
-1
View File
@@ -52,7 +52,6 @@ jobs:
# (act sets env.ACT, the Gitea runner does not). The force-push to the
# `pages` branch is what triggers the git-pages webhook.
- name: Publish to pages branch
if: ${{ !env.ACT }}
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
+3 -1
View File
@@ -1,6 +1,6 @@
# Generated site and pinned toolchain
public/
tools/
/tools/
# Calepin build artifacts
.calepin/
@@ -8,3 +8,5 @@ tools/
# IDE
.idea/
.zed/
.vscode/
+4
View File
@@ -22,6 +22,10 @@ watch: tools
clean:
./scripts/clean.sh
# Remove all EXIF metadata from a file
strip-exif file:
exiftool -all= -overwrite_original {{ quote(file) }}
# Run the CI workflow locally with act (requires act + docker)
ci:
act push -W .gitea/workflows/build.yml -j build --artifact-server-path /tmp/act-artifacts
+78 -19
View File
@@ -1,14 +1,16 @@
#!/usr/bin/env bash
# Bootstrap the pinned toolchain (Calepin + Typst) into tools/.
# Idempotent: skips downloads when the binaries are already in place.
# Supports x86_64 Linux and Windows (run through Git Bash / MSYS2).
set -euo pipefail
# Pinned toolchain -- bump both binaries together and re-verify checksums.
calepin_version="0.0.61"
typst_version="0.15.1"
# Typst publishes no .sha256 assets; this digest comes from the official
# release metadata (GitHub asset digest of typst-x86_64-unknown-linux-musl.tar.xz).
typst_sha256="a6d077d0a95eed5a2eba715b2dae06be954f624ccbf85758a03f389ded33118c"
# Typst publishes no .sha256 assets; these digests come from the official
# release metadata (GitHub asset digests of the downloads below).
typst_sha256_linux="a6d077d0a95eed5a2eba715b2dae06be954f624ccbf85758a03f389ded33118c"
typst_sha256_windows="19ce3551153c2fe7ee9fa2f95208310c8f4d3209fedb699e0333faf8913f6736"
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
tools="$root/tools"
@@ -18,26 +20,83 @@ if [ "$(uname -m)" != "x86_64" ]; then
exit 1
fi
case "$(uname -s)" in
Linux*)
exe=""
calepin_name="calepin-x86_64-unknown-linux-gnu.tar.xz"
typst_name="typst-x86_64-unknown-linux-musl.tar.xz"
typst_sha256="$typst_sha256_linux"
;;
MINGW*|MSYS*|CYGWIN*)
exe=".exe"
calepin_name="calepin-x86_64-pc-windows-msvc.zip"
typst_name="typst-x86_64-pc-windows-msvc.zip"
typst_sha256="$typst_sha256_windows"
;;
*)
echo "error: unsupported operating system $(uname -s)" >&2
exit 1
;;
esac
# Extract a single binary from a zip into tools/. The zip may or may not nest
# it in a top-level directory. Git Bash ships no unzip, so fall back to the
# bsdtar.exe bundled with Windows 10+.
install_zip_binary() {
local archive="$1" bin="$2"
local tmp="$tools/.extract"
rm -rf "$tmp"
mkdir -p "$tmp"
if command -v unzip >/dev/null 2>&1; then
unzip -q -o "$archive" -d "$tmp"
else
local wintar=""
if command -v cygpath >/dev/null 2>&1; then
wintar="$(cygpath -u "${SYSTEMROOT:-C:/Windows}")/System32/tar.exe"
fi
if [ -z "$wintar" ] || [ ! -x "$wintar" ]; then
echo "error: extracting $archive needs unzip or Windows tar.exe" >&2
return 1
fi
"$wintar" -xf "$archive" -C "$tmp"
fi
local found
found="$(find "$tmp" -type f -name "$bin" -print -quit)"
if [ -z "$found" ]; then
echo "error: $bin not found in $archive" >&2
return 1
fi
mv "$found" "$tools/$bin"
rm -rf "$tmp"
}
mkdir -p "$tools"
if [ ! -x "$tools/calepin" ]; then
name="calepin-x86_64-unknown-linux-gnu.tar.xz"
if [ ! -x "$tools/calepin$exe" ]; then
# Calepin publishes .sha256 assets next to its downloads.
base="https://github.com/vincentarelbundock/calepin/releases/download/v$calepin_version"
curl -fsSLo "$tools/$name" "$base/$name"
curl -fsSLo "$tools/$name.sha256" "$base/$name.sha256"
(cd "$tools" && sha256sum -c "$name.sha256")
tar -xJf "$tools/$name" -C "$tools" --strip-components=1 "calepin-x86_64-unknown-linux-gnu/calepin"
rm "$tools/$name" "$tools/$name.sha256"
curl -fsSLo "$tools/$calepin_name" "$base/$calepin_name"
curl -fsSLo "$tools/$calepin_name.sha256" "$base/$calepin_name.sha256"
(cd "$tools" && sha256sum -c "$calepin_name.sha256")
if [ "$exe" ]; then
install_zip_binary "$tools/$calepin_name" "calepin.exe"
else
tar -xJf "$tools/$calepin_name" -C "$tools" --strip-components=1 "${calepin_name%.tar.xz}/calepin"
fi
rm "$tools/$calepin_name" "$tools/$calepin_name.sha256"
fi
if [ ! -x "$tools/typst" ]; then
name="typst-x86_64-unknown-linux-musl.tar.xz"
curl -fsSLo "$tools/$name" "https://github.com/typst/typst/releases/download/v$typst_version/$name"
echo "$typst_sha256 $name" > "$tools/$name.sha256"
(cd "$tools" && sha256sum -c "$name.sha256")
tar -xJf "$tools/$name" -C "$tools" --strip-components=1 "typst-x86_64-unknown-linux-musl/typst"
rm "$tools/$name" "$tools/$name.sha256"
if [ ! -x "$tools/typst$exe" ]; then
curl -fsSLo "$tools/$typst_name" "https://github.com/typst/typst/releases/download/v$typst_version/$typst_name"
echo "$typst_sha256 $typst_name" > "$tools/$typst_name.sha256"
(cd "$tools" && sha256sum -c "$typst_name.sha256")
if [ "$exe" ]; then
install_zip_binary "$tools/$typst_name" "typst.exe"
else
tar -xJf "$tools/$typst_name" -C "$tools" --strip-components=1 "${typst_name%.tar.xz}/typst"
fi
rm "$tools/$typst_name" "$tools/$typst_name.sha256"
fi
"$tools/calepin" --version
"$tools/typst" --version
"$tools/calepin$exe" --version
"$tools/typst$exe" --version
+7 -2
View File
@@ -4,9 +4,14 @@ set -euo pipefail
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
if [ ! -x "$root/tools/calepin" ]; then
exe=""
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*) exe=".exe" ;;
esac
if [ ! -x "$root/tools/calepin$exe" ]; then
"$root/scripts/bootstrap.sh"
fi
export PATH="$root/tools:$PATH"
exec "$root/tools/calepin" "$@"
exec "$root/tools/calepin$exe" "$@"
+17 -15
View File
@@ -22,12 +22,16 @@ include = [
]
exclude = ["drafts/**"]
[toc]
enabled = true
depth = 2
floating = true
[menus]
main = [
{ label = "Home", target = "home/index.typ" },
{ label = "IT", target = "it/index.typ" },
{ label = "OT", target = "ot/index.typ" },
{ label = "Security", target = "security/index.typ" },
{ label = "Computer Science", target = "cs/index.typ" },
{ label = "HomeLab", target = "homelab/index.typ" },
{ label = "Medias", target = "medias/index.typ" },
]
social = [
@@ -54,24 +58,22 @@ item = [
[[sidebar.section]]
title = "IT"
title = "Computer Science"
item = [
{ target = "it/index.typ" },
{ glob = "it/*" }
{ target = "cs/index.typ" },
{ glob = "cs/*" }
]
section = [
{ title = "Tools", item = [{ glob = "cs/tools/*.typ" }] }
]
[[sidebar.section]]
title = "OT"
item = [
{ target = "ot/index.typ" },
{ glob = "ot/*" }
]
[[sidebar.section]]
title = "Security"
title = "HomeLab"
item = [
{ target = "security/index.typ" },
{ glob = "security/*" }
{ target = "homelab/index.typ" },
{ glob = "homelab/*" }
]
[[sidebar.section]]
+7
View File
@@ -0,0 +1,7 @@
#set document(title: [Computer Science])
#metadata((title: "Overview", translation_key: "cs-index")) <website-metadata>
#title()
Placeholder page for the Computer Science category.
The real content comes later.
+85
View File
@@ -0,0 +1,85 @@
#import "/lib/lib.typ": *
#set document(title: [Git])
#metadata((
title: "Git",
translation_key: "git",
summary: "What's git and lot of usefull command"
)) <website-metadata>
#calepin.setup(eval: false)
= What's Git
This is git
= Bascis command
TODO:
- fetch
- pull
- push
- commit (with sign)
- checkout
- rebase
= Config
Git config live in `~/.gitconfig`
== User
In User section, we can specify default `name` and `email`:
```yaml
[user]
name = Rémi Heredero
email = remi@heredero.ch
```
== Signing
To sign commit and tag by default, you can set the flag on the configfile:
```yaml
[commit]
gpgsign = true
[tag]
gpgSign = true
```
You also probably want to specify your default gpg key in the user section:
```yaml
[user]
signingkey = 4A8C1907D8B15B47
```
Sometime (often in windows), you need to specify the path of the gpg program with:
```yaml
[gpg]
program = C:/Users/her/dev/GnuPG/bin/gpg.exe
```
== Default editor
You can define a default editor to edit commit message or solve conflict. In my case, my favourite code editor is Zed, so:
```yaml
[core]
editor = zed --wait
```
== Include If
You maybe want a different config for some repo. It's easy to do that with `includeIf`. You can define a gitconfig overlay to apply to a specific repository:
```yaml
[includeIf "gitdir:<path-to-work-repo>"]
path = ~/.gitconfig-work
```
= Advanced command
== Reset author
If you didn't use the right config for commiting somewhere, you can reset the author of commit with the following command.
=== Single commit
```sh
git commit --amend --no-edit --reset-author
```
=== Entire project history
```sh
git rebase -r --root --exec "git commit --amend --no-edit --reset-author"
```
=== From a specific commit
```sh
git rebase -r <hash> --exec "git commit --amend --no-edit --reset-author"
```
+25
View File
@@ -0,0 +1,25 @@
#import "/lib/lib.typ": *
#set document(title: [Lazygit])
#metadata((
title: "Lazygit",
translation_key: "lazygit",
summary: "Simple TUI for git commands build in GO"
)) <website-metadata>
#calepin.setup(eval: false)
= Install
TODO
= Config file
On linux:
`~/.config/lazygit/config.yml`
On Windows:
`%USERPROFILE%\AppData\Local\lazygit\config.yml `
= Disable auto-fetch
Add the following code in your config gile:
```yaml
git:
autoFetch: false
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB

+52 -2
View File
@@ -1,6 +1,56 @@
#import "/lib/lib.typ": *
#set document(title: [Gardening])
#metadata((title: "Gardening", translation_key: "home-gardening")) <website-metadata>
#metadata((
title: "Gardening",
translation_key: "home-gardening",
date: "2026-10-11",
tags: ("plants", "yucca", "dracaena", "light", "water"),
author: "Rémi Herdero",
summary: "Some plants description and advices for keep them alive"
)) <website-metadata>
#title()
Placeholder page — the real content comes later.
= Yucca elephantipes <home:gardening:yucca>
#calepin.elements.columns(
columns: 2,
wrap: true,
[
Yucca (@fig:plant:yucca_elephantipes) from central America is accustomed to arid conditions.
#tag(fill: yellow.lighten(30%))[Light ++]
#tag(fill: blue.lighten(50%))[Water --]
This plant love light and should be placed on one of the most brightful parts of the room. It even tolerates direct sunlight very well.
The Yucca stores water in its thick trunk. You need to let the soil dry out almost completely between waterings. Generally speaking, watering once *every 2 to 3 weeks* is more than enough. It's better to forget about it for a while than to overwater it, otherwise its roots will decay. Usually we can put around #frackable(1, 2) liter every 2 Weeks. But it's important to check the dirt is dry before watering.
],[
#figure(
image("assets/yucca_elephantipes.jpg", width: 60%),
caption: "Yucca elephantipes"
) <fig:plant:yucca_elephantipes>
]
)
= Dracaena marginata <home:gardening:dracaena>
#calepin.elements.columns(
columns: 2,
wrap: true,
[
The Dracaena (@fig:plant:dracaena_marginata) come from Madagascar.
#tag(fill: yellow.lighten(30%))[Light +]
#tag(fill: blue.lighten(50%))[Water -]
This plant prefer lot of indirect light. Avoid to place it in direct sunlight because it can burn its leaves.
The Dracaena don't need a lot of water. Before watering, make sure the first 3 or 4 centimeters of soil are dry. In average, water the plant once with #frackable(1, 2) litre *every 10 to 14 days*. The extremity of the leaves tend to turn brown when the air is too dry or the water contain too much calcium or chlorine.
], [
#figure(
image("assets/dracaena_marginata.jpg", width: 60%),
caption: [Dracaena marginata]
) <fig:plant:dracaena_marginata>
]
)
-6
View File
@@ -1,6 +0,0 @@
#set document(title: [Washing clothes])
#metadata((title: "Washing clothes", translation_key: "home-washing-clothes")) <website-metadata>
#title()
Placeholder page — the real content comes later.
+6
View File
@@ -0,0 +1,6 @@
#set document(title: [Backup])
#metadata((title: "Backup", translation_key: "homelab-backup")) <website-metadata>
#title()
Placeholder page — the real content comes later.
+7
View File
@@ -0,0 +1,7 @@
#set document(title: [HomeLab])
#metadata((title: "Overview", translation_key: "homelab")) <website-metadata>
#title()
Placeholder page for the homelab category.
The real content comes later.
-7
View File
@@ -1,7 +0,0 @@
#set document(title: [IT])
#metadata((title: "Overview", translation_key: "it-index")) <website-metadata>
#title()
Placeholder page for the IT category.
The real content comes later.
+51
View File
@@ -0,0 +1,51 @@
// #import "@preview/calepin:0.1.0" as calepin
#import "@preview/hes-so-core:0.1.0"
#import "@preview/frackable:0.2.0": *
// #import "@preview/cetz:0.5.2"
//
// #let drawing(..args) = {
// let canvas = cetz.canvas(..args)
// context if target() == "html" {
// html.frame(canvas)
// } else {
// canvas
// }
// }
#let tag(body, fill: yellow, stroke: auto) = {
let stroke-color = if stroke == auto {
fill.darken(25%)
} else if type(stroke) == color {
stroke
} else if type(stroke) == stroke {
stroke.paint
} else {
fill.darken(25%)
}
let stroke-rule = if stroke == auto {
1pt + stroke-color
} else if type(stroke) == color {
1pt + stroke
} else {
stroke
}
context if target() == "html" {
let bg-hex = fill.to-hex()
let border-hex = stroke-color.to-hex()
html.elem("span", attrs: (
style: "display: inline-block; background-color: " + bg-hex
+ "; border: 1px solid " + border-hex
+ "; color: #1f2933; border-radius: 1em; padding: 0.2em 0.6em; font-size: 0.85em; font-weight: 500; line-height: 1.2;"
))[#body]
} else {
box(
fill: fill,
stroke: stroke-rule,
radius: 1em,
inset: (x: 0.5em, y: 0.5em)
)[#body]
}
}
-7
View File
@@ -1,7 +0,0 @@
#set document(title: [OT])
#metadata((title: "Overview", translation_key: "ot-index")) <website-metadata>
#title()
Placeholder page for the OT category.
The real content comes later.
-7
View File
@@ -1,7 +0,0 @@
#set document(title: [Security])
#metadata((title: "Overview", translation_key: "security")) <website-metadata>
#title()
Placeholder page for the security category.
The real content comes later.
-6
View File
@@ -1,6 +0,0 @@
#set document(title: [SSH])
#metadata((title: "SSH", translation_key: "security-ssh")) <website-metadata>
#title()
Placeholder page — the real content comes later.