# 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. 🙌
