<p align="center">
  <img src="assets/icon.ico" alt="MarkLite" width="128" height="128">
</p>

<h1 align="center">MarkLite</h1>

<p align="center">
  <strong>轻量级 Windows 本地 Markdown 编辑器</strong>
</p>

<p align="center">
  <img src="https://img.shields.io/badge/Platform-Windows%20x64-blue?style=flat-square&logo=windows" alt="Platform">
  <img src="https://img.shields.io/badge/Electron-28-47848F?style=flat-square&logo=electron" alt="Electron">
  <img src="https://img.shields.io/badge/TypeScript-5.6-3178C6?style=flat-square&logo=typescript" alt="TypeScript">
  <img src="https://img.shields.io/badge/React-18-61DAFB?style=flat-square&logo=react" alt="React">
  <img src="https://img.shields.io/badge/License-MIT-green?style=flat-square" alt="License">
  <img src="https://img.shields.io/badge/Version-v0.3.12-orange?style=flat-square" alt="Version">
</p>

<p align="center">
  基于 Electron + React + TypeScript 构建的现代化 Markdown 桌面编辑器。<br>
  多标签页 · 实时预览 · 代码高亮 · 暗色主题 · 拖拽打开 · 搜索替换 · 文件树 · IndexedDB 持久化。
</p>

---

## ✨ 功能特性

| 功能 | 说明 |
|------|------|
| 📑 **多标签页** | 同时打开多个文件，Ctrl+T 新建、Ctrl+W 关闭、Ctrl+Tab MRU 切换 |
| 📂 **文件打开** | 按钮打开 / 拖拽打开 / 文件关联（双击 .md） / 命令行参数 |
| ✏️ **双编辑模式** | Milkdown WYSIWYG 编辑器（格式化工具栏/搜索替换/正则/自动配对）+ 源码模式（textarea）|
| 👁 **实时预览** | 右侧预览面板，基于 unified/rehype 管线渲染，编辑即更新 |
| 🔤 **代码高亮** | 基于 rehype-highlight，支持 180+ 种编程语言语法高亮 |
| 🎨 **两种视图** | 编辑模式 / 预览模式，自由切换 |
| 🌙 **暗色主题** | 一键切换亮色/暗色主题，偏好自动记忆（IndexedDB） |
| 🔔 **文件监听** | 外部修改文件时自动提示，支持重新加载或忽略 |
| 💾 **文件保存** | 保存 / 另存为，支持 .md / .markdown / .txt 格式 |
| 🔍 **搜索替换** | Ctrl+F 搜索、Ctrl+H 替换，支持高亮匹配、大小写、正则表达式 |
| 📁 **文件树** | 侧边栏浏览项目目录，点击打开文件，目录变化自动刷新 |
| 💾 **状态持久化** | 标签页状态、用户设置通过 IndexedDB 持久化，关闭后可恢复 |
| ⌨️ **快捷键** | 完整的键盘快捷键支持，操作高效 |
| 📦 **NSIS 安装包** | 一键打包为 Windows exe 安装程序 / 便携版 |

## 🚀 快速开始

### 环境要求

- **Node.js** >= 18.x
- **npm** >= 9.x
- **Windows** 10/11 x64

### 安装与运行

```bash
# 克隆仓库
git clone https://gitee.com/thzxx/MarkLite.git
cd MarkLite

# 安装依赖
npm install

# 启动开发模式（带 HMR 热更新）
npm run dev
```

### 打包为 exe 安装包

```bash
# 打包 Windows x64 NSIS 安装包
npm run build

# 打包为便携版（免安装）
npm run build:portable
```

打包完成后，安装包位于 `dist/` 目录。详见 [DEVSETUP.md](DEVSETUP.md)。

### 其他命令

```bash
# TypeScript 类型检查
npm run typecheck

# ESLint 代码检查
npm run lint

# 运行单元测试
npm run test

# 监听模式运行测试
npm run test:watch

# 生成测试覆盖率报告
npm run test:coverage
```

## 🧪 测试

项目使用 **Vitest** + **React Testing Library** 作为测试框架。

```bash
# 运行全部测试
npm run test

# 监听模式（开发时持续运行）
npm run test:watch

# 生成覆盖率报告
npm run test:coverage
```

测试覆盖以下核心模块：
- `stores/` — Zustand 状态管理（tabStore, editorStore）
- `lib/` — 工具库（fileUtils, markdown, errorHandler）
- `hooks/` — 自定义 Hooks

测试文件位于对应模块的 `__tests__/` 目录下，命名格式为 `*.test.ts`。

## ⌨️ 快捷键

| 快捷键 | 功能 |
|:-------|:-----|
| `Ctrl + T` | 新建标签页 |
| `Ctrl + W` | 关闭当前标签页 |
| `Ctrl + Tab` | 切换到下一个标签页（MRU 顺序） |
| `Ctrl + Shift + Tab` | 切换到上一个标签页 |
| `Ctrl + O` | 打开文件 |
| `Ctrl + S` | 保存文件 |
| `Ctrl + Shift + S` | 另存为 |
| `Ctrl + 1` | 编辑模式 |
| `Ctrl + 2` | 预览模式 |
| `Ctrl + 3` | 源码模式 |
| `Ctrl + F` | 搜索 |
| `Ctrl + H` | 搜索并替换 |
| `Ctrl + B` | 粗体 |
| `Ctrl + I` | 斜体 |
| `Enter` / `Shift+Enter` | 下一个 / 上一个匹配 |
| `Esc` | 关闭搜索栏 |

## 🛠️ 技术栈

| 组件 | 技术 | 说明 |
|:-----|:-----|:-----|
| 桌面框架 | [Electron](https://www.electronjs.org/) v28 | 跨平台桌面应用框架 |
| 前端框架 | [React](https://react.dev/) v18 | 函数组件 + Hooks |
| 类型系统 | [TypeScript](https://www.typescriptlang.org/) v5.6 | 全量类型安全 |
| 编辑器 | [Milkdown](https://milkdown.dev/) v7 | WYSIWYG 编辑器 + 源码模式 |
| 状态管理 | [Zustand](https://zustand-demo.pmnd.rs/) v5 | 轻量级状态管理 |
| 持久化 | [Dexie.js](https://dexie.org/) v4 (IndexedDB) | 标签页状态 & 用户设置持久化 |
| Markdown 解析 | [unified](https://unifiedjs.com/) / [remark](https://remark.js.org/) / [rehype](https://rehype.js.org/) | 插件化 Markdown 渲染管线 |
| 代码高亮 | [rehype-highlight](https://github.com/rehypejs/rehype-highlight) | 基于 highlight.js 的语法高亮 |
| 构建工具 | [electron-vite](https://electron-vite.org/) v3 | Electron + Vite 集成，HMR 热更新 |
| 打包工具 | [electron-builder](https://www.electron.build/) | 生成 exe 安装包 |
| 样式 | CSS Variables | 主题驱动，亮色/暗色切换 |

## 📁 项目结构

```
MarkLite/
├── package.json                    # 项目配置 & 依赖 & electron-builder 打包配置
├── tsconfig.json                   # TypeScript 配置
├── tsconfig.node.json              # Node 端 TypeScript 配置
├── electron.vite.config.ts         # electron-vite 构建配置
├── vitest.config.ts                # Vitest 测试框架配置
├── .eslintrc.cjs                   # ESLint + TypeScript 规则
├── CONTRIBUTING.md                 # 贡献指南
│
├── src/
│   ├── main/                       # 主进程 (Node.js)
│   │   ├── index.ts                # 入口：窗口创建、app 生命周期、单实例锁
│   │   ├── ipc-handlers.ts         # 所有 ipcMain.handle 注册
│   │   ├── file-system.ts          # 文件读写、目录树构建、BOM 剥离
│   │   ├── file-watcher.ts         # fs.watch 封装（单文件 + 目录监听）
│   │   └── window-manager.ts       # 窗口创建、关闭拦截、单实例锁
│   │
│   ├── preload/                    # 预加载脚本
│   │   └── index.ts                # contextBridge 类型安全暴露
│   │
│   ├── renderer/                   # 渲染进程 (React 18)
│   │   ├── index.html              # 入口 HTML（含 CSP 策略）
│   │   ├── main.tsx                # React 入口
│   │   ├── App.tsx                 # 根组件：布局编排、全局事件
│   │   │
│   │   ├── components/             # UI 组件 (23个)
│   │   │   ├── Toolbar/            # 工具栏
│   │   │   ├── TabBar/             # 标签页栏 (含拖拽排序)
│   │   │   ├── Editor/             # Milkdown 编辑器 + 工具栏
│   │   │   ├── Preview/            # Markdown 预览面板
│   │   │   ├── SourceEditor/       # 源码编辑模式 (textarea)
│   │   │   ├── Sidebar/            # 侧边栏文件树
│   │   │   ├── FileTree/           # 递归文件树
│   │   │   ├── OutlinePanel/       # 文档大纲 (活跃标题高亮)
│   │   │   ├── StatusBar/          # 状态栏 (自动保存开关)
│   │   │   ├── SearchReplace/      # 搜索替换面板 (支持正则)
│   │   │   ├── WelcomeScreen/      # 欢迎屏幕
│   │   │   ├── Toast/              # Toast 通知
│   │   │   ├── ConfirmDialog/      # 确认对话框
│   │   │   ├── ModifiedBanner/     # 文件外部修改提示
│   │   │   ├── DropOverlay/        # 拖拽文件覆盖层
│   │   │   ├── ErrorBoundary/      # 错误边界
│   │   │   ├── AboutDialog/        # 关于对话框
│   │   │   ├── LoadingSpinner/     # 加载指示器
│   │   │   └── Icons.tsx           # SVG 图标库
│   │   │
│   │   ├── stores/                 # Zustand 状态管理
│   │   │   ├── tabStore.ts         # 标签页状态
│   │   │   ├── editorStore.ts      # 编辑器状态
│   │   │   └── sidebarStore.ts     # 侧边栏状态
│   │   │
│   │   ├── hooks/                  # 自定义 Hooks (19个)
│   │   │   ├── useTheme.ts         # 暗色/亮色主题
│   │   │   ├── useSettings.ts      # 视图模式
│   │   │   ├── useSettingsInit.ts  # 设置初始加载
│   │   │   ├── useKeyboard.ts      # 全局快捷键
│   │   │   ├── useDragDrop.ts      # 拖拽打开
│   │   │   ├── useFileWatch.ts     # 外部修改监听
│   │   │   ├── useUnsavedWarning.ts # 未保存提醒
│   │   │   ├── useAutoSave.ts      # 自动保存
│   │   │   ├── useAutoExpandDir.ts # 自动展开目录
│   │   │   ├── useActiveHeading.ts # 活跃标题追踪
│   │   │   └── ...                 # 文件操作、IPC监听等
│   │   │
│   │   ├── lib/                    # 工具库
│   │   │   ├── markdown.ts         # Markdown 渲染管线
│   │   │   ├── fileUtils.ts        # 文件工具函数
│   │   │   ├── errorHandler.ts     # 错误处理
│   │   │   └── constants.ts        # 常量定义
│   │   │
│   │   ├── db/                     # IndexedDB 持久化层
│   │   │   ├── schema.ts           # Dexie 数据库定义
│   │   │   ├── tabRepository.ts    # 标签页 CRUD
│   │   │   ├── settingsRepository.ts # 设置 CRUD
│   │   │   └── recentFilesRepository.ts # 最近文件
│   │   │
│   │   ├── types/                  # TypeScript 类型
│   │   └── styles/                 # 全局样式
│   │
│   └── shared/                     # 主进程/渲染进程共享
│       ├── ipc-channels.ts         # IPC 通道名常量
│       └── types.ts                # 共享类型定义
│
├── assets/
│   └── icon.ico                    # 应用图标
├── DESIGN.md                       # 架构设计文档
├── DEVSETUP.md                     # 开发环境配置指南
├── LICENSE                         # MIT 许可证
└── README.md                       # 本文件
```

## 📝 支持的 Markdown 语法

- ✅ 标题（h1 ~ h6）
- ✅ **粗体** / *斜体* / ~~删除线~~
- ✅ 有序列表 / 无序列表
- ✅ 任务列表 `- [x]`
- ✅ 代码块（围栏式 + 语法高亮，180+ 语言）
- ✅ 行内代码
- ✅ 链接 / 图片（支持相对路径）
- ✅ 表格
- ✅ 引用块
- ✅ 水平线
- ✅ HTML 内联元素
- ✅ GFM（GitHub Flavored Markdown）

## 🔧 Git Hooks

项目使用 **Husky** + **lint-staged** 自动执行代码检查：

- **pre-commit**: 对暂存的 `.ts/.tsx` 文件运行 ESLint 和 TypeScript 类型检查；对 `.json/.css/.md` 文件运行 Prettier 格式化

```bash
# 初始化 git hooks（npm install 时自动执行）
npm run prepare
```

## 📄 许可证

[MIT License](LICENSE) © 2026 [thzxx](https://gitee.com/thzxx)

---

<p align="center">
  如果觉得有用，请点个 ⭐ Star 支持一下！
</p>
