Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

xuanxin

Write Markdown blogs anywhere, generate beautiful static HTML with easy style customization.

Quick start

cd ~/xuanxin
pip install -e .

# Write posts in examples/content/*.md, then build:
xuanxin build -i examples/content -o examples/dist -t "My Blog"

# Open in browser
python -m http.server 8080 --directory examples/dist
# → http://localhost:8080

Write a post

Create content/my-post.md:

---
title: "My First Post"
slug: "my-first-post"
date: "2025-06-06"
author: "You"
tags: ["blog"]
description: "A short intro shown on the index page."
theme: "default"          # optional: default | dark | minimal
featured_image_url: "https://example.com/cover.jpg"
---

# Hello World

Your **markdown** content here.

Inline math: $E = mc^2$

https://youtu.be/VIDEO_ID   ← auto-embeds YouTube

Build commands

# Basic build
xuanxin build -i content/ -o dist/

# Dark theme
xuanxin build -i content/ -o dist/ --theme dark

# Custom CSS (overrides variables & adds rules)
xuanxin build -i content/ -o dist/ --css my-style.css

# Preview HTML body for one file
xuanxin preview content/my-post.md

# List built-in themes
xuanxin themes

# Diary site (dated .md files → flat HTML, paginated index)
xuanxin diary -i input_folder -o output_folder -gtag gtag.js -home wu-99.com --page-size 20

Customize styles (3 ways)

1. Built-in themes

default, dark, minimal — pass --theme dark or set theme: dark in frontmatter.

2. CSS variables (copy a theme file)

Each theme is just a :root { ... } block. Copy xuanxin/static/themes/default.css and change colors:

:root {
  --color-primary: #059669;
  --color-bg: #fafafa;
  --font-serif: "Georgia", serif;
  --max-width: 800px;
}

Use with --css my-theme.css.

3. Full custom CSS

Pass any CSS file with --css. It loads after the base theme, so you can override anything:

:root { --color-primary: hotpink; }
.prose h2 { border-bottom: 2px dashed var(--color-primary); }
.post { box-shadow: none; border: 2px solid black; }

See examples/custom.css for a gradient-title example.

Python API

from pathlib import Path
from xuanxin import BlogBuilder, MarkdownProcessor

# Full site build
BlogBuilder(
    content_dir=Path("content"),
    output_dir=Path("dist"),
    site_title="My Blog",
    theme="dark",
    custom_css=Path("custom.css"),
).build()

# Single file MD → HTML
processor = MarkdownProcessor()
result = processor.process_file("content/post.md")
print(result["content"])   # HTML body
print(result["metadata"])  # title, slug, tags, ...

MD → HTML pipeline

  1. Parse YAML frontmatter (python-frontmatter)
  2. Protect LaTeX $...$ / $$...$$ from Markdown
  3. Convert with Python-Markdown (+ code highlighting, tables, TOC, fenced code)
  4. Custom extensions: image CSS classes, YouTube/Vimeo embeds
  5. Restore LaTeX (rendered client-side via MathJax in output HTML)
  6. Wrap in Jinja2 template → static .html files

Output structure

dist/
├── index.html           # post listing
├── manifest.json        # build metadata
├── assets/
│   ├── theme.css        # merged theme + base styles
│   └── custom.css       # your overrides (if --css used)
└── posts/
    ├── my-first-post.html
    └── ...

License

MIT

Metadata

Release files for xuanxin 0.1.1.dev2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xuanxin 0.1.1.dev2
File Size Uploaded Provenance
xuanxin-0.1.1.dev2.tar.gz 60.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for xuanxin 0.1.1.dev2
File Interpreter ABI Platform
xuanxin-0.1.1.dev2-py3-none-any.whl Python 3 none any Details

Total release size: 125.3 kB

Release files / xuanxin-0.1.1.dev2.tar.gz

Download URL xuanxin-0.1.1.dev2.tar.gz
Size 60.9 kB
Tags Source
SHA-256 checksum
How to use checksums
57d842d59233cdfdd80b7b67ac1b4a5a85871eabbc625c2963a13cb8ba0f7a40
BLAKE2b-256 checksum
How to use checksums
9024b79f67c259271d24d5594b83785c89eb7912357c72df0c15b92d17bd5a02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release files / xuanxin-0.1.1.dev2-py3-none-any.whl

Download URL xuanxin-0.1.1.dev2-py3-none-any.whl
Size 64.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
66627f627ed4362856a69b80d7b7f4c73d74e2f3f116994a2c2aa2669a88e7cc
BLAKE2b-256 checksum
How to use checksums
ddded51088fc6a715b4b0334a7f7329bd89ce3f41a84bd15b4b0a84d052fdad1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Security for xuanxin 0.1.1.dev2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page