#! /usr/bin/env python3 import os import subprocess import rwx.io def run(*args): subprocess.call(args) def main(): style = 'css' script = 'js' root = os.path.dirname(os.path.realpath(__file__)) input_directory = os.path.join(root, 'in') out = os.path.join(root, 'out') web = os.path.join(out, 'web') css = os.path.join(web, style) js = os.path.join(web, script) # run('rsync', '--archive', f'{input_directory}/', f'{web}/') for directory in [css, js]: os.makedirs(directory, exist_ok=True) # link_gv = os.path.join(root, 'link.gv') link_svg = os.path.join(web, 'link.svg') run('dot', link_gv, '-Tsvg', '-o', link_svg) with open(link_svg, 'br') as f: link_text = f.read().decode('u8') page_file = os.path.join(web, 'index.html') page_text = f'''\ Marc Beninca

Marc Beninca

Dark
{tabs['bio']}
{tabs['cv']}
{tabs['git']}
{tabs['id']}
{tabs['links']}
{tabs['thesis']}
{tabs['unsorted']}
{tabs['learn']}
{tabs['mirrors']}
{tabs['music']}
{tabs['health']}
{tabs['vegan']}
''' css_file = os.path.join(css, 'index.css') css_text = f'''\ /* * {{ border: 1px solid; }} /**/ @media screen and (max-aspect-ratio: 10/16) {{ body {{ font-size: 2em; }} }} body {{ background: rgb(255,255,255); color: rgb(0,0,0); font-family: sans; margin: .5em; }} body.dark {{ background: rgb(0,0,0); color: rgb(160,160,160); }} header {{ background-image: url("../img/debian.jpeg"); background-position: center; background-size: cover; display: flex; flex-wrap: wrap; }} .tabs {{ display: flex; flex-wrap: wrap; }} .tabs > input {{ display: none; }} .tabs > input:checked + label + div {{ display: block; }} .tabs > label {{ order: 1; }} .tabs > div {{ display: none; flex-basis: 100%; order: 2; }} .tabs {{ margin: 0; }} .tabs > input:checked + label {{ background: linear-gradient(rgba(128,128,128,1), rgba(128,128,128,0)); }} .tabs > label {{ background: linear-gradient(rgba(64,64,64,1), rgba(64,64,64,0)); border-color: rgb(128,128,128); border-radius: .5em; border-style: solid; border-width: 1px 1px 0 1px; font-weight: bold; margin: 0; padding: .5em 1.5em; }} .tabs > label:hover {{ background: linear-gradient(rgba(64,64,64,0), rgba(64,64,64,1)); color: rgb(192,0,0); }} .tabs > div {{ margin: 0 padding: 1em 0 0 0; }} a {{ color: rgb(0,192,192); text-decoration: none; }} a:hover {{ color: rgb(192,0,0); }} a:visited {{ color: rgb(0,160,160); }} img {{ border: 1px solid; border-color: rgb(192,192,192); border-radius: 1em; height: 8em; }} table {{ empty-cells: hide; }} th,td {{ border-radius: .2em; }} th:hover,td:hover {{ background: rgb(48,0,0); }} th {{ background: rgb(64,64,64); color: rgb(128,128,0); }} td {{ background: rgb(48,48,48); border: 1px solid; border-color: rgb(192,192,192); text-align: center; }} .cards {{ display: flex; }} .card {{ list-style: none; margin: 0 1em; text-align: center; }} .card img {{ border: none; height: 4em; }} /******************************************************************************* body {{ font-size: 1.25em; }} ''' js_file = os.path.join(js, 'index.js') js_text = f'''\ function check(tab) {{ const tabs = tab.split('/') let id = 'tab' let element for (tab of tabs) {{ id = `${{id}}/${{tab}}` element = document.getElementById(id) if (element) {{ element.checked = true }} }} }} function push(tab) {{ window.history.pushState(null, null, `?tab=${{tab}}`) }} function update(id) {{ const tab = id.split('/').slice(1).join('/') push(tab) }} function main() {{ let tab = (new URL(document.location)).searchParams.get('tab') if (tab) {{ check(tab) }} else {{ tab = 'my/bio' check(tab) push(tab) }} const dark = document.getElementById('dark') if (dark) {{ dark.click() }} }} function swap() {{ document.body.classList.toggle('dark') }} ''' # {link_text} with open(page_file, 'bw') as f: f.write(page_text.encode('u8')) with open(css_file, 'bw') as f: f.write(css_text.encode('u8')) with open(js_file, 'bw') as f: f.write(js_text.encode('u8')) tabs = { #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'bio': f'''\ ''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'cv': f'''\ ''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'git': f'''\

''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'health': f'''\
''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'id': f'''\
OpenPGP
marc.beninca.link
meta.sr.ht
keys.openpgp.org
Key
Base
Key
Oxide
Libera
Pay
Patreon Tip
eee
CC / BTC Mastodon Discord
CC / ZEC GitLab YouTube
DMOJ Pleroma FaceBook
GalacticTalk PixelFed OpenStreetMap Instagram
Reddit Twitch Vimeo
Twitter
HackerNews BitBucket
Lobsters LinuxFR
GitHub
DNS
beninca.link
computing.land
marc-beninca.fr
rwx.work
tilde.link
GitLab
Debian
FramaGit
FrogGit
GitGud
Insomnia
Gitea
42l
AFPy
Chapril
CodeBerg
DisRoot
Envs
Froggies
FSFE
GitDab
Gitea
ProjectSegfault
TildeGit
TildeVarsh
StackExchange
Meta
ServerFault
StackOverflow
TeX
Unix
''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'learn': f'''\ ''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'links': f'''\ ''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'mirrors': f'''\
''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'music': f'''\
''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'thesis': f'''\ ''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'vegan': f'''\
''', #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 'unsorted': f'''\

''', } if __name__ == '__main__': main()