160 lines
5.4 KiB
Markdown
160 lines
5.4 KiB
Markdown
# Markdown To Web
|
||
|
||
> Turn a local Markdown notes folder into a deployable static React site.
|
||
|
||
This project scans all `.md` files inside `public/mengyanote/`, generates JSON datasets (directory tree, file contents, stats) at build time, and renders them client‑side with React + `react-markdown`. The output is a **pure static site** (no server / no DB) suitable for GitHub Pages, Netlify, Vercel, or any static hosting.
|
||
|
||
Chinese documentation: see `README.md`.
|
||
|
||
## ✨ Features
|
||
|
||
- 🚀 One‑command data generation (recursive scan → JSON assets)
|
||
- 📦 Fully static deployment (no runtime backend needed)
|
||
- 🧭 Expandable directory tree with stable IDs / paths
|
||
- 📝 Rich Markdown: GFM (tables, task lists, strikethrough), soft line breaks, math (KaTeX), code highlighting
|
||
- 🧮 Math via `remark-math` + `rehype-katex`
|
||
- 💡 Enhanced code blocks: language label + copy button
|
||
- 📚 Breadcrumb navigation derived from file path
|
||
- 🔌 Pluggable remark / rehype pipeline (easy to remove / replace)
|
||
- 🕶 Dark theme (fully customizable via CSS)
|
||
- 🔍 Multi-path fallback when fetching generated JSON (`/data` → `/src/data` → `./data`)
|
||
- 🧯 Ignore mechanism via `ignore.json`
|
||
- 📊 Basic statistics (file count, folder count, timestamp)
|
||
|
||
## 🛠 Tech Stack
|
||
|
||
- React 19 + Hooks + Context
|
||
- Vite
|
||
- `react-markdown` + remark / rehype plugins:
|
||
- `remark-gfm`, `remark-math`, `remark-breaks`
|
||
- `rehype-raw`, `rehype-katex`, `rehype-highlight`
|
||
- Highlight.js theme (replaceable)
|
||
- KaTeX (optional)
|
||
|
||
## ⚡ Quick Start
|
||
|
||
```bash
|
||
npm install
|
||
npm run dev # generate data + start dev server
|
||
npm run build # generate data + build static site (dist/)
|
||
npm run preview # preview production build
|
||
npm run generate-data # only regenerate JSON
|
||
npm run lint
|
||
```
|
||
|
||
## 📂 Key Structure
|
||
|
||
```
|
||
public/
|
||
mengyanote/ # Source Markdown tree (add your .md here)
|
||
data/ # Public copy of generated JSON
|
||
scripts/
|
||
generateData.js # Node script: scans + emits JSON
|
||
src/
|
||
data/ # Generated JSON (consumed in dev/build)
|
||
components/ # UI (MarkdownRenderer, Sidebar, ...)
|
||
context/ # AppContext (state + actions)
|
||
utils/fileUtils.js # Fetch + helpers + breadcrumbs
|
||
```
|
||
|
||
## 🧬 How It Works
|
||
|
||
1. `generateData.js` walks `public/mengyanote/` (applying `ignore.json` rules)
|
||
2. Builds:
|
||
- `directoryTree.json` (hierarchical tree)
|
||
- `fileContents.json` (path → raw markdown text)
|
||
- `stats.json` (counts + timestamp)
|
||
3. Writes duplicates to `src/data/` (for imports / dev) and `public/data/` (for runtime fetch in final build)
|
||
4. Frontend loads JSON (tries `/data` → `/src/data` → `./data`) and renders selected file
|
||
|
||
```
|
||
Markdown(.md) --> generateData.js --> JSON (tree, contents, stats) --> React (render)
|
||
```
|
||
|
||
## 🧯 Ignore Rules
|
||
|
||
Default ignored: `.obsidian`, `.trash`, `.git`, `node_modules`, any dot‑prefixed file/dir.
|
||
|
||
Custom ignore: create `public/mengyanote/ignore.json`:
|
||
|
||
```json
|
||
{ "ignore": ["Drafts", "private", "Scratch.md"] }
|
||
```
|
||
|
||
## 🎨 Customization Cheatsheet
|
||
|
||
| Goal | Where | Action |
|
||
|------|-------|--------|
|
||
| Remove math | `MarkdownRenderer.jsx` | Drop `remark-math` + `rehype-katex` + CSS import |
|
||
| Remove code highlighting | `MarkdownRenderer.jsx` | Remove `rehype-highlight` and theme CSS |
|
||
| New highlight theme | Add dependency | Replace imported highlight style |
|
||
| Inline code as plain text | Already done | Custom plugin strips inline code styling |
|
||
| Change image layout | `MarkdownRenderer.css` | Adjust `.markdown-image img` |
|
||
| Change breadcrumb format | `fileUtils.generateBreadcrumbs` | Modify join logic |
|
||
|
||
## 🚢 Deployment
|
||
|
||
Build output: `dist/` (fully static).
|
||
|
||
Platforms:
|
||
|
||
| Platform | Notes |
|
||
|----------|-------|
|
||
| GitHub Pages | Push `dist/` to `gh-pages` or use an Action |
|
||
| Netlify | Build: `npm run build`, Publish: `dist` |
|
||
| Vercel | Auto-detect Vite |
|
||
| Any static host / Nginx | Upload `dist/` |
|
||
|
||
Example Nginx:
|
||
|
||
```
|
||
server {
|
||
listen 80;
|
||
server_name example.com;
|
||
root /var/www/markdown-to-web/dist;
|
||
location / { try_files $uri /index.html; }
|
||
add_header Cache-Control "public, max-age=31536000";
|
||
}
|
||
```
|
||
|
||
## FAQ
|
||
|
||
**New file not appearing?** Regenerate data: `npm run generate-data` (or rerun dev/build).
|
||
|
||
**Ignore not working?** Ensure `ignore.json` sits directly in `public/mengyanote/` and key is exactly `ignore`.
|
||
|
||
**Large number of files causes slow load?** Consider splitting `fileContents.json` into per‑file JSON (enhancement idea).
|
||
|
||
**Search support?** Not yet. You can integrate `minisearch` or `lunr` during build.
|
||
|
||
**Can I support frontmatter?** Extend the generator to parse YAML frontmatter and attach metadata to each node.
|
||
|
||
## Roadmap (Open for Contributions)
|
||
|
||
- [ ] Full‑text search
|
||
- [ ] Per‑file lazy loading
|
||
- [ ] Recent updates panel / changelog
|
||
- [ ] Frontmatter tags + filters
|
||
- [ ] RSS / JSON feed generation
|
||
- [ ] PDF / print friendly mode
|
||
- [ ] Service Worker caching
|
||
- [ ] GitHub Actions deploy workflow example
|
||
|
||
## Contributing & License
|
||
|
||
Issues / PRs welcome. Please open an issue before large feature work; attach screenshots for UI changes. License: see `LICENSE`.
|
||
|
||
## Contact
|
||
|
||
Open an issue describing:
|
||
|
||
- Desired visual style (links / screenshots)
|
||
- Needed deployment pipeline (e.g., GitHub Pages Action)
|
||
- Theming or performance concerns
|
||
|
||
I can suggest patches or configuration examples.
|
||
|
||
---
|
||
|
||
Happy publishing! If you build cool themes (minimal / book‑like / image‑first), consider sharing them back. 🙌
|