Compare commits
49 Commits
fa03ca647c
...
presentati
Author | SHA1 | Date | |
---|---|---|---|
1fdd75cec6
|
|||
a03f31e237
|
|||
65dce1b060
|
|||
5b2683b3a4
|
|||
43de32edd2
|
|||
263e1c5f20
|
|||
f1eba8b28a
|
|||
b9c070b6c8
|
|||
957c8e2ed1
|
|||
1eed4d7ca3
|
|||
ee6946373c
|
|||
30b1ce923f
|
|||
886221e821
|
|||
665efa6b77
|
|||
9806dbd95b
|
|||
19dcc79a98
|
|||
6e08f67ea4
|
|||
87a2de2a07
|
|||
5f07ecae00
|
|||
1f2d9a9b3d
|
|||
2f1f346735
|
|||
34f2980123
|
|||
5ba13f48b7
|
|||
4da2ad6e6e
|
|||
6f0881d984
|
|||
330a3d6b4e
|
|||
110c31099a
|
|||
5364463d1f
|
|||
57e445a02d
|
|||
0eec47dc72
|
|||
f3eade6ef6
|
|||
198c798f2c
|
|||
85c5fcf3a2
|
|||
b35823a0a3
|
|||
9aa3e1cb4d
|
|||
c68e027c01
|
|||
59fe511c25
|
|||
7f1d2b274e
|
|||
ddb749e247
|
|||
8fc7b7346f
|
|||
b13c2c7ff3
|
|||
2bd00b4b46 | |||
120df63984 | |||
9d086e6436 | |||
39a90c8245 | |||
eb653d1196 | |||
62d90435c3 | |||
492165db60 | |||
ac87a6080d |
3
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
output
|
output
|
||||||
__pycache__
|
__pycache__
|
||||||
Makefile
|
|
||||||
*.pid
|
*.pid
|
||||||
plugins
|
cache
|
||||||
|
8
.gitmodules
vendored
@ -1,3 +1,9 @@
|
|||||||
[submodule "themes/clean-blog"]
|
[submodule "themes/clean-blog"]
|
||||||
path = themes/clean-blog
|
path = themes/clean-blog
|
||||||
url = ssh://gitea@git.epheme.re:2222/fmouhart/pelican-clean-blog.git
|
url = https://git.epheme.re/fmouhart/pelican-clean-blog.git
|
||||||
|
[submodule "plugins/autopages"]
|
||||||
|
path = plugins/autopages
|
||||||
|
url = https://git.epheme.re/fmouhart/pelican-autopages.git
|
||||||
|
[submodule "plugins/i18n_subsites"]
|
||||||
|
path = plugins/i18n_subsites
|
||||||
|
url = https://git.epheme.re/fmouhart/pelican-i18n_subsites.git
|
||||||
|
21
Makefile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
all: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
uv run pelican -s publishconf.py
|
||||||
|
|
||||||
|
dev:
|
||||||
|
uv run invoke livereload
|
||||||
|
|
||||||
|
publish:
|
||||||
|
uv run invoke publish
|
||||||
|
|
||||||
|
clean:
|
||||||
|
uv run invoke clean
|
||||||
|
|
||||||
|
%.mo: %.po
|
||||||
|
msgfmt "$^" -o "$@"
|
||||||
|
|
||||||
|
init: themes/clean-blog/translations/fr/LC_MESSAGES/messages.mo
|
||||||
|
uv sync
|
||||||
|
|
||||||
|
.PHONY: clean build publish dev init
|
@ -2,7 +2,7 @@
|
|||||||
Title: wget/curl
|
Title: wget/curl
|
||||||
Date: 2022-07-25 13:45 CEST
|
Date: 2022-07-25 13:45 CEST
|
||||||
Author: Fabrice
|
Author: Fabrice
|
||||||
Category: cheat sheets
|
Category: antisèches
|
||||||
Tags: wget, curl, cli
|
Tags: wget, curl, cli
|
||||||
Slug: wget-curl
|
Slug: wget-curl
|
||||||
Header_Cover: ../images/covers/speedboat.jpg
|
Header_Cover: ../images/covers/speedboat.jpg
|
||||||
|
BIN
content/examples/revealjs-speakerview.png
Normal file
After Width: | Height: | Size: 381 KiB |
147
content/examples/tikz-graph.svg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
content/examples/typst-example.pdf
Normal file
Before Width: | Height: | Size: 553 KiB After Width: | Height: | Size: 548 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 224 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 220 KiB |
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 199 KiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 319 KiB After Width: | Height: | Size: 309 KiB |
BIN
content/images/covers/garamond.jpg
Normal file
After Width: | Height: | Size: 481 KiB |
Before Width: | Height: | Size: 469 KiB After Width: | Height: | Size: 465 KiB |
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 281 KiB |
Before Width: | Height: | Size: 473 KiB After Width: | Height: | Size: 451 KiB |
Before Width: | Height: | Size: 511 KiB After Width: | Height: | Size: 487 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 267 KiB |
BIN
content/images/covers/printing-press.jpg
Normal file
After Width: | Height: | Size: 470 KiB |
BIN
content/images/covers/pts24-talk.jpg
Normal file
After Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 219 KiB After Width: | Height: | Size: 213 KiB |
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 182 KiB |
Before Width: | Height: | Size: 320 KiB After Width: | Height: | Size: 308 KiB |
@ -24,7 +24,7 @@ Si vous cherchez une version anglophone de ce blog, c'est [par là]({filename}in
|
|||||||
|
|
||||||
Pour toutes remarques ou commentaires, n’hésitez pas à me contacter par e-mail à l’adresse suivante : <img style="height:2em" src="/images/mel.png" alt="courriel"/>.
|
Pour toutes remarques ou commentaires, n’hésitez pas à me contacter par e-mail à l’adresse suivante : <img style="height:2em" src="/images/mel.png" alt="courriel"/>.
|
||||||
|
|
||||||
Si vous voulez être mis au courant des nouveaux articles (en anglais en et français), des flux de syndications sont disponibles:
|
Si vous voulez être mis au courant des nouveaux articles (en anglais et en français), des flux de syndication sont disponibles:
|
||||||
|
|
||||||
* [Atom](/feeds/all.atom.xml)
|
* [Atom](/feeds/all.atom.xml)
|
||||||
* [RSS](/feeds/all.rss.xml)
|
* [RSS](/feeds/all.rss.xml)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
Title: Setup Neovim with kickstart.nvim
|
Title: Setup Neovim with kickstart.nvim
|
||||||
Date: 2023-12-25 17:15
|
Date: 2023-12-25 17:15
|
||||||
|
Modified: 2025-02-12 13:00
|
||||||
Lang: en
|
Lang: en
|
||||||
Author: Fabrice
|
Author: Fabrice
|
||||||
Category: software
|
Category: software
|
||||||
@ -21,38 +22,38 @@ incrementally before it starts getting too big for me to find anything inside
|
|||||||
it and not using even half of the plugins I installed. That goes without saying,
|
it and not using even half of the plugins I installed. That goes without saying,
|
||||||
there were quite a bit on conflicting keymaps as well as I'm using
|
there were quite a bit on conflicting keymaps as well as I'm using
|
||||||
[bépo](http://bepo.fr/) as my keyboard layout with [partial remaps
|
[bépo](http://bepo.fr/) as my keyboard layout with [partial remaps
|
||||||
(fr)](https://cdn.bepo.fr/Vim-bepo-066.png).
|
(fr)](https://cdn.bepo.fr/images/Vim-bepo-066.png).
|
||||||
|
|
||||||
Obviously, it slowly became quite a mess. To address this issue, I
|
Obviously, it slowly became quite a mess. To address this issue, I decided to
|
||||||
decided to reorganise my `$HOME/.config/vim` directory using the [vim directory
|
reorganise my `$HOME/.config/vim` directory using the [vim directory
|
||||||
structure](www.panozzaj.com/blog/2011/09/09/vim-directory-structure/) and did
|
structure](https://www.panozzaj.com/blog/2011/09/09/vim-directory-structure/)
|
||||||
some cleanup at this point of time. I think it was also around this period that
|
and did some cleanup at this point of time. I think it was also around this
|
||||||
I discovered that Vim8 added a native package manager that I started to use.
|
period that I discovered that Vim8 added a native package manager that I started
|
||||||
Thus, at this point, I started organising my configuration with semantic files,
|
to use. Thus, at this point, I started organising my configuration with semantic
|
||||||
such as `$VIMHOME/plugin/spelling.vim` to manage my spelling configuration for
|
files, such as `$VIMHOME/plugin/spelling.vim` to manage my spelling
|
||||||
instance. This approach makes debugging easier, and also checking custom
|
configuration for instance. This approach makes debugging easier, and also
|
||||||
keyboard shortcuts easier, as I just have to check
|
checking custom keyboard shortcuts easier, as I just have to check
|
||||||
`$VIMHOME/plugin/omnicomplete.vim` for instance to know which shortcuts I set up
|
`$VIMHOME/plugin/omnicomplete.vim` for instance to know which shortcuts I set up
|
||||||
when I'm still getting the habits of using them.
|
when I'm still getting the habits of using them.
|
||||||
|
|
||||||
At some point of time, I moved to Neovim, and I simply moved my configuration
|
At some point of time, I moved to Neovim, and simply moved my configuration from
|
||||||
from Vim to Neovim and continue on adding more and more plugins on top of each
|
Vim to Neovim. All the while continuing adding more and more plugins on top of
|
||||||
other depending on my hype, especially because the world of Neovim plugins
|
each other depending on my hype, especially because the world of Neovim plugins
|
||||||
opened up to me. Needless to say that less than half of these plugins were put
|
opened up to me. Needless to say that less than half of these plugins were put
|
||||||
into good use. Which leads to my first configuration big cleanup.
|
into good use. Which leads to my first configuration big cleanup.
|
||||||
|
|
||||||
Six months ago, I wiped my frankenconfig, and started back from scratch in
|
Six months ago, I wiped my _frankenconfig_, and started back from scratch in
|
||||||
[lua](https://lua.org/about.html), with the same structural approach as
|
[lua](https://lua.org/about.html), with the same structural approach as
|
||||||
previously, but now wondering if the plugin would be useful or not. Since my
|
previously, but now wondering if the plugin would be useful or not. Since my
|
||||||
first time using Vim, there were some big changes in the vim ecosystem,
|
first time using Vim, there were some big changes in the vim ecosystem,
|
||||||
especially in language management with
|
especially in language management with
|
||||||
[tree-sitter](https://tree-sitter.github.io/tree-sitter/) and
|
[tree-sitter](https://tree-sitter.github.io/tree-sitter/) and
|
||||||
[lsp](https://en.wikipedia.org/wiki/Language_Server_Protocol). These two bring
|
[lsp](https://en.wikipedia.org/wiki/Language_Server_Protocol). These two bring
|
||||||
into the environment a unified way to manage languages without having to depend
|
into the environment a unified way to manage languages without depending on
|
||||||
on language-specific plugins, henceforth I didn't need specific plugins to have
|
language-specific plugins. Henceforth, I didn't need specific plugins to have
|
||||||
nice syntax coloration for obscure languages anymore, or get frustrated with
|
nice syntax coloration for obscure languages anymore, or get frustrated with
|
||||||
[omnicomplete](https://vim.fandom.com/wiki/Omni_completion) which decided not to
|
[omnicomplete](https://vim.fandom.com/wiki/Omni_completion) which decided not to
|
||||||
work for some languages… While it's not an absolute rule (for instance, I'm
|
work only for some languages… While it's not an absolute rule (for instance, I'm
|
||||||
using [vimtex]({filename}./nvim-latex.md) for latex, which includes a more
|
using [vimtex]({filename}./nvim-latex.md) for latex, which includes a more
|
||||||
accurate syntax coloring than tree-sitter). I also moved from the native vim way
|
accurate syntax coloring than tree-sitter). I also moved from the native vim way
|
||||||
of managing plugins to use [`Lazy`](https://github.com/folke/lazy.nvim) as a
|
of managing plugins to use [`Lazy`](https://github.com/folke/lazy.nvim) as a
|
||||||
@ -69,10 +70,10 @@ However, I was unhappy with some of my configurations, and if I managed to have
|
|||||||
something functional, there were many details that annoy me that stemmed for
|
something functional, there were many details that annoy me that stemmed for
|
||||||
some configuration I wrote some times ago and of course didn't document. This
|
some configuration I wrote some times ago and of course didn't document. This
|
||||||
leads us to today, where I just decided to use
|
leads us to today, where I just decided to use
|
||||||
[`kickstart.nvim`](https://github.com/nvim-lua/kickstart.nvim), which is a
|
[`kickstart.nvim`](https://github.com/nvim-lua/kickstart.nvim). It is a well
|
||||||
well-documented vim starting configuration (it's not a distribution, it still
|
documented vim starting configuration (it's not a distribution, it still
|
||||||
requires your input to obtain something that fits your needs), which was exactly
|
requires your inputs to obtain something that fits your needs), which was
|
||||||
what I needed to start anew… but not fully from scratch.
|
exactly what I needed to start anew… but not fully from scratch.
|
||||||
|
|
||||||
## The migration
|
## The migration
|
||||||
|
|
||||||
@ -83,10 +84,11 @@ that is over 600 lines long. I thus decided to split it into short files that
|
|||||||
manages a specific part of the configuration: completion, lsps, treesitter,
|
manages a specific part of the configuration: completion, lsps, treesitter,
|
||||||
mappings after reading the different configuration default from nvim-kickstart
|
mappings after reading the different configuration default from nvim-kickstart
|
||||||
and changing what I disliked. To do that, I started with using the
|
and changing what I disliked. To do that, I started with using the
|
||||||
[`NVIM_APP`](https://practical.li/neovim/configuration/) environment option in
|
[`NVIM_APPNAME`](https://practical.li/neovim/configuration/) environment option
|
||||||
order to make the move in a non-destructive way. After installing the bare
|
in order to make the move in a non-destructive way.
|
||||||
minimum to make it usable for me (as a bépo user), I exported the `NVIM_APP`
|
After installing the bare minimum to make it usable for me (as a bépo user), I
|
||||||
variable to start using my configuration to help me debug it on the fly.
|
exported the `NVIM_APPNAME` variable to start using my configuration to help me
|
||||||
|
debug it on the fly.
|
||||||
I also decided to write this blog post to remember the process and maybe helped
|
I also decided to write this blog post to remember the process and maybe helped
|
||||||
some people who want to configure their text editor.
|
some people who want to configure their text editor.
|
||||||
|
|
||||||
@ -193,11 +195,11 @@ vim.g.ip_skipfold=true
|
|||||||
```
|
```
|
||||||
|
|
||||||
Once all of that is done, at this point of time, I started moving to use the
|
Once all of that is done, at this point of time, I started moving to use the
|
||||||
configuration by exporting `NVIM_APP=new_nvim` inside my `.zshrc`. The idea is
|
configuration by exporting `NVIM_APPNAME=new_nvim` inside my `.zshrc`.
|
||||||
that now I bootstrapped my Neovim config to proficiently edit the configuration,
|
The idea is that now I bootstrapped my Neovim config to proficiently edit the
|
||||||
which in lua also uses LSP and many of `kickstart.nvim` features. During this
|
configuration, which in lua also uses LSP and many of `kickstart.nvim` features.
|
||||||
process I notice what I liked and disliked to know how to edit the configuration
|
During this process I notice what I liked and disliked to know how to edit the
|
||||||
while editing the configuration.
|
configuration while editing the configuration.
|
||||||
|
|
||||||
## Importing my former configuration
|
## Importing my former configuration
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
Title: Gérer vos mots de passe avec pass
|
Title: Gérer vos mots de passe avec pass
|
||||||
Date: 2019-04-22 19:00
|
Date: 2019-04-22 19:00
|
||||||
Modified: 2019-04-24 11:12
|
Modified: 2024-02-24 18:00
|
||||||
Lang: fr
|
Lang: fr
|
||||||
Author: Fabrice
|
Author: Fabrice
|
||||||
Category: programmes
|
Category: programmes
|
||||||
@ -14,9 +14,9 @@ Summary: Un gestionnaire de mots de passe simple qui repose sur gpg, et synchron
|
|||||||
Comme nous vivons dans un monde dangereux où les failles de sécurité sont découvertes tous les jours et où les fuites de données sont devenues monnaies courantes, il est recommandé d’utiliser un mot de passe différent pour chacune de nos identités numériques.
|
Comme nous vivons dans un monde dangereux où les failles de sécurité sont découvertes tous les jours et où les fuites de données sont devenues monnaies courantes, il est recommandé d’utiliser un mot de passe différent pour chacune de nos identités numériques.
|
||||||
Cependant, cela devient vite une horreur à maintenir manuellement, j’avais essayé d’utiliser un bloc note en 2003 que j’ai perdu au bout d’un mois (et les mots de passe avec).
|
Cependant, cela devient vite une horreur à maintenir manuellement, j’avais essayé d’utiliser un bloc note en 2003 que j’ai perdu au bout d’un mois (et les mots de passe avec).
|
||||||
|
|
||||||
Heureusement, les gestionnaires de mots de passes ont fleurit depuis, et plusieurs proposent des fonctionnalités de base similaires : multiplateforme (en particulier sur les téléphones intelligents), génération de mots de passe « sécurisés », intégration navigateur…
|
Heureusement, les gestionnaires de mots de passes ont fleuri depuis, et plusieurs proposent des fonctionnalités de base similaires : mufti plateforme (en particulier sur les téléphones intelligents), génération de mots de passe « sécurisés », intégration navigateur…
|
||||||
|
|
||||||
Je ne vais pas pour faire une comparaison détaillée, mais si vous souhaitez jeter un coup d’œil, [wikipedia](https://en.wikipedia.org) propose une table de comparaison détaillée [**par ici** (en)](https://en.wikipedia.org/wiki/List_of_password_managers).
|
Je ne vais pas pour faire une comparaison détaillée, mais si vous souhaitez jeter un coup d’œil, [Wikipédia](https://en.wikipedia.org) propose une table de comparaison détaillée [**par ici** (en)](https://en.wikipedia.org/wiki/List_of_password_managers).
|
||||||
|
|
||||||
Dans cette recherche, grâce à [moviuro](https://try.popho.be), mon choix s’est porté sur [pass](https://www.passwordstore.org/) avec [pass-otp](https://github.com/tadfisher/pass-otp#readme) (et [passmenu](https://git.zx2c4.com/password-store/tree/contrib/dmenu)).
|
Dans cette recherche, grâce à [moviuro](https://try.popho.be), mon choix s’est porté sur [pass](https://www.passwordstore.org/) avec [pass-otp](https://github.com/tadfisher/pass-otp#readme) (et [passmenu](https://git.zx2c4.com/password-store/tree/contrib/dmenu)).
|
||||||
Je n’ai pas non plus la prétention de faire un guide détaillé sur pass, comme ceux-ci sont déjà faciles à trouver sur internet, par exemple [**par ici** (en)](https://medium.com/@chasinglogic/the-definitive-guide-to-password-store-c337a8f023a1).
|
Je n’ai pas non plus la prétention de faire un guide détaillé sur pass, comme ceux-ci sont déjà faciles à trouver sur internet, par exemple [**par ici** (en)](https://medium.com/@chasinglogic/the-definitive-guide-to-password-store-c337a8f023a1).
|
||||||
@ -32,6 +32,34 @@ Pour **re**générer un mot de passe, l’option `-i` ici est **importante** pui
|
|||||||
Cela évite donc de devoir utiliser du [git sale]({filename}/cheat-sheets/git-fr.md) pour retirer l’erreur de l’arbre des commits vu que `pass <cmd>` fait automatiquement un commit atomique à la fin de la commande.
|
Cela évite donc de devoir utiliser du [git sale]({filename}/cheat-sheets/git-fr.md) pour retirer l’erreur de l’arbre des commits vu que `pass <cmd>` fait automatiquement un commit atomique à la fin de la commande.
|
||||||
Je l’oublie parfois, c’est pourquoi je laisse ça ici en guise de rappel.
|
Je l’oublie parfois, c’est pourquoi je laisse ça ici en guise de rappel.
|
||||||
|
|
||||||
|
Sur certains services, il arrive que l’on ait besoin de spécifier un ensemble de caractères admissibles pour les mots de passe.
|
||||||
|
Cela peut être fait via la variable d’environnement `PASSWORD_STORE_CHARACTER_SET`.
|
||||||
|
Le contenu de cette variable est transmis à la [commande `tr`](https://fr.wikipedia.org/wiki/Tr_(Unix)).
|
||||||
|
Ainsi, pour créer un code PIN, on peut spécifier la valeur suivante : `PASSWORD_STORE_CHARACTER_SET='[:digit:]'` et indiquer la longueur désirée du mot de passe en dernier argument de la commande.
|
||||||
|
|
||||||
|
Par exemple, pour générer un code PIN de 6 chiffres :
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PASSWORD_STORE_CHARACTER_SET='[:digit:]' pass generate <pass-name> 6
|
||||||
|
```
|
||||||
|
|
||||||
|
Je n’ai en revanche pas trouvé comment forcer la présence de caractères spéciaux… je lance donc la commande plusieurs fois dans ces cas avec l’option `-i` pour écrire en place après la première tentative.
|
||||||
|
Ce n’est pas la meilleure solution, qui en plus pollue l’historique git mais bon… ça fonctionne.
|
||||||
|
|
||||||
|
Par exemple, pour générer un mot de passe sur un service _fictif_ qui supporterait les caractères spéciaux suivants: `-_@$<>` pour des mots de passe d’au plus 20 caractères, on peut utiliser la commande suivante :
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PASSWORD_STORE_CHARACTER_SET='[:alnum:]-_@$<>' pass generate <pass-name> 20
|
||||||
|
```
|
||||||
|
|
||||||
|
Si on souhaite faire de la rotation de clefs ou simplement mettre à jour ses identités, il est possible de relancer la commande `pass init`, où on peut y spécifier l’identifiant de la nouvelle clef… ou plusieurs identifiants.
|
||||||
|
Cela peut être utile pour avoir plusieurs clefs sur des périphériques différents pour mieux contrôler les risques de fuite de clef.
|
||||||
|
On peut également avoir des sous dossiers de son dossier `$HOME/.password-store/` chiffrés sous des clefs spécifiques (cela se contrôle avec l’option `-p/--path=` de `pass init`).
|
||||||
|
Une application possible étant de séparer les clefs personnelles des clefs professionnelles (qui peuvent alors être chiffré sous une clef partagée entre les personnes ayant accès au jeu de mots-de-passe).
|
||||||
|
On pourrait imaginer coupler ça avec les [sous-modules git](https://git-scm.com/book/en/v2/Git-Tools-Submodules), mais je ne m’y suis pas aventuré…
|
||||||
|
|
||||||
|
Pour finir :
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pass git <ce que vous voulez>
|
pass git <ce que vous voulez>
|
||||||
```
|
```
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
Title: Manage your passwords with pass
|
Title: Manage your passwords with pass
|
||||||
Date: 2019-04-22 19:00
|
Date: 2019-04-22 19:00
|
||||||
Modified: 2019-04-23 14:24
|
Modified: 2024-02-24 18:00
|
||||||
Author: Fabrice
|
Author: Fabrice
|
||||||
Category: software
|
Category: software
|
||||||
Tags: pass, git, cli
|
Tags: pass, git, cli
|
||||||
@ -16,7 +16,7 @@ However, this task is obviously a pain to maintain by hand. I did use a notebook
|
|||||||
|
|
||||||
Hopefully, many password managers exist, with similar features: cross-platform (especially smartphone support), password generation, browser integration…
|
Hopefully, many password managers exist, with similar features: cross-platform (especially smartphone support), password generation, browser integration…
|
||||||
|
|
||||||
I'm not here to compare them, if you want to give a look, [wikipedia](https://en.wikipedia.org) provides a nice comparison table [**there**](https://en.wikipedia.org/wiki/List_of_password_managers).
|
I'm not here to compare them, if you want to give a look, [Wikipedia](https://en.wikipedia.org) provides a nice comparison table [**there**](https://en.wikipedia.org/wiki/List_of_password_managers).
|
||||||
|
|
||||||
However, thanks to [moviuro](https://try.popho.be), my choice is [pass](https://www.passwordstore.org/) along with [pass-otp](https://github.com/tadfisher/pass-otp#readme) (and [passmenu](https://git.zx2c4.com/password-store/tree/contrib/dmenu)).
|
However, thanks to [moviuro](https://try.popho.be), my choice is [pass](https://www.passwordstore.org/) along with [pass-otp](https://github.com/tadfisher/pass-otp#readme) (and [passmenu](https://git.zx2c4.com/password-store/tree/contrib/dmenu)).
|
||||||
I don't intend either to make a comprehensive guide, as those already populate the internet, for example [**here**](https://medium.com/@chasinglogic/the-definitive-guide-to-password-store-c337a8f023a1).
|
I don't intend either to make a comprehensive guide, as those already populate the internet, for example [**here**](https://medium.com/@chasinglogic/the-definitive-guide-to-password-store-c337a8f023a1).
|
||||||
@ -28,7 +28,32 @@ Here are just some commands I often use.
|
|||||||
```sh
|
```sh
|
||||||
pass generate -i <pass-name>
|
pass generate -i <pass-name>
|
||||||
```
|
```
|
||||||
To regenerate a password, the `-i` is important to avoid overwritting the whole file and having to rely on [dirty git]({filename}/cheat-sheets/git.md) to withdraw your mistake (`pass <cmd>` will automatically commit your change)… I sometimes forget it, so let's put it here as a reminder.
|
To regenerate a password, the `-i` is important to avoid overwriting the whole file and having to rely on [dirty git]({filename}/cheat-sheets/git.md) to withdraw your mistake (`pass <cmd>` will automatically commit your change)… I sometimes forget it, so let's put it here as a reminder.
|
||||||
|
|
||||||
|
Sometimes it can be useful to specify the accepted special chars, this can be done using the `PASSWORD_STORE_CHARACTER_SET` environment variable.
|
||||||
|
This value is interpreted by the [`tr` command](https://en.wikipedia.org/wiki/Tr_(Unix)),
|
||||||
|
hence to create a PIN, you can use the following value: `PASSWORD_STORE_CHARACTER_SET='[:digit:]'`, then specify the length with the last argument.
|
||||||
|
|
||||||
|
For instance, to generate a 6 digit PIN:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PASSWORD_STORE_CHARACTER_SET='[:digit:]' pass generate <pass-name> 6
|
||||||
|
```
|
||||||
|
|
||||||
|
I didn’t manage to specify how to have at least one of them, so I run the command multiple times (with the `-i` option to change the file in place after the first one)…
|
||||||
|
It pollutes a bit the git history but, well… it works.
|
||||||
|
|
||||||
|
For instance, for a service supporting only the following characters: `-_@$<>` of at most 20 char long (fictive example), you can use the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PASSWORD_STORE_CHARACTER_SET='[:alnum:]-_@$<>' pass generate <pass-name> 20
|
||||||
|
```
|
||||||
|
|
||||||
|
If for some reasons you want to rotate your keys, you can rerun the `pass init` command by indicating the new gpg ID (or multiple keys to have it available under multiple devices that don’t share the same key to limit the risks of key leakage).
|
||||||
|
Note that you can also have a subfolder encrypted under a specific key (it can be specified using the `-p/--path=` option for `pass init`) if you want to share it to some other devices, or to separate work from personal passwords.
|
||||||
|
It should be possible to use [`git submodule`](https://git-scm.com/book/en/v2/Git-Tools-Submodules) as well, but I didn’t try.
|
||||||
|
|
||||||
|
To finish:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pass git <whatever you want>
|
pass git <whatever you want>
|
||||||
|
252
content/software/typst.md
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
---
|
||||||
|
Title: Typesetting with Typst
|
||||||
|
Date: 2024-10-19 18:00
|
||||||
|
Modified: 2025-02-14 12:45
|
||||||
|
Lang: en
|
||||||
|
Author: Fabrice
|
||||||
|
Category: software
|
||||||
|
Tags: vim, neovim, typst
|
||||||
|
Slug: typst-intro
|
||||||
|
table-of-contents: true
|
||||||
|
Summary: An overview of Typst for simple usage.
|
||||||
|
Header_Cover: ../images/covers/printing-press.jpg
|
||||||
|
---
|
||||||
|
|
||||||
|
For about ten years now, I’ve been using _LaTeX_ to typeset any document which
|
||||||
|
aims to be printed. The main reason is that I’m quite familiar with the syntax
|
||||||
|
to adjust the page setting to what I imagine. Other solutions exist to ease this
|
||||||
|
workflow, such as [Pandoc](https://pandoc.org/) to convert easier to write syntax to
|
||||||
|
other formats. However, this solution was not palatable to me as the universal
|
||||||
|
aspect of Pandoc, makes it a pain to specify pagination properties. And, to
|
||||||
|
produce a PDF in the end, Pandoc calls _LaTeX_, and for the sake of simplicity I
|
||||||
|
prefer to directly write in _LaTeX_ (see the conclusion for clarification).
|
||||||
|
|
||||||
|
However, for some kind of documents that I don’t write very often, such as
|
||||||
|
letters, it’s sometimes a pain to find the syntax of the [LaTeX class for
|
||||||
|
letters](https://texlive.mycozy.space/macros/latex/contrib/lettre/lettre.pdf)<sup>(fr)</sup>
|
||||||
|
I use. Recently, I had to write small documents (approx 3 pages), with a
|
||||||
|
bibliography, and that just needed to have a nice and neat presentation. Before
|
||||||
|
going farther, I decided to give a try to [typst](https://typst.app/). It is an
|
||||||
|
open-source typesetting engine that is written in
|
||||||
|
[rust](https://rust-lang.org/), that promotes modern features such as
|
||||||
|
_incremental compilation_, and a scripting language that is actually readable by
|
||||||
|
humans. Moreover, the markup language is clean, and as in
|
||||||
|
[markdown] or [asciidoc], it can be read from the source (without a
|
||||||
|
[concealer](https://alok.github.io/2018/04/26/using-vim-s-conceal-to-make-languages-more-tolerable/))
|
||||||
|
to have an idea of the typeset text before compiling it.
|
||||||
|
|
||||||
|
|
||||||
|
The project is still in development and some features may break before the first
|
||||||
|
major version is out. However, to quickly generate a document, it can be a good
|
||||||
|
idea to consider. Also, please note that there is no native output from Typst to
|
||||||
|
HTML. However, Pandoc can read and write `.typ` files, so it’s an alternative
|
||||||
|
worth considering given that native LaTeX is **not** easy to write for that
|
||||||
|
purpose.
|
||||||
|
|
||||||
|
In the following, it will be a quick overview of the features that I find nice
|
||||||
|
in Typst. Please don’t expect an in-depth review, I only used it for a couple of
|
||||||
|
opportunities.
|
||||||
|
|
||||||
|
# Syntax
|
||||||
|
|
||||||
|
To illustrate Typst, here follows a simple document, with its corresponding [compiled
|
||||||
|
version]({static}/examples/typst-example.pdf).
|
||||||
|
|
||||||
|
```typst
|
||||||
|
/* Set some variables for the authors and the title */
|
||||||
|
#let title = [How to type in Typst]
|
||||||
|
#let authors = ("Fabrice Mouhartem", )
|
||||||
|
|
||||||
|
/* Set some document properties:
|
||||||
|
* - Numbering of sections (default: none)
|
||||||
|
* - PDF properties (it does not print anything) */
|
||||||
|
#set heading(numbering: "I.")
|
||||||
|
#set document(title: title, author: authors)
|
||||||
|
|
||||||
|
/* Now we can print the title and the authors */
|
||||||
|
#align(center, text(size: 17pt, strong(title)))
|
||||||
|
#for author in authors { // TODO: would be better in a grid
|
||||||
|
align(center, text(author))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table of contents */
|
||||||
|
#outline()
|
||||||
|
|
||||||
|
/* To define a section */
|
||||||
|
= Introduction
|
||||||
|
/* And to write the content: */
|
||||||
|
To _type_ in Typst, you just have to… *type*.
|
||||||
|
|
||||||
|
= Conclusion
|
||||||
|
See, it was #strike[hard] easy.
|
||||||
|
```
|
||||||
|
|
||||||
|
Besides the programmatic part at the start, we can see that the syntax is close
|
||||||
|
to what we may know in other simple markup languages such as [markdown] or
|
||||||
|
[asciidoc]. However, it is its own and Typst [doesn’t
|
||||||
|
plan](https://github.com/typst/typst/discussions/2498) to converge toward
|
||||||
|
another markup language, especially knowing that the markdown syntax is
|
||||||
|
[ambiguous](https://roopc.net/posts/2014/markdown-cfg/).
|
||||||
|
|
||||||
|
For the preamble of the file, it can be deferred to another file to accentuate
|
||||||
|
the separation between content and typesetting. We won’t go into details, but it
|
||||||
|
was mostly there to illustrate some parts of the language, such as variable
|
||||||
|
declaration (`#let …`) or loops over arrays (`#for … in …`). We also set some
|
||||||
|
values about the document using either static values (for the numbering) or the
|
||||||
|
defined variables (authors and title options).
|
||||||
|
|
||||||
|
Let us now check that these options are indeed well set:
|
||||||
|
```bash
|
||||||
|
❯ pdfinfo "typst-example.pdf" | head -n 3
|
||||||
|
Title: How to type in Typst
|
||||||
|
Author: Fabrice Mouhartem
|
||||||
|
Creator: Typst 0.12.0
|
||||||
|
```
|
||||||
|
|
||||||
|
The generated document is a bit bare, but we can easily change it, and as easily
|
||||||
|
create a template to automate this work for us.
|
||||||
|
|
||||||
|
# Example: a letter (the French way)
|
||||||
|
|
||||||
|
For a simple example, I’ll take the letter one, for which I wrote a simple
|
||||||
|
template to generate them. The template is available in [this
|
||||||
|
repository](https://git.epheme.re/fmouhart/typst-lettre). The main issue I had
|
||||||
|
is that the French way of doing letters revert the order of the addresses of the
|
||||||
|
sender and recipient are… reverted compared to the English style.
|
||||||
|
|
||||||
|
Let us dig in what it does by looking at the example file.
|
||||||
|
|
||||||
|
First thing first, the file is loading the template from `lettre.typ`. This file
|
||||||
|
defines the typesetting and the paginations properties, and provide an
|
||||||
|
initialisation function to define the different headers, which you can look into
|
||||||
|
if you feel curious. If you find it a bit unbearable, you can create a new file
|
||||||
|
`preamble.typ` to hide everything, and include it with `#include "preamble.typ"`
|
||||||
|
at the outset of the file.
|
||||||
|
|
||||||
|
```typst
|
||||||
|
#import "lettre.typ": *
|
||||||
|
|
||||||
|
#show: doc => lettre.with(
|
||||||
|
de: [
|
||||||
|
Sender\
|
||||||
|
Address
|
||||||
|
],
|
||||||
|
pour: [
|
||||||
|
Recipient\
|
||||||
|
Address
|
||||||
|
],
|
||||||
|
objet: "subject of the letter", // optional
|
||||||
|
date: "date of sending", // optional
|
||||||
|
lieu: "location",
|
||||||
|
introduction: "opening",
|
||||||
|
cloture: "closing",
|
||||||
|
signature: "signature",
|
||||||
|
post: [
|
||||||
|
post-letter (e.g., post-scriptum)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
This will generate the template with the elements where they should be, in a
|
||||||
|
very simple fashion. Now, we just have to write the content of the letter and
|
||||||
|
have a `pdf` file pretty easily with `typst compile` without all the files that
|
||||||
|
_LaTeX_ generates for us. As a bonus, it also set some PDFs metadata from the
|
||||||
|
input variables.
|
||||||
|
|
||||||
|
# Bibliography
|
||||||
|
|
||||||
|
Another nice feature is that Typst embeds a bibliography engine, that is
|
||||||
|
compatible with the bibtex format. Meaning that I don’t have to change the way I
|
||||||
|
manage my bibliography or directly use [community-managed
|
||||||
|
bibliography](https://cryptobib.di.ens.fr/).
|
||||||
|
|
||||||
|
For that you simply have to call the bibliography function where you want it to be generated:
|
||||||
|
|
||||||
|
```typst
|
||||||
|
#bibliography("bibliography.bib", title: "References", style: "springer-basic")
|
||||||
|
```
|
||||||
|
|
||||||
|
And cite the references you want with the `@bibkey` syntax (note that it’s the
|
||||||
|
same syntax for cross-referencing) or the `#cite` function. Note that if you
|
||||||
|
have a `+` in your bibliography key, the label won’t be recognized. It is my
|
||||||
|
case as my bibkeys are in the _alpha_ style with the initials of the authors +
|
||||||
|
year up to 3 names, and a `+` afterward… To be able to cite the reference
|
||||||
|
anyway, just do `#cite(label("bib+key"))`.
|
||||||
|
|
||||||
|
The full list of natively available style is given in the [Typst
|
||||||
|
documentation](https://typst.app/docs/reference/model/bibliography/#parameters-style),
|
||||||
|
however you can define your own in the [Citation Style
|
||||||
|
Language](https://citationstyles.org/). Meaning that you can pick the best one
|
||||||
|
for your usage in the [CSL
|
||||||
|
repository](https://github.com/citation-style-language/styles).
|
||||||
|
|
||||||
|
To put multiple citations (as in `\cite{ref1, ref2}` in _LaTeX_), you just have
|
||||||
|
to concatenate them, like `@ref1 @ref2`. If the citation style supports it, it would automatically
|
||||||
|
merge them under the same bracket (however, it’s not the case for all citation
|
||||||
|
styles).
|
||||||
|
|
||||||
|
# Tooling
|
||||||
|
|
||||||
|
Unlike my [blogpost about using nvim for LaTeX]({filename}./nvim-latex.md),
|
||||||
|
it’s pretty much easier here.
|
||||||
|
|
||||||
|
I just added the [`typst.vim`](https://github.com/kaarmu/typst.vim) plugin to
|
||||||
|
_neovim_, added a binding for the `:TypstWatch` command and that’s basically
|
||||||
|
all. It is possible to set the `g:typst_pdf_viewer` (`vim.g.typst_pdf_viewer` in
|
||||||
|
Lua) global variable as well if you want to have a different default PDF viewer
|
||||||
|
for your system and for edition.
|
||||||
|
|
||||||
|
Now, each time I save, the document is incrementally compiled (I think) and
|
||||||
|
updated in my PDF viewer.
|
||||||
|
|
||||||
|
I tried using typst language servers as well, but they don’t seem mature enough
|
||||||
|
yet. In the end, the `typst.vim` plugin suffices to my needs without being too
|
||||||
|
nosy.
|
||||||
|
|
||||||
|
Hopefully, the tooling will get better with time.
|
||||||
|
|
||||||
|
# Conclusion
|
||||||
|
|
||||||
|
For simple document typesetting, even with features such as bibliography,
|
||||||
|
cross-referencing, and table of contents, Typst seems to be a good choice.
|
||||||
|
However, for long-term support documents, such as documentation, I would wait to
|
||||||
|
see it being more stable. Even while writing this blog post, the _lettre_
|
||||||
|
template I made was done in Typst 0.11, and preparing it in a repository raised
|
||||||
|
some warnings about [breaking changes from
|
||||||
|
0.12](https://typst.app/docs/changelog/0.12.0/) which has been published…
|
||||||
|
[yesterday](https://typst.app/blog/2024/typst-0.12/) (at the time of writing):
|
||||||
|
|
||||||
|
> Added
|
||||||
|
> [`par.spacing`](https://typst.app/docs/reference/model/par/#parameters-spacing
|
||||||
|
> "Typst Documentation: paragraph spacing") property for configuring paragraph
|
||||||
|
> spacing. This should now be used instead of `show par: set block(spacing: ..)`
|
||||||
|
> **(Breaking change)**
|
||||||
|
|
||||||
|
Which also leads me to say that one other advantage of Typst is… the readability of
|
||||||
|
error messages. They are way much cleaner than the ones from _LaTeX_. Leading to
|
||||||
|
easier debugging as well. I, however, can’t say for sure as I didn’t typeset big
|
||||||
|
documents using Typst yet (which is unlikely to happen given my stance so far,
|
||||||
|
but who knows…).
|
||||||
|
|
||||||
|
Finally, to complete the note about compiling in _LaTeX_ from Pandoc in the
|
||||||
|
introduction of this blogpost… I’m apparently not up to date. For the sake of
|
||||||
|
transparency, it is possible to use different PDF engines with Pandoc according
|
||||||
|
to the [documentation](https://pandoc.org/MANUAL.html#option--pdf-engine). I
|
||||||
|
didn’t try them yet, so I can’t provide feedbacks about them. Note that Typst is
|
||||||
|
part of the PDF generators, as well as other nice typesetting projects such as
|
||||||
|
[pagedjs](https://pagedjs.org/) that aims at paginating HTML sources to have
|
||||||
|
great web page and print-ready PDFs. However, the argument about avoiding
|
||||||
|
intermediate steps if possible still holds (moreover when the syntax of Typst is
|
||||||
|
already clean enough).
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Awesome Typst](https://github.com/qjcg/awesome-typst): a repository listing
|
||||||
|
useful links for typst users.
|
||||||
|
- [Typst for _LaTeX_ users](https://typst.app/docs/guides/guide-for-latex-users/
|
||||||
|
"Typst documentation: guide for LaTeX users"): a comprehensive guide for typst
|
||||||
|
for _LaTeX_ users.
|
||||||
|
|
||||||
|
[markdown]: https://daringfireball.net/projects/markdown/
|
||||||
|
[asciidoc]: https://asciidoc.org/
|
||||||
|
|
218
content/tips/presenting.md
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
---
|
||||||
|
Title: Tools for making and giving presentations
|
||||||
|
Date: 2024-11-03
|
||||||
|
Author: Fabrice
|
||||||
|
Category: Tips
|
||||||
|
Tags: presentation, vim, latex
|
||||||
|
Slug: presenting
|
||||||
|
Header_Cover: ../images/covers/pts24-talk.jpg
|
||||||
|
Summary: Some of the tools I use for making and giving presentations.
|
||||||
|
lang: en
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Over the past year, I have to give quite a few presentations in different
|
||||||
|
contexts: internal to the company, for open-source conferences, for business
|
||||||
|
conferences…
|
||||||
|
|
||||||
|
I used these different opportunities to refine a bit my presentation tools, and
|
||||||
|
I just summarize them here for curious people. Please note that this blog post
|
||||||
|
will only cover the tooling needed to produce slides, not what to put inside.
|
||||||
|
|
||||||
|
This page may be updated, for instance if I start using yet another tool for
|
||||||
|
slide making that I think is worth mentioning. If you have subscribed to this
|
||||||
|
blog’s [RSS feed], you will be notified of future updates.
|
||||||
|
|
||||||
|
# Making Slides
|
||||||
|
|
||||||
|
For slide making, I prefer using tools that separate the content from the actual
|
||||||
|
design. I’m thus not using fancy WYSIWYG tools for that. If you are not
|
||||||
|
interested in that, you can already skip to the [presenting slides] section.
|
||||||
|
|
||||||
|
## LaTeX Beamer
|
||||||
|
|
||||||
|
As explained in the [typst article], I’m mostly using [LaTeX] to produce/typeset
|
||||||
|
documents, and presentations are not an exception. For this purpose I’m using
|
||||||
|
[beamer].
|
||||||
|
|
||||||
|
For this purpose, my [vim setup for LaTeX] proved to be pretty useful,
|
||||||
|
especially with the “compilation on save” feature. It allows me to have an
|
||||||
|
already set up text editor for LaTeX without having to fiddle and twiddle with
|
||||||
|
multiple setups. However, the backward search is not very accurate with beamer
|
||||||
|
slides.
|
||||||
|
|
||||||
|
### Overlays and Graphics
|
||||||
|
|
||||||
|
The main advantage, besides my familiarity with [LaTeX], lays in the [overlay]
|
||||||
|
system in beamer, that is quite powerful and provides a very precise way to
|
||||||
|
display elements. This overlay mechanism also compounds well with [TikZ] to
|
||||||
|
design animated graphics.
|
||||||
|
|
||||||
|
For instance in the example below, I can show the top part of the graph
|
||||||
|
initially, then the bottom, and change the name of the last node for the second
|
||||||
|
slide. That can be easily adjusted to have more steps in the process.
|
||||||
|
|
||||||
|
```latex
|
||||||
|
…
|
||||||
|
\usetikzlibrary{positioning}
|
||||||
|
…
|
||||||
|
\begin{tikzpicture}
|
||||||
|
\tikzstyle{node} = [draw, rectangle, fill=blue!40, minimum height=2em]
|
||||||
|
\tikzstyle{arrow} = [->, >=stealth, very thick]
|
||||||
|
\node[node] (start) {Data};
|
||||||
|
\node[node, right=1cm of start] (a1) {Enc($\cdot$)};
|
||||||
|
\node<2->[node, below=5mm of a1] (a2) {Sig($\cdot$)};
|
||||||
|
\node<1>[node, right=1cm of a1] (stop) {Encrypted Data};
|
||||||
|
\node<2->[node, right=1cm of a1] (stop) {Encrypted and Signed Data};
|
||||||
|
|
||||||
|
\draw[arrow] (start) -- (a1);
|
||||||
|
\draw<2->[arrow] (start) -- (a2);
|
||||||
|
\draw[arrow] (a1) -- (stop);
|
||||||
|
\draw<2->[arrow] (a2) -- (stop);
|
||||||
|
\end{tikzpicture}
|
||||||
|
```
|
||||||
|
|
||||||
|
Resulting in:
|
||||||
|
|
||||||
|
{width=66%}
|
||||||
|
|
||||||
|
Moreover, you have access to the whole latex ecosystem, especially those for
|
||||||
|
neat illustrations such as [tikzpingus].
|
||||||
|
|
||||||
|
**Note:** I feel compelled to say that the above technique is unsafe under fairly
|
||||||
|
reasonable assumptions. Long story short you should sign first *then* encrypt
|
||||||
|
and not do both in parallel. Please see [this paper](https://ia.cr/2001/045)
|
||||||
|
from the Crypto 2001 conference if you want a more detailed explanation.
|
||||||
|
|
||||||
|
### Customisation
|
||||||
|
|
||||||
|
It is also quite easy to customise slides with beamer. For instance, with
|
||||||
|
[metropolis], from its
|
||||||
|
[documentation](https://ctan.tetaneutral.net/macros/latex/contrib/beamer-contrib/themes/metropolis/doc/metropolistheme.pdf),
|
||||||
|
section 8 describes where to find specific colours. As for the fonts, if you are
|
||||||
|
using xelatex/lualatex, a simple `\setmainfont` suffices to redefine it.
|
||||||
|
|
||||||
|
For instance, if I want to have the alert text in orange:
|
||||||
|
|
||||||
|
```latex
|
||||||
|
\setbeamercolor[alerted text]{fg=orange}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Drawbacks
|
||||||
|
|
||||||
|
However, LaTeX starts to slow down quickly, especially with a lot of [TikZ]
|
||||||
|
drawings… On documents, it’s not really an issue as it is possible to cache the
|
||||||
|
drawings with the `externalize` tikz library. However, when mixing overlays and
|
||||||
|
TikZ, it starts to [need some
|
||||||
|
tweaks](https://tex.stackexchange.com/questions/78955/use-tikz-external-feature-with-beamer-only).
|
||||||
|
I never included them in my workflow as they make TikZ drawings more complicated
|
||||||
|
than they are.
|
||||||
|
|
||||||
|
## Typst Touying
|
||||||
|
|
||||||
|
## Pandoc and reveal.js
|
||||||
|
|
||||||
|
[reveal.js] is a javascript framework to produce clean and dynamic slides. My
|
||||||
|
settings to generate them are liberally inspired by [Pablo
|
||||||
|
Coves](https://pcoves.gitlab.io/blog/pandoc-markdown-revealjs/).
|
||||||
|
|
||||||
|
[Pandoc] on the other hand is a document converter tool that supports a very
|
||||||
|
extensive spectrum of formats and syntaxes. My most use case is to convert
|
||||||
|
markdown to some other reflowable format (usually HTML, and sometimes EPUB).
|
||||||
|
|
||||||
|
Using both in conjunction allows for quick and dynamic presentations which don’t
|
||||||
|
require _accuracy_ in placements. That may be the case for lightning talks for
|
||||||
|
instance. The main advantage compared to the two above solutions is that
|
||||||
|
[reveal.js] takes advantage of web browser capabilities to produce dynamic
|
||||||
|
transitions. Those are otherwise hard to get from PDFs (some people made custom
|
||||||
|
PDF reader for that).
|
||||||
|
|
||||||
|
I know that it’s also possible to use [pandoc] to produce directly [beamer] slides
|
||||||
|
for instance, thus benefiting from the simpler [Markdown] syntax while having
|
||||||
|
[LaTeX] as an engine. I however find this approach too rigid. It is indeed easy
|
||||||
|
to feed some LaTeX‑specific commands via the YAML header, e.g., for styling.
|
||||||
|
Unfortunately, when the need arises to do some specific positioning on a slide
|
||||||
|
for example, then we end up with some markdown-TeX mix that I found deeply
|
||||||
|
inelegant. That’s why I usually stick to LaTeX (or more recently [typst]) to
|
||||||
|
produce PDFs, as these tools are designed with an awareness of the page layout
|
||||||
|
(which blends well into the language). This property is not the case with
|
||||||
|
[Markdown], which is a markup language for text formatting (not typesetting).
|
||||||
|
|
||||||
|
### Ease of use
|
||||||
|
|
||||||
|
One nice thing about [pandoc] + [reveal.js] slide making is that, for simple
|
||||||
|
intends and purpose, there are very little structural codes (contrary to
|
||||||
|
[beamer] for instance where you have to define several variables before
|
||||||
|
starting).
|
||||||
|
|
||||||
|
From the following code, you can start making a presentation:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: Example Presentation
|
||||||
|
subtitle: It’s all about presenting
|
||||||
|
author: Fabrice Mouhartem
|
||||||
|
date: 2025-01-29
|
||||||
|
theme: solarized
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pandoc --standalone -t revealjs -o output.html input.md
|
||||||
|
```
|
||||||
|
|
||||||
|
And that’s all… well, it’s just a title slide and an empty slide, but it’s the
|
||||||
|
beginning of a **wonderful** presentation.
|
||||||
|
|
||||||
|
Then, similarly to [typst] + [touying], a level 1 heading creates a title slide,
|
||||||
|
and a level 2 heading spawns a new content slide. You can also spawn a new slide
|
||||||
|
with three hyphens (`---`).
|
||||||
|
|
||||||
|
### Speaker view
|
||||||
|
|
||||||
|
One of the advantage of [reveal.js] is the built-in [speaker view]. It spans a
|
||||||
|
pop-up with useful pieces of information for the speaker: a chronometer, a preview of the
|
||||||
|
upcoming slide and notes if there are any.
|
||||||
|
|
||||||
|
Its behaviour is similar to what you can have with `pdfpc` that I’ll show later
|
||||||
|
for PDF slides.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Customisation
|
||||||
|
|
||||||
|
- List of default [reveal.js styles]
|
||||||
|
- Simple customisation with CSS:
|
||||||
|
<https://gist.github.com/jsoma/629b9564af5b1e7fa62d0a3a0a47c296#styling> see
|
||||||
|
<https://github.com/hakimel/reveal.js/blob/master/css/theme/template/exposer.scss>
|
||||||
|
as well for exposed variables.
|
||||||
|
- However, in standalone mode, changing the font does not work well…
|
||||||
|
- Create custom theme: <https://github.com/hakimel/reveal.js/blob/master/css/theme/README.md>
|
||||||
|
- <https://github.com/Chouhartem/reveal.js/tree/cryptpad-theme>
|
||||||
|
|
||||||
|
# Presenting Slides {#presenting-slides}
|
||||||
|
|
||||||
|
## wl-mirror
|
||||||
|
|
||||||
|
## pdfpc
|
||||||
|
|
||||||
|
[RSS feed]: /feeds/all.rss.xml
|
||||||
|
[typst]: https://typst.app/
|
||||||
|
[touying]: https://touying-typ.github.io/
|
||||||
|
[typst article]: {filename}../software/typst.md
|
||||||
|
[presenting slides]: #presenting-slides
|
||||||
|
[LaTeX]: https://www.latex-project.org/
|
||||||
|
[beamer]: https://ctan.org/pkg/beamer
|
||||||
|
[vim setup for LaTeX]: {filename}../software/nvim-latex.md
|
||||||
|
[overlay]: https://www.overleaf.com/learn/latex/Beamer_Presentations%3A_A_Tutorial_for_Beginners_(Part_4)%E2%80%94Overlay_Specifications
|
||||||
|
[TikZ]: https://www.ctan.org/pkg/pgf
|
||||||
|
[tikzpingus]: https://github.com/EagleoutIce/tikzpingus
|
||||||
|
[reveal.js]: https://revealjs.com/
|
||||||
|
[reveal.js styles]: https://revealjs.com/themes/
|
||||||
|
[pandoc]: https://pandoc.org/
|
||||||
|
[metropolis]: https://github.com/matze/mtheme
|
||||||
|
[markdown]: https://en.wikipedia.org/wiki/Markdown
|
||||||
|
[speaker view]: https://revealjs.com/speaker-view/
|
@ -32,7 +32,7 @@ TIMEZONE = 'Europe/Paris'
|
|||||||
|
|
||||||
#LANG
|
#LANG
|
||||||
DEFAULT_LANG = 'en'
|
DEFAULT_LANG = 'en'
|
||||||
LOCALE = 'en_GB.UTF-8'
|
LOCALE = 'en_GB.utf8'
|
||||||
DEFAULT_DATE_FORMAT = '%A, %B %d, %Y'
|
DEFAULT_DATE_FORMAT = '%A, %B %d, %Y'
|
||||||
I18N_SUBSITES = {
|
I18N_SUBSITES = {
|
||||||
'fr': {
|
'fr': {
|
||||||
|
1
plugins/autopages
Submodule
1
plugins/i18n_subsites
Submodule
16
pyproject.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[project]
|
||||||
|
authors = [
|
||||||
|
{name = "Fabrice Mouhartem", email = "chouhartem@epheme.re"},
|
||||||
|
]
|
||||||
|
license = {text = "CC-by-SA"}
|
||||||
|
requires-python = "<4.0,>=3.12"
|
||||||
|
dependencies = [
|
||||||
|
"pelican<5.0.0,>=4.10.1",
|
||||||
|
"markdown<4.0,>=3.7",
|
||||||
|
"invoke<3.0.0,>=2.2.0",
|
||||||
|
"livereload<3.0.0,>=2.7.0",
|
||||||
|
]
|
||||||
|
name = "blog"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Personal blog (blog.epheme.re)"
|
||||||
|
readme = "README.md"
|
51
readme.md
@ -1 +1,52 @@
|
|||||||
|
This repository contains the sources necessary to build the blog at:
|
||||||
<https://blog.epheme.re>
|
<https://blog.epheme.re>
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
To use this repository as intended, you need, to build the blog, the following
|
||||||
|
software:
|
||||||
|
|
||||||
|
- `git`
|
||||||
|
- `make`
|
||||||
|
- `uv`
|
||||||
|
- `gettext`
|
||||||
|
|
||||||
|
To synchronise the blog remotely with its intended target, the synchronisation
|
||||||
|
is done using `rsync` over `ssh`.
|
||||||
|
|
||||||
|
# Install
|
||||||
|
|
||||||
|
To install a local copy to work on this blog, you also need other components,
|
||||||
|
such as the [theme](https://git.epheme.re/fmouhart/pelican-clean-blog) and
|
||||||
|
[some](https://git.epheme.re/fmouhart/pelican-autopages)
|
||||||
|
[plugins](https://git.epheme.re/fmouhart/pelican-clean-blog). Those are embedded
|
||||||
|
in the repository as a git submodule. You can thus simply run git clone with the
|
||||||
|
`--recurse-submodule` option:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone --recurse-submodule https://git.epheme.re/fmouhart/blog.git fmouhart-blog
|
||||||
|
```
|
||||||
|
|
||||||
|
This blog relies on [pelican](https://getpelican.com) as a static site
|
||||||
|
generator. To manage the different python dependencies of this project, we are
|
||||||
|
using [`uv`](https://github.com/astral-sh/uv) as a python project manager.
|
||||||
|
|
||||||
|
Moreover, translations are managed with python `gettext` which requires
|
||||||
|
compiling the translation file.
|
||||||
|
|
||||||
|
Those two steps are performed with the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make init
|
||||||
|
```
|
||||||
|
|
||||||
|
# Development
|
||||||
|
|
||||||
|
When writing an article, you can run the blog with `livereload` enabled with the
|
||||||
|
command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make dev
|
||||||
|
```
|
||||||
|
|
||||||
|
It’ll span a local development server on port `8000`: <http://localhost:8000>
|
||||||
|
150
tasks.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
import os
|
||||||
|
import shlex
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from invoke import task
|
||||||
|
from invoke.main import program
|
||||||
|
from pelican import main as pelican_main
|
||||||
|
from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer
|
||||||
|
from pelican.settings import DEFAULT_CONFIG, get_settings_from_file
|
||||||
|
|
||||||
|
OPEN_BROWSER_ON_SERVE = False
|
||||||
|
SETTINGS_FILE_BASE = "pelicanconf.py"
|
||||||
|
SETTINGS = {}
|
||||||
|
SETTINGS.update(DEFAULT_CONFIG)
|
||||||
|
LOCAL_SETTINGS = get_settings_from_file(SETTINGS_FILE_BASE)
|
||||||
|
SETTINGS.update(LOCAL_SETTINGS)
|
||||||
|
|
||||||
|
CONFIG = {
|
||||||
|
"settings_base": SETTINGS_FILE_BASE,
|
||||||
|
"settings_publish": "publishconf.py",
|
||||||
|
# Output path. Can be absolute or relative to tasks.py. Default: 'output'
|
||||||
|
"deploy_path": SETTINGS["OUTPUT_PATH"],
|
||||||
|
# Host and port for `serve`
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 8000,
|
||||||
|
# for publication
|
||||||
|
"ssh_user": "fmouhart",
|
||||||
|
"ssh_host": "blog.epheme.re",
|
||||||
|
"ssh_port": 22,
|
||||||
|
"ssh_path": "/srv/http/blog",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def clean(c):
|
||||||
|
"""Remove generated files"""
|
||||||
|
if os.path.isdir(CONFIG["deploy_path"]):
|
||||||
|
shutil.rmtree(CONFIG["deploy_path"])
|
||||||
|
os.makedirs(CONFIG["deploy_path"])
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def build(c):
|
||||||
|
"""Build local version of site"""
|
||||||
|
pelican_run("-s {settings_base}".format(**CONFIG))
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def rebuild(c):
|
||||||
|
"""`build` with the delete switch"""
|
||||||
|
pelican_run("-d -s {settings_base}".format(**CONFIG))
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def regenerate(c):
|
||||||
|
"""Automatically regenerate site upon file modification"""
|
||||||
|
pelican_run("-r -s {settings_base}".format(**CONFIG))
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def serve(c):
|
||||||
|
"""Serve site at http://$HOST:$PORT/ (default is localhost:8000)"""
|
||||||
|
|
||||||
|
class AddressReuseTCPServer(RootedHTTPServer):
|
||||||
|
allow_reuse_address = True
|
||||||
|
|
||||||
|
server = AddressReuseTCPServer(
|
||||||
|
CONFIG["deploy_path"],
|
||||||
|
(CONFIG["host"], CONFIG["port"]),
|
||||||
|
ComplexHTTPRequestHandler,
|
||||||
|
)
|
||||||
|
|
||||||
|
if OPEN_BROWSER_ON_SERVE:
|
||||||
|
# Open site in default browser
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
|
webbrowser.open("http://{host}:{port}".format(**CONFIG))
|
||||||
|
|
||||||
|
sys.stderr.write("Serving at {host}:{port} ...\n".format(**CONFIG))
|
||||||
|
server.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def reserve(c):
|
||||||
|
"""`build`, then `serve`"""
|
||||||
|
build(c)
|
||||||
|
serve(c)
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def preview(c):
|
||||||
|
"""Build production version of site"""
|
||||||
|
pelican_run("-s {settings_publish}".format(**CONFIG))
|
||||||
|
|
||||||
|
@task
|
||||||
|
def livereload(c):
|
||||||
|
"""Automatically reload browser tab upon file modification."""
|
||||||
|
from livereload import Server
|
||||||
|
|
||||||
|
def cached_build():
|
||||||
|
cmd = "-s {settings_base} -e CACHE_CONTENT=true LOAD_CONTENT_CACHE=true"
|
||||||
|
pelican_run(cmd.format(**CONFIG))
|
||||||
|
|
||||||
|
cached_build()
|
||||||
|
server = Server()
|
||||||
|
theme_path = SETTINGS["THEME"]
|
||||||
|
watched_globs = [
|
||||||
|
CONFIG["settings_base"],
|
||||||
|
f"{theme_path}/templates/**/*.html",
|
||||||
|
]
|
||||||
|
|
||||||
|
content_file_extensions = [".md", ".rst"]
|
||||||
|
for extension in content_file_extensions:
|
||||||
|
content_glob = "{}/**/*{}".format(SETTINGS["PATH"], extension)
|
||||||
|
watched_globs.append(content_glob)
|
||||||
|
|
||||||
|
static_file_extensions = [".css", ".js"]
|
||||||
|
for extension in static_file_extensions:
|
||||||
|
static_file_glob = f"{theme_path}/static/**/*{extension}"
|
||||||
|
watched_globs.append(static_file_glob)
|
||||||
|
|
||||||
|
for glob in watched_globs:
|
||||||
|
server.watch(glob, cached_build)
|
||||||
|
|
||||||
|
if OPEN_BROWSER_ON_SERVE:
|
||||||
|
# Open site in default browser
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
|
webbrowser.open("http://{host}:{port}".format(**CONFIG))
|
||||||
|
|
||||||
|
server.serve(host=CONFIG["host"], port=CONFIG["port"], root=CONFIG["deploy_path"])
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def publish(c):
|
||||||
|
"""Publish to production via rsync"""
|
||||||
|
pelican_run("-s {settings_publish}".format(**CONFIG))
|
||||||
|
c.run(
|
||||||
|
'rsync --delete --exclude ".DS_Store" -rv -c '
|
||||||
|
'-e "ssh -p {ssh_port}" '
|
||||||
|
"{} {ssh_user}@{ssh_host}:{ssh_path}".format(
|
||||||
|
CONFIG["deploy_path"].rstrip("/") + "/", **CONFIG
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def pelican_run(cmd):
|
||||||
|
cmd += " " + program.core.remainder # allows to pass-through args to pelican
|
||||||
|
pelican_main(shlex.split(cmd))
|
348
uv.lock
generated
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
version = 1
|
||||||
|
requires-python = ">=3.12, <4.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyio"
|
||||||
|
version = "4.8.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "idna" },
|
||||||
|
{ name = "sniffio" },
|
||||||
|
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blinker"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blog"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = { virtual = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "invoke" },
|
||||||
|
{ name = "livereload" },
|
||||||
|
{ name = "markdown" },
|
||||||
|
{ name = "pelican" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "invoke", specifier = ">=2.2.0,<3.0.0" },
|
||||||
|
{ name = "livereload", specifier = ">=2.7.0,<3.0.0" },
|
||||||
|
{ name = "markdown", specifier = ">=3.7,<4.0" },
|
||||||
|
{ name = "pelican", specifier = ">=4.10.1,<5.0.0" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "docutils"
|
||||||
|
version = "0.21.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "feedgenerator"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "pytz" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/5e/4e/0efde53652edbae3f86c0ec67260bb53287edc67033ac8d00fe08cd02557/feedgenerator-2.1.0.tar.gz", hash = "sha256:f075f23f28fd227f097c36b212161c6cf012e1c6caaf7ff53d5d6bb02cd42b9d", size = 20682 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/a1/b7b1711d9bf43c3795366431633ab6ba6942744243aad809272ebfa59b39/feedgenerator-2.1.0-py3-none-any.whl", hash = "sha256:93b7ce1c5a86195cafd6a8e9baf6a2a863ebd6d9905e840ce5778f73efd9a8d5", size = 21796 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "3.10"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "invoke"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/f9/42/127e6d792884ab860defc3f4d80a8f9812e48ace584ffc5a346de58cdc6c/invoke-2.2.0.tar.gz", hash = "sha256:ee6cbb101af1a859c7fe84f2a264c059020b0cb7fe3535f9424300ab568f6bd5", size = 299835 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0a/66/7f8c48009c72d73bc6bbe6eb87ac838d6a526146f7dab14af671121eb379/invoke-2.2.0-py3-none-any.whl", hash = "sha256:6ea924cc53d4f78e3d98bc436b08069a03077e6f85ad1ddaa8a116d7dad15820", size = 160274 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jinja2"
|
||||||
|
version = "3.1.5"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "markupsafe" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "livereload"
|
||||||
|
version = "2.7.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "tornado" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/43/6e/f2748665839812a9bbe5c75d3f983edbf3ab05fa5cd2f7c2f36fffdf65bd/livereload-2.7.1.tar.gz", hash = "sha256:3d9bf7c05673df06e32bea23b494b8d36ca6d10f7d5c3c8a6989608c09c986a9", size = 22255 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e4/3e/de54dc7f199e85e6ca37e2e5dae2ec3bce2151e9e28f8eb9076d71e83d56/livereload-2.7.1-py3-none-any.whl", hash = "sha256:5201740078c1b9433f4b2ba22cd2729a39b9d0ec0a2cc6b4d3df257df5ad0564", size = 22657 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markdown"
|
||||||
|
version = "3.7"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markdown-it-py"
|
||||||
|
version = "3.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "mdurl" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markupsafe"
|
||||||
|
version = "3.0.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mdurl"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-set"
|
||||||
|
version = "4.1.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/4c/ca/bfac8bc689799bcca4157e0e0ced07e70ce125193fc2e166d2e685b7e2fe/ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8", size = 12826 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/33/55/af02708f230eb77084a299d7b08175cff006dea4f2721074b92cdb0296c0/ordered_set-4.1.0-py3-none-any.whl", hash = "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562", size = 7634 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pelican"
|
||||||
|
version = "4.11.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "blinker" },
|
||||||
|
{ name = "docutils" },
|
||||||
|
{ name = "feedgenerator" },
|
||||||
|
{ name = "jinja2" },
|
||||||
|
{ name = "ordered-set" },
|
||||||
|
{ name = "pygments" },
|
||||||
|
{ name = "python-dateutil" },
|
||||||
|
{ name = "rich" },
|
||||||
|
{ name = "tzdata", marker = "sys_platform == 'win32'" },
|
||||||
|
{ name = "unidecode" },
|
||||||
|
{ name = "watchfiles" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/27/42/c06c1a7a3136729ece5a1f98544ede83edd593b3cd9110c9ad61bcc7f4dd/pelican-4.11.0.tar.gz", hash = "sha256:b90234487b818d391733acc1306b785934009749b1fc112b879df9bd89478bd8", size = 24148058 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/79/32/01df483f255438e792771b11ebe804af15957739e88673ca95c89289c0f4/pelican-4.11.0-py3-none-any.whl", hash = "sha256:aca6993f6b8a03a20f6828471089cb0504a4dca71e0d30b341fa80ab65668fa4", size = 24127868 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pygments"
|
||||||
|
version = "2.18.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dateutil"
|
||||||
|
version = "2.9.0.post0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "six" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytz"
|
||||||
|
version = "2024.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rich"
|
||||||
|
version = "13.9.4"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "markdown-it-py" },
|
||||||
|
{ name = "pygments" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "six"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sniffio"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tornado"
|
||||||
|
version = "6.4.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/59/45/a0daf161f7d6f36c3ea5fc0c2de619746cc3dd4c76402e9db545bd920f63/tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b", size = 501135 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/26/7e/71f604d8cea1b58f82ba3590290b66da1e72d840aeb37e0d5f7291bd30db/tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1", size = 436299 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/96/44/87543a3b99016d0bf54fdaab30d24bf0af2e848f1d13d34a3a5380aabe16/tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803", size = 434253 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cb/fb/fdf679b4ce51bcb7210801ef4f11fdac96e9885daa402861751353beea6e/tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec", size = 437602 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/3b/e31aeffffc22b475a64dbeb273026a21b5b566f74dee48742817626c47dc/tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946", size = 436972 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/22/55/b78a464de78051a30599ceb6983b01d8f732e6f69bf37b4ed07f642ac0fc/tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf", size = 437173 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/79/5e/be4fb0d1684eb822c9a62fb18a3e44a06188f78aa466b2ad991d2ee31104/tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634", size = 437892 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f5/33/4f91fdd94ea36e1d796147003b490fe60a0215ac5737b6f9c65e160d4fe0/tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73", size = 437334 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/ae/c1b22d4524b0e10da2f29a176fb2890386f7bd1f63aacf186444873a88a0/tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c", size = 437261 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/25/36dbd49ab6d179bcfc4c6c093a51795a4f3bed380543a8242ac3517a1751/tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482", size = 438463 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/61/cc/58b1adeb1bb46228442081e746fcdbc4540905c87e8add7c277540934edb/tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38", size = 438907 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "4.12.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tzdata"
|
||||||
|
version = "2025.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unidecode"
|
||||||
|
version = "1.3.8"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/f7/89/19151076a006b9ac0dd37b1354e031f5297891ee507eb624755e58e10d3e/Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4", size = 192701 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/84/b7/6ec57841fb67c98f52fc8e4a2d96df60059637cba077edc569a302a8ffc7/Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39", size = 235494 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "watchfiles"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "anyio" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/f5/26/c705fc77d0a9ecdb9b66f1e2976d95b81df3cae518967431e7dbf9b5e219/watchfiles-1.0.4.tar.gz", hash = "sha256:6ba473efd11062d73e4f00c2b730255f9c1bdd73cd5f9fe5b5da8dbd4a717205", size = 94625 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5b/1a/8f4d9a1461709756ace48c98f07772bc6d4519b1e48b5fa24a4061216256/watchfiles-1.0.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:229e6ec880eca20e0ba2f7e2249c85bae1999d330161f45c78d160832e026ee2", size = 391345 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bc/d2/6750b7b3527b1cdaa33731438432e7238a6c6c40a9924049e4cebfa40805/watchfiles-1.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5717021b199e8353782dce03bd8a8f64438832b84e2885c4a645f9723bf656d9", size = 381515 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4e/17/80500e42363deef1e4b4818729ed939aaddc56f82f4e72b2508729dd3c6b/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0799ae68dfa95136dde7c472525700bd48777875a4abb2ee454e3ab18e9fc712", size = 449767 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/10/37/1427fa4cfa09adbe04b1e97bced19a29a3462cc64c78630787b613a23f18/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:43b168bba889886b62edb0397cab5b6490ffb656ee2fcb22dec8bfeb371a9e12", size = 455677 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c5/7a/39e9397f3a19cb549a7d380412fd9e507d4854eddc0700bfad10ef6d4dba/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb2c46e275fbb9f0c92e7654b231543c7bbfa1df07cdc4b99fa73bedfde5c844", size = 482219 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/45/2d/7113931a77e2ea4436cad0c1690c09a40a7f31d366f79c6f0a5bc7a4f6d5/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:857f5fc3aa027ff5e57047da93f96e908a35fe602d24f5e5d8ce64bf1f2fc733", size = 518830 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f9/1b/50733b1980fa81ef3c70388a546481ae5fa4c2080040100cd7bf3bf7b321/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55ccfd27c497b228581e2838d4386301227fc0cb47f5a12923ec2fe4f97b95af", size = 497997 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/b4/9396cc61b948ef18943e7c85ecfa64cf940c88977d882da57147f62b34b1/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c11ea22304d17d4385067588123658e9f23159225a27b983f343fcffc3e796a", size = 452249 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fb/69/0c65a5a29e057ad0dc691c2fa6c23b2983c7dabaa190ba553b29ac84c3cc/watchfiles-1.0.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:74cb3ca19a740be4caa18f238298b9d472c850f7b2ed89f396c00a4c97e2d9ff", size = 614412 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7f/b9/319fcba6eba5fad34327d7ce16a6b163b39741016b1996f4a3c96b8dd0e1/watchfiles-1.0.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7cce76c138a91e720d1df54014a047e680b652336e1b73b8e3ff3158e05061e", size = 611982 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f1/47/143c92418e30cb9348a4387bfa149c8e0e404a7c5b0585d46d2f7031b4b9/watchfiles-1.0.4-cp312-cp312-win32.whl", hash = "sha256:b045c800d55bc7e2cadd47f45a97c7b29f70f08a7c2fa13241905010a5493f94", size = 271822 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ea/94/b0165481bff99a64b29e46e07ac2e0df9f7a957ef13bec4ceab8515f44e3/watchfiles-1.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:c2acfa49dd0ad0bf2a9c0bb9a985af02e89345a7189be1efc6baa085e0f72d7c", size = 285441 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/11/de/09fe56317d582742d7ca8c2ca7b52a85927ebb50678d9b0fa8194658f536/watchfiles-1.0.4-cp312-cp312-win_arm64.whl", hash = "sha256:22bb55a7c9e564e763ea06c7acea24fc5d2ee5dfc5dafc5cfbedfe58505e9f90", size = 277141 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/08/98/f03efabec64b5b1fa58c0daab25c68ef815b0f320e54adcacd0d6847c339/watchfiles-1.0.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:8012bd820c380c3d3db8435e8cf7592260257b378b649154a7948a663b5f84e9", size = 390954 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/16/09/4dd49ba0a32a45813debe5fb3897955541351ee8142f586303b271a02b40/watchfiles-1.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa216f87594f951c17511efe5912808dfcc4befa464ab17c98d387830ce07b60", size = 381133 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/76/59/5aa6fc93553cd8d8ee75c6247763d77c02631aed21551a97d94998bf1dae/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c9953cf85529c05b24705639ffa390f78c26449e15ec34d5339e8108c7c407", size = 449516 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4c/aa/df4b6fe14b6317290b91335b23c96b488d365d65549587434817e06895ea/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7cf684aa9bba4cd95ecb62c822a56de54e3ae0598c1a7f2065d51e24637a3c5d", size = 454820 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5e/71/185f8672f1094ce48af33252c73e39b48be93b761273872d9312087245f6/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f44a39aee3cbb9b825285ff979ab887a25c5d336e5ec3574f1506a4671556a8d", size = 481550 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/85/d7/50ebba2c426ef1a5cb17f02158222911a2e005d401caf5d911bfca58f4c4/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38320582736922be8c865d46520c043bff350956dfc9fbaee3b2df4e1740a4b", size = 518647 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f0/7a/4c009342e393c545d68987e8010b937f72f47937731225b2b29b7231428f/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39f4914548b818540ef21fd22447a63e7be6e24b43a70f7642d21f1e73371590", size = 497547 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0f/7c/1cf50b35412d5c72d63b2bf9a4fffee2e1549a245924960dd087eb6a6de4/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f12969a3765909cf5dc1e50b2436eb2c0e676a3c75773ab8cc3aa6175c16e902", size = 452179 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/a9/3db1410e1c1413735a9a472380e4f431ad9a9e81711cda2aaf02b7f62693/watchfiles-1.0.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:0986902677a1a5e6212d0c49b319aad9cc48da4bd967f86a11bde96ad9676ca1", size = 614125 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f2/e1/0025d365cf6248c4d1ee4c3d2e3d373bdd3f6aff78ba4298f97b4fad2740/watchfiles-1.0.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:308ac265c56f936636e3b0e3f59e059a40003c655228c131e1ad439957592303", size = 611911 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/55/55/035838277d8c98fc8c917ac9beeb0cd6c59d675dc2421df5f9fcf44a0070/watchfiles-1.0.4-cp313-cp313-win32.whl", hash = "sha256:aee397456a29b492c20fda2d8961e1ffb266223625346ace14e4b6d861ba9c80", size = 271152 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f0/e5/96b8e55271685ddbadc50ce8bc53aa2dff278fb7ac4c2e473df890def2dc/watchfiles-1.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:d6097538b0ae5c1b88c3b55afa245a66793a8fec7ada6755322e465fb1a0e8cc", size = 285216 },
|
||||||
|
]
|