diff --git a/docs/changelog.md b/docs/changelog.md index 232fabe..624d96f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -4,31 +4,107 @@ ## [1.1.0] - 2026-05-09 -### 新增 -- Markdown 渲染器重构:从"一行流"改为 AST 架构(`pkg/mdprint/`) - - 块级解析器:Heading / Paragraph / CodeBlock / Blockquote / List / Table / ThematicBreak - - 行内解析器:Bold / Italic / Code / Link + 递归嵌套 - - ANSI 渲染器:type switch 分发,标题按级别分色 -- 标题视觉系统:1-3 级 `▪` 符号 + 加粗,4-5 级 `▫` 符号 + 加粗,6 级纯加粗 - - 所有标题前插空行,1 级标题前后各插空行 -- 真彩色支持:`style.FgHex("#RRGGBB")` / `style.BgHex("#RRGGBB")`,兼容原有 8 色 ANSI -- 莫奈《睡莲》配色方案:H1 雾蓝灰 / H2 鼠尾草绿 / H3 薄荷青 / H4 淡紫粉 / H5 暖灰绿 / H6 浅灰 -- 排版间距优化:`---` 横线前后空行、输入与响应之间空行、输出末尾空行 +### 发布摘要 +第二版发布。核心变化:Markdown 渲染器从"一行流"重构为 AST 架构,新增终端视觉系统(标题符号 + Monet 配色),Go 版本升级至 1.25,项目结构从 `src/` 扁平目录重组为根目录 + `pkg/` 子包架构。 + +--- + +### 新增:pkg/mdprint — Markdown → ANSI 渲染引擎 + +从头编写的 AST 架构渲染引擎,替代原来的"一行流"字符串匹配逻辑: + +**块级解析**(`parse.go`):有限状态机逐行扫描,识别 7 种块级元素 +| 类型 | 语法 | 解析策略 | +|------|------|---------| +| Heading | `#` ~ `######` | 前缀匹配,记录级别 | +| CodeBlock | ` ``` ` fence | 状态切换,支持语言标识 | +| Blockquote | `>` 前缀 | 前缀剥离,递归解析 | +| List | `-` / `*` / `1.` | 前缀匹配,自动编号检测 | +| Table | `|` 分隔 | 行首检测,首行为表头 | +| ThematicBreak | `---` 独占一行 | 精确匹配 | +| Paragraph | 默认兜底 | 连续非空文本块合并 | + +**行内解析**(`inline.go`):递归下降扫描,支持 4 种行内元素嵌套 +| 类型 | 语法 | 特性 | +|------|------|------| +| Bold | `**text**` | 可嵌套 Italic / Code / Link | +| Italic | `*text*` | 可嵌套 Bold / Code / Link | +| Code | `` `text` `` | 原始文本(内部不解析) | +| Link | `[text](url)` | text 可嵌套 Bold / Italic | + +**ANSI 渲染**(`render.go`):type switch 按节点类型分发,标题按级别分配颜色和符号 + +**测试覆盖**:19 个单元测试,覆盖所有块级/行内类型的正常、边界和嵌套场景 + +--- + +### 新增:标题视觉系统 + +用符号 `▪` / `▫` 替代 Markdown 原生 `#` 前缀,视觉效果更接近"标题"而非"标记": + +| 级别 | 符号 | 字体 | 色彩(Monet 睡莲) | 色值 | +|------|------|------|-------------------|------| +| H1 | `▪` | 加粗 | 雾蓝灰 | `#6B8E9B` | +| H2 | `▪` | 加粗 | 鼠尾草绿 | `#89A894` | +| H3 | `▪` | 加粗 | 薄荷青 | `#A6C0B5` | +| H4 | `▫` | 加粗 | 淡紫粉 | `#C3B1BD` | +| H5 | `▫` | 加粗 | 暖灰绿 | `#7B8E8A` | +| H6 | 无 | 加粗(Dim) | 浅灰 | 继承 | + +排版规则:所有标题前插空行,H1 前后各插空行,`---` 横线前后空行,响应与输入之间空行,输出末尾空行。 + +--- + +### 新增:pkg/style — 终端颜色样式库 + +在原有 8 色 ANSI 基础上新增 24-bit 真彩色支持: + +- `Fg(color)` / `Bg(color)`:保留原有 8 色 API +- `FgHex("#RRGGBB")` / `BgHex("#RRGGBB")`:新增真彩色,输出 `\033[38;2;R;G;Bm` 格式 +- 所有 `.Render(text)` 使用统一占位板 `.codes []string`,颜色和样式可组合 +- `NO_COLOR` / `TERM=dumb` 环境变量自动禁用颜色 + +--- + +### 新增:pkg/termui — 终端输入组件 + +提供三个交互式输入函数,统一使用 `bufio.NewReader(os.Stdin)` + `ensureLineMode()` 解决 Windows 控制台输入问题: + +| 函数 | 用途 | 特性 | +|------|------|------| +| `ReadLine()` | 基础行输入 | 去除 `\r\n` | +| `TextInput()` | 文本输入 | 支持默认值、必填校验、自定义验证器 | +| `PasswordInput()` | 密码输入 | 输入后隐藏回显,用 `*` 遮盖 | +| `Confirm()` | 确认提示 | 支持 Y/n / y/N 默认值 | + +--- ### 修复 -- 行内解析器未闭合分隔符(`*` / `` ` ``)导致死循环 -- 代码 fence 检测不识别 ` ```go` 等带语言标识的写法 -- Windows 终端输入模式导致 `bufio.Scanner` 无法获取行输入 + +1. **行内解析器未闭合分隔符死循环**:扫描 `*` / `` ` `` 分隔符时未处理文件末尾无闭合标记的情况,改为找到匹配闭合或到达末尾时终止 +2. **代码 fence 不识语言标识**:` ```go `、` ```json ` 等带语言的 fence 被当作文本行,改为行首 ` ``` ` 后允许非空白后缀 +3. **Windows 控制台输入模式冲突**:`bufio.Scanner` 在 Windows 控制台因 `ENABLE_WINDOW_INPUT` 标志导致 `Scan()` 永久阻塞。改为每轮输入前调用 `GetConsoleMode` + `SetConsoleMode` 确保模式为 `ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT`,并使用 `bufio.NewReader.ReadString('\n')` 替代 Scanner +4. **尝试自实现 Tab 补全未成功**(后放弃):raw mode + `ReadConsoleInputW` 方案遇到光标位置计算不一致问题,最终回退到简单 `ReadLine()`。后续如需补全功能引入第三方库 + +--- ### 变更 -- 项目结构:`src/` → 根目录 + `pkg/` 子包 -- `pkg/style` 新增真彩色 API,向后兼容 + +- **项目结构重组**:`src/` 目录删除,全部 `.go` 文件移至根目录;新增 `pkg/` 子包,按职责分离为 `mdprint/`、`style/`、`termui/` +- **模块名修改**:`yunshu` → `hub.gaomia.site/titor/YunShu` +- **Go 版本升级**:`1.21` → `1.25.0` +- **`Completer` 类型和 `ReadLineWithCompletion` 函数移除**:`completer.go` 清空,相关测试删除 +- **`.gitignore` 修复**:`yunshu.exe` → `yunshu.exe*`(避免调试版本遗漏) + +--- ### 技术栈 -- 语言:Go 1.25 -- 依赖:仅 `gopkg.in/yaml.v3` -- 默认 LLM:豆包(火山引擎)`doubao-seed-2-0-pro-260215` -- 数据源:MSN 天气非公开 API(`assets.msn.cn`) +- **语言**:Go 1.25.0 +- **依赖**:仅 `gopkg.in/yaml.v3` +- **默认 LLM**:豆包(火山引擎)`doubao-seed-2-0-pro-260215` +- **数据源**:MSN 天气非公开 API(`assets.msn.cn`) +- **运行平台**:Windows 10+(基于 kernel32 控制台 API,ANSI VT 处理) +- **输入编码**:UTF-8(通过 `SetConsoleOutputCP(65001)` 设置控制台代码页) ## [1.0.0] - 2026-05-08 diff --git a/main.go b/main.go index 687dfb3..44ec7d2 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,7 @@ import ( "hub.gaomia.site/titor/YunShu/pkg/termui" ) -const version = "1.0.0" +const version = "1.1.0" func init() { kernel32 := syscall.NewLazyDLL("kernel32.dll")