强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第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 实体(如 &amp;&
  • 只检查可见文本内容
# 基本使用
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 过滤器参考表

过滤器用途模式名关键选项
HTMLHTML / XHTML 文档html--add-html-skip, --dont-html-check-alt
TeXTeX / LaTeX 文档tex--add-tex-command, --dont-tex-check-params
Email电子邮件email--email-check, --dont-email-quote
URLURL / 路径url无特殊选项
NroffMan pages / nroffnroff无特殊选项
MarkdownMarkdown 文档markdown部分版本支持
TexinfoGNU Texinfo 文档texinfo无特殊选项
none不使用过滤器none-

5.8 本章小结

要点说明
过滤器作用智能识别并跳过非文本内容,减少误报
常用模式--mode=html--mode=tex--mode=email
多过滤器--add-filter=<filter> 叠加多个过滤器
自定义过滤器通过过滤器配置文件定义分隔符和规则
调试使用 --list 或管道模式查看过滤后的内容

下一步

第 6 章:编程接口 — 学习通过 C API 和 Python 绑定编程调用 Aspell。