The blog has always been markdown-first. Write a .md file, run the build script, and get a fully styled HTML page. This workflow was frictionless for text content, but what happens when you need an interactive visualization?
This post documents how we extended the system to support inline scripts and styles—and includes live demos you can play with right now.
the problem
I wanted to add an interactive algorithm visualization to blog post 017. The visualization needed custom CSS, JavaScript functions, event handlers, and dynamic DOM updates.
The existing system couldn't handle this. Markdown files became HTML through marked.js, but there was no way to inject custom scripts or styles into individual posts.
the solution: frontmatter injection
We extended the YAML frontmatter to accept inlineStyles and inlineScripts fields:
--- title: "Post Title" inlineStyles: | .custom-class { color: #55ff55; } inlineScripts: | function demo() { alert('hello!'); } ---The build script extracts these fields and injects them into the HTML template. Simple, clean, backward compatible.
live demos
Let's see what this enables. Try these interactive examples—they're all powered by the inline script system.
demo 1: terminal greeting
Type your name and press enter (or click the button).
How it works: The greetUser() function is defined in the frontmatter's inlineScripts. When you click the button, it reads the input, processes it, and updates the output div with terminal-style text.
demo 2: terminal color palette
Click the buttons to change the color. This demonstrates CSS variable updates from JavaScript.
How it works: The changeColor() function updates the swatch's background color and adds a glow effect using inline styles. All the color definitions are in the frontmatter CSS.
demo 3: click counter
A simple state management demo. See how many clicks you can get.
How it works: JavaScript maintains a clickCount variable. The buttons call functions that modify the count and update the DOM. The color changes when you hit certain thresholds.
demo 4: matrix rain mini
The classic Matrix falling characters effect—in your blog post.
How it works: A Canvas 2D context with an interval-based animation loop. The startMatrix() function creates falling characters using Unicode characters and alpha blending for the trail effect.
implementation details
The system works through three simple changes:
1. Build script extraction - Modified blog/scripts/build.js to extract inlineStyles and inlineScripts from frontmatter and inject them into the HTML template using placeholder replacement.
2. Template injection points - Added placeholder markers to blog/templates/post.html that get replaced during build with the actual CSS and JavaScript from frontmatter.
3. Frontmatter fields - Added two optional YAML fields (inlineStyles and inlineScripts) that accept multi-line CSS and JavaScript code blocks.
For developers interested in the implementation details, see the source code on GitHub - view the raw markdown to see the frontmatter with all 170 lines of CSS and 94 lines of JavaScript powering the demos above.
markdown HTML rules
When embedding HTML in markdown for these demos, critical rules:
- No blank lines within the HTML block—markdown parsers reset on blank lines
- Consistent indentation—keeps the parser happy
- Treat as single unit—the entire HTML block should flow without interruption
Example of what not to do:
<div class="demo"> <button>Click</button> <div class="output"></div> <!-- blank line above breaks this --> </div>Example of what works:
<div class="demo"> <button>Click</button> <div class="output"></div> </div>what this enables
The inline script system makes these possible:
Algorithm visualizations - Like the sorting visualizer in post 017, with state tracking and step-by-step execution.
Interactive code playgrounds - Users can modify code and see results instantly.
Data visualizations - Charts, graphs, and diagrams that update based on user input.
Games - Simple browser games embedded directly in blog posts.
Calculators and tools - Practical utilities that solve real problems.
All of this while maintaining the markdown-first philosophy. No complex build pipeline, no frontend framework, just YAML frontmatter and vanilla JavaScript.
benefits
Separation of concerns: Content lives in markdown, styling in CSS, behavior in JavaScript—all colocated in one file.
Backward compatibility: Posts without inline scripts work perfectly. Old posts don't break.
Terminal aesthetic preservation: Custom CSS ensures every interactive element matches the 90s BBS aesthetic.
Maintainability: Fix a bug? Edit the frontmatter, rebuild. No scattered files or complex refactors.
Performance: Static HTML generation means fast page loads. JavaScript only runs for interactive features.
the full picture
This post demonstrates the inline script system by using it—all four demos above are powered by CSS and JavaScript in the frontmatter. The algorithm visualization in post 017 takes it further with a complete step-by-step execution interface.
The blog remains what it's always been: text files that become beautiful, functional web pages. No build complexity, no frameworks—just markdown, YAML, and vanilla JavaScript.
Try the demos above. Every button click, color change, and matrix character proves the system works. The blog is no longer just static text—it's an interactive platform.