Grammarly 语法错误标记——推测实现逻辑
Grammarly 插件在检测到错误后,Grammarly 插件会通过以下方式在网页上标记错误并显示下划线提示:
错误标记
动态插入元素:插件会在检测到错误的文本位置动态插入 HTML 元素(如
<span>
),并为这些元素添加特定的 CSS 类(如grammarly-error
)。CSS 样式:通过 CSS 样式为这些元素添加下划线(通常是红色波浪线)或其他视觉提示。
逻辑推测
在 Overleaf 或其他类似的在线编辑器中,虽然表面上没有明显的 <input>
或 <textarea>
输入框,但实际上编辑器是通过 自定义的富文本编辑器 或 代码编辑器 来实现文本输入的。这些编辑器通常基于 内容可编辑的 HTML 元素(如 contenteditable
)或 自定义的 DOM 结构,Grammarly 插件能够通过监听这些元素的输入事件来实现语法检查。
以下是 Grammarly 插件在 Overleaf 中实现监听和语法检查的原理:
1. 内容可编辑的 HTML 元素
Overleaf 的编辑器通常使用 contenteditable
属性来实现文本输入。contenteditable
是 HTML5 的一个特性,允许用户直接编辑 HTML 元素的内容。
示例
<div class="cm-content" contenteditable="true" spellcheck="false">
\documentclass{article}
\usepackage{graphicx}
\title{AI Helper}
\author{福来科技 金}
\date{July 2024}
\begin{document}
\maketitle
\section{Introduction}
\end{document}
</div>
运行 HTML
contenteditable="true"
:表示该元素的内容可以被用户编辑。spellcheck="false"
:禁用浏览器的默认拼写检查(因为 Grammarly 会接管)。
Grammarly 的监听机制
Grammarly 插件会通过以下方式监听 contenteditable
元素的输入事件:
DOM 监听:插件会监听
contenteditable
元素的input
事件,实时捕获用户输入的内容。文本分析:捕获的文本会被发送到 Grammarly 的服务器进行分析,返回语法错误和建议。
错误标记:插件会在
contenteditable
元素中动态插入 HTML 元素(如<span>
),并通过 CSS 样式添加下划线提示。
2. 自定义的代码编辑器
Overleaf 的编辑器是基于 CodeMirror 或 Monaco Editor 等代码编辑器实现的。这些编辑器通常会将用户输入的内容渲染为自定义的 DOM 结构,而不是传统的 <input>
或 <textarea>
。
示例
从代码片段中可以看到,Overleaf 使用了类似以下的 DOM 结构:
<div class="cm-content" role="textbox" aria-multiline="true" spellcheck="false" autocorrect="off" autocapitalize="off" translate="no" contenteditable="true">
<div class="cm-line">\documentclass{article}</div>
<div class="cm-line">\usepackage{graphicx}</div>
<div class="cm-line">\title{AI Helper}</div>
<div class="cm-line">\author{福来科技 金}</div>
<div class="cm-line">\date{July 2024}</div>
<div class="cm-line">\begin{document}</div>
<div class="cm-line">\maketitle</div>
<div class="cm-line">\section{Introduction}</div>
<div class="cm-line">\end{document}</div>
</div>
运行 HTML
每一行文本都被渲染为一个
<div class="cm-line">
元素。整个编辑器区域是一个
contenteditable
的容器。
Grammarly 的监听机制
Grammarly 插件会通过以下方式监听自定义编辑器的输入事件:
监听 DOM 变化:插件会监听
cm-content
容器的input
事件或MutationObserver
,实时捕获用户输入的内容。文本分析:捕获的文本会被发送到 Grammarly 的服务器进行分析,返回语法错误和建议。
错误标记:插件会在
cm-line
元素中动态插入 HTML 元素(如<span>
),并通过 CSS 样式添加下划线提示。
3. Grammarly 插件的实现细节
Grammarly 插件通过以下技术实现监听和错误标记:
DOM 监听
MutationObserver
:Grammarly 使用MutationObserver
监听contenteditable
元素或其子元素的变化(如文本插入、删除、修改等)。input
事件:插件会监听input
事件,实时捕获用户输入的内容。
错误标记
动态插入元素:插件会在检测到错误的文本位置动态插入 HTML 元素(如
<span>
),并为这些元素添加特定的 CSS 类(如grammarly-error
)。CSS 样式:通过 CSS 样式为这些元素添加下划线(通常是红色波浪线)或其他视觉提示。
示例代码
以下是一个简化的示例,展示 Grammarly 插件如何实现错误标记:
// 监听 contenteditable 元素的 input 事件
document.querySelector('.cm-content').addEventListener('input', function(event) {
const text = event.target.textContent;
// 发送文本到 Grammarly 服务器进行分析
grammarlyAnalyze(text).then(errors => {
// 动态插入错误标记
errors.forEach(error => {
const span = document.createElement('span');
span.className = 'grammarly-error';
span.textContent = error.text;
event.target.insertBefore(span, error.position);
});
});
});
4.请求处理
在每次编辑后并没有每次都发送请求?那么他是如何获取到我最新的输入的?
Grammarly 插件在浏览器中运行一个 轻量级的本地分析引擎,用于实时检测常见的语法错误、拼写错误和标点问题。这种设计是为了提供快速反馈并减少对服务器的依赖,从而提升用户体验。
以下是一些支持 Grammarly 使用本地分析引擎的证据:
(1)快速反馈
如果你使用 Grammarly 插件,你会发现它在你输入时几乎 立即 提供拼写和简单语法错误的反馈。这种低延迟的反馈表明,Grammarly 在本地进行了初步分析,而不是每次都依赖服务器。
(2)离线功能
Grammarly 插件在 离线状态 下仍然可以检测拼写错误和部分语法错误。这表明它确实在本地运行了一个分析引擎,而不是完全依赖网络请求。
(3)网络请求优化
通过浏览器的开发者工具(F12 -> Network 选项卡),你可以观察到 Grammarly 插件并不会在每次输入时都发送请求。相反,它会在特定条件下(如复杂语法分析或用户交互)才向服务器发送请求。
(4)官方文档
虽然 Grammarly 没有公开详细的实现细节,但其官方文档和开发者资源中提到,插件会在本地进行初步分析,以减少对服务器的依赖并提高性能。
5.本地分析引擎的实现推测
5.1 自定义实现
(1)拼写检查器
拼写检查器是本地分析引擎的核心组件之一。它通常基于以下技术实现:
本地词典:使用预编译的词典文件(如 Hunspell)来检测拼写错误。
词形变化:支持不同语言的词形变化(如复数、时态等)。
自定义词典:允许用户添加自定义词汇。
(2)简单语法规则
简单语法规则通常以预定义的规则集形式嵌入到插件中。这些规则可以检测常见的语法错误,例如:
主谓一致
时态错误
冠词使用错误
(3)标点符号检查
标点符号检查通常基于简单的规则和上下文分析。例如:
检测缺少句号。
检测逗号使用是否正确。
5.2 本地 AI 模型的可能性
现代浏览器和 JavaScript 引擎的性能已经足够强大,可以运行轻量级的 AI 模型。Grammarly 的本地分析引擎很可能使用了以下技术:
(1)轻量级 AI 模型
模型压缩:通过模型压缩技术(如量化、剪枝、蒸馏等),将 AI 模型压缩到适合在浏览器中运行的规模。
预训练模型:使用预训练的轻量级模型(如 BERT 的小型版本)进行语法和拼写检查。
本地推理:在浏览器中使用 JavaScript 或 WebAssembly 运行这些模型。
(2)WebAssembly 支持
高性能计算:WebAssembly(Wasm)是一种可以在浏览器中运行的高性能二进制格式,适合运行计算密集型的 AI 模型。
TensorFlow.js:Google 的 TensorFlow.js 是一个 JavaScript 库,支持在浏览器中运行 AI 模型。
5.3 本地 AI 模型的实现
以下是一个简化的示例,展示如何在浏览器中运行轻量级的 AI 模型:
(1)使用 TensorFlow.js
TensorFlow.js 是一个流行的 JavaScript 库,支持在浏览器中运行 AI 模型。Grammarly 可能使用了类似的技术。
示例代码
// 加载 TensorFlow.js
import * as tf from '@tensorflow/tfjs';
// 加载预训练的轻量级模型
const model = await tf.loadLayersModel('https://example.com/grammar-model.json');
// 输入文本
const text = "This is a example sentence.";
// 将文本转换为模型输入
const input = preprocessText(text);
// 运行模型
const output = model.predict(input);
// 解析模型输出
const errors = parseOutput(output);
console.log(errors); // 输出: [{ error: '语法错误', suggestion: 'an', position: 10 }]
(2)使用 WebAssembly
WebAssembly 可以提供更高的性能,适合运行计算密集型的 AI 模型。
示例代码
// 加载 WebAssembly 模块
const wasmModule = await WebAssembly.compileStreaming(fetch('grammar-checker.wasm'));
// 实例化 WebAssembly 模块
const instance = await WebAssembly.instantiate(wasmModule);
// 输入文本
const text = "This is a example sentence.";
// 将文本传递给 WebAssembly 模块
const errors = instance.exports.checkGrammar(text);
console.log(errors); // 输出: [{ error: '语法错误', suggestion: 'an', position: 10 }]
6. 总结
在 Overleaf 或其他类似的在线编辑器中,虽然没有传统的 <input>
或 <textarea>
输入框,但编辑器通过 contenteditable
或自定义的 DOM 结构实现了文本输入。Grammarly 插件通过监听这些元素的输入事件,并结合 AI 和 NLP 技术,实现了语法错误的实时检测和下划线提示。
- 感谢你赐予我前进的力量