Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,4 @@ coverage/
# Agent/IDE local state
.omc/
.omx/
CLAUDE.md
docs/
151 changes: 151 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

md++ (package name: `easy-md`) is a lightweight Markdown viewer and editor for Windows and macOS, built with Tauri v2 (Rust backend + React/TypeScript frontend). Licensed MIT, version 0.2.0.

## Commands

```bash
pnpm install # Install dependencies
pnpm tauri dev # Start dev server (Vite on port 14300 + Tauri backend)
pnpm dev # Frontend-only dev server
pnpm build # Frontend build (tsc + vite)
pnpm test # Run frontend tests (vitest run)
pnpm test:watch # Frontend tests in watch mode
pnpm test -- src/stores/tabsStore.test.ts # Run single test file
cd src-tauri && cargo test # Run Rust backend tests
pnpm tauri build # Production build (MSI + NSIS installers)
```

First `pnpm tauri dev` compiles Rust dependencies (~5-10 min); subsequent starts are fast.

## CI/CD

- **CI** (`.github/workflows/ci.yml`) — push/PR to main 触发,跑前端测试 + 构建检查
- **Release** (`.github/workflows/release.yml`) — push `v*` tag 触发,自动构建安装包并创建 Draft Release
- Release 发布流程:改版本号 → `git tag v0.x.x` → `git push origin v0.x.x` → GitHub Actions 自动构建

## Keyboard Shortcuts

| Shortcut | Action |
|----------|--------|
| `Ctrl+O` | Open file |
| `Ctrl+W` | Close current tab |
| `Ctrl+F` | Full-text search |
| `Ctrl+Shift+T` | Toggle light/dark theme |
| `Ctrl+P` | Print / export PDF |
| `Ctrl+Shift+C` | Copy rendered content |
| `Ctrl+Shift+R` | Toggle revision mode (track changes) |
| `Ctrl+E` | Toggle edit mode |

macOS will use `⌘` instead of `Ctrl`.

## Architecture

**Tauri v2 separation:** Rust backend handles only file I/O, file watching, and system integration. All rendering, UI, and business logic lives in the React frontend. Platform differences are isolated behind Rust `#[cfg(...)]` — the frontend has zero platform coupling.

### Backend (src-tauri/src/)

- `lib.rs` — Tauri Builder setup, plugin registration, CLI arg parsing, emits `open-on-startup` event
- `commands/files.rs` — `read_text_file`, `write_file`, `resolve_image` (local images → base64 data URLs)
- `commands/recent.rs` — `list_recent`/`add_recent` persisted to `recent.json` in app data dir
- `commands/opener.rs` — `open_containing_folder`, `check_file_association`, `register_file_association` (file association management)
- `watcher.rs` — `notify` crate with 300ms debounce, emits `file-changed` events to frontend

### Frontend (src/)

- `App.tsx` — Root layout orchestrator, wires hooks: `useOpenFile`, `useThemeInit`, `useGlobalShortcuts`, `useFileWatcher`, `useRevisionShortcuts`
- `stores/tabsStore.ts` — Core state: tab CRUD, active tab, scroll memory, file reading + rendering pipeline
- `stores/revisionStore.ts` — Revision mode state: track changes, navigate between diffs
- `features/markdown/render.ts` — Main rendering entry: markdown-it → shiki → mermaid → image resolution → DOM injection
- `features/export/export.ts` — Document export: PDF (via system print), HTML, Markdown
- `utils/diff.ts` — Line-level diff computation using `diff` package
- `ipc/` — Tauri command wrappers (`invoke` calls)

### Markdown Rendering Pipeline

```
Source → markdown-it (katex, task-lists, footnote, mark, linkify, emoji, containers, tabs)
→ shiki code highlighting
→ mermaid async rendering
→ image resolution (local paths → base64 via Rust)
→ DOM injection + post-processing (anchors, copy buttons, lightbox)
```

### Revision Mode

Revision mode allows users to track and navigate changes in markdown files:

- **Activation**: `Ctrl+Shift+R` or click the revision icon in TitleBar
- **State**: `revisionStore` manages revision history, current revision, and segment navigation
- **Diff computation**: `utils/diff.ts` uses the `diff` package for line-level diffing
- **Rendering**: `renderMarkdownWithHtml()` allows HTML comments for injecting highlight markers
- **Types**: `RevisionHunk`, `Revision` in `types/index.ts`
- **Navigation**: Navigate between change segments within and across revisions

### State Management (Zustand)

- `tabsStore` — Tab lifecycle, scroll memory, rendering, watcher sync
- `themeStore` — Light/dark/system theme, CSS variables via `data-theme` attribute
- `searchStore` — Full-text search keyword, visibility, match navigation
- `recentStore` — Recent files synced with Rust backend
- `revisionStore` — Revision mode: track changes, navigate between diffs
- `editStore` — Edit mode state management
- `zenStore` — Zen (distraction-free) mode state
- `customThemeStore` — Custom theme management

### Styling

- CSS variables for theming in `themes.css` (applied via `data-theme` on `<html>`)
- TailwindCSS for utilities (custom color tokens map to CSS vars)
- `prose.css` for GitHub-like markdown typography
- Responsive breakpoints at 768px and 600px

## Key Conventions

- **Package manager:** pnpm (v9+), not npm/yarn
- **Dev server port:** 14300 (avoids Windows reserved ports 1394-1493 for Hyper-V/WSL)
- **TypeScript types:** Shared types in `src/types/index.ts` (Tab, TocItem, RecentFile, ThemeMode, Revision, RevisionHunk)
- **IPC pattern:** All Tauri commands wrapped in `src/ipc/` files, never called raw from components
- **Test framework:** Vitest with jsdom; setup in `src/test/setup.ts`
- **Test location:** Co-located with source (`*.test.ts` next to implementation)
- **Git 提交注释:** 使用中文撰写 commit message(如 `feat: 添加文件拖拽支持`、`fix: 修复主题切换闪屏`)
- **作者:** leonan
- **仓库:** https://github.com/Gitleonan/easy-md

## Features

- **Multi-tab interface** — Open multiple markdown files in tabs
- **Edit mode** — Toggle with `Ctrl+E` to edit markdown source
- **Zen mode** — Distraction-free reading mode
- **Revision mode** — Track and navigate changes in documents
- **File association** — Register as default app for `.md`/`.markdown` files
- **Export** — PDF (via system print), HTML, and Markdown formats
- **Custom themes** — Create and manage custom color themes
- **Search** — Full-text search with match navigation
- **Table of Contents** — Sidebar TOC with active heading tracking
- **Lightbox** — Image preview with zoom
- **Syntax highlighting** — Shiki-based code highlighting with 100+ languages
- **Mermaid diagrams** — Render Mermaid flowcharts, sequence diagrams, etc.
- **KaTeX math** — LaTeX math expressions rendering
- **GitHub Alerts** — Support for `> [!NOTE]`, `> [!TIP]`, etc.
- **Task lists** — GitHub-style checkboxes
- **Footnotes** — Markdown footnote syntax
- **Emoji** — Shortcode emoji support (`:smile:` → 😄)

## Agent skills

### Issue tracker

Local markdown — issues live as files under `.scratch/<feature>/`. See `docs/agents/issue-tracker.md`.

### Triage labels

Five canonical roles: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`. See `docs/agents/triage-labels.md`.

### Domain docs

Single-context — `CONTEXT.md` + `docs/adr/` at repo root. See `docs/agents/domain.md`.
130 changes: 80 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,67 @@
# md++
# md++ — 轻量 Markdown 阅读器

> **md++** — 轻量化 Markdown 阅读器,支持 Windows / macOS。
> **md++** (easy-md) — 快速、轻量的 Markdown 阅读器,支持 Windows & macOS。双击 `.md` 即开即看,无需重型编辑器。内置文件监听模式,实时捕获外部修改并可视化展示内容变更。

> 🌐 [English Version](./README_EN.md)

[![made with Tauri](https://img.shields.io/badge/made%20with-Tauri%20v2-orange)](https://tauri.app)
[![React](https://img.shields.io/badge/frontend-React%2018%20%2B%20TS-blue)](https://react.dev)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![GitHub Release](https://img.shields.io/github/v/release/Gitleonan/easy-md)](https://github.com/Gitleonan/easy-md/releases)
[![GitHub Stars](https://img.shields.io/github/stars/Gitleonan/easy-md?style=social)](https://github.com/Gitleonan/easy-md)

---
![md++ 软件界面介绍图](assets/github-promo.png)

---

## 🤔 为什么做这个

Windows 下一直没有好用的 Markdown 预览工具。想快速看一眼 `.md` 文件的内容,要么得打开 VS Code 这样的重量级编辑器,要么得用浏览器配合插件,体验都不够便捷。

**md++** 就是为了解决这个问题——一个轻量、纯粹的 Markdown 阅读器,双击文件即可预览,需要时也能快速编辑。
**md++** 就是为了解决这个问题——一个轻量、纯粹的 Markdown 阅读器,双击文件即可预览,需要时也能快速编辑。**v0.3 新增的监听模式**,能像专业 diff 工具一样监听文件的外部变化、自动计算差异并可视化展示变更内容。

[📥 下载](https://github.com/Gitleonan/easy-md/releases) · [🐛 报告问题](https://github.com/Gitleonan/easy-md/issues) · [💬 讨论](https://github.com/Gitleonan/easy-md/discussions)

## ✨ 特性
### ✨ 特性

### 阅读体验
#### 阅读体验
- 🎨 **全语法渲染** — 标准 Markdown + KaTeX 数学公式 + shiki 代码高亮 + Mermaid 图表
- 📑 **双栏 TOC** — 左侧目录树,点击跳转,滚动联动高亮,支持搜索过滤
- 🖼️ **图片增强** — 相对/绝对/网络图片,点击 Lightbox 放大,支持缩放(`+` / `-`)
- 📝 **代码块增强** — 行号、语言标签、一键复制
- 💡 **GitHub 风格** — NOTE / TIP / WARNING / CAUTION 警报块 + `:::` 自定义容器
- 🔗 **智能链接** — 外链用系统浏览器打开,`.md` 链接自动在新标签页打开
- ✏️ **快速编辑** — `Ctrl+E` 切换编辑模式,语法着色,`Ctrl+S` 保存

### 效率工具
#### 监听模式(新功能 🆕)
- 🔍 **文件监听** — `Ctrl+Shift+R` 开启监听,自动监控当前文件的外部变化
- 🟢 **新增行** — 绿色文字 + 浅绿背景 + 绿色左边框,一目了然
- 🔴 **删除行** — 红色文字 + 删除线 + 浅红背景 + 红色左边框,清晰标注
- 🧭 **逐条浏览** — 「上一个」「下一个」按钮逐条浏览变更,浮动工具栏显示「变更 1/3」
- 📊 **变更摘要** — 底部悬浮胶囊实时显示「+5 行新增 -2 行删除」
- 🔄 **自动捕获** — 文件监听器自动捕获外部修改,计算逐行差异并记录变更历史
- 🫧 **活跃指示器** — 呼吸光点 + 毛玻璃胶囊,直观展示监听状态与变更统计

#### 效率工具
- 🗂️ **多标签页** — 浏览器风格标签栏,拖拽排序,独立记忆滚动位置与目录状态
- 🔍 **全文搜索** — `Ctrl+F` 浮动搜索栏,高亮所有匹配,上下导航
- ✏️ **快速编辑** — `Ctrl+E` 切换编辑模式,语法着色,`Ctrl+S` 保存
- 📤 **多格式导出** — PDF / HTML / Markdown 原文件
- 🔄 **文件监听** — 外部修改自动刷新,编辑模式下自动跳过
- 🚀 **多入口** — 右键关联 / 拖拽 / 文件对话框 / 最近文件列表
- 💾 **会话恢复** — 重启后自动恢复上次打开的所有标签

### 界面与主题
#### 界面与主题
- 🌗 **深浅主题** — 浅色 / 深色 / 跟随系统,一键切换(`Ctrl+Shift+T`)
- 🎨 **自定义主题** — 导入 CSS 文件自定义正文样式,内置「清新」「午夜」「学术」三套主题
- 🧘 **Zen 专注模式** — `Ctrl+Shift+Z` 进入,隐藏所有 UI 仅显示内容,`ESC` 退出
- 🪟 **毛玻璃 UI** — 标题栏、搜索栏、字数统计等采用毛玻璃模糊效果
- 🔝 **平滑滚动** — 回到顶部 / TOC 跳转 / 搜索导航均带缓动动画

### 跨平台
#### 跨平台
- 🍎 平台差异隔离在 Rust 层,前端零耦合,Windows / macOS 均已适配

---

## 📦 下载安装

前往 [Releases](../../releases) 下载对应平台的安装包:

| 平台 | 格式 | 系统要求 |
|------|------|----------|
| Windows | `.msi` | Windows 10 1809+(需 WebView2 运行时,Win11 默认自带) |
| macOS | `.dmg` | macOS 11.0+ (Big Sur) |

安装后可自动注册 `.md` / `.markdown` 文件的右键菜单 **"用 md++ 打开"**

---

## 🎹 快捷键
### ⌨️ 快捷键

| 快捷键 | 功能 |
|--------|------|
Expand All @@ -68,17 +70,59 @@ Windows 下一直没有好用的 Markdown 预览工具。想快速看一眼 `.md
| `Ctrl+E` | 切换编辑 / 预览模式 |
| `Ctrl+S` | 保存(编辑模式) |
| `Ctrl+P` | 导出 |
| `Ctrl+Shift+R` | 切换文件监听模式 |
| `Ctrl+Shift+T` | 切换深浅主题 |
| `Ctrl+Shift+Z` | 进入 / 退出 Zen 专注模式 |
| `ESC` | 关闭搜索 / 退出 Zen 模式 / 关闭灯箱 |

> macOS 使用 `⌘` 替代 `Ctrl`。

---
### 📦 下载安装

前往 [Releases](https://github.com/Gitleonan/easy-md/releases) 下载对应平台的安装包:

| 平台 | 格式 | 系统要求 |
|------|------|----------|
| Windows | `.msi` | Windows 10 1809+(需 WebView2 运行时,Win11 默认自带) |
| macOS | `.dmg` | macOS 11.0+ (Big Sur) |

安装后可自动注册 `.md` / `.markdown` 文件的右键菜单 **"用 md++ 打开"**

### 🏗️ 架构

```
Tauri v2 (Rust) ── 文件 IO / 文件监听 / 系统集成 / 平台隔离
↕ Tauri Command 契约
React 18 + TS ── 渲染管线 / UI / 状态管理 / 业务逻辑
```

- **Rust 后端**只做前端做不了的事(文件系统、监听、系统集成)
- **前端**完全平台无关,所有平台差异由 Rust `#[cfg(...)]` 隔离
- **渲染管线**纯前端:`markdown-it` → `shiki` → `mermaid` → 图片路径解析
- **状态管理**:zustand(tabsStore / editStore / themeStore / zenStore / searchStore / revisionStore)
- **图标库**:lucide-react(按需导入,最小打包)

### 🔎 适用场景

| 场景 | 说明 |
|------|------|
| **Markdown 快速预览** | 双击 `.md` 文件即开即看,无需启动 IDE |
| **Typora 替代品** | 免费、开源、轻量的 Markdown 阅读器 |
| **Windows Markdown 查看器** | 原生 Windows 应用,非 Electron,内存占用低 |
| **macOS Markdown 阅读器** | 原生 macOS 适配,支持 `.dmg` 安装 |
| **技术文档阅读** | KaTeX 数学公式 + Mermaid 图表 + 代码高亮 |
| **笔记浏览** | 多标签页、目录导航、全文搜索 |
| **文档变更追踪** | 监听文件外部变化,差异可视化对比 |

### 🗺️ 路线图

## 🛠️ 开发
- [x] v0.1 — Windows 首发,完整阅读功能
- [x] v0.2 — 编辑模式 / 自定义主题 / Zen 专注模式 / macOS 适配
- [x] v0.3 — 文件监听模式(逐行差异对比、变更导航、实时指示器)

### 前置环境
### 🛠️ 开发

**前置环境**

| 工具 | 版本 | 说明 |
|------|------|------|
Expand All @@ -87,7 +131,7 @@ Windows 下一直没有好用的 Markdown 预览工具。想快速看一眼 `.md
| Rust | stable | Tauri 后端编译([安装](https://www.rust-lang.org/tools/install)) |
| Git | ≥ 2.30 | 版本控制 |

### 启动开发
**启动开发**

```bash
git clone https://github.com/Gitleonan/easy-md.git
Expand All @@ -98,14 +142,14 @@ pnpm tauri dev

首次启动会编译 Rust 依赖(约 5-10 分钟),之后启动很快。

### 运行测试
**运行测试**

```bash
pnpm test # 前端单元测试(Vitest)
cd src-tauri && cargo test # 后端 Rust 测试
```

### 构建安装包
**构建安装包**

```bash
pnpm tauri build
Expand All @@ -117,30 +161,16 @@ pnpm tauri build

---

## 🏗️ 架构

```
Tauri v2 (Rust) ── 文件 IO / 文件监听 / 系统集成 / 平台隔离
↕ Tauri Command 契约
React 18 + TS ── 渲染管线 / UI / 状态管理 / 业务逻辑
```
## 🙏 致谢

- **Rust 后端**只做前端做不了的事(文件系统、监听、系统集成)
- **前端**完全平台无关,所有平台差异由 Rust `#[cfg(...)]` 隔离
- **渲染管线**纯前端:`markdown-it` → `shiki` → `mermaid` → 图片路径解析
- **状态管理**:zustand(tabsStore / editStore / themeStore / zenStore / searchStore)
- **图标库**:lucide-react(按需导入,最小打包)
本项目 Markdown 渲染方案参考了 [vuepress-theme-plume](https://github.com/pengzhanbo/vuepress-theme-plume) 项目,特此感谢。

---

## 🗺️ 路线图
## 📄 License

- [x] v0.1 — Windows 首发,完整阅读功能
- [x] v0.2 — 编辑模式 / 自定义主题 / Zen 专注模式 / macOS 适配
- [ ] v0.3 — 监听修订模式
MIT

---

## 📄 License

MIT
**Keywords**: markdown viewer, markdown reader, markdown preview, windows markdown, macos markdown, tauri app, open source, lightweight, multi-tab, pdf export, code highlight, katex, mermaid, file monitoring, change diff, line diff, markdown-it, react, zustand
Loading
Loading