commit c18aae8a6cf4a7655108a2f09ef9cd1c09df26cc Author: Thomas Forgione Date: Mon Nov 27 15:40:19 2023 +0100 Initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..622623b --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +all: + mkdir -p build && typst compile --font-path assets/fonts main.typ build/main.pdf diff --git a/assets/fonts/cmunss.ttf b/assets/fonts/cmunss.ttf new file mode 100644 index 0000000..4f904f1 Binary files /dev/null and b/assets/fonts/cmunss.ttf differ diff --git a/assets/fonts/cmunssdc.ttf b/assets/fonts/cmunssdc.ttf new file mode 100644 index 0000000..c46b443 Binary files /dev/null and b/assets/fonts/cmunssdc.ttf differ diff --git a/assets/icons/adjust.svg b/assets/icons/adjust.svg new file mode 100644 index 0000000..cfa0e38 --- /dev/null +++ b/assets/icons/adjust.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/github.svg b/assets/icons/github.svg new file mode 100644 index 0000000..37fa923 --- /dev/null +++ b/assets/icons/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/location.svg b/assets/icons/location.svg new file mode 100644 index 0000000..d93dc15 --- /dev/null +++ b/assets/icons/location.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/mail.svg b/assets/icons/mail.svg new file mode 100644 index 0000000..60ac7e4 --- /dev/null +++ b/assets/icons/mail.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/phone.svg b/assets/icons/phone.svg new file mode 100644 index 0000000..a0d6c23 --- /dev/null +++ b/assets/icons/phone.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/world.svg b/assets/icons/world.svg new file mode 100644 index 0000000..9df7ef4 --- /dev/null +++ b/assets/icons/world.svg @@ -0,0 +1 @@ + diff --git a/assets/moi.png b/assets/moi.png new file mode 100644 index 0000000..a775f9f Binary files /dev/null and b/assets/moi.png differ diff --git a/build/main.pdf b/build/main.pdf new file mode 100644 index 0000000..36149b8 Binary files /dev/null and b/build/main.pdf differ diff --git a/main.typ b/main.typ new file mode 100644 index 0000000..7008ae7 --- /dev/null +++ b/main.typ @@ -0,0 +1,171 @@ +#import "template.typ" +#show: doc => template.apply(doc) + +#v(1cm) + +#grid( + columns: (6cm, 1fr), + + [], + + [ + #v(-0.25cm) + #set text(size: 40pt, fill: white) + Thomas Forgione \ + #set text(size: 18pt, style: "italic") + Docteur en informatique et télécommunications + ], +) + + + +#v(1cm) +#set text(size: 12pt) + +#let leftcolumn = [ + + #show link: content => { + underline(content) + } + + #show heading.where(level: 1): it => { + v(0.75cm) + text(size: 16pt, weight: "bold", it.body) + v(-0.5cm) + line(length: 5cm) + } + + #v(-0.5cm) + + = Contact + + #align(left + top, [ + #grid(columns: (auto, auto), row-gutter: 0.5cm, column-gutter: 0.2cm, + [ #image("assets/icons/location.svg", height: 10pt) ], + [ 9 bd de la Gare, appt 83 \ + 31500 Toulouse France + ], + [ #image("assets/icons/phone.svg", height: 10pt) ], [ 06.71.22.05.84 ], + [ #image("assets/icons/mail.svg", height: 10pt) ], [ #link("mailto:thomas@forgione.fr")[thomas\@forgione.fr] ], + [ #image("assets/icons/world.svg", height: 10pt) ], [ #link("https://tforgione.fr")[https://tforgione.fr] ], + [ #image("assets/icons/github.svg", height: 10pt) ], [ #link("https://github.com/tforgione")[\@tforgione] ] + ) + ]) + + = Programmation + + #align(left + top, [ + #grid(columns: (2cm, auto), row-gutter: 0.5cm, column-gutter: 0.5cm, + [ Rust ], [ #template.score(level: 4) ], + [ Elm ], [ #template.score(level: 4) ], + [ JS ], [ #template.score(level: 4) ], + [ C++ ], [ #template.score(level: 3) ], + [ Python ], [ #template.score(level: 3) ], + [ Java ], [ #template.score(level: 3) ], + [ Shell ], [ #template.score(level: 4) ], + ) + ]) + + = DevOps + + #align(left + top, [ + #grid(columns: (2cm, auto), row-gutter: 0.5cm, column-gutter: 0.5cm, + [ Docker ], [ #template.score(level: 3) ], + [ Kubernetes ], [ #template.score(level: 3) ], + [ RabbitMQ ], [ #template.score(level: 2) ], + [ S3 ], [ #template.score(level: 3) ], + ) + ]) + + = Langues + + #align(left + top, [ + #grid(columns: (auto, auto), row-gutter: 0.5cm, column-gutter: 0.3cm, + [ *Français* ], [ _Langue maternelle_ ], + [ *Anglais* ], [ _Niveau C1_ ] + ) + ]) + + +] + +#leftcolumn + +#style(styles => { + let size = measure(leftcolumn, styles) + v(-size.height - 0.75cm) +}) + + +#show link: content => { + set text(fill: blue) + underline(content) +} + +#v(0.21cm) += Parcours + +#template.entry2( + left: image(height: 15pt, "./assets/icons/adjust.svg"), + heading: [*Polymny Studio*, _Toulouse_, #link("https://polymny.studio")], + description: [ Logiciel SAAS permettant la réalisation de MOOC facilement ], + note: [ + Co-fondateur, responsable R&D, développeur + - président de l'Association Polymny Studio jusqu'en Sept 2022 + - base de données unique pour deux instances : gratuite / payante + - partie gratuite auto-hébergée chez tetaneutral + - partie payante sur cluster kubernetes OVHcloud avec stockage S3 + ] +) + +#template.entry2( + left: [2019], + heading: [*Doctorat*, _Toulouse INP_, #link("https://tforgione.fr/phd/")], + description: [Doctorat en informatique et télécommunications], + note: [ + Transmission adaptative de modèles 3D massifs + - encodage de modèle 3D optimisé pour le streaming interactif + - streaming adapté au point de vue + - interface du bureau avec clavier / souris + - interface smartphone avec joystick virtuel et gyroscope + ] +) + +#template.entry2( + left: [2015], + heading: [*Diplôme d'ingénieur*, _ENSEEIHT_], + description: [_Diplôme d'ingénieur en informatique et mathématiques appliquées_], + note: [_Spécialisation en multimédia et traitement d'images_] +) + += Projets + +#template.entry2( + left: [2021], + heading: [*Ergol*, #link("https://ergol-rs.github.io")], + description: [ORM asynchrone pour Rust], + note: [ + - proc macro via annotation pour génération de code lié aux tables + - gestion des one-to-one, one-to-many, many-to-many + - création / réinitialisation de tables automatiques + - fonctions utilitaires pour SELECT, UPDATE, DELETE + - intégration avec le framework web Rocket + ] +) + +#template.entry2( + left: [2019], + heading: [*My Twitch Replays*, #link("https://twitch.tforgione.fr")], + description: [Plate-forme de vidéo à la demande serverless via HTTP], + note: [ + - encodage vidéo multi-résolution en HLS avec FFmpeg + - lecteur vidéo custom en elm avec miniatures de navigation + - selection manuelle ou automatique de la résolution via hls.js + ] +) + += Loisirs + +#template.entry(left: [Sport])[*jiujitsu brésilien depuis 2021, ceinture bleue*] +#template.entry(left: [Moto])[*permis A2 depuis 2016, permis A depuis 2018*] +#template.entry(left: [Musique])[*guitare acoustique et éléctrique depuis 2008*] diff --git a/template.typ b/template.typ new file mode 100644 index 0000000..2f70152 --- /dev/null +++ b/template.typ @@ -0,0 +1,97 @@ +#let apply(doc) = { + set page( + paper: "a4", + numbering: none, + margin: (left: 0.25cm, right: 0.25cm, top: 0.5cm, bottom: 0.5cm), + background: [ + #align(top + left, rect(width: 5.55cm, height: 100%, fill: blue.lighten(90%))) + #v(-100%) + #v(-1.3em) + #align(top, rect(width: 100%, height: 4.4cm, fill: blue)) + #v(-5cm) + #align(top + left, box(inset: (x: 0.8cm, y: 1cm), image("./assets/moi.png", height: 4cm))) + ], + ) + + set text(font: "CMU Sans Serif") + set par(leading: 0.4em) + + show heading.where(level: 1): it => { + set text(fill: blue) + grid( + gutter: 1em, + columns: (5cm, 7fr), + [], // align(horizon, [#v(3pt) #rect(width: 1cm, height: 0.33em, fill: blue)]), + [ + #it.body + #v(-0.5cm) + #line(stroke: blue, length: 100%) + ], + ) + } + + doc +} + +#let entry(body, left: content) = { + grid( + gutter: 1em, + columns: (5.5cm, 0.75fr, 7fr), + [], + align(right, left), + body, + ) + v(-4pt) +} + +#let entry2(left: content, heading: content, description: content, note: content) = { + + let content = [ + #heading \ + #set text(size: 12pt, style: "italic") + #description \ + #set text(size: 11pt, style: "normal") + #note + ] + + style(styles => { + let size = measure(content, styles) + let offset = measure(left, styles) + grid( + gutter: 1em, + columns: (5.5cm, 0.75fr, 7fr), + [], + align(center, [ + #left + #v(-0.5em) + #line(angle: 90deg, length: size.height - offset.height - 0.5em) + ]), + content + ) + v(-4pt) + + }) +} + +#let score(level: int) = { + + let elems = () + + for x in range(5) { + if level > x { + elems.push(rect(width: 0.4cm, height: 0.2cm, fill: blue)) + } else { + elems.push(rect(width: 0.4cm, height: 0.2cm, fill: blue.lighten(60%))) + } + } + + v(0.1cm) + stack( + dir: ltr, + elems.at(0), h(0.1cm), + elems.at(1), h(0.1cm), + elems.at(2), h(0.1cm), + elems.at(3), h(0.1cm), + elems.at(4), + ) +}