第5章 过滤模式
第 5 章:过滤模式
Aspell 的过滤器(Filter)系统能够智能识别文档中的非自然语言内容(如 TeX 命令、HTML 标签、URL 等),只对实际文本进行拼写检查。本章详解各类内置过滤器的使用方法及自定义过滤器开发。
5.1 过滤器概述
5.1.1 为什么需要过滤器
未经过滤的文本会将代码、标记语言标签也当作"单词"进行检查,导致大量误报:
# 不使用过滤器检查 HTML
echo '<p class="highlight">Hello teh world</p>' | aspell list
# 输出: p, class, highlight, teh
# 只有 "teh" 是真正的拼写错误!
# 使用 HTML 过滤器
echo '<p class="highlight">Hello teh world</p>' | aspell list --mode=html
# 输出: teh
# 正确!只报告真正的拼写错误
5.1.2 过滤器工作原理
输入文本 → 过滤器链 → 自然语言文本 → 拼写检查 → 结果
│
├─ 识别并跳过: <html标签>
├─ 识别并跳过: \tex命令
├─ 识别并跳过: https://url
└─ 只传递: 实际文本内容
5.1.3 查看可用过滤器
# 列出所有已安装的过滤器
aspell dump filters
# 典型输出:
# email
# html
# markdown
# nroff
# tex
# texinfo
# url
5.2 内置过滤器详解
5.2.1 HTML 过滤器
HTML 过滤器能够:
- 跳过 HTML 标签名和属性值
- 跳过
<script>和<style>块 - 解码 HTML 实体(如
&→&) - 只检查可见文本内容
# 基本使用
aspell check --mode=html page.html
# 管道模式
echo '<div class="container"><p>Hello <strong>teh</strong> world</p></div>' | \
aspell list --mode=html
# 输出: teh
HTML 过滤器处理示例
<!-- 输入 HTML -->
<h1>Welcome to teh Aspell tutorial</h1>
<p>Aspell is a <em>spellling</em> checker.</p>
<a href="https://example.com">Click hre</a>
<script>var x = "dont check this";</script>
<style>.error { color: red; }</style>
echo '<h1>Welcome to teh Aspell tutorial</h1>
<p>Aspell is a <em>spellling</em> checker.</p>
<a href="https://example.com">Click hre</a>
<script>var x = "dont check this";</script>
<style>.error { color: red; }</style>' | aspell list --mode=html
# 输出:
# teh
# spellling
# hre
HTML 过滤器配置选项
# 不检查 alt 属性(默认检查)
echo '<img alt="teh image" src="pic.jpg">' | aspell list --mode=html
# 输出: teh
# 跳过 alt 属性检查
echo '<img alt="teh image" src="pic.jpg">' | aspell list --mode=html -H
5.2.2 TeX / LaTeX 过滤器
TeX 过滤器是 Aspell 最强大的过滤器之一,能够智能解析 TeX 命令语法:
# 基本使用
aspell check --mode=tex paper.tex
# 管道模式
echo '\section{Introduction to teh Aspell}' | aspell list --mode=tex
# 输出: teh
TeX 过滤器处理规则
| TeX 元素 | 处理方式 | 示例 |
|---|---|---|
\command | 跳过命令名 | \textbf → 跳过 |
\command{text} | 检查花括号内容 | \textbf{hello teh} → 检查 “hello teh” |
% comment | 可配置是否检查 | % TODO: fix teh → 可选 |
$math$ | 跳过数学模式 | $E = mc^2$ → 跳过 |
\begin{...} | 跳过环境名 | \begin{itemize} → 跳过 |
\\ | 跳过转义 | \\ → 跳过 |
\~\#\$\%\& | 跳过特殊字符转义 | \$ → 跳过 |
TeX 过滤器详细示例
% 输入 LaTeX 文档
\documentclass{article}
\title{Aspell: A Spellling Checker}
\author{John Doe}
\date{\today}
\begin{document}
\maketitle
\section{Introduction}
Aspell is a poweful spell checker for Unix systems.
It was designed as a replacment for ispell.
% This is a commnt that should be checked
Aspell uses phonetc algorithms for suggestions.
\begin{equation}
E = mc^2
\end{equation}
The cost is \$5.99 per mnth.
\end{document}
# TeX 过滤器会正确处理:
# - 跳过 \documentclass, \title, \author, \begin 等命令
# - 检查花括号中的文本(如 "A Spellling Checker")
# - 跳过数学模式
# - 跳过 \$ 等转义字符
# - 可选检查注释
echo '\title{Aspell: A Spellling Checker}' | aspell list --mode=tex
# 输出: Spellling
echo 'Aspell is a poweful spell checker.' | aspell list --mode=tex
# 输出: poweful
echo '$E = mc^2$ is importnt' | aspell list --mode=tex
# 输出: importnt
TeX 过滤器选项
# 检查注释(默认不检查)
echo '% teh fix' | aspell list --mode=tex --mode=tex-comments
# 不检查命令参数
echo '\textbf{teh}' | aspell list --mode=tex --dont-tex-check-params
# 自定义不检查的命令
echo '\label{fig:teh}' | aspell list --mode=tex \
--add-tex-command="label op"
5.2.3 Email 过滤器
Email 过滤器处理邮件格式的文本:
# 基本使用
aspell check --mode=email message.eml
# 管道模式
cat message.eml | aspell list --mode=email
Email 过滤器处理规则
| 元素 | 处理方式 |
|---|---|
From:, To:, Subject: 等头部 | 可选检查 |
> quoted text | 可配置是否检查 |
-- 签名分隔符 | 跳过分隔符后的内容 |
Content-Type: 等 MIME 头 | 跳过 |
| Base64 编码内容 | 跳过 |
Email 过滤器示例
From: John Doe <[email protected]>
Subject: Meeting about teh project
Hi team,
Please review the atached document.
> The prevous version had some isues.
Let's fix them ASAP.
--
John Doe
CEO, Exampl Corp
# Email 过滤器会:
# - 检查正文("teh", "atached")
# - 可选检查引用文本
# - 跳过签名块
cat message.eml | aspell list --mode=email
# 输出(不检查引用):
# teh
# atached
# 检查引用文本
cat message.eml | aspell list --mode=email --email-check=
5.2.4 URL 过滤器
URL 过滤器跳过 URL 和文件路径:
# 跳过 URL
echo 'Visit https://example.com/path?q=1 for teh docs' | aspell list --mode=url
# 输出: Visit, teh, docs
# 跳过文件路径
echo 'See /usr/local/bin/aspell for teh binary' | aspell list --mode=url
URL 过滤器处理规则
| 模式 | 示例 |
|---|---|
http://... / https://... | 完整 URL |
ftp://... | FTP 地址 |
mailto:... | 邮件地址 |
/path/to/file | 绝对路径 |
file.txt | 可选:文件名 |
5.2.5 Nroff 过滤器
Nroff 过滤器用于 man page 和其他 nroff/troff 格式文档:
# 检查 man page 源文件
aspell check --mode=nroff manpage.1
# 管道模式
echo '.SH NAME
aspell \- a spellng checker
.SH SYNOPSYS
.B aspell
.RI [ options ]
.I command' | aspell list --mode=nroff
# 输出: spellng, SYNOPSYS
5.2.6 Markdown 过滤器
Markdown 过滤器(部分 Aspell 版本内置,否则需要自定义):
# 使用 markdown 模式
echo '# Welcome to teh Aspell tutorial
This is a **bold** statment.
```python
print("dont check code blocks")
Click hre’ | aspell list –mode=markdown
输出: teh, statment, hre
---
## 5.3 过滤器组合使用
### 5.3.1 多过滤器叠加
```bash
# 同时使用多个过滤器(通过 --add-filter)
echo 'Visit \url{https://example.com} for teh docs' | \
aspell list --mode=tex --add-filter=url
# 输出: teh
5.3.2 过滤器模式语法
# 基本模式
--mode=<filter>
# 添加额外过滤器
--add-filter=<filter>
# 组合使用
--mode=tex --add-filter=email --add-filter=url
# 禁用过滤器
--mode=none
5.3.3 过滤器配置选项
每个过滤器都有配置选项,使用 --<filter>-<option> 格式:
# TeX 过滤器选项
--add-tex-command="label op" # 添加 TeX 命令定义
--dont-tex-check-params # 不检查命令参数
# HTML 过滤器选项
--add-html-skip="nav" # 跳过 <nav> 标签
--dont-html-skip="p" # 不跳过 <p> 标签
# Email 过滤器选项
--email-check="all" # 检查所有邮件部分
--dont-email-quote # 不检查引用文本
5.4 自定义过滤器
5.4.1 过滤器配置文件
过滤器配置文件位于 Aspell 数据目录下的 filter/ 子目录:
# 查看过滤器配置文件位置
aspell config filter-dir
# 通常为: /usr/lib/aspell-0.60/filter/
# 查看已安装的过滤器
ls /usr/lib/aspell-0.60/filter/
5.4.2 创建简单过滤器
创建一个过滤 YAML 前置元数据的过滤器:
# 创建过滤器配置文件
cat > /usr/local/lib/aspell-0.60/filter/yaml-frontmatter.filter << 'EOF'
# YAML Front Matter 过滤器
# 跳过文档开头的 YAML 前置元数据
NAME yaml-frontmatter
DESCRIPTION Skip YAML front matter in Markdown files
FILTERING
# 跳过 --- 到 --- 之间的内容
START_DELIM ^---$
END_DELIM ^---$
EOF
5.4.3 过滤器配置文件语法
# 过滤器定义
NAME <filter-name>
DESCRIPTION <描述>
FILTERING
# 以下为过滤规则
# 开始和结束分隔符
START_DELIM <正则表达式>
END_DELIM <正则表达式>
# 替换规则
REPLACE <正则表达式> <替换文本>
5.4.4 使用自定义过滤器
# 加载自定义过滤器
aspell check --add-filter=yaml-frontmatter README.md
# 管道模式
cat README.md | aspell list --add-filter=yaml-frontmatter
5.5 过滤器调试
5.5.1 查看过滤后的文本
# 使用 --list 模式查看过滤后的内容
echo '<p class="test">Hello teh world</p>' | aspell list --mode=html --list
# 使用管道模式查看过滤后的单词
echo '\textbf{Hello teh world}' | aspell -a --mode=tex
5.5.2 过滤器问题排查
# 问题:过滤器过度过滤(跳过了应该检查的内容)
# 解决:检查过滤器配置,使用 --dont-filter-<type> 禁用特定规则
# 问题:过滤器不足(仍然检查了不该检查的内容)
# 解决:添加更多过滤器或自定义过滤规则
# 调试:查看 Aspell 处理流程
echo '<script>var x = "test teh";</script>' | aspell -a --mode=html
# 脚本内容应该被跳过
5.6 业务场景
场景 1:Jekyll/Hugo 博客文章
#!/bin/bash
# check_blog_post.sh — 检查 Jekyll/Hugo 文章拼写
FILE="$1"
# 使用组合过滤器:跳过 YAML 前置元数据 + Markdown 格式
# (需要自定义 yaml-frontmatter 过滤器)
aspell list --mode=markdown --personal=./blog-dict.pws < "$FILE"
场景 2:技术文档(含代码块)
# 检查含代码块的 Markdown 文件
# 注意:Markdown 过滤器会自动跳过代码块
cat README.md | aspell list --mode=markdown --extra-dicts=./tech.pws
场景 3:LaTeX 学术论文
#!/bin/bash
# check_paper.sh — 检查 LaTeX 论文拼写
FILE="$1"
MODE="tex"
# 如果文件包含 BibTeX,额外添加 bib 过滤
if grep -q '\\bibliography{' "$FILE"; then
echo "检测到 BibTeX 引用"
fi
# 检查正文(跳过命令、数学公式)
aspell list --mode=$MODE --personal=./academic.pws < "$FILE"
# 单独检查注释(可选)
echo "--- 检查注释 ---"
aspell list --mode=${MODE} --mode=${MODE}-comments --personal=./academic.pws < "$FILE"
场景 4:HTML 静态页面
# 批量检查 HTML 文件
find ./public -name "*.html" -exec aspell list --mode=html {} \; | sort -u
场景 5:邮件列表管理
# 检查邮件模板
cat newsletter.eml | aspell list --mode=email --personal=./newsletter-dict.pws
5.7 过滤器参考表
| 过滤器 | 用途 | 模式名 | 关键选项 |
|---|---|---|---|
| HTML | HTML / XHTML 文档 | html | --add-html-skip, --dont-html-check-alt |
| TeX | TeX / LaTeX 文档 | tex | --add-tex-command, --dont-tex-check-params |
| 电子邮件 | email | --email-check, --dont-email-quote | |
| URL | URL / 路径 | url | 无特殊选项 |
| Nroff | Man pages / nroff | nroff | 无特殊选项 |
| Markdown | Markdown 文档 | markdown | 部分版本支持 |
| Texinfo | GNU Texinfo 文档 | texinfo | 无特殊选项 |
| none | 不使用过滤器 | none | - |
5.8 本章小结
| 要点 | 说明 |
|---|---|
| 过滤器作用 | 智能识别并跳过非文本内容,减少误报 |
| 常用模式 | --mode=html、--mode=tex、--mode=email |
| 多过滤器 | --add-filter=<filter> 叠加多个过滤器 |
| 自定义过滤器 | 通过过滤器配置文件定义分隔符和规则 |
| 调试 | 使用 --list 或管道模式查看过滤后的内容 |
下一步
→ 第 6 章:编程接口 — 学习通过 C API 和 Python 绑定编程调用 Aspell。