字符画复制出去就散架了:等宽、折行、尾随空格和注释里的陷阱

· 约 4 分钟 🔤 ASCII 艺术字

在生成页面上看,字符画横平竖直。复制到 README 里,歪了;粘进聊天窗口,散了;提交之后再打开,右边缘塌了一块。

这三种情况的原因各不相同,但都源于同一件事:字符画的全部信息都在「每个字符占多宽、每行有多长」里,而这两样东西在传输途中会被各种环节悄悄改掉。

一、等宽字体是硬前提

字符画的对齐完全依赖每个字符占一样宽。比例字体里 i 比 M 窄得多,每一行的实际长度都不一样,图形立刻散架。

各处的做法:

场合做法
Markdown三个反引号包起来,或每行前加四个空格
聊天工具微信、飞书、Slack、Discord 都支持三反引号代码块
Word / PPT / 邮件手动改字体为 Consolas、Menlo 等
HTML放进 <pre>,只用 <code> 不够

最后一条值得展开:<code> 不保留换行和连续空格,它只负责字体。必须是 <pre>,或者 <pre><code> 配合使用。

二、代码块不要标语言

围栏写法结果
三个反引号,后面什么都不写✅ 原样输出
三个反引号 + bash / js 等语言名❌ 被语法高亮弄花
三个反引号 + text / plain✅ 平台要求必填时用这个

标了语言,语法高亮器会去解析里面的内容。而字符画里大量出现 / \ * # " ' | < > ——这些在各种语言里都是语法符号。结果是整段被涂成五颜六色,更糟的情况是某个片段被当成未闭合的字符串,把后面的正文一起染色。

平台要求必须写的话,用 text 或 plain。

还有一个相关的坑:如果字符画本身包含三个连续的反引号(某些填充字符组合会产生),代码块会提前闭合。这时改用四个反引号作围栏,或者换一组填充字符。

三、尾随空格:右边缘为什么会塌

这一条最隐蔽,因为它发生在保存的那一刻。

字符画的每一行常常以空格结尾——图形的右边本来就是空的。而绝大多数团队都开了「保存时删除行尾空白」:

  • EditorConfig 的 trim_trailing_whitespace
  • Prettier 和各类格式化器
  • 提交前的 lint 钩子

删掉之后每行长度不再一致,右侧的图形边界就塌了。你在生成页面上看到的和提交后看到的不是同一个东西。

三种解法:

  1. 在每行末尾补一个非空白字符(| 或 .),让右边界成为实体
  2. 在 .editorconfig 里为这个文件单独关掉:
[assets/banner.txt]
trim_trailing_whitespace = false

并把它加进格式化器的忽略列表

  1. 把字符画放进单独的文件(如 banner.txt),程序运行时读取,不参与代码格式化

第三种最省心,尤其是 CLI 工具的启动 banner——顺带把下面要讲的转义问题也一次性解决了。

四、注释里的字符画:*/ 会提前闭合

想在长文件里用字符画做分区标记,第一个坑就在这儿:

/*
   ██  ██   *\/*   ← 这里的 */ 把注释闭掉了
*/

C 系语言(JS、Java、C、Go、CSS)的块注释以 */ 结束,而字符画里只要出现相邻的星号和斜杠,注释就在那里断了,后面的图形变成一堆语法错误。

做法:

  • 用行注释——每行前面加 // 或 #。最稳,没有任何例外
  • 确实要用块注释,就换一组不含 * 和 / 的填充字符

其他语言各有各的坑:

语言坑解法
Python docstring\ 被当转义序列用 r"""..."""
JS 模板字符串反引号和 ${普通字符串拼接
Shell 双引号$ 和 ` 会展开用单引号,或 heredoc

通用建议还是那句:banner 放进独立的文本文件,运行时读取,所有转义问题一次性消失。

五、80 列这条线

超过 80 列会折行,而字符画一旦折行就彻底散架——折下来的半行接在下一行开头,图形完全认不出来。

80 这个数字来自打孔卡,一直沿用到今天:大多数终端默认 80 列,GitHub 的代码块在常见屏宽下也差不多是这个量级。

控制宽度的办法按模式不同:

  • 英文(figlet) —— 换更紧凑的字体,或者调小字间距
  • 中文点阵 —— 把输出行数调小。宽度是由行数推出来的,不能单独设

ASCII 艺术字 在超过 80 列时会提示,按提示调就行。

六、块字符的宽度歧义

█ ▓ ▒ ░ 这几个字符观感确实比 @ # * . 好,但它们在 Unicode 里属于「东亚宽度歧义」类:西文环境下占一格,中日韩环境的终端里可能占两格。

同一份字符画,在你的编辑器里对齐,同事的终端里就歪了。

要发给别人看、要进 README 或代码注释的场合,用纯 ASCII 的那几个字符更稳。

七、几个常见场合的宽度参考

场合建议宽度
终端 banner≤ 80 列
GitHub README≤ 80 列
Git commit message≤ 72 列
代码注释分区≤ 60 列,太大反而碍事

commit message 那条是 Git 的传统惯例——不过话说回来,字符画不太适合放进 commit message,它会出现在每一次 git log 里。

发布前的检查清单

  • 放进代码块了(三反引号,不标语言)
  • 行尾空格不会被格式化器删掉,或者右边界有实体字符
  • 宽度在 80 列以内
  • 不含 */(如果要进块注释)
  • 不用块字符(如果要发给别人)
  • 在目标环境里实际看一眼 —— 这一步能拦下上面全部五条

❓ 常见问题

粘进聊天工具或文档就歪了,怎么办?

它被用比例字体渲染了,必须放进代码块。原理:字符画的全部对齐信息来自「每个字符占一样宽」这个前提。比例字体里 i 比 M 窄得多,每一行的实际长度都不一样,图形立刻散架。各处的做法:(1) Markdown(GitHub、多数文档系统)—— 用三个反引号包起来,或者每行前面加四个空格;(2) 聊天工具 —— 微信、飞书、Slack、Discord 都支持三反引号的代码块,发之前包一下;(3) Word、PPT、邮件 —— 手动把那段文字的字体改成 Consolas、Menlo、等宽这类;(4) HTML —— 放进 <pre> 标签,只用 <code> 不够,<code> 不保留换行和连续空格。验证方法:发出去之后自己看一眼,歪了就是没进代码块。

Markdown 代码块要不要标语言?

不要标,标了反而会被语法高亮弄花。原因:标了语言之后高亮器会去解析里面的内容,而字符画里大量出现 / \ * # " ' | < > 这些在各种语言里都是语法符号——结果是整段被涂成五颜六色,甚至有的片段被当成未闭合的字符串,把后面的内容一起染色。正确写法:三个反引号后面什么都不写,直接换行。如果平台要求必须写,用 text 或 plain。另一个相关的坑:字符画里如果本身包含三个连续的反引号(某些填充字符组合会),代码块会提前闭合——这时改用四个反引号作为围栏,或者换一组填充字符。

保存之后右边缘为什么塌了一块?

尾随空格被编辑器或格式化器删掉了。机制:字符画的每一行常常以空格结尾(图形右边是空的),而绝大多数团队都开了「保存时删除行尾空白」——EditorConfig 的 trim_trailing_whitespace、Prettier、各种 lint 规则都会做这件事。删掉之后每行长度不一,右侧的图形边界就塌了。三种解法:(1) 在每行末尾补一个非空白字符,比如 | 或 .,让图形的右边界成为实体;(2) 在 .editorconfig 里为这个文件单独关掉 trim_trailing_whitespace = false,并把它加进格式化器的忽略列表;(3) 把字符画放进单独的文件(如 banner.txt),程序运行时读取,不参与代码格式化。第三种最省心,尤其是 CLI 工具的启动 banner。

把字符画放进代码注释要注意什么?

最大的坑是块注释会被提前闭合。问题:C 系语言(JS、Java、C、Go、CSS)的块注释以 */ 结束,而字符画里只要出现相邻的星号和斜杠,注释就在那里断了,后面的图形变成语法错误。做法:(1) 用行注释 —— 每行前面加 // 或 #,这是最稳的;(2) 确实要用块注释就换一组填充字符,避开 * 和 /。其他语言的坑:(1) Python 的 docstring —— 里面的 \ 会被当转义序列,用 r"""...""" 原始字符串;(2) JS 模板字符串 —— 反引号和 ${ 要转义,普通字符串拼接更省事;(3) Shell —— 单引号里最安全,双引号里的 $ 和 ` `` 会被展开。通用建议:banner 这类内容放进独立的文本文件,运行时读取,所有转义问题一次性消失。

🔤 打开 ASCII 艺术字 英文 figlet 20 款字形·中文点阵支持黑/宋/楷/圆/仿宋五种字体 × 实心/灰度/轮廓/反白四种风格·行数与笔画阈值可调·复制或下载 TXT →

🔗 相关阅读

全部教程 →