本文档介绍了 bat 的文本预处理系统,该系统在语法高亮和输出格式化之前处理原始输入文本。预处理管道包括制表符扩展、非打印字符处理和 ANSI 转义序列处理。有关预处理后发生的语法高亮的信息,请参阅 语法高亮系统。有关预处理后发生的输出格式化和终端样式的信息,请参阅 终端输出和 ANSI 处理。
bat 中的文本预处理系统会转换原始输入文本,以确保一致的格式和对特殊字符的正确处理。此预处理在语法高亮之前发生,并包括三个主要操作:
文本预处理管道
expand_tabs 函数在保留 ANSI 转义序列的同时,将制表符转换为适当数量的空格。这确保了无论制表符宽度设置如何,都能实现一致的视觉对齐。
制表符扩展流程
该函数处理 ANSI 转义序列之间的文本片段。
| 操作 | 代码位置 | 目的 |
|---|---|---|
| 序列检测 | src/preprocessor.rs12 | 解析 ANSI 和文本段 |
| 制表符位置 | src/preprocessor.rs16 | 在文本中查找制表符 |
| 空格计算 | src/preprocessor.rs24-25 | 计算对齐所需的空格 |
| 光标跟踪 | src/preprocessor.rs19-32 | 保持列位置 |
replace_nonprintable 函数将控制字符和非打印字符转换为可见表示。它支持两种表示样式:插入符号表示法和 Unicode 符号。
字符处理决策树
try_parse_utf8_char 函数通过尝试解析 1-4 个字节来处理多字节 UTF-8 序列。
| 字节长度 | 字符范围 | 示例 |
|---|---|---|
| 1 字节 | ASCII (0x00-0x7F) | 'A', ' ', '\t' |
| 2 字节 | 扩展拉丁字母等 | 'ä' (0xC3 0xA4) |
| 3 字节 | 大多数 Unicode | '€' (0xE2 0x82 0xAC) |
| 4 字节 | 表情符号、稀有 Unicode | '🌂' (0xF0 0x9F 0x8C 0x82) |
该系统支持由 NonprintableNotation 控制的两种表示样式。
插入符号表示法 (^X):
^A, ^B, ^C 等。^J^?Unicode 符号:
␀, ␁, ␂ 等 (0x2400 + 编码)。␊␡strip_ansi 函数在保留实际内容的同时,从文本中删除 ANSI 转义序列。这由 StripAnsiMode 配置控制。
ANSI 序列处理流程
StripAnsiMode 枚举控制何时剥离 ANSI 序列。
| 模式 | 行为 | 用例 |
|---|---|---|
从不 | 保留所有 ANSI 序列 | 当输出支持颜色时 |
始终 | 剥离所有 ANSI 序列 | 纯文本输出 |
汽车 | 基于上下文剥离 | 自动检测 |
来源: src/preprocessor.rs139-158
预处理系统通过几个关键接口与 bat 的核心架构集成。
预处理集成架构
| 组件 | 接口 | 目的 |
|---|---|---|
| 输入系统 | 原始文本 → expand_tabs | 初始制表符处理 |
| 配置 | 设置 → 预处理函数 | 控制行为 |
| 语法高亮 | 处理后的文本 → syntect | 干净的输入用于高亮 |
| vscreen 模块 | EscapeSequenceOffsetsIterator | ANSI 序列解析 |
预处理系统使用 vscreen 模块中的 EscapeSequenceOffsetsIterator 来解析 ANSI 转义序列,确保在制表符扩展和剥离操作期间正确处理格式代码。