From 1cd021d0a75c02f417e35ea465e38c0e25a1b0d4 Mon Sep 17 00:00:00 2001 From: Saji Date: Fri, 2 May 2025 22:37:23 -0500 Subject: [PATCH] lint --- .ignore | 1 + README.md | 60 ++-- _data/colors.js | 182 +++++----- _data/metadata.js | 20 +- content/404.md | 1 + content/about/index.md | 1 + content/blog/SNESAPU.md | 2 - content/blog/blog.11tydata.js | 6 +- content/blog/github-codesarch.md | 1 + .../hacking-hikmicro-pt1/hacking-hikmicro.md | 10 +- content/blog/nix-unprivileged-deployments.md | 9 +- content/blog/wy-60-repairs/wy-60-repairs.md | 3 +- content/blog/yosys4gal/yosys4gal.md | 18 +- content/blog/zig-is-dark-souls/index.md | 4 +- content/decks/decks.11tydata.js | 5 +- content/decks/test.html | 77 +++-- content/now.md | 1 + eleventy.config.drafts.js | 78 +++-- eleventy.config.js | 313 +++++++++--------- flake.nix | 113 ++++--- markdown-it-figcaption.js | 70 ++-- markdown-it-revealjs.js | 251 +++++++------- package.json | 78 ++--- package.nix | 59 ++-- public/css/fonts.css | 67 ++-- public/css/index.css | 285 ++++++++-------- public/css/prism-diff.css | 42 +-- 27 files changed, 886 insertions(+), 871 deletions(-) diff --git a/.ignore b/.ignore index 5a06a39..d8b0427 100644 --- a/.ignore +++ b/.ignore @@ -1 +1,2 @@ .jj/ +node_modules/ diff --git a/README.md b/README.md index 61873b0..2be0895 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A starter repository showing how to build a blog with the [Eleventy](https://www ## Getting Started -* [Want a more generic/detailed getting started guide?](https://www.11ty.dev/docs/getting-started/) +- [Want a more generic/detailed getting started guide?](https://www.11ty.dev/docs/getting-started/) 1. Make a directory and navigate to it: @@ -46,38 +46,38 @@ Or you can run [debug mode](https://www.11ty.dev/docs/debugging/) to see all the ## Features - Using [Eleventy v2.0](https://www.11ty.dev/blog/eleventy-v2/) with zero-JavaScript output. - - Content is exclusively pre-rendered (this is a static site). - - Can easily [deploy to a subfolder without changing any content](https://www.11ty.dev/docs/plugins/html-base/) - - All URLs are decoupled from the content’s location on the file system. - - Configure templates via the [Eleventy Data Cascade](https://www.11ty.dev/docs/data-cascade/) + - Content is exclusively pre-rendered (this is a static site). + - Can easily [deploy to a subfolder without changing any content](https://www.11ty.dev/docs/plugins/html-base/) + - All URLs are decoupled from the content’s location on the file system. + - Configure templates via the [Eleventy Data Cascade](https://www.11ty.dev/docs/data-cascade/) - **Performance focused**: four-hundos Lighthouse score out of the box! - - [View the Lighthouse report for the latest build](https://eleventy-base-blog.netlify.app/reports/lighthouse/) courtesy of the [Netlify Lighthouse plugin](https://github.com/netlify/netlify-plugin-lighthouse). - - _0 Cumulative Layout Shift_ - - _0ms Total Blocking Time_ + - [View the Lighthouse report for the latest build](https://eleventy-base-blog.netlify.app/reports/lighthouse/) courtesy of the [Netlify Lighthouse plugin](https://github.com/netlify/netlify-plugin-lighthouse). + - _0 Cumulative Layout Shift_ + - _0ms Total Blocking Time_ - Local development live reload provided by [Eleventy Dev Server](https://www.11ty.dev/docs/dev-server/). - Content-driven [navigation menu](https://www.11ty.dev/docs/plugins/navigation/) - [Image optimization](https://www.11ty.dev/docs/plugins/image/) via the `{% image %}` shortcode. - - Zero-JavaScript output. - - Support for modern image formats automatically (e.g. AVIF and WebP) - - Prefers `` markup if possible (single image format) but switches automatically to `` for multiple image formats. - - Automated `` syntax markup with `srcset` and optional `sizes` - - Includes `width`/`height` attributes to avoid [content layout shift](https://web.dev/cls/). - - Includes `loading="lazy"` for native lazy loading without JavaScript. - - Includes [`decoding="async"`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding) - - Images can be co-located with blog post files. - - View the [Image plugin source code](https://github.com/11ty/eleventy-base-blog/blob/main/eleventy.config.images.js) + - Zero-JavaScript output. + - Support for modern image formats automatically (e.g. AVIF and WebP) + - Prefers `` markup if possible (single image format) but switches automatically to `` for multiple image formats. + - Automated `` syntax markup with `srcset` and optional `sizes` + - Includes `width`/`height` attributes to avoid [content layout shift](https://web.dev/cls/). + - Includes `loading="lazy"` for native lazy loading without JavaScript. + - Includes [`decoding="async"`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding) + - Images can be co-located with blog post files. + - View the [Image plugin source code](https://github.com/11ty/eleventy-base-blog/blob/main/eleventy.config.images.js) - Per page CSS bundles [via `eleventy-plugin-bundle`](https://github.com/11ty/eleventy-plugin-bundle). - Built-in [syntax highlighter](https://www.11ty.dev/docs/plugins/syntaxhighlight/) (zero-JavaScript output). - Blog Posts - - Draft posts: use `draft: true` to mark a blog post as a draft. Drafts are **only** included during `--serve`/`--watch` and are excluded from full builds. View the [Drafts plugin source code](https://github.com/11ty/eleventy-base-blog/blob/main/eleventy.config.drafts.js). - - Automated next/previous links - - Accessible deep links to headings + - Draft posts: use `draft: true` to mark a blog post as a draft. Drafts are **only** included during `--serve`/`--watch` and are excluded from full builds. View the [Drafts plugin source code](https://github.com/11ty/eleventy-base-blog/blob/main/eleventy.config.drafts.js). + - Automated next/previous links + - Accessible deep links to headings - Generated Pages - - Home, Archive, and About pages. - - [Feeds for Atom and JSON](https://www.11ty.dev/docs/plugins/rss/) - - `sitemap.xml` - - Zero-maintenance tag pages ([View on the Demo](https://eleventy-base-blog.netlify.app/tags/)) - - Content not found (404) page + - Home, Archive, and About pages. + - [Feeds for Atom and JSON](https://www.11ty.dev/docs/plugins/rss/) + - `sitemap.xml` + - Zero-maintenance tag pages ([View on the Demo](https://eleventy-base-blog.netlify.app/tags/)) + - Content not found (404) page ## Demos @@ -105,12 +105,12 @@ Deploy this Eleventy site in just a few clicks on these services: - Content can be in _any template format_ (blog posts needn’t exclusively be markdown, for example). Configure your project’s supported templates in `eleventy.config.js` -> `templateFormats`. - The `public` folder in your input directory will be copied to the output folder (via `addPassthroughCopy` in the `eleventy.config.js` file). This means `./public/css/*` will live at `./_site/css/*` after your build completes. - Provides two content feeds: - - `content/feed/feed.njk` - - `content/feed/json.njk` + - `content/feed/feed.njk` + - `content/feed/json.njk` - This project uses three [Eleventy Layouts](https://www.11ty.dev/docs/layouts/): - - `_includes/layouts/base.njk`: the top level HTML structure - - `_includes/layouts/home.njk`: the home page template (wrapped into `base.njk`) - - `_includes/layouts/post.njk`: the blog post template (wrapped into `base.njk`) + - `_includes/layouts/base.njk`: the top level HTML structure + - `_includes/layouts/home.njk`: the home page template (wrapped into `base.njk`) + - `_includes/layouts/post.njk`: the blog post template (wrapped into `base.njk`) - `_includes/postslist.njk` is a Nunjucks include and is a reusable component used to display a list of all the posts. `content/index.njk` has an example of how to use it. #### Content Security Policy diff --git a/_data/colors.js b/_data/colors.js index 00674cd..5be7370 100644 --- a/_data/colors.js +++ b/_data/colors.js @@ -1,92 +1,92 @@ export default { - dark: { - "source": "rootloops.sh", - "hex": { - "background": "#0a0808", - "foreground": "#e7e1e2", - "cursor": "#c2b5b8", - "black": "#272022", - "red": "#cf5080", - "green": "#7b8d39", - "yellow": "#b57235", - "blue": "#3c8cbf", - "magenta": "#9468d8", - "cyan": "#3b9586", - "white": "#c2b5b8", - "brightBlack": "#5a4e51", - "brightRed": "#e26b95", - "brightGreen": "#8fa445", - "brightYellow": "#cf8544", - "brightBlue": "#4fa1d7", - "brightMagenta": "#a782e5", - "brightCyan": "#47ac9b", - "brightWhite": "#f3f0f1" - }, - "hsl": { - "background": "hsl(345.13, 15.37%, 3.54%)", - "foreground": "hsl(344.94, 10.53%, 89.29%)", - "cursor": "hsl(344.63, 9.37%, 73.52%)", - "black": "hsl(344.1, 8.9%, 13.97%)", - "red": "hsl(337.55, 56.97%, 56.34%)", - "green": "hsl(72.88, 42.49%, 38.93%)", - "yellow": "hsl(28.49, 54.76%, 45.89%)", - "blue": "hsl(203.33, 52.42%, 49.09%)", - "magenta": "hsl(264.05, 58.81%, 62.59%)", - "cyan": "hsl(169.71, 43.35%, 40.84%)", - "white": "hsl(344.63, 9.37%, 73.52%)", - "brightBlack": "hsl(344.15, 7.1%, 32.99%)", - "brightRed": "hsl(339.06, 67.64%, 65.41%)", - "brightGreen": "hsl(72.99, 40.55%, 45.65%)", - "brightYellow": "hsl(28.18, 58.94%, 53.93%)", - "brightBlue": "hsl(203.73, 63.27%, 57.72%)", - "brightMagenta": "hsl(262.71, 65.56%, 70.29%)", - "brightCyan": "hsl(169.62, 41.51%, 47.79%)", - "brightWhite": "hsl(345.03, 10.68%, 94.62%)" - } - }, - light: { - "source": "rootloops.sh", - "hex": { - "background": "#f3f0f1", - "foreground": "#40373a", - "cursor": "#74666a", - "black": "#e7e1e2", - "red": "#cf5080", - "green": "#7b8d39", - "yellow": "#b57235", - "blue": "#3c8cbf", - "magenta": "#9468d8", - "cyan": "#3b9586", - "white": "#74666a", - "brightBlack": "#b5a7ab", - "brightRed": "#e26b95", - "brightGreen": "#8fa445", - "brightYellow": "#cf8544", - "brightBlue": "#4fa1d7", - "brightMagenta": "#a782e5", - "brightCyan": "#47ac9b", - "brightWhite": "#272022" - }, - "hsl": { - "background": "hsl(345.03, 10.68%, 94.62%)", - "foreground": "hsl(344.11, 7.75%, 23.41%)", - "cursor": "hsl(344.2, 6.49%, 42.82%)", - "black": "hsl(344.94, 10.53%, 89.29%)", - "red": "hsl(337.55, 56.97%, 56.34%)", - "green": "hsl(72.88, 42.49%, 38.93%)", - "yellow": "hsl(28.49, 54.76%, 45.89%)", - "blue": "hsl(203.33, 52.42%, 49.09%)", - "magenta": "hsl(264.05, 58.81%, 62.59%)", - "cyan": "hsl(169.71, 43.35%, 40.84%)", - "white": "hsl(344.2, 6.49%, 42.82%)", - "brightBlack": "hsl(344.53, 8.76%, 68.33%)", - "brightRed": "hsl(339.06, 67.64%, 65.41%)", - "brightGreen": "hsl(72.99, 40.55%, 45.65%)", - "brightYellow": "hsl(28.18, 58.94%, 53.93%)", - "brightBlue": "hsl(203.73, 63.27%, 57.72%)", - "brightMagenta": "hsl(262.71, 65.56%, 70.29%)", - "brightCyan": "hsl(169.62, 41.51%, 47.79%)", - "brightWhite": "hsl(344.1, 8.9%, 13.97%)" - } - }, -} + dark: { + source: "rootloops.sh", + hex: { + background: "#0a0808", + foreground: "#e7e1e2", + cursor: "#c2b5b8", + black: "#272022", + red: "#cf5080", + green: "#7b8d39", + yellow: "#b57235", + blue: "#3c8cbf", + magenta: "#9468d8", + cyan: "#3b9586", + white: "#c2b5b8", + brightBlack: "#5a4e51", + brightRed: "#e26b95", + brightGreen: "#8fa445", + brightYellow: "#cf8544", + brightBlue: "#4fa1d7", + brightMagenta: "#a782e5", + brightCyan: "#47ac9b", + brightWhite: "#f3f0f1", + }, + hsl: { + background: "hsl(345.13, 15.37%, 3.54%)", + foreground: "hsl(344.94, 10.53%, 89.29%)", + cursor: "hsl(344.63, 9.37%, 73.52%)", + black: "hsl(344.1, 8.9%, 13.97%)", + red: "hsl(337.55, 56.97%, 56.34%)", + green: "hsl(72.88, 42.49%, 38.93%)", + yellow: "hsl(28.49, 54.76%, 45.89%)", + blue: "hsl(203.33, 52.42%, 49.09%)", + magenta: "hsl(264.05, 58.81%, 62.59%)", + cyan: "hsl(169.71, 43.35%, 40.84%)", + white: "hsl(344.63, 9.37%, 73.52%)", + brightBlack: "hsl(344.15, 7.1%, 32.99%)", + brightRed: "hsl(339.06, 67.64%, 65.41%)", + brightGreen: "hsl(72.99, 40.55%, 45.65%)", + brightYellow: "hsl(28.18, 58.94%, 53.93%)", + brightBlue: "hsl(203.73, 63.27%, 57.72%)", + brightMagenta: "hsl(262.71, 65.56%, 70.29%)", + brightCyan: "hsl(169.62, 41.51%, 47.79%)", + brightWhite: "hsl(345.03, 10.68%, 94.62%)", + }, + }, + light: { + source: "rootloops.sh", + hex: { + background: "#f3f0f1", + foreground: "#40373a", + cursor: "#74666a", + black: "#e7e1e2", + red: "#cf5080", + green: "#7b8d39", + yellow: "#b57235", + blue: "#3c8cbf", + magenta: "#9468d8", + cyan: "#3b9586", + white: "#74666a", + brightBlack: "#b5a7ab", + brightRed: "#e26b95", + brightGreen: "#8fa445", + brightYellow: "#cf8544", + brightBlue: "#4fa1d7", + brightMagenta: "#a782e5", + brightCyan: "#47ac9b", + brightWhite: "#272022", + }, + hsl: { + background: "hsl(345.03, 10.68%, 94.62%)", + foreground: "hsl(344.11, 7.75%, 23.41%)", + cursor: "hsl(344.2, 6.49%, 42.82%)", + black: "hsl(344.94, 10.53%, 89.29%)", + red: "hsl(337.55, 56.97%, 56.34%)", + green: "hsl(72.88, 42.49%, 38.93%)", + yellow: "hsl(28.49, 54.76%, 45.89%)", + blue: "hsl(203.33, 52.42%, 49.09%)", + magenta: "hsl(264.05, 58.81%, 62.59%)", + cyan: "hsl(169.71, 43.35%, 40.84%)", + white: "hsl(344.2, 6.49%, 42.82%)", + brightBlack: "hsl(344.53, 8.76%, 68.33%)", + brightRed: "hsl(339.06, 67.64%, 65.41%)", + brightGreen: "hsl(72.99, 40.55%, 45.65%)", + brightYellow: "hsl(28.18, 58.94%, 53.93%)", + brightBlue: "hsl(203.73, 63.27%, 57.72%)", + brightMagenta: "hsl(262.71, 65.56%, 70.29%)", + brightCyan: "hsl(169.62, 41.51%, 47.79%)", + brightWhite: "hsl(344.1, 8.9%, 13.97%)", + }, + }, +}; diff --git a/_data/metadata.js b/_data/metadata.js index 465fcda..0871779 100644 --- a/_data/metadata.js +++ b/_data/metadata.js @@ -1,11 +1,11 @@ export default { - title: "Musings", - url: "https://saji.dev/", - language: "en", - description: "Random notes and ideas.", - author: { - name: "Saji", - email: "saji@saji.dev", - url: "https://saji.dev/about-me/" - } -} + title: "Musings", + url: "https://saji.dev/", + language: "en", + description: "Random notes and ideas.", + author: { + name: "Saji", + email: "saji@saji.dev", + url: "https://saji.dev/about-me/", + }, +}; diff --git a/content/404.md b/content/404.md index bd51f61..3ed3db7 100644 --- a/content/404.md +++ b/content/404.md @@ -3,6 +3,7 @@ layout: layouts/home.njk permalink: 404.html eleventyExcludeFromCollections: true --- + # Content not found. Go home. diff --git a/content/about/index.md b/content/about/index.md index 18367d8..42bddcb 100644 --- a/content/about/index.md +++ b/content/about/index.md @@ -4,6 +4,7 @@ eleventyNavigation: key: About Me order: 3 --- + # About Me I am a person that writes stuff. diff --git a/content/blog/SNESAPU.md b/content/blog/SNESAPU.md index b1f9c9f..7caf6d7 100644 --- a/content/blog/SNESAPU.md +++ b/content/blog/SNESAPU.md @@ -6,6 +6,4 @@ tags: - project --- - This is a test - diff --git a/content/blog/blog.11tydata.js b/content/blog/blog.11tydata.js index 614f505..2724a81 100644 --- a/content/blog/blog.11tydata.js +++ b/content/blog/blog.11tydata.js @@ -1,6 +1,4 @@ export default { - tags: [ - "posts" - ], - "layout": "layouts/post.njk", + tags: ["posts"], + layout: "layouts/post.njk", }; diff --git a/content/blog/github-codesarch.md b/content/blog/github-codesarch.md index d0fb1f4..445454b 100644 --- a/content/blog/github-codesarch.md +++ b/content/blog/github-codesarch.md @@ -12,6 +12,7 @@ has been documented to death by skids, I haven't seen anyone reference this yet. I'm sure someone is using it, since it's powerful. Case in point: + ``` /"[a-z]{4}(?: [a-z]{4}){3}"/ language:Python SMTP ``` diff --git a/content/blog/hacking-hikmicro-pt1/hacking-hikmicro.md b/content/blog/hacking-hikmicro-pt1/hacking-hikmicro.md index 8a61bd6..ab64900 100644 --- a/content/blog/hacking-hikmicro-pt1/hacking-hikmicro.md +++ b/content/blog/hacking-hikmicro-pt1/hacking-hikmicro.md @@ -13,7 +13,7 @@ Part one focuses on the image format. # Introduction -*[ITAR]: International Traffic in Arms Regulations +\*[ITAR]: International Traffic in Arms Regulations In the past few years, Chinese manufacturers have brought cheap, performant microbolometer arrays to the consumer market. These arrays are higher resolution and faster framerates than what can reasonably be acquired in the West - mostly due to low competition and ITAR restrictions. Most popular are the low-cost modules by Infiray, which provides whitelabel solutions @@ -35,10 +35,8 @@ odd phone app. However this choice seems less popular on forums and there is no reverse engineering project that exists already, so we'll have to start from scratch. - # Getting the picture - To start with something simple, lets figure out how their image format works. They call it "radiometric JPEG". This isn't to be confused with FLIR's RJPEG format, which is already well understood.. When using regular image viewers, we get a screenshot of the display. Where things get interesting is when we open the image with the Hikmicro Analyzer software, we can see the full @@ -69,9 +67,3 @@ Well that's something. It's not perfect, but it means that our thermal data is r # I'm hexing here Imhex is pretty great. You can perform a lot of analysis without needing other tools. - - - - - - diff --git a/content/blog/nix-unprivileged-deployments.md b/content/blog/nix-unprivileged-deployments.md index 6b981cf..5afe729 100644 --- a/content/blog/nix-unprivileged-deployments.md +++ b/content/blog/nix-unprivileged-deployments.md @@ -11,7 +11,6 @@ complex Ansible playbooks. While I don't think NixOS is ready for personal computers, it absolutely makes sense on less dynamic devices like servers or embedded-ish machines. - We can use NixOS and nixpkgs to derive a fully defined operating system and services. Then, we can: @@ -118,12 +117,10 @@ $ ls /nix/store | grep myblog mqhssdlmg9f03avpajwcqaah2apknl02-myblog ``` - Before we go any further, let's set up the nginx server, as well as a well-known path for our website. I'll also add a user here that we can use to deploy. - ```nix { config, @@ -194,17 +191,15 @@ in } ``` - Now we have a scoped user, with an ssh key authorized. It needs a shell so we can actually log in remotely. The last step is creating that symlink. This is where the concept of "activation" comes into play. - For NixOS, `deploy-rs` activation just calls `switch-to-configuration` to make the system change the profile. We can effectively do whatever we want here. - Reading the [custom activator](https://github.com/serokell/deploy-rs/blob/aa07eb05537d4cd025e2310397a6adcedfe72c76/flake.nix#L58C13-L96C17) source: + ```nix custom = { __functor = customSelf: base: activate: @@ -246,7 +241,6 @@ custom = { }; ``` - This is a bit difficult to parse because there's the whole `__functor` bit. Essentially, we use `buildEnv` to add some new scripts to the `base` package, which are then used to call `activate`, which can be a shell script or a binary. @@ -314,7 +308,6 @@ The chain looks like this: A profile is just a symlink to a derivation in the nix store. One layer of indirection exists to make rollbacks easier. - # End I hope this was useful for you. I think non-root deployment is diff --git a/content/blog/wy-60-repairs/wy-60-repairs.md b/content/blog/wy-60-repairs/wy-60-repairs.md index 0083e84..f54011e 100644 --- a/content/blog/wy-60-repairs/wy-60-repairs.md +++ b/content/blog/wy-60-repairs/wy-60-repairs.md @@ -113,7 +113,7 @@ This highlights the two styles of troubleshooting: 2. Hypothesis -> Validate -> Solution It feels pretty good to zero-shot a repair or fix, but it also can leave you -with blind spots. In my case, I didn't want to try to probe the board while +with blind spots. In my case, I didn't want to try to probe the board while hot, but later it became necessary unless I just started replacing chips indiscriminately. Once I started probing, I wanted to find something that seemed "off" before going further. I would have noticed the character RAM @@ -140,4 +140,3 @@ to hack around that with a shim but that's a problem for later. It works fine at 9600 baud using software flow control. To the folks who rave about the terminals of yore, I get it now. - diff --git a/content/blog/yosys4gal/yosys4gal.md b/content/blog/yosys4gal/yosys4gal.md index 22dafe6..8288f6d 100644 --- a/content/blog/yosys4gal/yosys4gal.md +++ b/content/blog/yosys4gal/yosys4gal.md @@ -4,8 +4,6 @@ description: Bringing modern synthesis to 30-year old technology with Yosys and date: 2024-06-14 --- - - GAL/PALs are ancient chips designed to implement custom logic as a precursor to CPLDs and FPGAs. They can implement any combinational logic using a Sum-of-Products architecture and a grid of wires with certain wires being connected at different coordinates: @@ -41,11 +39,9 @@ DESCRIPTION Simple test of combinatorial logic. ``` - I don't want to deal with this. It's annoying to think about. What if we could create our own Verilog flow for GAL chips? Then we could take advantage of the simulation and synthesis capabilities, which would make these chips a bit more useful. - # The idea We use Yosys to synthesize Verilog, and do technology-mapping onto a set of primitive blocks that are then mapped by a custom tool. @@ -54,20 +50,15 @@ onto actual positions based on a pin constraints file. There's two components - Yosys technology mapping, and writing a "place-and-route" tool. We'll start with Yosys. - - ## Yosys Technology Mapping This process is cursed and low level, but it works a little like this: - Yosys takes a generic synthesis pass at a netlist, which simplifies the design without looking at any physical implementation - The simplified design is then mapped into Verilog-based "blocks", which could be things like AND gates, or complex blocks like a LUT. -This process turns generic blocks like an adder into a set of gates. + This process turns generic blocks like an adder into a set of gates. - certain sequences of gates are then grouped and unified in the "extract" pass. Extraction would convert an operation like `mul -> add` -into a single `mul_add` block. - - - + into a single `mul_add` block. ## A history lesson @@ -127,7 +118,6 @@ logic chip, changing the function depending on what you need. Additionally, GALs operate at 5 volts is useful when interfacing with older systems and removes the need for a level shifter. - In practice, this isn't all great. Programming GALs is an exercise in frustration. Take a look at a basic combinatorial assembly file: @@ -159,18 +149,16 @@ test this in a larger system (we'll get back to this). Compared to the Verilog flow, with simulation, testbenches, and synthesis, the raw assembly is stuck in the 80s and requires manual logic simplification. -Verilog compilers for GALs *did exist*, but they ran on old-as-dirt systems, +Verilog compilers for GALs _did exist_, but they ran on old-as-dirt systems, didn't have any significant optimization capabilities, and were almost always proprietary. What if we could make our own open-source Verilog flow for GAL chips? Then we could write test benches in Verilog, map complex designs onto the chip, and even integrate our designs with FPGAs later down the line. - # The idea GAL assembly appears occasionally when working with older systems, especially in a retro emulation context. - # Is this useful? Not particularly. diff --git a/content/blog/zig-is-dark-souls/index.md b/content/blog/zig-is-dark-souls/index.md index 3e3adf2..b516b1b 100644 --- a/content/blog/zig-is-dark-souls/index.md +++ b/content/blog/zig-is-dark-souls/index.md @@ -15,8 +15,8 @@ C interop, interesting features, and fast. Some of the headlines: - `comptime`: Lispers are in shambles. Run Zig code to generate Zig code. - Cross compilation. For real. Not Rust cross where you need to find a sysroot. -Not Go cross locking you out of CGO. You can literally change a variable and make -a Mac binary on Windows like it's nothing. + Not Go cross locking you out of CGO. You can literally change a variable and make + a Mac binary on Windows like it's nothing. - Web target, both WASI and freestanding. - SIMD Vectors? We take those I guess. - It's got a build/test system built in. More on that later. diff --git a/content/decks/decks.11tydata.js b/content/decks/decks.11tydata.js index 7c8932a..9dadf15 100644 --- a/content/decks/decks.11tydata.js +++ b/content/decks/decks.11tydata.js @@ -1,5 +1,4 @@ export default { - tags: [ - ], - "layout": "layouts/deck.njk", + tags: [], + layout: "layouts/deck.njk", }; diff --git a/content/decks/test.html b/content/decks/test.html index 94e32e3..f195312 100644 --- a/content/decks/test.html +++ b/content/decks/test.html @@ -1,14 +1,12 @@
-

Object (dis)orientation

-
How to survive a "post-OO" world
+

Object (dis)orientation

+
How to survive a "post-OO" world
-
- Class/Inheritance has challenges -
-
- Combining Data + Code -

+  
Class/Inheritance has challenges
+
+ Combining Data + Code +

 		class MyBase {
 			protected:
 				int useless;
@@ -20,35 +18,46 @@
 				};
 		};
 		
-

You have to know if this is an "interface", abstract class, or regular class.

- (it's an abstract class, since makeSound is pure virtual) -
-
-

A class can be one of many things

-
    -
  • Interface - abstract class with no members, and purely virtual
  • -
  • Abstract Class - class with some pure virtual methods
  • -
  • "Regular" Class - class that is standalone and is fully implemented
  • -
- These concepts all exist under the class keyword -
+

+ You have to know if this is an "interface", abstract class, or regular + class. +

+ (it's an abstract class, since makeSound is pure + virtual) +
+
+

A class can be one of many things

+
    +
  • Interface - abstract class with no members, and purely virtual
  • +
  • Abstract Class - class with some pure virtual methods
  • +
  • + "Regular" Class - class that is standalone and is fully implemented +
  • +
+ These concepts all exist under the class keyword + +
- In Rust, you trade Inheritance for Traits and Types. + In Rust, you trade Inheritance for Traits and + Types.
-
-

Traits are Interfaces

-

+  
+

Traits are Interfaces

+

 	pub trait Mammal {
 		fn get_temp(&self) -> i32;
 	}
 	
-
-
-

... that are explicitly implemented

-

+  
+
+

... that are explicitly implemented

+

 		pub struct Cat {
 			age: i32,
 			outdoor: bool,
@@ -63,11 +72,10 @@
 			}
 		}
 		
- -
-
-

And can be used statically or dynamically!

-

+  
+
+

And can be used statically or dynamically!

+

 		fn static_mammal<T: Mammal>(m: T) {
 			// the type of T must be known at compile time.
 		}
@@ -75,6 +83,5 @@
 			// This uses a vtable to dispatch at runtime.
 		}
 		
-
+
- diff --git a/content/now.md b/content/now.md index 5da8164..7fe5ace 100644 --- a/content/now.md +++ b/content/now.md @@ -6,6 +6,7 @@ eleventyNavigation: key: Now order: 4 --- + ## Save Slot 0 Rate-Monotonic scheduling my life. diff --git a/eleventy.config.drafts.js b/eleventy.config.drafts.js index 49190e3..927ceb2 100644 --- a/eleventy.config.drafts.js +++ b/eleventy.config.drafts.js @@ -1,47 +1,53 @@ export function eleventyComputedPermalink() { - // When using `addGlobalData` and you *want* to return a function, you must nest functions like this. - // `addGlobalData` acts like a global data file and runs the top level function it receives. - return (data) => { - // Always skip during non-watch/serve builds - if(data.draft && !process.env.BUILD_DRAFTS) { - return false; - } + // When using `addGlobalData` and you *want* to return a function, you must nest functions like this. + // `addGlobalData` acts like a global data file and runs the top level function it receives. + return (data) => { + // Always skip during non-watch/serve builds + if (data.draft && !process.env.BUILD_DRAFTS) { + return false; + } - return data.permalink; - } -}; + return data.permalink; + }; +} export function eleventyComputedExcludeFromCollections() { - // When using `addGlobalData` and you *want* to return a function, you must nest functions like this. - // `addGlobalData` acts like a global data file and runs the top level function it receives. - return (data) => { - // Always exclude from non-watch/serve builds - if(data.draft && !process.env.BUILD_DRAFTS) { - return true; - } + // When using `addGlobalData` and you *want* to return a function, you must nest functions like this. + // `addGlobalData` acts like a global data file and runs the top level function it receives. + return (data) => { + // Always exclude from non-watch/serve builds + if (data.draft && !process.env.BUILD_DRAFTS) { + return true; + } - return data.eleventyExcludeFromCollections; - } -}; + return data.eleventyExcludeFromCollections; + }; +} export default function (eleventyConfig) { - eleventyConfig.addGlobalData("eleventyComputed.permalink", eleventyComputedPermalink); - eleventyConfig.addGlobalData("eleventyComputed.eleventyExcludeFromCollections", eleventyComputedExcludeFromCollections); + eleventyConfig.addGlobalData( + "eleventyComputed.permalink", + eleventyComputedPermalink, + ); + eleventyConfig.addGlobalData( + "eleventyComputed.eleventyExcludeFromCollections", + eleventyComputedExcludeFromCollections, + ); - let logged = false; - eleventyConfig.on("eleventy.before", ({runMode}) => { - let text = "Excluding"; - // Only show drafts in serve/watch modes - if(runMode === "serve" || runMode === "watch") { - process.env.BUILD_DRAFTS = true; - text = "Including"; - } + let logged = false; + eleventyConfig.on("eleventy.before", ({ runMode }) => { + let text = "Excluding"; + // Only show drafts in serve/watch modes + if (runMode === "serve" || runMode === "watch") { + process.env.BUILD_DRAFTS = true; + text = "Including"; + } - // Only log once. - if(!logged) { - console.log( `[11ty/eleventy-base-blog] ${text} drafts.` ); - } + // Only log once. + if (!logged) { + console.log(`[11ty/eleventy-base-blog] ${text} drafts.`); + } - logged = true; - }); + logged = true; + }); } diff --git a/eleventy.config.js b/eleventy.config.js index bed8c22..53fc3b7 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -11,191 +11,186 @@ import pluginNavigation from "@11ty/eleventy-navigation"; import { EleventyHtmlBasePlugin } from "@11ty/eleventy"; import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"; - import pluginDrafts from "./eleventy.config.drafts.js"; -import fs from 'fs/promises' +import fs from "fs/promises"; /** @param {import('@11ty/eleventy').UserConfig} eleventyConfig */ -export default async function(eleventyConfig) { - // Copy the contents of the `public` folder to the output folder - // For example, `./public/css/` ends up in `_site/css/` - eleventyConfig.addPassthroughCopy({ - "./public/": "/", - "./node_modules/katex/dist/fonts/": "/bundle/fonts/", // needs to be here for css reasons. - }); +export default async function (eleventyConfig) { + // Copy the contents of the `public` folder to the output folder + // For example, `./public/css/` ends up in `_site/css/` + eleventyConfig.addPassthroughCopy({ + "./public/": "/", + "./node_modules/katex/dist/fonts/": "/bundle/fonts/", // needs to be here for css reasons. + }); - // Watch content images for the image pipeline. - eleventyConfig.addWatchTarget("content/**/*.{svg,webp,png,jpeg}"); + // Watch content images for the image pipeline. + eleventyConfig.addWatchTarget("content/**/*.{svg,webp,png,jpeg}"); - // App plugins - eleventyConfig.addPlugin(pluginDrafts); - // eleventyConfig.addPlugin(pluginFonts); - // Official plugins - let mkFeed = function(type, path) { - eleventyConfig.addPlugin(feedPlugin, { - type: type, - outputPath: path, - collection: { - name: "posts", - limit: 0 - }, - metadata: { - title: "Musings", - base: "https://saji.dev", - language: "en", + // App plugins + eleventyConfig.addPlugin(pluginDrafts); + // eleventyConfig.addPlugin(pluginFonts); + // Official plugins + let mkFeed = function (type, path) { + eleventyConfig.addPlugin(feedPlugin, { + type: type, + outputPath: path, + collection: { + name: "posts", + limit: 0, + }, + metadata: { + title: "Musings", + base: "https://saji.dev", + language: "en", + }, + }); + }; + mkFeed("rss", "/rss.feed.xml"); + mkFeed("atom", "/atom.feed.xml"); + mkFeed("json", "/feed.json"); - }, - }); + eleventyConfig.addPlugin(pluginSyntaxHighlight, { + preAttributes: { tabindex: 0 }, + }); + eleventyConfig.addPlugin(pluginNavigation); + eleventyConfig.addPlugin(EleventyHtmlBasePlugin); + eleventyConfig.addPlugin(pluginBundle); + eleventyConfig.addPlugin(eleventyImageTransformPlugin, { + extensions: "html", + formats: ["webp", "jpeg", null], + widths: [400, 800, 1280, null], + defaultAttributes: { + loading: "lazy", + decoding: "async", + sizes: "auto", + }, + }); + // Filters + eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => { + // Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens + return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat( + format || "dd LLLL yyyy", + ); + }); - }; - mkFeed("rss", "/rss.feed.xml"); - mkFeed("atom", "/atom.feed.xml"); - mkFeed("json", "/feed.json"); + eleventyConfig.addFilter("htmlDateString", (dateObj) => { + // dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string + return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat("yyyy-LL-dd"); + }); - eleventyConfig.addPlugin(pluginSyntaxHighlight, { - preAttributes: { tabindex: 0 } - }); - eleventyConfig.addPlugin(pluginNavigation); - eleventyConfig.addPlugin(EleventyHtmlBasePlugin); - eleventyConfig.addPlugin(pluginBundle); - eleventyConfig.addPlugin(eleventyImageTransformPlugin, { - extensions: "html", - formats: ["webp", "jpeg", null], - widths: [400, 800, 1280, null], - defaultAttributes: { - loading: "lazy", - decoding: "async", - sizes: "auto", - } - }) + // Get the first `n` elements of a collection. + eleventyConfig.addFilter("head", (array, n) => { + if (!Array.isArray(array) || array.length === 0) { + return []; + } + if (n < 0) { + return array.slice(n); + } + return array.slice(0, n); + }); + // Return the smallest number argument + eleventyConfig.addFilter("min", (...numbers) => { + return Math.min.apply(null, numbers); + }); - // Filters - eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => { - // Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens - return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat(format || "dd LLLL yyyy"); - }); + // Return all the tags used in a collection + eleventyConfig.addFilter("getAllTags", (collection) => { + let tagSet = new Set(); + for (let item of collection) { + (item.data.tags || []).forEach((tag) => tagSet.add(tag)); + } + return Array.from(tagSet); + }); - eleventyConfig.addFilter('htmlDateString', (dateObj) => { - // dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string - return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat('yyyy-LL-dd'); - }); + eleventyConfig.addFilter("filterTagList", function filterTagList(tags) { + return (tags || []).filter( + (tag) => ["all", "nav", "post", "posts"].indexOf(tag) === -1, + ); + }); - // Get the first `n` elements of a collection. - eleventyConfig.addFilter("head", (array, n) => { - if (!Array.isArray(array) || array.length === 0) { - return []; - } - if (n < 0) { - return array.slice(n); - } + let mdIt; + // Customize Markdown library settings: + eleventyConfig.amendLibrary("md", (mdLib) => { + // hack to let us use the markdown renderer for later. + mdIt = mdLib; + mdLib.use(markdownItAnchor, { + permalink: markdownItAnchor.permalink.ariaHidden({ + placement: "after", + class: "header-anchor", + symbol: "@", + ariaHidden: false, + }), + level: [1, 2, 3, 4], + slugify: eleventyConfig.getFilter("slugify"), + }); + mdLib.use(markdownItAbbr); + mdLib.use(markdownItKatex.default); + }); - return array.slice(0, n); - }); + eleventyConfig.addShortcode("currentBuildDate", () => { + return new Date().toISOString(); + }); - // Return the smallest number argument - eleventyConfig.addFilter("min", (...numbers) => { - return Math.min.apply(null, numbers); - }); + eleventyConfig.addShortcode("includeRaw", async (file) => + fs.readFile(file, "utf8"), + ); - // Return all the tags used in a collection - eleventyConfig.addFilter("getAllTags", collection => { - let tagSet = new Set(); - for (let item of collection) { - (item.data.tags || []).forEach(tag => tagSet.add(tag)); - } - return Array.from(tagSet); - }); + //eleventyConfig.addPairedShortcode("section", async (content, transition = "none") => { + // return `
${mdIt.renderInline(content)}
`; + //}) + // + eleventyConfig.addPairedShortcode("callout", function (content) { + // The 'content' variable holds the text/HTML placed between + // {% callout %} and {% endcallout %} + // We wrap it with our div structure. + return `
${content}
`; + }); - eleventyConfig.addFilter("filterTagList", function filterTagList(tags) { - return (tags || []).filter(tag => ["all", "nav", "post", "posts"].indexOf(tag) === -1); - }); + eleventyConfig.addBundle("css"); + eleventyConfig.addBundle("js"); + eleventyConfig.addBundle("html"); - let mdIt; - // Customize Markdown library settings: - eleventyConfig.amendLibrary("md", mdLib => { - // hack to let us use the markdown renderer for later. - mdIt = mdLib; - mdLib.use(markdownItAnchor, { - permalink: markdownItAnchor.permalink.ariaHidden({ - placement: "after", - class: "header-anchor", - symbol: "@", - ariaHidden: false, - }), - level: [1, 2, 3, 4], - slugify: eleventyConfig.getFilter("slugify") - }); - mdLib.use(markdownItAbbr); - mdLib.use(markdownItKatex.default); - }); + // Features to make your build faster (when you need them) - eleventyConfig.addShortcode("currentBuildDate", () => { - return (new Date()).toISOString(); - }) + // If your passthrough copy gets heavy and cumbersome, add this line + // to emulate the file copy on the dev server. Learn more: + // https://www.11ty.dev/docs/copy/#emulate-passthrough-copy-during-serve - eleventyConfig.addShortcode("includeRaw", async (file) => fs.readFile(file, "utf8")); + // eleventyConfig.setServerPassthroughCopyBehavior("passthrough"); - //eleventyConfig.addPairedShortcode("section", async (content, transition = "none") => { - // return `
${mdIt.renderInline(content)}
`; - //}) - // - eleventyConfig.addPairedShortcode("callout", function(content) { - // The 'content' variable holds the text/HTML placed between - // {% callout %} and {% endcallout %} - // We wrap it with our div structure. - return `
${content}
`; - }); + return { + // Control which files Eleventy will process + // e.g.: *.md, *.njk, *.html, *.liquid + templateFormats: ["md", "njk", "html", "liquid"], - eleventyConfig.addBundle("css"); - eleventyConfig.addBundle("js"); - eleventyConfig.addBundle("html"); + // Pre-process *.md files with: (default: `liquid`) + markdownTemplateEngine: "njk", - // Features to make your build faster (when you need them) + // Pre-process *.html files with: (default: `liquid`) + htmlTemplateEngine: "njk", - // If your passthrough copy gets heavy and cumbersome, add this line - // to emulate the file copy on the dev server. Learn more: - // https://www.11ty.dev/docs/copy/#emulate-passthrough-copy-during-serve + // These are all optional: + dir: { + input: "content", // default: "." + includes: "../_includes", // default: "_includes" + data: "../_data", // default: "_data" + output: "_site", + }, - // eleventyConfig.setServerPassthroughCopyBehavior("passthrough"); + // ----------------------------------------------------------------- + // Optional items: + // ----------------------------------------------------------------- - return { - // Control which files Eleventy will process - // e.g.: *.md, *.njk, *.html, *.liquid - templateFormats: [ - "md", - "njk", - "html", - "liquid", - ], + // If your site deploys to a subdirectory, change `pathPrefix`. + // Read more: https://www.11ty.dev/docs/config/#deploy-to-a-subdirectory-with-a-path-prefix - // Pre-process *.md files with: (default: `liquid`) - markdownTemplateEngine: "njk", - - // Pre-process *.html files with: (default: `liquid`) - htmlTemplateEngine: "njk", - - // These are all optional: - dir: { - input: "content", // default: "." - includes: "../_includes", // default: "_includes" - data: "../_data", // default: "_data" - output: "_site" - }, - - // ----------------------------------------------------------------- - // Optional items: - // ----------------------------------------------------------------- - - // If your site deploys to a subdirectory, change `pathPrefix`. - // Read more: https://www.11ty.dev/docs/config/#deploy-to-a-subdirectory-with-a-path-prefix - - // When paired with the HTML plugin https://www.11ty.dev/docs/plugins/html-base/ - // it will transform any absolute URLs in your HTML to include this - // folder name and does **not** affect where things go in the output folder. - pathPrefix: "/", - }; -}; + // When paired with the HTML plugin https://www.11ty.dev/docs/plugins/html-base/ + // it will transform any absolute URLs in your HTML to include this + // folder name and does **not** affect where things go in the output folder. + pathPrefix: "/", + }; +} diff --git a/flake.nix b/flake.nix index 5f0cdd3..0619c8c 100644 --- a/flake.nix +++ b/flake.nix @@ -1,62 +1,75 @@ { - description = "Bloggy time!"; + description = "Bloggy time!"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - deploy-rs.url = "github:serokell/deploy-rs"; + deploy-rs.url = "github:serokell/deploy-rs"; treefmt-nix.url = "github:numtide/treefmt-nix"; - }; + }; - outputs = { self, nixpkgs, deploy-rs, systems, treefmt-nix }: let - # systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; - forAllSystems = fn: - nixpkgs.lib.genAttrs (import systems) (system: fn nixpkgs.legacyPackages.${system}); + outputs = + { + self, + nixpkgs, + deploy-rs, + systems, + treefmt-nix, + }: + let + # systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; + forAllSystems = + fn: nixpkgs.lib.genAttrs (import systems) (system: fn nixpkgs.legacyPackages.${system}); - treefmtEval = forAllSystems (pkgs: treefmt-nix.lib.evalModule pkgs ./treefmt.nix); + treefmtEval = forAllSystems (pkgs: treefmt-nix.lib.evalModule pkgs ./treefmt.nix); - in { - apps = forAllSystems (pkgs: { - "deploy" = { - type = "app"; - program = let - ci = (pkgs.writeShellApplication { - name = "ci.sh"; - text = '' - nix build - ''; - }); - in "${ci}/ci.sh"; - }; - }); - packages = forAllSystems (pkgs: { - default = pkgs.callPackage ./package.nix {}; - }); - deploy.nodes.myblog = { - hostname = "saji.dev"; - profiles.mysite = { - sshUser = "static-site"; - user = "static-site"; - path = deploy-rs.lib.x86_64-linux.activate.custom self.packages.x86_64-linux.default '' - rm -rf /var/lib/static-site/public - ln -sn $PROFILE/public /var/lib/static-site/public - ''; - }; - }; + in + { + apps = forAllSystems (pkgs: { + "deploy" = { + type = "app"; + program = + let + ci = ( + pkgs.writeShellApplication { + name = "ci.sh"; + text = '' + nix build + ''; + } + ); + in + "${ci}/ci.sh"; + }; + }); + packages = forAllSystems (pkgs: { + default = pkgs.callPackage ./package.nix { }; + }); + deploy.nodes.myblog = { + hostname = "saji.dev"; + profiles.mysite = { + sshUser = "static-site"; + user = "static-site"; + path = deploy-rs.lib.x86_64-linux.activate.custom self.packages.x86_64-linux.default '' + rm -rf /var/lib/static-site/public + ln -sn $PROFILE/public /var/lib/static-site/public + ''; + }; + }; - formatter = forAllSystems (pkgs: treefmtEval.${pkgs.system}.config.build.wrapper); + formatter = forAllSystems (pkgs: treefmtEval.${pkgs.system}.config.build.wrapper); - checks = forAllSystems (pkgs: { - formatting = treefmtEval.${pkgs.system}.config.build.check self; - }); + checks = forAllSystems (pkgs: { + formatting = treefmtEval.${pkgs.system}.config.build.check self; + }); - devShells = forAllSystems (pkgs: { - default = pkgs.mkShell { - packages = with pkgs; [ - nodejs - vips - pkg-config - ]; - }; - }); - }; + devShells = forAllSystems (pkgs: { + default = pkgs.mkShell { + packages = with pkgs; [ + nodejs + vips + pkg-config + ]; + }; + }); + }; } diff --git a/markdown-it-figcaption.js b/markdown-it-figcaption.js index 88d8b13..b47420c 100644 --- a/markdown-it-figcaption.js +++ b/markdown-it-figcaption.js @@ -7,36 +7,40 @@ export default function figcaptionPlugin(md) { for (let i = 0; i < tokens.length; i++) { // Check for paragraph containing only an image if ( - tokens[i].type === 'paragraph_open' && + tokens[i].type === "paragraph_open" && i + 2 < tokens.length && - tokens[i + 1].type === 'inline' && + tokens[i + 1].type === "inline" && tokens[i + 1].children && tokens[i + 1].children.length === 1 && - tokens[i + 1].children[0].type === 'image' && - tokens[i + 2].type === 'paragraph_close' + tokens[i + 1].children[0].type === "image" && + tokens[i + 2].type === "paragraph_close" ) { // Check if the next token is a paragraph starting with emphasis if ( i + 5 < tokens.length && - tokens[i + 3].type === 'paragraph_open' && - tokens[i + 4].type === 'inline' && + tokens[i + 3].type === "paragraph_open" && + tokens[i + 4].type === "inline" && tokens[i + 4].children && tokens[i + 4].children.length > 0 && - tokens[i + 4].children[0].type === 'em_open' && - tokens[i + 5].type === 'paragraph_close' + tokens[i + 4].children[0].type === "em_open" && + tokens[i + 5].type === "paragraph_close" ) { figcaptionStartIndex = i + 3; // Start index of the caption paragraph // --- Replace tokens --- // 1. Change paragraph_open to figure_open - const figureOpen = new state.Token('figure_open', 'figure', 1); + const figureOpen = new state.Token("figure_open", "figure", 1); tokens[i] = figureOpen; // Replace paragraph_open // 2. Keep the inline token with the image as is (tokens[i+1]) // 3. Change paragraph_close to figcaption_open - const figcaptionOpen = new state.Token('figcaption_open', 'figcaption', 1); + const figcaptionOpen = new state.Token( + "figcaption_open", + "figcaption", + 1, + ); tokens[i + 2] = figcaptionOpen; // Replace paragraph_close // 4. Remove the caption's paragraph_open @@ -45,23 +49,29 @@ export default function figcaptionPlugin(md) { // 5. Modify the caption's inline content: remove outer tags const captionInlineToken = tokens[figcaptionStartIndex]; // Now at index i+3 after splice if ( - captionInlineToken.children[0].type === 'em_open' && - captionInlineToken.children[captionInlineToken.children.length - 1].type === 'em_close' + captionInlineToken.children[0].type === "em_open" && + captionInlineToken.children[captionInlineToken.children.length - 1] + .type === "em_close" ) { captionInlineToken.children.shift(); // Remove em_open captionInlineToken.children.pop(); // Remove em_close } // Adjust level for caption content captionInlineToken.level += 1; - captionInlineToken.children.forEach(child => { child.level += 1; }); - + captionInlineToken.children.forEach((child) => { + child.level += 1; + }); // 6. Change the caption's paragraph_close to figcaption_close - const figcaptionClose = new state.Token('figcaption_close', 'figcaption', -1); + const figcaptionClose = new state.Token( + "figcaption_close", + "figcaption", + -1, + ); tokens[figcaptionStartIndex + 1] = figcaptionClose; // Replace paragraph_close (now at i+4) // 7. Add figure_close after figcaption_close - const figureClose = new state.Token('figure_close', 'figure', -1); + const figureClose = new state.Token("figure_close", "figure", -1); tokens.splice(figcaptionStartIndex + 2, 0, figureClose); // Insert figure_close (at i+5) // Adjust token index to skip the newly inserted/modified tokens @@ -71,13 +81,27 @@ export default function figcaptionPlugin(md) { } } - md.core.ruler.after('inline', 'figcaption', figcaptionRule); + md.core.ruler.after("inline", "figcaption", figcaptionRule); // Add renderer rules if they don't exist - md.renderer.rules.figure_open = md.renderer.rules.figure_open || function () { return '
\n'; }; - md.renderer.rules.figure_close = md.renderer.rules.figure_close || function () { return '
\n'; }; - md.renderer.rules.figcaption_open = md.renderer.rules.figcaption_open || function () { return '
'; }; - md.renderer.rules.figcaption_close = md.renderer.rules.figcaption_close || function () { return '
\n'; }; + md.renderer.rules.figure_open = + md.renderer.rules.figure_open || + function () { + return "
\n"; + }; + md.renderer.rules.figure_close = + md.renderer.rules.figure_close || + function () { + return "
\n"; + }; + md.renderer.rules.figcaption_open = + md.renderer.rules.figcaption_open || + function () { + return "
"; + }; + md.renderer.rules.figcaption_close = + md.renderer.rules.figcaption_close || + function () { + return "
\n"; + }; } - - diff --git a/markdown-it-revealjs.js b/markdown-it-revealjs.js index 9ccd14c..0a9c86d 100644 --- a/markdown-it-revealjs.js +++ b/markdown-it-revealjs.js @@ -3,7 +3,6 @@ const HSEP = "---"; const VSEP = "==="; - /** * MarkdownIt plugin to generate revealjs friendly markup. * @@ -14,142 +13,140 @@ const VSEP = "==="; * @param {*} options */ export default function revealjs_plugin(md, options) { - function isVSep(token) { - return token.type === "inline" && token.content === VSEP; + function isVSep(token) { + return token.type === "inline" && token.content === VSEP; + } + + function isHSep(token) { + return token.type === "hr" && token.markup === HSEP; + } + + function isSep(token) { + return isHSep(token) || isVSep(token); + } + + function renderOpening(tokens, idx, options, env, slf) { + var token = tokens[idx]; + return `<${tokens[idx].tag}${slf.renderAttrs(tokens[idx])}>`; + } + + function renderClosing(tokens, idx, options, env, slf) { + var token = tokens[idx]; + return ``; + } + + md.renderer.rules.pres_open = renderOpening; + md.renderer.rules.pres_close = renderClosing; + md.renderer.rules.slide_open = renderOpening; + md.renderer.rules.slide_close = renderClosing; + + function nextDivider(tokens, start) { + for (let i = start; i < tokens.length; i++) { + if (isSep(tokens[i])) { + return i; + } } + return -1; + } - function isHSep(token) { - return token.type === "hr" && token.markup === HSEP; + function previousSlideOpen(tokens, before) { + for (let i = before - 1; i >= 0; i--) { + if (tokens[i].type === "slide_open") { + return i; + } } + return -1; + } - function isSep(token) { - return isHSep(token) || isVSep(token); - } + var openSlides = 0; - function renderOpening(tokens, idx, options, env, slf) { - var token = tokens[idx]; - return `<${tokens[idx].tag}${slf.renderAttrs(tokens[idx])}>`; - }; + function presentationOpen(state) { + var token = new state.Token("pres_open", "section", 1); + token.block = true; + token.attrs = [["class", "reveal"]]; + return token; + } - function renderClosing(tokens, idx, options, env, slf) { - var token = tokens[idx]; - return ``; - }; + function presentationClose(state) { + return new state.Token("pres_close", "section", -1); + } - md.renderer.rules.pres_open = renderOpening; - md.renderer.rules.pres_close = renderClosing; - md.renderer.rules.slide_open = renderOpening; - md.renderer.rules.slide_close = renderClosing; + function slidesOpen(state) { + var token = new state.Token("slides_open", "div", 1); + token.block = true; + token.attrs = [["class", "slides"]]; + return token; + } - function nextDivider(tokens, start) { - for (let i = start; i < tokens.length; i++) { - if (isSep(tokens[i])) { - return i; - } - } - return -1; - } + function slidesClose(state) { + return new state.Token("slides_close", "div", -1); + } - function previousSlideOpen(tokens, before) { - for (let i = before - 1; i >= 0; i--) { - if (tokens[i].type === "slide_open") { - return i; - } - } - return -1; - } + function slideOpen(state) { + openSlides++; + return new state.Token("slide_open", "section", 1); + } - var openSlides = 0; - - function presentationOpen(state) { - var token = new state.Token("pres_open", "section", 1); - token.block = true; - token.attrs = [ - ["class", "reveal"] - ]; - return token; - } - - function presentationClose(state) { - return new state.Token("pres_close", "section", -1); - } - - function slidesOpen(state) { - var token = new state.Token("slides_open", "div", 1); - token.block = true; - token.attrs = [ - ["class", "slides"] - ]; - return token; - } - - function slidesClose(state) { - return new state.Token("slides_close", "div", -1); - } - - function slideOpen(state) { - openSlides++; - return new state.Token("slide_open", "section", 1); - } - - function slideClose(state) { - openSlides--; - return new state.Token("slide_close", "section", -1); - } - - md.core.ruler.push("revealjs", function(state) { - let divIdx = 0; - while (true) { - divIdx = nextDivider(state.tokens, divIdx); - if (divIdx === -1) { - break; - } - let divider = state.tokens[divIdx]; - if (isSep(divider) && openSlides === 0) { - state.tokens.unshift(slideOpen(state)); - divIdx++; // we added a token at the beginning, we need to update divIdx - } - let tags = []; - if (isHSep(divider)) { - while (openSlides > 0) { - tags.push(slideClose(state)); - } - tags.push(slideOpen(state)); - // because "---" is hijacked from plain markdown, it translates - // to one token which we remove - state.tokens.splice(divIdx, 1, ...tags); - } else if (isVSep(divider)) { - // if it is a vertical separator, we need to wrap the current slide - // in it's own section - if (openSlides === 1) { - let slideOpenIdx = previousSlideOpen(state.tokens, divIdx); - state.tokens.splice(slideOpenIdx, 1, - state.tokens[slideOpenIdx], // reuse it to avoid increasing openSlides - slideOpen(state) - ); - divIdx++; // we added a token before the divider, we need to update divIdx - } - // if the current slide is already a vertical child, we need to close - // it; this will be indicated by a nesting level of two: - //
- //
- // - if (openSlides === 2) { - tags.push(slideClose(state)); - } - tags.push(slideOpen(state)); - // because this is a custom token, it is first wrapped by the processor - // in a paragraph, so we need to replace para_open, sep, para_close - state.tokens.splice(divIdx - 1, 3, ...tags); - } - } + function slideClose(state) { + openSlides--; + return new state.Token("slide_close", "section", -1); + } + md.core.ruler.push("revealjs", function (state) { + let divIdx = 0; + while (true) { + divIdx = nextDivider(state.tokens, divIdx); + if (divIdx === -1) { + break; + } + let divider = state.tokens[divIdx]; + if (isSep(divider) && openSlides === 0) { + state.tokens.unshift(slideOpen(state)); + divIdx++; // we added a token at the beginning, we need to update divIdx + } + let tags = []; + if (isHSep(divider)) { while (openSlides > 0) { - state.tokens.push(slideClose(state)); + tags.push(slideClose(state)); } - state.tokens.unshift(slidesOpen(state)); - state.tokens.unshift(presentationOpen(state)); - state.tokens.push(slidesClose(state)); - state.tokens.push(presentationClose(state)); - }); -}; + tags.push(slideOpen(state)); + // because "---" is hijacked from plain markdown, it translates + // to one token which we remove + state.tokens.splice(divIdx, 1, ...tags); + } else if (isVSep(divider)) { + // if it is a vertical separator, we need to wrap the current slide + // in it's own section + if (openSlides === 1) { + let slideOpenIdx = previousSlideOpen(state.tokens, divIdx); + state.tokens.splice( + slideOpenIdx, + 1, + state.tokens[slideOpenIdx], // reuse it to avoid increasing openSlides + slideOpen(state), + ); + divIdx++; // we added a token before the divider, we need to update divIdx + } + // if the current slide is already a vertical child, we need to close + // it; this will be indicated by a nesting level of two: + //
+ //
+ // + if (openSlides === 2) { + tags.push(slideClose(state)); + } + tags.push(slideOpen(state)); + // because this is a custom token, it is first wrapped by the processor + // in a paragraph, so we need to replace para_open, sep, para_close + state.tokens.splice(divIdx - 1, 3, ...tags); + } + } + + while (openSlides > 0) { + state.tokens.push(slideClose(state)); + } + state.tokens.unshift(slidesOpen(state)); + state.tokens.unshift(presentationOpen(state)); + state.tokens.push(slidesClose(state)); + state.tokens.push(presentationClose(state)); + }); +} diff --git a/package.json b/package.json index 80de56b..7dc7fe3 100644 --- a/package.json +++ b/package.json @@ -1,41 +1,41 @@ { - "name": "eleventy-base-blog", - "version": "8.0.0", - "description": "A starter repository for a blog web site using the Eleventy site generator.", - "scripts": { - "build": "npx @11ty/eleventy", - "build-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/", - "start": "npx @11ty/eleventy --serve --quiet", - "debug": "DEBUG=Eleventy* npx @11ty/eleventy", - "debugstart": "DEBUG=Eleventy* npx @11ty/eleventy --serve --quiet", - "benchmark": "DEBUG=Eleventy:Benchmark* npx @11ty/eleventy" - }, - "type": "module", - "repository": { - "type": "git", - "url": "git://github.com/11ty/eleventy-base-blog.git" - }, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "dependencies": { - "@11ty/eleventy": "^3.0.0", - "@11ty/eleventy-img": "^4.0.2", - "@vscode/markdown-it-katex": "^1.1.1", - "katex": "^0.16.22", - "markdown-it-abbr": "^2.0.0", - "markdown-it-container": "^4.0.0", - "reveal.js": "^5.2.1", - "ttf2woff2": "^6.0.1" - }, - "devDependencies": { - "@11ty/eleventy-navigation": "^0.3.5", - "@11ty/eleventy-plugin-bundle": "^1.0.4", - "@11ty/eleventy-plugin-rss": "^2.0.2", - "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", - "luxon": "^3.3.0", - "markdown-it-anchor": "^8.6.7" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + "name": "eleventy-base-blog", + "version": "8.0.0", + "description": "A starter repository for a blog web site using the Eleventy site generator.", + "scripts": { + "build": "npx @11ty/eleventy", + "build-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/", + "start": "npx @11ty/eleventy --serve --quiet", + "debug": "DEBUG=Eleventy* npx @11ty/eleventy", + "debugstart": "DEBUG=Eleventy* npx @11ty/eleventy --serve --quiet", + "benchmark": "DEBUG=Eleventy:Benchmark* npx @11ty/eleventy" + }, + "type": "module", + "repository": { + "type": "git", + "url": "git://github.com/11ty/eleventy-base-blog.git" + }, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "dependencies": { + "@11ty/eleventy": "^3.0.0", + "@11ty/eleventy-img": "^4.0.2", + "@vscode/markdown-it-katex": "^1.1.1", + "katex": "^0.16.22", + "markdown-it-abbr": "^2.0.0", + "markdown-it-container": "^4.0.0", + "reveal.js": "^5.2.1", + "ttf2woff2": "^6.0.1" + }, + "devDependencies": { + "@11ty/eleventy-navigation": "^0.3.5", + "@11ty/eleventy-plugin-bundle": "^1.0.4", + "@11ty/eleventy-plugin-rss": "^2.0.2", + "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", + "luxon": "^3.3.0", + "markdown-it-anchor": "^8.6.7" + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/package.nix b/package.nix index 5282464..b099ed5 100644 --- a/package.nix +++ b/package.nix @@ -1,32 +1,33 @@ { - nodejs, - pkg-config, - buildNpmPackage, - importNpmLock, - vips, + nodejs, + pkg-config, + buildNpmPackage, + importNpmLock, + vips, lib, -}: buildNpmPackage { - name = "myblog"; - version = "unstable"; - buildInputs = [ - ]; - nativeBuildInputs = [ - pkg-config - nodejs - vips - ]; - npmDeps = importNpmLock { - npmRoot = ./.; - }; - npmConfigHook = importNpmLock.npmConfigHook; - src = ./.; - installPhase = '' - mkdir -p $out/public - cp -ar _site/* $out/public/ - ''; - meta = { - description = "My blog, yay"; - homepage = "https://saji.dev"; - platforms = lib.platforms.all; - }; +}: +buildNpmPackage { + name = "myblog"; + version = "unstable"; + buildInputs = [ + ]; + nativeBuildInputs = [ + pkg-config + nodejs + vips + ]; + npmDeps = importNpmLock { + npmRoot = ./.; + }; + npmConfigHook = importNpmLock.npmConfigHook; + src = ./.; + installPhase = '' + mkdir -p $out/public + cp -ar _site/* $out/public/ + ''; + meta = { + description = "My blog, yay"; + homepage = "https://saji.dev"; + platforms = lib.platforms.all; + }; } diff --git a/public/css/fonts.css b/public/css/fonts.css index a54e1ae..fec7426 100644 --- a/public/css/fonts.css +++ b/public/css/fonts.css @@ -1,46 +1,51 @@ @font-face { - font-family: 'WO3'; - src: url('/fonts/WO3.woff2') format('woff2'), - url('/fonts/WO3.ttf') format('ttf'); - font-weight: normal; - font-style: normal; + font-family: "WO3"; + src: + url("/fonts/WO3.woff2") format("woff2"), + url("/fonts/WO3.ttf") format("ttf"); + font-weight: normal; + font-style: normal; } @font-face { - font-family: "wip3out"; - src: url('/fonts/wip3out.woff2') format('woff2'), - url('/fonts/wip3out.ttf') format('ttf'); - font-weight: normal; - font-style: normal; - font-stretch: semi-expanded; + font-family: "wip3out"; + src: + url("/fonts/wip3out.woff2") format("woff2"), + url("/fonts/wip3out.ttf") format("ttf"); + font-weight: normal; + font-style: normal; + font-stretch: semi-expanded; } @font-face { - font-family: 'SometypeMono'; - src: url('/fonts/SometypeMono-Regular.woff2') format('woff2'), - url('/fonts/SometypeMono-Regular.ttf') format('ttf') ; - font-weight: normal; - font-style: normal; + font-family: "SometypeMono"; + src: + url("/fonts/SometypeMono-Regular.woff2") format("woff2"), + url("/fonts/SometypeMono-Regular.ttf") format("ttf"); + font-weight: normal; + font-style: normal; } @font-face { - font-family: 'SometypeMono'; - src: url('/fonts/SometypeMono-Bold.woff2') format('woff2'), - url('/fonts/SometypeMono-Bold.ttf') format('ttf') ; - font-weight: bold; - font-style: normal; + font-family: "SometypeMono"; + src: + url("/fonts/SometypeMono-Bold.woff2") format("woff2"), + url("/fonts/SometypeMono-Bold.ttf") format("ttf"); + font-weight: bold; + font-style: normal; } @font-face { - font-family: 'SometypeMono'; - src: url('/fonts/SometypeMono-Medium.woff2') format('woff2'), - url('/fonts/SometypeMono-Medium.ttf') format('ttf') ; - font-weight: 500; - font-style: normal; + font-family: "SometypeMono"; + src: + url("/fonts/SometypeMono-Medium.woff2") format("woff2"), + url("/fonts/SometypeMono-Medium.ttf") format("ttf"); + font-weight: 500; + font-style: normal; } @font-face { - font-family: "Orbitron"; - src: url('/fonts/Orbitron-VariableFont_wght.woff2') format('woff2'); - font-weight: 600; - font-style: normal; -} \ No newline at end of file + font-family: "Orbitron"; + src: url("/fonts/Orbitron-VariableFont_wght.woff2") format("woff2"); + font-weight: 600; + font-style: normal; +} diff --git a/public/css/index.css b/public/css/index.css index 2b6bf0c..aacdf9c 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -1,288 +1,284 @@ /* Defaults */ :root { - /* --font-family: -apple-system, system-ui, sans-serif; */ - --font-family: SometypeMono; - --font-family-monospace: SometypeMono; + /* --font-family: -apple-system, system-ui, sans-serif; */ + --font-family: SometypeMono; + --font-family-monospace: SometypeMono; } /* Theme colors */ :root { + --text-color-link: var(--color-cyan); + --text-color-link-active: var(--color-cyan-bright); + --text-color-link-visited: var(--color-cyan); - - --text-color-link: var(--color-cyan); - --text-color-link-active: var(--color-cyan-bright); - --text-color-link-visited: var(--color-cyan); - - --syntax-tab-size: 2; + --syntax-tab-size: 2; } @media (prefers-color-scheme: dark) { - :root { - - /* --text-color is assigned to --color-gray-_ above */ - /* --text-color-link: #1493fb; */ - /* --text-color-link-active: #6969f7; */ - /* --text-color-link-visited: #a6a6f8; */ - --text-color-link: var(--color-cyan); - --text-color-link-active: var(--color-cyan-bright); - --text-color-link-visited: var(--color-cyan); - - } + :root { + /* --text-color is assigned to --color-gray-_ above */ + /* --text-color-link: #1493fb; */ + /* --text-color-link-active: #6969f7; */ + /* --text-color-link-visited: #a6a6f8; */ + --text-color-link: var(--color-cyan); + --text-color-link-active: var(--color-cyan-bright); + --text-color-link-visited: var(--color-cyan); + } } - /* list style custom */ ul { - /* list-style: symbols(cyclic "\25E5" "\25E2" "\25E3" "\25E4"); */ - list-style: symbols(cyclic "\25E9"); + /* list-style: symbols(cyclic "\25E5" "\25E2" "\25E3" "\25E4"); */ + list-style: symbols(cyclic "\25E9"); } /* Global stylesheet */ * { - box-sizing: border-box; + box-sizing: border-box; } html, body { - padding: 0; - margin: 0 auto; - font-family: var(--font-family); - color: var(--color-fg); - background-color: var(--color-bg); + padding: 0; + margin: 0 auto; + font-family: var(--font-family); + color: var(--color-fg); + background-color: var(--color-bg); } html { - overflow-y: scroll; + overflow-y: scroll; } body { - max-width: 40em; + max-width: 40em; } img { - max-width: 100%; - height: auto; + max-width: 100%; + height: auto; } /* https://www.a11yproject.com/posts/how-to-hide-content/ */ .visually-hidden { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; } p:last-child { - margin-bottom: 0; + margin-bottom: 0; } p { - line-height: 1.5; + line-height: 1.5; } li { - line-height: 1.5; + line-height: 1.5; } a[href] { - color: var(--text-color-link); + color: var(--text-color-link); } a[href]:visited { - color: var(--text-color-link-visited); + color: var(--text-color-link-visited); } a[href]:hover, a[href]:active { - color: var(--text-color-link-active); + color: var(--text-color-link-active); } main { - padding: 1rem; + padding: 1rem; } main :first-child { - margin-top: 0; + margin-top: 0; } header { - border-bottom: 1px dashed var(--color-white); + border-bottom: 1px dashed var(--color-white); } header:after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } .links-nextprev { - list-style: none; - border-top: 1px dashed var(--color-white); - padding: 1em 0; + list-style: none; + border-top: 1px dashed var(--color-white); + padding: 1em 0; } table { - margin: 1em 0; + margin: 1em 0; } table td, table th { - padding-right: 1em; + padding-right: 1em; } pre, code { - font-family: var(--font-family-monospace); + font-family: var(--font-family-monospace); } pre:not([class*="language-"]) { - margin: .5em 0; - line-height: 1.375; /* 22px /16 */ - -moz-tab-size: var(--syntax-tab-size); - -o-tab-size: var(--syntax-tab-size); - tab-size: var(--syntax-tab-size); - -webkit-hyphens: none; - -ms-hyphens: none; - hyphens: none; - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; + margin: 0.5em 0; + line-height: 1.375; /* 22px /16 */ + -moz-tab-size: var(--syntax-tab-size); + -o-tab-size: var(--syntax-tab-size); + tab-size: var(--syntax-tab-size); + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; } code { - /* word-break: break-all; */ + /* word-break: break-all; */ - color: var(--color-black); - background-color: var(--color-white); + color: var(--color-black); + background-color: var(--color-white); } /* Header */ header { - display: flex; - gap: 1em .5em; - flex-wrap: wrap; - align-items: center; - padding: 1em; + display: flex; + gap: 1em 0.5em; + flex-wrap: wrap; + align-items: center; + padding: 1em; } .home-link { - font-size: 1em; /* 16px /16 */ - font-weight: 700; - margin-right: 2em; + font-size: 1em; /* 16px /16 */ + font-weight: 700; + margin-right: 2em; } .home-link:link:not(:hover) { - text-decoration: none; + text-decoration: none; } /* Nav */ .nav { - display: flex; - padding: 0; - margin: 0; - list-style: none; + display: flex; + padding: 0; + margin: 0; + list-style: none; } .nav-item { - display: inline-block; - margin-right: 1em; + display: inline-block; + margin-right: 1em; } .nav-item a[href]:not(:hover) { - text-decoration: none; + text-decoration: none; } .nav a[href][aria-current="page"] { - text-decoration: underline; + text-decoration: underline; } /* Posts list */ .postlist { - list-style: none; - padding: 0; - padding-left: 1.5rem; + list-style: none; + padding: 0; + padding-left: 1.5rem; } .postlist-item { - display: flex; - flex-wrap: wrap; - align-items: baseline; - counter-increment: start-from -1; - margin-bottom: 1em; + display: flex; + flex-wrap: wrap; + align-items: baseline; + counter-increment: start-from -1; + margin-bottom: 1em; } .postlist-item:before { - display: inline-block; - pointer-events: none; - content: "" counter(start-from, decimal-leading-zero) ". "; - line-height: 100%; - text-align: right; - margin-left: -1.5rem; + display: inline-block; + pointer-events: none; + content: "" counter(start-from, decimal-leading-zero) ". "; + line-height: 100%; + text-align: right; + margin-left: -1.5rem; } .postlist-date, .postlist-item:before { - font-size: 0.8125em; /* 13px /16 */ - color: var(--color-gray-90); + font-size: 0.8125em; /* 13px /16 */ + color: var(--color-gray-90); } .postlist-date { - word-spacing: -0.5px; + word-spacing: -0.5px; } .postlist-link { - font-size: 1.1875em; /* 19px /16 */ - font-weight: 700; - flex-basis: calc(100% - 1.5rem); - padding-left: .25em; - padding-right: .5em; - text-underline-position: from-font; - text-underline-offset: 0; - text-decoration-thickness: 1px; + font-size: 1.1875em; /* 19px /16 */ + font-weight: 700; + flex-basis: calc(100% - 1.5rem); + padding-left: 0.25em; + padding-right: 0.5em; + text-underline-position: from-font; + text-underline-offset: 0; + text-decoration-thickness: 1px; } .postlist-item-active .postlist-link { - font-weight: bold; + font-weight: bold; } /* Tags */ .post-tag { - display: inline-flex; - align-items: center; - justify-content: center; - text-transform: capitalize; - font-style: italic; + display: inline-flex; + align-items: center; + justify-content: center; + text-transform: capitalize; + font-style: italic; } .postlist-item > .post-tag { - align-self: center; + align-self: center; } /* Tags list */ .post-metadata { - display: inline-flex; - flex-wrap: wrap; - gap: .5em; - list-style: none; - padding: 0; - margin: 0; + display: inline-flex; + flex-wrap: wrap; + gap: 0.5em; + list-style: none; + padding: 0; + margin: 0; } .post-metadata time { - margin-right: 1em; + margin-right: 1em; } /* Direct Links / Markdown Headers */ .header-anchor { - text-decoration: none; - font-style: normal; - font-size: 1em; - margin-left: .1em; + text-decoration: none; + font-style: normal; + font-size: 1em; + margin-left: 0.1em; } a[href].header-anchor, a[href].header-anchor:visited { - color: transparent; + color: transparent; } a[href].header-anchor:focus, a[href].header-anchor:hover { - text-decoration: underline; + text-decoration: underline; } a[href].header-anchor:focus, :hover > a[href].header-anchor { - color: #aaa; + color: #aaa; } h2 + .header-anchor { - font-size: 1.5em; + font-size: 1.5em; } -h1, h2, h3 { - font-family: WO3; - letter-spacing: .1rem; +h1, +h2, +h3 { + font-family: WO3; + letter-spacing: 0.1rem; } - /* blockquote styling */ blockquote { @@ -299,7 +295,7 @@ blockquote p { /* Top-left corner bracket */ blockquote::before { - content: ''; + content: ""; position: absolute; top: 0.5em; /* Adjust position */ left: 0.5em; /* Adjust position */ @@ -312,7 +308,7 @@ blockquote::before { /* Bottom-right corner bracket */ blockquote::after { - content: ''; + content: ""; position: absolute; bottom: 0.5em; /* Adjust position */ right: 0.5em; /* Adjust position */ @@ -322,4 +318,3 @@ blockquote::after { border-right: 3px solid var(--color-white); /* White border, adjust thickness */ box-sizing: border-box; } - diff --git a/public/css/prism-diff.css b/public/css/prism-diff.css index 9f7e676..a0dae68 100644 --- a/public/css/prism-diff.css +++ b/public/css/prism-diff.css @@ -3,43 +3,43 @@ */ pre[class*="language-diff-"] { - --eleventy-code-padding: 1.25em; - padding-left: var(--eleventy-code-padding); - padding-right: var(--eleventy-code-padding); + --eleventy-code-padding: 1.25em; + padding-left: var(--eleventy-code-padding); + padding-right: var(--eleventy-code-padding); } .token.deleted { - background-color: hsl(0, 51%, 37%); - color: inherit; + background-color: hsl(0, 51%, 37%); + color: inherit; } .token.inserted { - background-color: hsl(126, 31%, 39%); - color: inherit; + background-color: hsl(126, 31%, 39%); + color: inherit; } /* Make the + and - characters unselectable for copy/paste */ .token.prefix.unchanged, .token.prefix.inserted, .token.prefix.deleted { - -webkit-user-select: none; - user-select: none; - display: inline-flex; - align-items: center; - justify-content: center; - padding-top: 2px; - padding-bottom: 2px; + -webkit-user-select: none; + user-select: none; + display: inline-flex; + align-items: center; + justify-content: center; + padding-top: 2px; + padding-bottom: 2px; } .token.prefix.inserted, .token.prefix.deleted { - width: var(--eleventy-code-padding); - background-color: rgba(0,0,0,.2); + width: var(--eleventy-code-padding); + background-color: rgba(0, 0, 0, 0.2); } /* Optional: full-width background color */ .token.inserted:not(.prefix), .token.deleted:not(.prefix) { - display: block; - margin-left: calc(-1 * var(--eleventy-code-padding)); - margin-right: calc(-1 * var(--eleventy-code-padding)); - text-decoration: none; /* override del, ins, mark defaults */ - color: inherit; /* override del, ins, mark defaults */ + display: block; + margin-left: calc(-1 * var(--eleventy-code-padding)); + margin-right: calc(-1 * var(--eleventy-code-padding)); + text-decoration: none; /* override del, ins, mark defaults */ + color: inherit; /* override del, ins, mark defaults */ }