如何用1000行代码实现 Grammarly 核心功能

348 阅读5分钟

背景:

大家好啊!第一次来掘金发文章,我是写码的威廉姆,我独立开发了一个在线简历制作与润色的网站 ElegantResume 。特点是:

  1. 能免费的功能都免费,同时无需注册登录即可使用;
  2. 数据本地保存,不会保存在服务器上,避免数据泄漏和贩卖问题;
  3. 易于上手,编辑体验类似于使用Word,零学习成本;
  4. 集成了ChatGPT,无需复制粘贴简历,直接使用ChatGPT自动修改简历,生成面试题。

最近闲来无事,又捣鼓了一个 Grammarly 的复刻并用在简历修改中啦(如下图),感兴趣的小伙伴欢迎体验哦,以下记录了整个开发的思路,希望大家喜欢。

image.png

正文

现如今,类似Grammarly这样的语法检查工具已经成了许多人的标配,点几下就能检查语法,简直方便到飞起。但是,尽管它们用起来挺爽,也有一些问题:

  1. 首先,遇到专业术语时就头疼,有时候甚至根本辨识不出来。哪怕是拼写错了,都有时候检测不到。
  2. 其次,大部分工具都是针对英语优化的,这就导致使用其他语言的用户,比如说中文,好多错误都检测不到。
  3. 还有呢,价格是真的贵。

但是,自从ChatGPT的出现,如今的 Grammarly 可以说只剩半条命了。ChatGPT用它那强大的语言处理能力解决了Grammarly很多解决不了的问题。但是,也有个小坑:ChatGPT用起来不像用Grammarly那么简单,而且用户界面也不如Grammarly那么直观。你要是让ChatGPT改一篇文章里的错误,它能给你一份毛病全无的版本,但是很难看出ChatGPT具体改了哪些地方。

为了解决这个问题,我就在想干嘛不把ChatGPT的能力和Grammarly的易用的界面结合起来呢?想象一下,一个工具,ChatGPT改好了文章,然后把所有的改动标出来,你想改就点个按钮,不想改就一键忽略。这样的工具不香吗?又便宜,又好用,跨语言的错误检测也没问题,改的也更靠谱。

好了,咱们有点儿想法了,可咱得从哪儿着手呢?ChatGPT这边已经准备好了,就差一个跟Grammarly核心功能类似的前端系统了。咱们来具体计划一下,看看这个工具需要实现些什么功能:

  1. 兼容各种输入框:这个工具得顺畅地嵌入到HTML编辑区域和其他输入框里,用户就能轻松输入文字。
  2. 对比和标记:ChatGPT处理完了文本后,工具得把原文和修改过的文字对比一下,标记出来给用户看。
  3. 用户互动:用户得能轻松地接受或者忽略ChatGPT的改动。

好,第一个目标,先从兼容HTML编辑区域开始吧。这一步简单点儿,用textContent 就能搞定,先搭个基础。接下来,咱们得有个方法来比较文本。这不是很容易,所以我跑去GitHub看看有没有现成的开源解决方案,结果还真找到了一个牛逼的库叫Diff-Match-Patch,甚至还有个npm包!这个库提供了强大的文字比较算法,比如说diff、match和patch,对于同步纯文本很有用。多亏了这个库,咱们能得到原文和修改后文本之间的不同之处。

好嘞,现在,咱们要有个办法来可视化这些不同之处。最大的挑战在于渲染Grammarly那种独特的下划线。这个任务不仅难以实现,而且还是我们的核心功能。可惜的是,没有现成的API来用浏览器自带的下划线,就是那种拼写检查器用的红色波浪线。所以,我们得自己动手来解决。

对于这个功能,咱们的主要要求是不改动内容编辑区域的DOM树。也就是说,下划线元素得单独显示,不能改动原来的文字。那咋办呢?咱们可以利用HTML Canvas来搞定。但是这种方法有个难点:得准确知道每个下划线放哪儿。不过还好有个叫 Range.getClientRects()  的API, 可以完美解决这个问题。这个API能给你一堆矩形,这些矩形包含了屏幕上指定文本的所有位置以及大小的信息。有了这些信息,咱们就能准确地确定需要显示下划线的文本的位置了。

最后一个任务,咱们得搞个弹框,让用户能接受或者忽略ChatGPT的改动。这个就容易多了,因为咱们已经有了文本改动,也知道弹出窗口应该放哪。咱们可以利用这些信息,给用户弄个简单直观的界面,方便用户们接受或者忽略改动。

好了,到此为止就做好啦,现在是时候测试一下这个工具了!我把它集成到了我的另一个项目 ElegantResume 里,那是个简历制作并可以用 Chat GPT 润色简历的网站,因为我想看看刚刚实现的小工具,相比较于Grammarly,效果如何。于是我让这俩工具检测简历技能部分的语法和拼写错误。

结果让我挺惊讶:Grammarly只发现了一个错误,而我的小工具发现了全部的6个错误。如下图,Grammarly只发现了"MvC"应该改成"MVC",其他的错误都没标注出来。

而我们的工具,却标记了一堆错误:"Anguar"应该是"Angular","MvC"应该是"MVC","Javascript"应该是"JavaScript","Net Core"应该是".NET Core","LINQQ"应该是"LINQ",最后,“TD”应该是“TDD”

image.png 总之,把ChatGPT的语言超能力和类似Grammarly的前端结合起来,我们就能搞出一个强大又好用的工具。这个小工具总共只有 1000 行代码,是用 React 实现的。目前来说这个工具还有一些不足和bug,我会在接下来的时间里逐步的修复这些bug。

希望大家喜欢!