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
- Parse YAML frontmatter (
python-frontmatter) - Protect LaTeX
$...$/$$...$$from Markdown - Convert with Python-Markdown (+ code highlighting, tables, TOC, fenced code)
- Custom extensions: image CSS classes, YouTube/Vimeo embeds
- Restore LaTeX (rendered client-side via MathJax in output HTML)
- Wrap in Jinja2 template → static
.htmlfiles
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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| xuanxin-0.1.1.dev2.tar.gz | 60.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.