<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: RequieMa</title>
    <description>The latest articles on DEV Community by RequieMa (@requiema).</description>
    <link>https://dev.to/requiema</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4023392%2Fbe2db4cb-1874-4795-ba6d-c3e272ff04ac.png</url>
      <title>DEV Community: RequieMa</title>
      <link>https://dev.to/requiema</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/requiema"/>
    <language>en</language>
    <item>
      <title>Farewell, All VS Code Preview Panes</title>
      <dc:creator>RequieMa</dc:creator>
      <pubDate>Sat, 18 Jul 2026 13:51:56 +0000</pubDate>
      <link>https://dev.to/requiema/farewell-all-vs-code-preview-panes-9db</link>
      <guid>https://dev.to/requiema/farewell-all-vs-code-preview-panes-9db</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is about my &lt;a href="https://marketplace.visualstudio.com/items?itemName=RequieMa.myst-notebook" rel="noopener noreferrer"&gt;VS Code Extension&lt;/a&gt;. Also &lt;a href="https://github.com/RequieMa/myst-notebook" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We've probably all gotten used to it...&lt;/p&gt;

&lt;p&gt;Writing Markdown on the left side of VS Code, then glancing over to the right to check the rendered result. And it never quite lines up!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa9hoga57eivb9j9fe0wm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa9hoga57eivb9j9fe0wm.png" alt="bad preview" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The maddening math symbols. Writing an article on math or physics means embedding formulas in every paragraph. &lt;code&gt;\mathcal{L}&lt;/code&gt; for the Lagrangian, &lt;code&gt;\boldsymbol{\theta}&lt;/code&gt; for the parameter vector, &lt;code&gt;\partial&lt;/code&gt; for the partial derivative. Every single one typed out in full. You've tried memorizing shortcuts, or keeping another file open for frequently-used snippets, or even scrolling all the way up to copy-paste a formula and then editing it.&lt;/p&gt;

&lt;p&gt;Every extra LaTeX formula adds another layer of friction. Something that should take two or three sentences ends up sending your mouse and eyes back and forth four or five times.&lt;/p&gt;

&lt;p&gt;Have you ever asked yourself: &lt;strong&gt;Why do I keep having to let go of the keyboard, reach for the mouse, and hunt through the text, when all I want to do is simply typing? Every one of these actions breaks my thought!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You may say: Just switch tools. There are plenty of Markdown editors out there, some with pretty advanced features.&lt;/p&gt;

&lt;p&gt;But, my friend, isn't VS Code a text editor? &lt;strong&gt;Why on earth can't I edit a text in a TEXT EDITOR!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The prize pool keeps stacking up...&lt;/p&gt;

&lt;p&gt;If you also like using MyST, then congratulations. The Python code in your &lt;code&gt;{code-cell}&lt;/code&gt; blocks actually runs, and your readers get to see the beautiful outputs.&lt;/p&gt;

&lt;p&gt;But what about you? Can you see them? All you see while typing is Markdown. You either trust that your codes, or secretly write up a &lt;code&gt;.py&lt;/code&gt; file somewhere else to test it.&lt;/p&gt;

&lt;p&gt;You may say: Why not just use Jupyter Notebook? It natively blends code with Markdown output.&lt;/p&gt;

&lt;p&gt;But have you ever opened a &lt;code&gt;.ipynb&lt;/code&gt; git diff? It's an entire JSON structure nesting base64-encoded output blobs. A two-line code change produces a mountain of diff. Merge conflicts? Best wishes.&lt;/p&gt;

&lt;p&gt;Plus, it's heavy!&lt;/p&gt;

&lt;p&gt;You just want to write an article — why do you have to suffer so much? &lt;strong&gt;Just because it's always been this way, does that make it the right way?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  There Are Not Four Problems — It's One
&lt;/h2&gt;

&lt;p&gt;These four pain points seem scattered — split panes, formulas, code output, format bloat.&lt;/p&gt;

&lt;p&gt;But they all point to the same root cause: &lt;strong&gt;We've separated "writing" from "seeing."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So why not make it &lt;strong&gt;what you write is what you see&lt;/strong&gt;, and &lt;strong&gt;what you see is what you saved&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Every character you type on the keyboard transforms in-place into its final form the moment your focus leaves it. No second pane, no build step, no JSON wrapping. Your &lt;code&gt;.md&lt;/code&gt; file stays a &lt;code&gt;.md&lt;/code&gt; file — it is its own notebook.&lt;/p&gt;

&lt;p&gt;I've always wanted this. I couldn't find it anywhere, and at one point it even dampened my own enthusiasm for writing.&lt;/p&gt;

&lt;p&gt;So, I built one!&lt;/p&gt;




&lt;h2&gt;
  
  
  And So, MyST Notebook
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/RequieMa/myst-notebook" rel="noopener noreferrer"&gt;MyST Notebook&lt;/a&gt; is a VS Code extension. What it does is simple: &lt;strong&gt;it turns &lt;code&gt;.md&lt;/code&gt; files into a native notebook editor experience inside VS Code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The core insight comes down to one sentence: since VS Code 1.85, the notebook editor API has matured enough to support custom notebook types. No need to invent a new editor, no Electron wrappers — the editor you're already using is the best host.&lt;/p&gt;

&lt;p&gt;Let's revisit those pain points one by one:&lt;/p&gt;

&lt;h3&gt;
  
  
  Preview Pane → Inline Rendering
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkfbxqy33j7qh7fu8qxnz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkfbxqy33j7qh7fu8qxnz.gif" alt="demo-render" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In MyST Notebook, there is no concept of "preview." You write a paragraph, press Enter to jump to the next cell, and the paragraph you just wrote renders in place. Headings, bold, links, lists, blockquotes — all visible in real time.&lt;/p&gt;

&lt;p&gt;Your eyes no longer dart left and right. Your screen no longer splits in half. What you see is what your readers will ultimately see.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An honest note:&lt;/strong&gt; MyST colon fence directives (&lt;code&gt;:::{note}&lt;/code&gt;, &lt;code&gt;:::{warning}&lt;/code&gt;, etc.) cannot yet be rendered inline in the editor — this is an architectural limitation of the VS Code notebook renderer's &lt;code&gt;md.renderInline()&lt;/code&gt;, and there's no way around it for now. While editing, they appear as plain text; &lt;code&gt;jupyter-book build&lt;/code&gt; will handle the final output correctly. This is the one compromise in v0.1 that bothers me the most, and I'll keep exploring solutions in future versions. If any fellow devs have good ideas, feel free to reach out anytime.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  LaTeX Hell → Math Panel + Autocomplete
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmq776e0ige43e5s2adwj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmq776e0ige43e5s2adwj.gif" alt="demo-math" width="760" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;\mathcal&lt;/code&gt; takes just four keystrokes. Even more commonly, &lt;code&gt;Ctrl+Shift+M&lt;/code&gt; opens the math symbol panel — recently used symbols appear at the top, one click to insert.&lt;/p&gt;

&lt;p&gt;Also, if you want (like me personally), the whole interaction can be done with keyboard only.&lt;/p&gt;

&lt;p&gt;And if you prefer the mouse, the Math Palette sidebar keeps every symbol you've ever typed, ready to click.&lt;/p&gt;

&lt;p&gt;This feature is actually tiny, just a handful of lines of code. But it saves you dozens of "type out the same LaTeX command" actions every single day. The flow of writing is built on eliminating these micro-frictions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can't See Python Output → Inline Code Execution
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwa6cqqh7ah1an8obu4iw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwa6cqqh7ah1an8obu4iw.gif" alt="demo-run" width="560" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ctrl+Shift+E&lt;/code&gt; toggles the current cell into a &lt;code&gt;{code-cell}&lt;/code&gt;, &lt;code&gt;Shift+Enter&lt;/code&gt; runs it. (You can also use &lt;strong&gt;MyST: Insert Executable Cell&lt;/strong&gt; from the command palette to insert a new one.) MyST Notebook manages the Jupyter kernel itself — no need to install the Jupyter extension, no need to start a server separately. It automatically discovers your Python environment, auto-installs &lt;code&gt;ipykernel&lt;/code&gt; and &lt;code&gt;jupyter-server&lt;/code&gt; (if they're missing), and streams the output below the cell in real time.&lt;/p&gt;

&lt;p&gt;The code you write shows you the result immediately. No build step, no "going backstage."&lt;/p&gt;

&lt;p&gt;Kernel died? It auto-restarts on the next run. Want to switch Python environments? Bring up &lt;strong&gt;MyST: Reinstall Runtime&lt;/strong&gt; from the command palette and pick again. Need to send SIGINT to a runaway loop? &lt;strong&gt;MyST: Interrupt Kernel&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's it. Write code, run code, see output. You focus on content, not environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Too Heavy → Plain &lt;code&gt;.md&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;MyST Notebook&lt;/code&gt; doesn't create a new file format. Your article is just a plain &lt;code&gt;.md&lt;/code&gt; file, sitting quietly in &lt;code&gt;docs/blog/posts/&lt;/code&gt;, perfectly compatible with &lt;code&gt;jupyter-book build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From Git's perspective, it's plain text. Fix a typo, and the diff shows only that one changed line. Two people editing different paragraphs in the same file? A normal merge, not JSON hell.&lt;/p&gt;

&lt;p&gt;And in the age of AI, plain Markdown is naturally agent-friendly too.&lt;/p&gt;

&lt;p&gt;Your writing output is forever-readable, forever-portable plain text. The extension is just a view — close it, and your article is still complete.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Following Is Not a Promo — This Is My Own Tool
&lt;/h2&gt;

&lt;p&gt;There are a few features I didn't originally plan to build, but added after using it myself for a week, because I kept noticing "something's missing here":&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto-split.&lt;/strong&gt; Press Enter after finishing a paragraph, and a new cell is automatically created with the cursor in place. No clicking an "add cell" button with the mouse, no memorizing shortcuts — just like pressing Enter for a new line. This is the feature that most impacts writing rhythm, yet it sounds the most trivial when you say it out loud.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge graph.&lt;/strong&gt; &lt;code&gt;Ctrl+Shift+G&lt;/code&gt; opens a D3 force-directed graph showing all &lt;code&gt;[[wikilinks]]&lt;/code&gt; and &lt;code&gt;{cite}&lt;/code&gt; references and backlinks in the current file. It was originally meant for navigating between notes, but I later discovered — when writing a book, using it to see the relationships between chapters is far more intuitive than hunting through the file tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxxidgtu30cej9g75voq4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxxidgtu30cej9g75voq4.gif" alt="demo-graph" width="560" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zotero citations.&lt;/strong&gt; Because I need to cite papers when I write. One command to configure, then &lt;code&gt;Alt+Shift+Z&lt;/code&gt; brings up the reference picker — select one and it inserts &lt;code&gt;{cite}&lt;/code&gt;. WSL2 users need a bit of extra network configuration; it's documented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shorthand fences.&lt;/strong&gt; In a prose cell, type &lt;code&gt;&lt;/code&gt;&lt;code&gt;run&lt;/code&gt;&lt;code&gt;then Enter, and it auto-expands into a&lt;/code&gt;{code-cell}&lt;code&gt;code block. Type&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;show&lt;/code&gt; and it expands into a display-only code block. Once muscle memory kicks in, it's faster than shortcuts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tools Should Fade Into the Background
&lt;/h2&gt;

&lt;p&gt;I wrote this entire article with this extension open. Not as a demo — I was genuinely using it.&lt;/p&gt;

&lt;p&gt;In the past, writing a three-thousand-word article meant my gaze would sweep back and forth between the left and right panes hundreds of times. I'd keep a separate "LaTeX common symbols.md" file open for copy-paste. I'd write a code block and then either comment it out or trust it, waiting for &lt;code&gt;jupyter book build&lt;/code&gt; to finish before verifying.&lt;/p&gt;

&lt;p&gt;Today, I never switched panes once.&lt;/p&gt;

&lt;p&gt;Not because this article is simple — quite the opposite. I was writing this while preparing the extension for release, constantly switching between prose and code. But that switching happened at the &lt;strong&gt;thinking level&lt;/strong&gt;, not the &lt;strong&gt;operational level&lt;/strong&gt;. In my head, I was thinking "how do I describe this feature to readers," not "first press Ctrl+1 to switch to the left editor, then Ctrl+\ to open the preview."&lt;/p&gt;

&lt;p&gt;That's the effect I was aiming for. A tool that quietly does its job when you don't need to be aware of it.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;MyST Notebook&lt;/code&gt; has been officially published on the Marketplace — the v0.1.3 &lt;code&gt;.vsix&lt;/code&gt;. I absolutely need to polish it. If you write technical documentation, use the Jupyter Book or MyST ecosystem, or have been stung by any of these pain points, follow this, try this. Any issues are welcomed on Github~&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you also have a pile of Markdown in VS Code, and you too want to say goodbye to those preview panes — then perhaps this extension is for you.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How To Build A Personal Blog With MkDocs</title>
      <dc:creator>RequieMa</dc:creator>
      <pubDate>Sun, 12 Jul 2026 03:26:48 +0000</pubDate>
      <link>https://dev.to/requiema/how-to-build-a-personal-blog-with-mkdocs-19ej</link>
      <guid>https://dev.to/requiema/how-to-build-a-personal-blog-with-mkdocs-19ej</guid>
      <description>&lt;h2&gt;
  
  
  How This Blog Was Built
&lt;/h2&gt;

&lt;p&gt;The first post is about the blog itself — a write-up of every decision and step that went into putting this site together. &lt;/p&gt;

&lt;p&gt;If you are setting up a similar lightweight developer blog with &lt;a href="https://squidfunk.github.io/mkdocs-material/" rel="noopener noreferrer"&gt;MkDocs Material&lt;/a&gt;, this should save you a couple of hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MkDocs Material?
&lt;/h2&gt;

&lt;p&gt;I wanted three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write posts in Markdown&lt;/strong&gt; — no CMS, no database, no WordPress.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy on every &lt;code&gt;git push&lt;/code&gt;&lt;/strong&gt; — GitHub Actions builds the site and deploys to GitHub Pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bilingual out of the box&lt;/strong&gt; — English and Chinese, with search that handles both.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://squidfunk.github.io/mkdocs-material/setup/setting-up-a-blog/" rel="noopener noreferrer"&gt;&lt;code&gt;blog&lt;/code&gt; plugin&lt;/a&gt; is first-class, not an afterthought.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step-by-step Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Scaffold
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; manages dependencies with a lockfile (&lt;code&gt;uv.lock&lt;/code&gt;) so builds are reproducible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv init
uv add mkdocs-material pillow cairosvg &lt;span class="se"&gt;\&lt;/span&gt;
  mkdocs-git-revision-date-localized-plugin &lt;span class="se"&gt;\&lt;/span&gt;
  mkdocs-rss-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, &lt;code&gt;mkdocs.yml&lt;/code&gt; and &lt;code&gt;docs/index.md&lt;/code&gt; are the only files you touch. Replace &lt;code&gt;index.md&lt;/code&gt; with your landing page.&lt;/p&gt;

&lt;p&gt;Local dev server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run mkdocs serve    &lt;span class="c"&gt;# → http://127.0.0.1:8000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Core Configuration
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;mkdocs.yml&lt;/code&gt; is the single source of truth. Here is what goes in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Blog plugin — posts, archive, categories, pagination&lt;/span&gt;
&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;blog&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;blog_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog&lt;/span&gt;
      &lt;span class="na"&gt;post_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{blog}/posts"&lt;/span&gt;
      &lt;span class="na"&gt;archive&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;pagination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;pagination_per_page&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
      &lt;span class="na"&gt;authors_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{blog}/.authors.yml"&lt;/span&gt;

  &lt;span class="c1"&gt;# Tags — auto-generates tag index pages&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tags&lt;/span&gt;

  &lt;span class="c1"&gt;# Search with Chinese tokenization&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;search&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;en&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;zh&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="c1"&gt;# RSS&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rss&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;match_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog/posts/.*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Bilingual Strategy
&lt;/h3&gt;

&lt;p&gt;No separate site builds, no &lt;code&gt;mkdocs-static-i18n&lt;/code&gt; plugin. Just a directory convention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/blog/posts/
├── en/    ← English posts go here, tagged `english`
└── zh/    ← 中文文章放这里，tag `chinese`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may be time-consuming for writing articles in two different languages. However, I prefer a full control of the content I wrote.&lt;/p&gt;

&lt;p&gt;Search indexes both languages — the &lt;code&gt;lang: [en, zh]&lt;/code&gt; line above tells the built-in segmenter to handle CJK characters. Readers filter by language via the tag system.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. GitHub Actions CI
&lt;/h3&gt;

&lt;p&gt;A single workflow file (&lt;code&gt;.github/workflows/ci.yml&lt;/code&gt;) does three things on every push to &lt;code&gt;Master&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checkout the repo (full depth, needed for &lt;code&gt;git-revision-date-localized&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pip install&lt;/code&gt; dependencies + &lt;code&gt;mkdocs build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;actions/deploy-pages&lt;/code&gt; to publish&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Set &lt;strong&gt;Settings → Pages → Source → GitHub Actions&lt;/strong&gt; in the repo and you are done.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Analytics &amp;amp; Comments
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Google Analytics 4&lt;/strong&gt; — one block in &lt;code&gt;mkdocs.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;extra&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;analytics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;google&lt;/span&gt;
    &lt;span class="na"&gt;property&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;G-XXXXXXXXXX&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;giscus&lt;/strong&gt; — free, no-ads comment system powered by GitHub Discussions. Enable Discussions in the repo settings, install the &lt;a href="https://github.com/apps/giscus" rel="noopener noreferrer"&gt;giscus app&lt;/a&gt;, and drop the repo/category IDs into &lt;code&gt;mkdocs.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Theme Polish — Atom One Dark Pro
&lt;/h3&gt;

&lt;p&gt;This site doesn't use the stock Material palette. &lt;/p&gt;

&lt;p&gt;Colors are inspired by &lt;strong&gt;Atom One Dark Pro&lt;/strong&gt; -- I always like this palette, and was really sad when Atom stopped updating 😿. All overrides live in a single CSS file (&lt;code&gt;docs/stylesheets/extra.css&lt;/code&gt;) loaded via &lt;code&gt;extra_css&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dark mode (default):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Hex&lt;/th&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Background&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#282c34&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Page body&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Surface&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#21252b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Code blocks, sidebar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#abb2bf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Body copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#61afef&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Links, header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#56b6c2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hover states&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Light mode:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Hex&lt;/th&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Background&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#fafafa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Page body&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Surface&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#ffffff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cards, sidebar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#383a42&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Body copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#4078f2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Links, header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#0184bc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hover states&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Key CSS snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-md-color-scheme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"slate"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--md-default-bg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#282c34&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--md-primary-fg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#61afef&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--md-accent-fg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="m"&gt;#56b6c2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-md-color-scheme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"default"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--md-default-bg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fafafa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--md-primary-fg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#4078f2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--md-accent-fg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="m"&gt;#0184bc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The home page gets a &lt;strong&gt;hero layout&lt;/strong&gt; — large title, single-line subtitle, and Material's &lt;code&gt;.md-button&lt;/code&gt; classes for CTA links. Blog post cards have rounded corners, subtle backgrounds, and a hover lift effect. A &lt;code&gt;fadeIn&lt;/code&gt; animation smooths page transitions.&lt;/p&gt;

&lt;p&gt;Dark mode is set as the &lt;strong&gt;default&lt;/strong&gt; — the &lt;code&gt;slate&lt;/code&gt; palette entry is listed first in &lt;code&gt;mkdocs.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a Post
&lt;/h2&gt;

&lt;p&gt;Every post is a Markdown file with frontmatter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;created&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-07-10&lt;/span&gt;
&lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;en&lt;/span&gt;             &lt;span class="c1"&gt;# language category: en or zh&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;topic-name&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;english&lt;/span&gt;     &lt;span class="c1"&gt;# or chinese&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;topic-tag&lt;/span&gt;
&lt;span class="na"&gt;authors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;requiema&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Title&lt;/span&gt;

Content goes here.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop it in &lt;code&gt;docs/blog/posts/en/&lt;/code&gt; or &lt;code&gt;docs/blog/posts/zh/&lt;/code&gt;, commit, push — the CI pipeline handles&lt;br&gt;
the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSG&lt;/td&gt;
&lt;td&gt;MkDocs Material 9.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;GitHub Pages (Actions CI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;en&lt;/code&gt; / &lt;code&gt;zh&lt;/code&gt; via directory convention + tags&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;Built-in, &lt;code&gt;lang: [en, zh]&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analytics&lt;/td&gt;
&lt;td&gt;Google Analytics 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comments&lt;/td&gt;
&lt;td&gt;giscus (GitHub Discussions)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mkdocs-rss-plugin&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Writing&lt;/td&gt;
&lt;td&gt;Markdown + YAML frontmatter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The full config is in the &lt;a href="https://github.com/RequieMa/requiema.github.io" rel="noopener noreferrer"&gt;repo source&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Go write something~&lt;/p&gt;

</description>
      <category>python</category>
      <category>showdev</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
