xuanxin 0.1.1.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. xuanxin-0.1.1.dev0/PKG-INFO +164 -0
  2. xuanxin-0.1.1.dev0/README.md +143 -0
  3. xuanxin-0.1.1.dev0/pyproject.toml +39 -0
  4. xuanxin-0.1.1.dev0/setup.cfg +4 -0
  5. xuanxin-0.1.1.dev0/tests/test_xuanxin.py +647 -0
  6. xuanxin-0.1.1.dev0/xuanxin/__init__.py +18 -0
  7. xuanxin-0.1.1.dev0/xuanxin/book.py +226 -0
  8. xuanxin-0.1.1.dev0/xuanxin/builder.py +128 -0
  9. xuanxin-0.1.1.dev0/xuanxin/cli.py +195 -0
  10. xuanxin-0.1.1.dev0/xuanxin/extensions.py +207 -0
  11. xuanxin-0.1.1.dev0/xuanxin/footnotes.py +41 -0
  12. xuanxin-0.1.1.dev0/xuanxin/image_attrs.py +513 -0
  13. xuanxin-0.1.1.dev0/xuanxin/includes.py +185 -0
  14. xuanxin-0.1.1.dev0/xuanxin/latex.py +35 -0
  15. xuanxin-0.1.1.dev0/xuanxin/note_sections.py +106 -0
  16. xuanxin-0.1.1.dev0/xuanxin/paginate.py +48 -0
  17. xuanxin-0.1.1.dev0/xuanxin/processor.py +201 -0
  18. xuanxin-0.1.1.dev0/xuanxin/renderer.py +175 -0
  19. xuanxin-0.1.1.dev0/xuanxin/section_nav.py +58 -0
  20. xuanxin-0.1.1.dev0/xuanxin/static/themes/_base.css +1081 -0
  21. xuanxin-0.1.1.dev0/xuanxin/static/themes/dark.css +23 -0
  22. xuanxin-0.1.1.dev0/xuanxin/static/themes/default.css +23 -0
  23. xuanxin-0.1.1.dev0/xuanxin/static/themes/minimal.css +23 -0
  24. xuanxin-0.1.1.dev0/xuanxin/templates/book_index.html +44 -0
  25. xuanxin-0.1.1.dev0/xuanxin/templates/index.html +53 -0
  26. xuanxin-0.1.1.dev0/xuanxin/templates/post.html +123 -0
  27. xuanxin-0.1.1.dev0/xuanxin.egg-info/PKG-INFO +164 -0
  28. xuanxin-0.1.1.dev0/xuanxin.egg-info/SOURCES.txt +30 -0
  29. xuanxin-0.1.1.dev0/xuanxin.egg-info/dependency_links.txt +1 -0
  30. xuanxin-0.1.1.dev0/xuanxin.egg-info/entry_points.txt +2 -0
  31. xuanxin-0.1.1.dev0/xuanxin.egg-info/requires.txt +7 -0
  32. xuanxin-0.1.1.dev0/xuanxin.egg-info/top_level.txt +1 -0
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.4
2
+ Name: xuanxin
3
+ Version: 0.1.1.dev0
4
+ Summary: Markdown blog to beautiful static HTML — write .md, customize CSS, publish.
5
+ Author: xuanxin
6
+ License: MIT
7
+ Keywords: markdown,blog,static-site,html
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
13
+ Requires-Python: >=3.9
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: markdown>=3.5
16
+ Requires-Dist: python-frontmatter>=1.1
17
+ Requires-Dist: jinja2>=3.1
18
+ Requires-Dist: pygments>=2.17
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest>=7.0; extra == "dev"
21
+
22
+ # xuanxin
23
+
24
+ Write Markdown blogs anywhere, generate beautiful static HTML with easy style customization.
25
+
26
+ ## Quick start
27
+
28
+ ```bash
29
+ cd ~/xuanxin
30
+ pip install -e .
31
+
32
+ # Write posts in examples/content/*.md, then build:
33
+ xuanxin build -i examples/content -o examples/dist -t "My Blog"
34
+
35
+ # Open in browser
36
+ python -m http.server 8080 --directory examples/dist
37
+ # → http://localhost:8080
38
+ ```
39
+
40
+ ## Write a post
41
+
42
+ Create `content/my-post.md`:
43
+
44
+ ```markdown
45
+ ---
46
+ title: "My First Post"
47
+ slug: "my-first-post"
48
+ date: "2025-06-06"
49
+ author: "You"
50
+ tags: ["blog"]
51
+ description: "A short intro shown on the index page."
52
+ theme: "default" # optional: default | dark | minimal
53
+ featured_image_url: "https://example.com/cover.jpg"
54
+ ---
55
+
56
+ # Hello World
57
+
58
+ Your **markdown** content here.
59
+
60
+ Inline math: $E = mc^2$
61
+
62
+ https://youtu.be/VIDEO_ID ← auto-embeds YouTube
63
+ ```
64
+
65
+ ## Build commands
66
+
67
+ ```bash
68
+ # Basic build
69
+ xuanxin build -i content/ -o dist/
70
+
71
+ # Dark theme
72
+ xuanxin build -i content/ -o dist/ --theme dark
73
+
74
+ # Custom CSS (overrides variables & adds rules)
75
+ xuanxin build -i content/ -o dist/ --css my-style.css
76
+
77
+ # Preview HTML body for one file
78
+ xuanxin preview content/my-post.md
79
+
80
+ # List built-in themes
81
+ xuanxin themes
82
+ ```
83
+
84
+ ## Customize styles (3 ways)
85
+
86
+ ### 1. Built-in themes
87
+
88
+ `default`, `dark`, `minimal` — pass `--theme dark` or set `theme: dark` in frontmatter.
89
+
90
+ ### 2. CSS variables (copy a theme file)
91
+
92
+ Each theme is just a `:root { ... }` block. Copy `xuanxin/static/themes/default.css` and change colors:
93
+
94
+ ```css
95
+ :root {
96
+ --color-primary: #059669;
97
+ --color-bg: #fafafa;
98
+ --font-serif: "Georgia", serif;
99
+ --max-width: 800px;
100
+ }
101
+ ```
102
+
103
+ Use with `--css my-theme.css`.
104
+
105
+ ### 3. Full custom CSS
106
+
107
+ Pass any CSS file with `--css`. It loads **after** the base theme, so you can override anything:
108
+
109
+ ```css
110
+ :root { --color-primary: hotpink; }
111
+ .prose h2 { border-bottom: 2px dashed var(--color-primary); }
112
+ .post { box-shadow: none; border: 2px solid black; }
113
+ ```
114
+
115
+ See `examples/custom.css` for a gradient-title example.
116
+
117
+ ## Python API
118
+
119
+ ```python
120
+ from pathlib import Path
121
+ from xuanxin import BlogBuilder, MarkdownProcessor
122
+
123
+ # Full site build
124
+ BlogBuilder(
125
+ content_dir=Path("content"),
126
+ output_dir=Path("dist"),
127
+ site_title="My Blog",
128
+ theme="dark",
129
+ custom_css=Path("custom.css"),
130
+ ).build()
131
+
132
+ # Single file MD → HTML
133
+ processor = MarkdownProcessor()
134
+ result = processor.process_file("content/post.md")
135
+ print(result["content"]) # HTML body
136
+ print(result["metadata"]) # title, slug, tags, ...
137
+ ```
138
+
139
+ ## MD → HTML pipeline
140
+
141
+ 1. Parse YAML frontmatter (`python-frontmatter`)
142
+ 2. Protect LaTeX `$...$` / `$$...$$` from Markdown
143
+ 3. Convert with Python-Markdown (+ code highlighting, tables, TOC, fenced code)
144
+ 4. Custom extensions: image CSS classes, YouTube/Vimeo embeds
145
+ 5. Restore LaTeX (rendered client-side via MathJax in output HTML)
146
+ 6. Wrap in Jinja2 template → static `.html` files
147
+
148
+ ## Output structure
149
+
150
+ ```
151
+ dist/
152
+ ├── index.html # post listing
153
+ ├── manifest.json # build metadata
154
+ ├── assets/
155
+ │ ├── theme.css # merged theme + base styles
156
+ │ └── custom.css # your overrides (if --css used)
157
+ └── posts/
158
+ ├── my-first-post.html
159
+ └── ...
160
+ ```
161
+
162
+ ## License
163
+
164
+ MIT
@@ -0,0 +1,143 @@
1
+ # xuanxin
2
+
3
+ Write Markdown blogs anywhere, generate beautiful static HTML with easy style customization.
4
+
5
+ ## Quick start
6
+
7
+ ```bash
8
+ cd ~/xuanxin
9
+ pip install -e .
10
+
11
+ # Write posts in examples/content/*.md, then build:
12
+ xuanxin build -i examples/content -o examples/dist -t "My Blog"
13
+
14
+ # Open in browser
15
+ python -m http.server 8080 --directory examples/dist
16
+ # → http://localhost:8080
17
+ ```
18
+
19
+ ## Write a post
20
+
21
+ Create `content/my-post.md`:
22
+
23
+ ```markdown
24
+ ---
25
+ title: "My First Post"
26
+ slug: "my-first-post"
27
+ date: "2025-06-06"
28
+ author: "You"
29
+ tags: ["blog"]
30
+ description: "A short intro shown on the index page."
31
+ theme: "default" # optional: default | dark | minimal
32
+ featured_image_url: "https://example.com/cover.jpg"
33
+ ---
34
+
35
+ # Hello World
36
+
37
+ Your **markdown** content here.
38
+
39
+ Inline math: $E = mc^2$
40
+
41
+ https://youtu.be/VIDEO_ID ← auto-embeds YouTube
42
+ ```
43
+
44
+ ## Build commands
45
+
46
+ ```bash
47
+ # Basic build
48
+ xuanxin build -i content/ -o dist/
49
+
50
+ # Dark theme
51
+ xuanxin build -i content/ -o dist/ --theme dark
52
+
53
+ # Custom CSS (overrides variables & adds rules)
54
+ xuanxin build -i content/ -o dist/ --css my-style.css
55
+
56
+ # Preview HTML body for one file
57
+ xuanxin preview content/my-post.md
58
+
59
+ # List built-in themes
60
+ xuanxin themes
61
+ ```
62
+
63
+ ## Customize styles (3 ways)
64
+
65
+ ### 1. Built-in themes
66
+
67
+ `default`, `dark`, `minimal` — pass `--theme dark` or set `theme: dark` in frontmatter.
68
+
69
+ ### 2. CSS variables (copy a theme file)
70
+
71
+ Each theme is just a `:root { ... }` block. Copy `xuanxin/static/themes/default.css` and change colors:
72
+
73
+ ```css
74
+ :root {
75
+ --color-primary: #059669;
76
+ --color-bg: #fafafa;
77
+ --font-serif: "Georgia", serif;
78
+ --max-width: 800px;
79
+ }
80
+ ```
81
+
82
+ Use with `--css my-theme.css`.
83
+
84
+ ### 3. Full custom CSS
85
+
86
+ Pass any CSS file with `--css`. It loads **after** the base theme, so you can override anything:
87
+
88
+ ```css
89
+ :root { --color-primary: hotpink; }
90
+ .prose h2 { border-bottom: 2px dashed var(--color-primary); }
91
+ .post { box-shadow: none; border: 2px solid black; }
92
+ ```
93
+
94
+ See `examples/custom.css` for a gradient-title example.
95
+
96
+ ## Python API
97
+
98
+ ```python
99
+ from pathlib import Path
100
+ from xuanxin import BlogBuilder, MarkdownProcessor
101
+
102
+ # Full site build
103
+ BlogBuilder(
104
+ content_dir=Path("content"),
105
+ output_dir=Path("dist"),
106
+ site_title="My Blog",
107
+ theme="dark",
108
+ custom_css=Path("custom.css"),
109
+ ).build()
110
+
111
+ # Single file MD → HTML
112
+ processor = MarkdownProcessor()
113
+ result = processor.process_file("content/post.md")
114
+ print(result["content"]) # HTML body
115
+ print(result["metadata"]) # title, slug, tags, ...
116
+ ```
117
+
118
+ ## MD → HTML pipeline
119
+
120
+ 1. Parse YAML frontmatter (`python-frontmatter`)
121
+ 2. Protect LaTeX `$...$` / `$$...$$` from Markdown
122
+ 3. Convert with Python-Markdown (+ code highlighting, tables, TOC, fenced code)
123
+ 4. Custom extensions: image CSS classes, YouTube/Vimeo embeds
124
+ 5. Restore LaTeX (rendered client-side via MathJax in output HTML)
125
+ 6. Wrap in Jinja2 template → static `.html` files
126
+
127
+ ## Output structure
128
+
129
+ ```
130
+ dist/
131
+ ├── index.html # post listing
132
+ ├── manifest.json # build metadata
133
+ ├── assets/
134
+ │ ├── theme.css # merged theme + base styles
135
+ │ └── custom.css # your overrides (if --css used)
136
+ └── posts/
137
+ ├── my-first-post.html
138
+ └── ...
139
+ ```
140
+
141
+ ## License
142
+
143
+ MIT
@@ -0,0 +1,39 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "xuanxin"
7
+ version = "0.1.1.dev0"
8
+ description = "Markdown blog to beautiful static HTML — write .md, customize CSS, publish."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "xuanxin" }]
13
+ keywords = ["markdown", "blog", "static-site", "html"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
20
+ ]
21
+ dependencies = [
22
+ "markdown>=3.5",
23
+ "python-frontmatter>=1.1",
24
+ "jinja2>=3.1",
25
+ "pygments>=2.17",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ dev = ["pytest>=7.0"]
30
+
31
+ [project.scripts]
32
+ xuanxin = "xuanxin.cli:main"
33
+
34
+ [tool.setuptools.packages.find]
35
+ where = ["."]
36
+ include = ["xuanxin*"]
37
+
38
+ [tool.setuptools.package-data]
39
+ xuanxin = ["templates/*", "static/themes/*", "static/themes/_base.css"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+