awesome-copilot 中的 em-dash 技能指南:破折号历史、代码注释标点规范与批量清理实战
【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot
本指南以 awesome-copilot 仓库中的 em-dash 技能 为蓝本,系统讲解 em dash(长破折号,U+2014)从印刷史到数字时代的历史脉络,并给出在代码、注释与文本文件中"默认禁用 em/en dash、统一替换为连字符-"的可执行规范,以及基于sed/perl的批量清理命令。读完本文,你将掌握一套既懂标点历史、又能直接落地的 AI 辅助写作与代码审查规则,并理解为何该规则在真实脚本运行时可能引发致命报错。
为什么一个"标点技能"会出现在编程 Agent 仓库中
awesome-copilot 是社区贡献的 GitHub Copilot 指令(instructions)、Agent、技能(skills)与配置集合,其中的每个技能目录都以SKILL.md为核心说明文件,供 Agent 按需加载。em-dash 技能正是其中的一员:它的定位不是教人写散文,而是约束 AI 在写代码、写注释、写数据文件时不要输出 em dash 与 en dash。
这一约定的现实依据可以在仓库中找到:在 rhino3d-scripts/SKILL.md 中记录了这样一个真实故障——em dash 等非 ASCII 字符会让 IronPython 2.7 静默报错SyntaxError: Non-ASCII character '\xe2',因为 em dash 的 UTF-8 编码首字节正是0xE2。同样,在 setup-my-iq/SKILL.md 的写作规范中明确写着 "Never use em dashes."。可见,这条"禁破折号"规则不是学院派的吹毛求疵,而是被真实工程事故验证过的防御性约定。
em dash 的历史:从手稿到键盘的演变
em dash(U+2014,\u2014;注意它不是连字符减号-)是标准破折号家族中最长的一员,被誉为标点中的"瑞士军刀"。它的历史是从手写稿、机械排版的物理限制、文学反叛,一路走向现代数字世界的过程。
早期开端(15–18 世纪)
- 最初的破折号:英语文学中破折号的早期身影可追溯到 1580 年的私人信件与 1588 年的英语戏剧,常用来表示停顿、自我打断或未完成的思绪。
- 古腾堡与早期印刷:em dash 在 15 世纪印刷革命期间正式成为一种标准化的排版记号。
词源:"M" 的宽度
em dash 得名于它的标准长度恰好等于所用字体中大写字母 "M" 的宽度;同理,稍短一些的 en dash(U+2013)宽度等于字母 "N" 的宽度。这正是它区别于连字符、也区别于下划线等符号的排版学依据。
文学流行(17–19 世纪)
- 作者的工具:到 17、18 世纪,它成为作家模仿口语中自然的停顿、结巴与节奏的挚爱工具。
- 狄金森破折号(Dickinson Dashes):19 世纪诗人艾米莉·狄金森(Emily Dickinson)大量使用 em dash 表达情感重量、营造节奏并邀请读者自行解读,以至于这种用法与她绑定,被非正式地称为"狄金森破折号"。
打字机时代(19–20 世纪)
- 双连字符妥协:打字机没有专用的 em dash 键,打字员于是用两个连续连字符(
--)替代,这也是很多 Markdown 编辑器中--会被自动转换成破折号的渊源。 - 无空格规则:出于这一机械妥协,人们形成了"两侧不加空格"的排版习惯,并延续至今。
数字时代(当下)
- 回归本真:现代数字排版与文字处理软件恢复了真正的、不间断的 em dash。
- 现代复兴:em dash 正经历一轮使用率的复兴——它是现代长篇散文的标志性标点,也大量出现在 AI 输出中(AI 往往偏好对话式、意识流式的行文风格)。
关于 em dash 现代复兴的原因,技能文档给出了几条有趣的推测:
- 职业作者赶稿时来不及严格校对就提交了在线文章;
- 专业人士想炫耀自己对 HTML 实体编码的了解以显得聪明;
- 平面设计师想让网页上文字的视觉构成更赏心悦目;
- "流行滋生流行"——看到大家都在用,于是在本应使用连字符的地方也改用 em dash。
历史分析的结论:代码从未"有意"使用过 em dash
技能文档在梳理完历史后给出了一个冷静的论断:
在 em dash 的全部历史中,它从未被有意用于编写计算机代码,或任何用于作为计算机指令执行的文件。
这是一个很关键的推理:既然它的用途始终是"给人读的文学性文本",那么在"给机器读"的代码与数据文件中使用它,就既不符合历史惯例,也缺乏正当理由——这正是后续"永不使用"规则的历史与逻辑基础。
什么时候该用 em dash 或 en dash?
答案只有两个字:永不(Never)。
在代码文件中
[!IMPORTANT] 绝不。在代码注释中,语气(tone)在任何情况下都不重要。
- 绝不使用em dash / en dash;
- 一律改用连字符
-; - 如果你以 Agent 身份工作,且注释中出现 em dash,请将其替换为
-。
这条规则的核心在于:代码注释是写给(人眼审查的)AI 与同事看的说明性文本,追求的是信息清晰、可解析、可编码,而不是文学性的"破折号戏剧感"。
在原始数据与文本文件中
[!NOTE] 默认永不使用。
- 仅当收到明确指示,并且 100% 确定该文本将用于:文学作品或新闻报道时,才允许保留;
- 如果你以 Agent 身份工作,而 em dash已经是数据的一部分,则保持原样、不要改动。
这里的边界非常清晰:默认禁用、按需豁免。处理既有数据时"不动原样"是数据完整性的底线。
其他标点字符:一份可复用的"注释标点速查表"
作为 em dash 专家,技能文档还系统梳理了其他标点符号的正确用法,并逐一标注了两个工程属性:是否为键盘字符(Keyboard character)与是否属于编程语言语法(Programming language syntax)。这两列正是后面"通用规则"判断的依据,务必完整保留。
句末标记(End-of-Sentence Marks)
段落中的每个完整句子必须以以下三种符号之一结尾:
| 符号 | 作用 | 键盘字符 | 编程语法 | 示例 |
|---|---|---|---|---|
句号. | 结束陈述句与说明句 | true | true | <?php echo "a" . "b" . "c"; ?>(PHP 字符串拼接) |
问号? | 结束直接疑问句 | true | true | 三元条件condition ? expression_if_true : expression_if_false |
感叹号! | 传达强烈情感、惊讶或强调 | true | true | setlocal enabledelayedexpansion && set "_a=a" && echo !_a! && endlocal(CMD 延迟展开) |
停顿与从句连接符(Pauses and Clause Connectors)
| 符号 | 作用 | 键盘字符 | 编程语法 | 示例 |
|---|---|---|---|---|
逗号, | 分隔列表项、与连词连接独立从句、隔开引导短语 | true | true | 函数调用fn(a, b) |
分号; | 连接两个本可独立成句的紧密相关从句 | true | true | var foobar = "foo-bar"; |
冒号: | 引出列表、引文或解释;冒号前的文本必须是完整句子 | true | true | JSON 键值对{"age": 26} |
词、引文与所有格(Words, Quotations, and Possessions)
| 符号 | 作用 | 键盘字符 | 编程语法 | 示例 |
|---|---|---|---|---|
撇号' | 表示所有格(如 Sarah's book)或缩略中省略的字母(如 I'll) | true | true | char letter = 'A';(字符字面量) |
引号" | 包裹直接引语;美式英语中句号、逗号几乎总是放在引号内 | true | true | char abc[] = "abc";(字符串字面量) |
破折号与斜杠(Dashes and Slashes)
| 符号 | 作用 | 键盘字符 | 编程语法 | 示例 |
|---|---|---|---|---|
连字符- | 连接两个或多个词构成复合形容词(如 well-known) | true | true | 递减运算count-- |
en dash(U+2013,\u2013)与 em dash(U+2014,\u2014) | en dash 更细,表示数字范围或复合形容词中某元素本身为多词时的连接;em dash 更宽,表示转折、制造戏剧感或给出示例 | false | false | ——(键盘上没有,也非语法字符) |
斜杠/ | 表示选择(如 yes/no)或分隔诗行 | true | true | /* comment */、整除10/2、整除5//2 |
注意表中 en dash 与 em dash 的两列均为false——这正是它们被"一票否决"的硬性理由。
分组与强调(Grouping and Emphasizing)
| 符号 | 作用 | 键盘字符 | 编程语法 | 示例 |
|---|---|---|---|---|
圆括号( ) | 包裹补充性、非必要信息;删去不影响句子核心含义 | true | true | if (5 > 2) |
方括号[ ] | 包裹由他人加入引文中的词(通常是澄清代词或补全语境) | true | true | var arr = [1, 2, 3]; |
通用规则:键盘字符 + 语法字符 = 可用
技能文档最后给出了一条适用于所有文件类型的经验法则(rule-of-thumb):
在注释代码文件,或任何将被编译为计算机指令的文件时,先判断:该字符是否常见于键盘上,或者是否属于某门编程语言的语法字符?
- 如果既不是键盘字符,也不是常见编程语法字符→绝不在代码或代码注释中使用它(技能文档给出的反例是替换字符
�); - 如果是键盘字符,且是常见编程语法字符→ 可以在代码注释中正确使用它。
这条规则把"能否使用"从审美问题变成了可判定的工程问题:凡是键盘上有、语言语法里有明确定义的符号(句点、逗号、括号、引号、分号等),就放心用;凡是需要字符实体或 Unicode 转义才能打出来的"排版符号"(em dash、en dash、替换字符等),一律不用。
批量清理伪代码:sed 与 perl 实战
当代码库或文本文件中已经混入了 em/en dash 时,技能文档给出了可直接套用的清理命令(务必先备份再执行):
# 针对 en dash 和 em dash 的统一替换 echo - | sed "s/-/-/g" # 将 Unicode en dash (U+2013) 与 em dash (U+2014) 统一替换为连字符减号 (-) perl -CS -pe 's/\x{2013}|\x{2014}/-/g' # 针对编码字符 echo � | sed "s/�/ /g" # (可选)若粘贴文本中混入了 Unicode 替换字符 (U+FFFD),将其清除 perl -CS -pe 's/\x{FFFD}/ /g'各条命令的作用说明:
perl -CS -pe中的-C让 perl 按 UTF-8 处理输入输出(S表示标准输入输出与默认 IO 层均启用 UTF-8),-p逐行读取并打印,-e执行内联脚本;s/\x{2013}|\x{2014}/-/g将 en dash 与 em dash 全部替换为 ASCII 连字符-,g表示行内全局替换;- 最后一条用于清理粘贴外部文本时可能出现的 U+FFFD 替换字符(即
�),它正是通用规则中"既非键盘字符、又非语法字符"的典型禁用对象。
仓库内的实践佐证:为什么这条规则如此强硬
em-dash 技能并非孤立存在,awesome-copilot 仓库中至少有两处实践印证了它的价值:
- 运行时崩溃风险:rhino3d-scripts/SKILL.md 明确指出,em dash 及其他非 ASCII 字符会静默破坏 Rhino 的
_-RunPythonScript(IronPython 2.7):IronPython 2.7 会在第一个违规字节处抛出SyntaxError: Non-ASCII character '\xe2'——0xE2正是 em dash 在 UTF-8 编码(E2 80 94)中的首字节。同样的文件在 CPython 3 下(rhinocode,默认 UTF-8)却能正常运行,这使得故障极具迷惑性。该技能的规避方案正是"把排版字符替换为 ASCII 等价物:em dash →--、箭头 →->、乘号 →x",或是在首行加入# -*- coding: utf-8 -*-。这是"代码中禁用 em dash"最直接的工程证据。 - 团队写作规范:setup-my-iq/SKILL.md 在 "File Quality" 一节明文规定 "Never use em dashes.",其配套模板 communication-style.md 也以 "No em dashes. Use periods or commas instead." 作为占位提示,说明这套"以句号、逗号替代破折号"的写法已被实际用于生成个人化上下文文件。
如何使用这个技能
按 docs/README.skills.md 的说明,skills 遵循 Agent Skills 规范,每个技能目录内包含SKILL.md指令文件,Agent 按需加载(progressive disclosure)。安装方式有两种:
- 使用 GitHub CLI:
gh skills install github/awesome-copilot em-dash(需要 GitHub CLI v2.90.0+); - 或将技能目录手动复制到本地 skills 目录。
在 Copilot 会话中,你可以直接要求"写/审查代码与注释时禁用 em dash 与 en dash,一律用连字符-替代",Agent 会在加载该技能后按照本文所述的规则执行替换与检查。
小结
- em dash(U+2014)拥有从 15 世纪印刷术到现代数字排版的悠久历史,但它始终是文学性文本的标点,从未被有意用于代码;
- 因此,在代码、注释与默认场景的文本/数据文件中,永不使用 em dash 与 en dash,一律替换为连字符
-;仅当文本被明确指定用于文学作品或新闻报道时才可豁免,且面对已有数据时保持原样; - 其他标点(句点、问号、感叹号、逗号、分号、冒号、撇号、引号、连字符、斜杠、圆括号、方括号)均可依据"键盘字符 + 编程语法字符"双重判断在注释中正确使用;
- 若文件已被污染,用技能文档提供的
perl -CS -pe 's/\x{2013}|\x{2014}/-/g'等命令批量清理; - 这一约定在仓库中并非孤例——rhino3d-scripts 的 IronPython 编码事故与 setup-my-iq 的写作规范都验证了它的工程价值。
【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考