From f9d58cbd7cd55261c99c91c9a9a4cac42e10bf83 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 24 Jan 2026 20:18:55 -0500 Subject: [PATCH] working markdown to html --- .gitignore | 4 + Cargo.lock | 87 +++++++- Cargo.toml | 3 + rust-toolchain.toml | 2 + shell.nix | 47 ++++ src/main.rs | 36 +++- static/home.html | 377 --------------------------------- static/strings/gamedev.md | 49 +++++ static/strings/home.md | 5 + static/strings/network.md | 64 ++++++ static/strings/phobos.md | 53 +++++ static/strings/uav.md | 59 ++++++ static/strings/work-history.md | 58 +++++ static/style.css | 53 ++--- templates/home.html | 27 +++ 15 files changed, 503 insertions(+), 421 deletions(-) create mode 100644 rust-toolchain.toml create mode 100644 shell.nix delete mode 100644 static/home.html create mode 100644 static/strings/gamedev.md create mode 100644 static/strings/home.md create mode 100644 static/strings/network.md create mode 100644 static/strings/phobos.md create mode 100644 static/strings/uav.md create mode 100644 static/strings/work-history.md create mode 100644 templates/home.html diff --git a/.gitignore b/.gitignore index ea8c4bf..f99a479 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ +# Dont commit compiled binaries /target + +# For nixos direnv +.envrc \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 537a738..eac1d5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,48 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "askama" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "askama_parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -60,6 +102,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "2.10.0" @@ -309,9 +360,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -337,13 +388,19 @@ checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" [[package]] name = "quote" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "ryu" version = "1.0.22" @@ -419,9 +476,12 @@ dependencies = [ name = "site" version = "0.1.0" dependencies = [ + "askama", "axum", "markdown", "pulldown-cmark", + "serde", + "serde_json", "tokio", "tower-http", ] @@ -434,9 +494,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", "windows-sys 0.60.2", @@ -691,7 +751,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] -name = "zmij" -version = "1.0.13" +name = "winnow" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac93432f5b761b22864c774aac244fa5c0fd877678a4c37ebf6cf42208f9c9ec" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65" diff --git a/Cargo.toml b/Cargo.toml index 65c52f2..7927e07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,6 @@ markdown = "1.0.0" pulldown-cmark = "0.13.0" tokio = { version = "1.49.0", features = ["macros", "rt-multi-thread"] } tower-http = { version = "0.5", features = ["fs"] } +askama = "0.14.0" +serde_json = "1.0.149" +serde = "1.0.228" \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..292fe49 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "stable" diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..a552460 --- /dev/null +++ b/shell.nix @@ -0,0 +1,47 @@ +{ pkgs ? import {} }: + let + overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml)); + libPath = with pkgs; lib.makeLibraryPath [ + # load external libraries that you need in your rust project here + ]; +in + pkgs.mkShell rec { + nativeBuildInputs = [ pkgs.pkg-config ]; + buildInputs = with pkgs; [ + clang + # Replace llvmPackages with llvmPackages_X, where X is the latest LLVM version (at the time of writing, 16) + llvmPackages.bintools + rustup + ]; + + RUSTC_VERSION = overrides.toolchain.channel; + + # https://github.com/rust-lang/rust-bindgen#environment-variables + LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ]; + + shellHook = '' + export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin + export PATH=$PATH:''${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-x86_64-unknown-linux-gnu/bin/ + ''; + + # Add precompiled library to rustc search path + RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [ + # add libraries here (e.g. pkgs.libvmi) + ]); + + LD_LIBRARY_PATH = libPath; + + # Add glibc, clang, glib, and other headers to bindgen search path + BINDGEN_EXTRA_CLANG_ARGS = + # Includes normal include path + (builtins.map (a: ''-I"${a}/include"'') [ + # add dev libraries here (e.g. pkgs.libvmi.dev) + pkgs.glibc.dev + ]) + # Includes with special directory paths + ++ [ + ''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"'' + ''-I"${pkgs.glib.dev}/include/glib-2.0"'' + ''-I${pkgs.glib.out}/lib/glib-2.0/include/'' + ]; + } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 2fd7a15..9a320d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,38 @@ use axum::{ - routing::get, - Router, - response::Html, + Router, response::Html, routing::get }; use tower_http::services::ServeDir; +use askama::Template; +use markdown::to_html; +use std::fs; + + +// Template for home +#[derive(Template)] +#[template(path = "home.html", ext = "html")] +struct HomeTemplate { + content: String +} + #[tokio::main] async fn main() { - let site = Router::new() - .route("/", get(home)) + + let home_html = Html( + HomeTemplate { + content: to_html(&fs::read_to_string( + "static/strings/home.md" + ).expect("Couldnt read file")) + }.render().unwrap() + ); + + let site: Router = Router::new() + .route("/", get(home_html)) .nest_service("/static", ServeDir::new("static")); + + let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); println!("Running on http://127.0.0.1:3000"); axum::serve(listener, site).await.unwrap(); } - -async fn home() -> Html<&'static str> { - const HTML: &'static str = include_str!("../static/home.html"); - Html(HTML) -} diff --git a/static/home.html b/static/home.html deleted file mode 100644 index 57fe883..0000000 --- a/static/home.html +++ /dev/null @@ -1,377 +0,0 @@ - - - - - - - - - - - -
- -
-
-

Jeremy Janella

-

About me

- -
- - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/static/strings/gamedev.md b/static/strings/gamedev.md new file mode 100644 index 0000000..0ef243c --- /dev/null +++ b/static/strings/gamedev.md @@ -0,0 +1,49 @@ +I am currently developing an underground-submarine openworld multiplayer +physics inspired game. As a gamer and enjoyer of large, rich maps and +depth to gameplay, I would really like to say thats what I started out +trying to create. Instead, the story goes that I had this random idea +for terrain manipulation. Games like Minecraft and Terraria use squares +and cubes, which just feels boring in my opinion. I thought I could do +something much more visceral As a sort of tech-demo/proof of +concept I programmed a shape that could be modified by boolean geometry +operations, mainly union and subtract with a second polygon. This led to +a very interesting, but quickly boring "game" to hop around in. However, +since I could drill through and place prettymuch any shape I wanted to, +it felt like I could "fly" through the land, much like a submarine +"flies" through water.

I implemented some modularly built +vehicles with use of graphs theory and object oriented programming, and +terrain generation using cellular noise. The reason I used cellular +noise is because if you look at the lines between cells, they form a +network without dead ends. Then by applying an algorithm using a density +function on depth I am able to fine tune the width and density of the +caves without impacting their interconnectedness. By using this method +chunks can generate completely independent of their neighbor, which is +optimal.

"Multiplayer is the hardest part of game dev, maybe +release that later" I have been told by a lot of people. However, as a +hobby-server configurer and network security nerd, I thought I could +take it on. I was right, however as a network security nerd I have more +layers of firewalls than I do braincells. Every single time I have an +issue with networking, its a firewall. Once I found which ports were +blocked, yes multiplayer was easy.

The result? I could fly +drilling vehicles through terrain, pop out of the ground or into random +caves, mine materials, play hide and seek with friends, and even orbit +the planet. One of the things important to me in this game was accurate +physics: thrust, torque, gravity, mass, all the fun stuff. While I am a +physics minor, I am more importantly a heavy player of physics and +rocket science games such as Kerbal Space Program. I was able to glide +through AP physics simply because it +just part of the games world, it included everything we would +learn in the classroom. Realistic physics also added to the depth of +gameplay I was looking for.

After some formal computer +science education, I discovered new ways to more efficiently implement +many of the algorithms I had initially generated and rewrote them +...multiple times. Currently everything runs buttery smooth and +framerates are high due to efficient caching of unloaded chunks, +multithreaded chunk generation, gpu accelerated compute shaders to +modify chunk density, enhanced use of object oriented programing and +graph algorithms to build massive modular vehicles, authoritative server +networking to disable hackers, and other performance tweaks.

+So this sounds amazing, where's the game? Well, a game needs graphics, audio, +a sound track. As much as I'd love to release it now, its unplayable for +these reasons along with a few minor implementations left such as NPC's and +reworking the tech tree. \ No newline at end of file diff --git a/static/strings/home.md b/static/strings/home.md new file mode 100644 index 0000000..70509a6 --- /dev/null +++ b/static/strings/home.md @@ -0,0 +1,5 @@ + +# About me +I'm a fungi + + _markdown in html :0_ \ No newline at end of file diff --git a/static/strings/network.md b/static/strings/network.md new file mode 100644 index 0000000..193868e --- /dev/null +++ b/static/strings/network.md @@ -0,0 +1,64 @@ +

Servers & Networking

+

+ Open source and networking hobbies led me to depoly a set of + interconnected Linux servers: +

+ \ No newline at end of file diff --git a/static/strings/phobos.md b/static/strings/phobos.md new file mode 100644 index 0000000..e803bcf --- /dev/null +++ b/static/strings/phobos.md @@ -0,0 +1,53 @@ +

Phobos

+

+ One of the coolest things I've developed is a game, fully written in + assembly.

+ I say this because it is the perfect intersection of many things I enjoy; + low level programming, physics, space, simulation development, and game design. + Also small enough of a project that I could complete it in under a couple + of months, so another win. I even named the game based on the emulator, as + Phobos is a moon of Mars

The instructions for this + assignment were very broad, to develop a platformer game in assembly. + This left a lot of room for creative freedom, especially due to the + loose definition of platformer. With infinite time I would have + developed a whole rocket simulator, and used the justification that the + launchpad was a platform. +
+
On the technical side this was a very difficult project. There are + only about 16 variables actually usable in MIPS, and a lot of them are reserved + to specific logical controls under best practice. Then following the many + loops and recursive, real-time functionality required extensive and efficient + use of the stack. Ideally accessing a few bytes shouldn't strike the fear + of low framerates to mind, but the Mars-MIPS emulator I was using was far + from efficient. +

+

Notable Features

+ +

+ Probably the most annoying part of this was that the emulator couldn't + handle simutaineous key inputs. Fortunately I have over a thousand hours + experience landing rockets on the Mün + so I was comfortable giving a few unique key inputs per second. I never imagined + this is something I would be proud, and I still don't think I am. However, + it works.

At this point you may have realized I am a bit of a + space nerd. Enjoy this recording I made at 1am demonstrating the + features of my game to a TA, compressed to the point that the audio has + texture. +

+
+ The + source code is also available + for your enjoyment. \ No newline at end of file diff --git a/static/strings/uav.md b/static/strings/uav.md new file mode 100644 index 0000000..3c3ba14 --- /dev/null +++ b/static/strings/uav.md @@ -0,0 +1,59 @@ +

Building a UAV

+

+ I chose to build a drone from scratch for my AP Physics final project. + We were given an open ended assignment to build something cool + and I wanted a drone. My choice was much more ambitious than the course required, + and took quite a while to complete.

+ + For the drones frame I finally had an excuse to purchase a 3d printer. I + modelled the frame and arms modularly to support future upgrades and + replacements from damage, reducing the cost of operation. Initially I + was using some 3d printed torodial propellers due to their higher + efficiency and lower sounds usage. Due to safety concerns of the + propellers not withstanding tension at higher RPMs and exploding I + switched to some generic acrylic propellers I bought. A challenge in + designing the frame was leaving enough room to contain the volume of the + wires. I went with the Elegoo Neptune 3 as the printer was open-source + and had a much better cost-to-utility than proprietary printers such as + the Ender series. I am not sponsored I just really like the printer.

+ + The flight computer was the most difficult part to program. Using an + ultrasonic distance sensor, gyroscope, and accelerometer the drone has + enough information to probably never crash. The autopilot is implemented + on an Arduino UNO using a + PID controller + for stabolization. The autopilot quality is currently impacted every time + the drones mass distribution changes, which can be fixed with a reinforcement + machine learning algorithm. For the higher level programming such as flight + automation, video transmission and WiFi communications I used a Raspberry + Pi Pico. There is also a 2.4GHz line of sight receiver for manual control. + A future upgrade may contain a SIM card for near-infinite remote control + connection, but drone regulations would make this difficult.

+ + The power system is the most physically challenging portion of the + drone. The motors took 14.6 Volts, while the UNO microcontroller took 5 + Volts, and the Pico and most sensors run at 3.3 Volts. All of the power + to the motors ran through the power distribution board, which I modified + to also output the lower voltages and used Bidirectional Logic Level + Converters to shift between 3.3 and 5V signals where needed. A potential + flaw with having all the power coming from the same source is spikes in + energy consumption to the motors may cause the microcomputers to receive + too little power, which could be fixed with a capacitor. Luckily, I + haven't experienced this yet as the 2C discharge rate on the 2.5Ah + capacity battery is more than enough. Having a battery this big does + mean it takes up about half the internal electronics volume and is half + of the drones mass, but it can also maintain full throttle for half an + hour making for long flights.

+ + The motors I used were a bit overkill for a 1.1kg drone, as going past + 20% throttle sends it shooting through the sky -- which is not a bad + issue to have. Here's the technical numbers behind that: I have + propellers with a 6cm radius on motors with a 2450KV rating (2450 rpm + per volt) at peaking at 14.6 Volts. From this the tip speed is computed + to be ~225m/s under no load at max throttle, quite a lot more than what + is safe or necessary to get into the air. +

\ No newline at end of file diff --git a/static/strings/work-history.md b/static/strings/work-history.md new file mode 100644 index 0000000..1136500 --- /dev/null +++ b/static/strings/work-history.md @@ -0,0 +1,58 @@ +

Work Experience

+ + + +
+

Volunteering

+

+ I volunteer within the Computer Science, Mathematics, and Statistics + department at the University of Toronto as a Computer Science Ambassador + to help cultivate interest in the Mathematical Sciences in high school + students, as well as providing direction for first year students within + the programs. +

\ No newline at end of file diff --git a/static/style.css b/static/style.css index 6869cfc..7a02fc9 100644 --- a/static/style.css +++ b/static/style.css @@ -6,10 +6,15 @@ font-display: swap; /* Shows fallback font until custom font loads */ } +* { + color: whitesmoke; + font-family: sans-serif; + text-align: center; +} header { - background-color: transparent; /* Light grey background */ - border-bottom: 1px solid #ddd; + background-color: transparent; + border-bottom: 1px solid whitesmoke; padding: 1rem 1rem; } @@ -22,38 +27,36 @@ nav { } nav ul { - list-style: none; /* Removes bullet points */ + list-style: none; display: flex; - gap: 20px; /* Space between links */ + gap: 20px; margin: 0; padding: 0; } #name { - font-size: 3rem; - margin: 20px; - padding: 0px; - text-shadow: - 1px 1px orangered, - 2px 2px yellow, - 3px 3px green, - 4px 4px cornflowerblue; - letter-spacing: 2px; - width: fit-content; - color: whitesmoke; - font-family: "Ethnocentric", sans-serif; + text-align: center; + font-size: 5rem; + margin: 20px; + padding: 0px; + animation: nameShadow 5s linear infinite; + letter-spacing: 2px; + color: whitesmoke; + font-family: "Ethnocentric", sans-serif; + transform: skewX(-20deg); } -nav a { - text-decoration: none; - color: #333; - font-family: sans-serif; -} - -nav a:hover { - color: #007bff; /* Changes color when you hover */ +@keyframes nameShadow { + 0% { + text-shadow: none; + } + 90% { + text-shadow: + -6px -3px cornflowerblue, + 6px 3px orangered; + } } body { - background-color: #111; + background-image: linear-gradient(315deg, #111, #222); } diff --git a/templates/home.html b/templates/home.html new file mode 100644 index 0000000..cfb1f20 --- /dev/null +++ b/templates/home.html @@ -0,0 +1,27 @@ + + + + + + + +
+ +
+
+
+

Jeremy Janella

+ +
+
+ {{ content|safe }} +
+
+ +