← Discover MCPs and Agents
t
MCPAI & MLGitHub

terminal-cjk-table-alignment

终端 AI(Claude Code / Codex 等)输出的表格复制到笔记就错乱?三层根因分析与彻底解决方案 | Why CJK tables from AI CLI tools break when pasted into notes, and the one-time fix

Links

README

From the repo.

终端 AI 输出的表格,复制到笔记就错乱 —— 根因与彻底解决方案

适用于:Claude Code / Codex / Gemini CLI 等所有在终端输出表格的 AI 工具 环境:Windows 11 + WSL2 + 印象笔记(结论同样适用于 macOS / Linux 与其他笔记软件) 结论先行:装一款 CJK 配平的等宽字体(Sarasa Fixed SC)即可根治,无需改变任何输出习惯。

Tables from AI CLI tools look perfect in the terminal but break when pasted into notes. Root cause is threefold — see English Summary at the bottom.


一、问题现象

终端里 AI 输出的表格看着整整齐齐:

┌───────┬────────────────┬─────────────┬────────────────────┐
│ 机器  │ 类型           │ 内网 IP     │ 所属网络           │
├───────┼────────────────┼─────────────┼────────────────────┤
│ Win-A │ 轻量应用服务器 │ 10.1.0.12   │ 轻量自己的私有网络 │
└───────┴────────────────┴─────────────┴────────────────────┘

复制到记事本或笔记软件,边框全乱:横线远长于内容行,竖线参差不齐。

很容易误判成「AI 输出的内容本身有问题」,实际不是 —— 字符流完全正确,问题出在渲染端。


二、三层根因

根因一:box-drawing 属于「歧义宽度」字符

用 Python 查 Unicode 属性:

import unicodedata
for c in '┌─┬│中文+-|':
    print(repr(c), unicodedata.east_asian_width(c))
字符East_Asian_Width含义
┌ ─ ┬ │ └ ┘A (Ambiguous)占 1 格还是 2 格没有定论,由接收端决定
中 文W (Wide)2 格
+ - |Na (Narrow)1 格

Ambiguous 是罪魁:这类字符在东亚传统编码里是全角,在西文语境里是半角。 终端按 1 格排版,接收端若按 2 格渲染,横线立刻撑成两倍长。

实测同一张表两种算法下的行宽:

横线行  ┌───────┬──...    A算1格: 61 格    A算2格: 122 格   ← 差一倍
内容行  │ 机器  │ 类型...  A算1格: 61 格    A算2格:  66 格

根因二:接收端字体中英不等宽

即使换成纯 ASCII 边框(+ - |,不含任何歧义字符),在记事本里照样歪。

因为 Consolas 根本不含中文字形。中文会 fallback 到微软雅黑,而 「雅黑的中文宽度」并不等于「Consolas 的 ASCII 宽度 × 2」,中英混排必然错位。

各环境实测:

环境字体结果
Notepad++Consolas 10✅ 全部对齐(含 box-drawing 表格)
记事本默认❌ 全崩
印象笔记微软雅黑❌ 全崩
印象笔记Consolas 10⚠️ 竖线基本齐,横线仍超长

根因三:你复制走的从来不是 Markdown 源码

这一层最隐蔽。AI 在对话里写的是 Markdown 源码:

| 机器 | 类型 |
|---|---|

终端会把它渲染成 box-drawing 表格再显示。你框选复制,拿到的是渲染后的 ┌─┬ 字符,不是源码。

所以「让 AI 改用 Markdown 输出」这条路是无效的 —— 只要你从终端框选复制, 出来的永远是最脆弱的 box-drawing 版本。

例外:表格放进代码块(```)时终端不渲染,此时复制到的才是原始字符。


三、快速诊断

把下面这段贴进任意编辑器,看每组的行末是否齐平(也可直接用 samples/table-format-test.txt):

--- 诊断A:中文宽度是否等于 2 倍 ASCII?三行右端必须齐平 ---
0123456789012345678901234567890123456789
中文中文中文中文中文中文中文中文中文中文
++++++++++++++++++++++++++++++++++++++++

--- 诊断B:制表符是否被当成全角?两行右端必须齐平 ---
0123456789012345678901234567890123456789
────────────────────────────────────────
结果判定对策
A 不齐字体中英不等宽换字体(见下)
A 齐、B 不齐制表符被当全角换字体,或让 AI 改用 ASCII 边框
全齐环境正常无需处理

四、解决方案:安装 Sarasa Fixed SC

为什么是这一款

更纱黑体 Sarasa Gothic(开源,SIL OFL 协议) 是少数把 CJK 与拉丁字符严格配平为 2:1 的等宽字体。

家族里有 5 个变体,按用途选:

变体等宽连字说明
Gothic / UI比例字体,不适合表格
Monoem dash 全宽
Termem dash 半宽,终端向
Fixed无连字,em dash 半宽 —— 表格场景最安全

Fixed 是因为它无连字:连字可能把 ---|> 之类合并成单一字形,给对齐引入不确定性。

其他常见等宽字体为什么不行:Consolas / JetBrains Mono / Fira Code 等都不含 CJK 字形, 中文一律 fallback 到系统字体,2:1 关系无法保证。必须选原生包含 CJK 的等宽字体。

实测字形宽度(用 fontTools 直接读字体文件)

from fontTools.ttLib import TTFont
f = TTFont('SarasaFixedSC-Regular.ttf')
cmap, hmtx = f.getBestCmap(), f['hmtx']
w = lambda ch: hmtx[cmap[ord(ch)]][0]
类别字符宽度 (upm=1000)相对 ASCII
ASCII0 A a | + -5001.00
CJK中 文 网 络10002.00
制表符─ │ ┌ ┼ ┘5001.00(半宽)
符号→ ↑ ○ ● ·5001.00

制表符是半宽,恰好等于终端排版时的假设 —— 这就是为什么装上它以后, 连最脆弱的 box-drawing 表格都能完美对齐。

安装步骤

下载(只需 SC 简中版,62 MB。TC/J/K 变体见 Releases):

curl -sL -o SarasaFixedSC.7z \
  https://github.com/be5invis/Sarasa-Gothic/releases/download/v1.0.40/SarasaFixedSC-TTF-1.0.40.7z

包内含 10 个字重,日常只需 Regular 和 Bold:

python3 -m pip install py7zr --break-system-packages
python3 -c "
import py7zr
with py7zr.SevenZipFile('SarasaFixedSC.7z') as z:
    z.extract(targets=['SarasaFixedSC-Regular.ttf','SarasaFixedSC-Bold.ttf'])
"

方式一:手动(最简单)—— 选中两个 .ttf → 右键 → 安装

方式二:用户级静默安装(无需管理员、不弹 UAC、随时可卸载)

$dst = "$env:LOCALAPPDATA\Microsoft\Windows\Fonts"
$key = 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Fonts'
New-Item -ItemType Directory -Force -Path $dst | Out-Null

@{
  'SarasaFixedSC-Regular.ttf' = 'Sarasa Fixed SC Regular (TrueType)'
  'SarasaFixedSC-Bold.ttf'    = 'Sarasa Fixed SC Bold (TrueType)'
}.GetEnumerator() | ForEach-Object {
  Copy-Item ".\$($_.Key)" $dst -Force
  New-ItemProperty -Path $key -Name $_.Value `
    -Value (Join-Path $dst $_.Key) -PropertyType String -Force | Out-Null
}

WSL 用户注意:可先用 cp 把 ttf 复制到 /mnt/c/Users/<用户名>/AppData/Local/Microsoft/Windows/Fonts/, 再用 PowerShell 只写注册表,可绕开中文路径的编码问题。

macOS / Linux 直接双击安装,或分别放入 ~/Library/Fonts/~/.local/share/fonts/ (Linux 需 fc-cache -f)。

启用

  1. 重启目标软件(印象笔记 / Word / 编辑器)—— 已运行的进程不会感知新字体
  2. 字体下拉框选 Sarasa Fixed SC,字号 10~12
  3. 可选:把终端字体也换成它(Windows Terminal:设置 → 配置文件 → 外观 → 字体), 做到终端所见即粘贴所得。缺点是这个字体风格偏硬朗,看个人喜好

五、备选方案(不想装字体时)

目标场景方案依赖字体
印象笔记 / Word / 邮件生成 HTML → 浏览器打开 → 全选复制 → 粘贴成原生表格
ExcelTSV(Tab 分隔),粘贴即自动分列
纯文本 / 代码注释纯 ASCII 边框 + - |,并让 AI 包进代码块
支持 Markdown 的笔记Markdown 表格,但必须让 AI 包进代码块才能复制到源码

这些都能用,但都需要每次多做一步。装字体是一次性投入、之后零成本,因此优先推荐。


六、仓库内容

文件用途
table_fmt.py多格式表格生成器:Unicode / ASCII / Markdown / TSV / HTML 五种输出,按 East_Asian_Width 正确计算列宽
samples/table-format-test.txt诊断标尺 + 5 种格式对照,用于检测任意新环境
samples/native-table.htmlHTML 原生表格样例,浏览器打开后全选复制即可粘成真表格
python3 table_fmt.py           # 打印诊断标尺 + 5 种格式对照
python3 table_fmt.py --html    # 输出 HTML 原生表格

table_fmt.py 顶部的 HEADERS / ROWS 即可换成自己的数据。

字体本身不在本仓库内(62 MB 二进制),请从 Sarasa-Gothic Releases 下载。


七、参考


English Summary

Problem. Tables printed by AI CLI tools (Claude Code, Codex, Gemini CLI…) look perfectly aligned in the terminal, but fall apart when pasted into Notepad, Evernote, OneNote or similar.

Three stacked root causes:

  1. Box-drawing characters (┌ ─ ┬ │) are East_Asian_Width = Ambiguous. Their width is undefined — 1 cell in Western context, 2 cells in CJK context. The terminal lays them out as 1 cell; if the receiving app renders them as 2, horizontal rules become twice as long as the content rows.
  2. The receiving font is not CJK-balanced. Consolas contains no CJK glyphs at all, so Chinese falls back to another font whose glyph width is not exactly 2× the Latin width. Any space-padded alignment is then impossible.
  3. You never copy the Markdown source. The terminal renders Markdown into box-drawing tables before display, so selecting and copying yields the rendered ┌─┬ text — which is the most fragile form. Telling the AI to "output Markdown instead" therefore does not help.

Fix. Install a monospace font that natively contains CJK with a strict 2:1 ratio — Sarasa Fixed SC (SIL OFL). Verified glyph advances: ASCII = 500, CJK = 1000 (exactly 2×), box-drawing = 500 (half width), which matches the terminal's layout assumption exactly. After installing it and selecting it in your note app, copy-paste works with no change to how the AI formats its output.

Use samples/table-format-test.txt to diagnose any environment, and table_fmt.py to emit tables in five formats with correct East_Asian_Width-aware column widths.


License

MIT

Collected info

  • 1 stars
  • Language: Python
  • Source updated: 8/14/2026

Config for your environment

Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.

Tool

OS

Config file: ~/.cursor/mcp.json

{
  "mcpServers": {
    "mcp-server": {
      "url": "{MCP_ENDPOINT_URL}"
    }
  }
}

Paste into mcpServers in the config file. Restart Cursor after saving.

If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.