langtool.el 用的是命令行版 (现在也支持 HTTP API 了) ,我们来试试用 HTTP API。
虽然我并没有用 LanguageTool,甚至连 FlySpell 也很少用,但我觉得应该用。langtool.el 的一个问题只支持纯文本,不支持 Markdown、Org Mode 等标记语言,就连注释、字符串貌似也不行。
按照 HTTP Server - LanguageTool Wiki 指令,下载、解压、运行:
java -cp languagetool-server.jar org.languagetool.server.HTTPServer --port 8081
测试
curl --data "language=en-US&text=a simple test" localhost:8081/v2/check | jq
像上面的 curl 命令一样,使用 text 参数
(let ((url-request-method "POST")
(url-request-extra-headers
'(("Content-Type" . "application/x-www-form-urlencoded")))
(url-request-data (encode-coding-string
(mapconcat
(lambda (pair)
(format "%s=%s"
(url-hexify-string (car pair))
(url-hexify-string (cdr pair))))
'(("language" . "en-US")
("text" . "a simple test"))
"&")
'utf-8)))
(pop-to-buffer (url-retrieve-synchronously "http://localhost:8081/v2/check")))
和 text 不同,data 的值为 JSON,而且支持 markup,比如
当然这个 markup 如何获得是个问题,需要编辑器支持或者有专门的 Parse 工具。
{
"annotation": [
{
"text": "A "
},
{
"markup": "<b>"
},
{
"text": "test"
},
{
"markup": "</b>"
}
]
}
先不管 markup
简单试下
(let ((url-request-method "POST")
(url-request-extra-headers
'(("Content-Type" . "application/x-www-form-urlencoded")))
(url-request-data
(encode-coding-string
(mapconcat
(lambda (pair)
(format "%s=%s"
(url-hexify-string (car pair))
(url-hexify-string (cdr pair))))
`(("language" . "en-US")
("data" . ,(json-encode
'(("annotation" . ((("text" . "I is 23 year old."))))))))
"&")
'utf-8)))
(pop-to-buffer (url-retrieve-synchronously "http://localhost:8081/v2/check")))
接下来是怎么处理 Markdown、注释、字符串了。
应该需要吧 Emacs is awesome. 解析成;
(json-encode
'(("annotation" . (((text . "Emacs is ") (markup . "*") (text . "awesome") (markup . "*") (text . "."))))))
把不需要检查的放到 markup 中。试试 Pandoc ?
echo -n "Emacs is *awesome*." | pandoc -f markdown -t json | jq
也不容易。
Parsec, tree-sitter?