新写的 Google 翻译插件

我这边挂代理也用不了。现在用论坛大佬新开发的 fanyi了,等以后支持长句了,就更舒服了。

题外话:长句翻译确实方便了,但是我发现用长句翻译多了,英语水平反而下降了,因为不大需要思考,拷贝过来读一遍中文,调整一下错误和语序就 OK :smile:

重写了整个插件。

支持单引擎、多引擎。目前添加的引擎有:

  • Google Translate,旧的 API (不挂代理也可访问)
  • Google Translate,新的 RPC API
  • DeepL

支持多种渲染方式。目前添加的渲染方式有:

  • 将结果拷贝到 Kill-Ring
  • 通过 buffer 显示结果
  • 通过 posframe 在当前位置弹出结果
  • 通过固定一个 posframe 窗口进行渲染 (推荐)

配置示例 (gts.el),有兴趣的可以尝试、探索,并给出意见:

;; 配置多个翻译语言对
(setq gts-translate-list '(("en" "zh") ("fr" "zh")))

;; 配置默认的 translator,配置完成之后,gts-do-translate 命令将用这些配置进行翻译
(setq gts-default-translator
      (gts-translator

       :picker
       ;; 选择其中一个 picker,用于拾取初始文本、from、to

       ;;(gts-noprompt-picker)
       ;;(gts-noprompt-picker :texter (gts-whole-buffer-texter))
       (gts-prompt-picker)
       ;;(gts-prompt-picker :single t)
       ;;(gts-prompt-picker :texter (gts-current-or-selection-texter) :single t)

       :engines
       ;; 设定若干翻译引擎,可以是一个,可以多个
       ;; 通过传入不同的 parser,配置其不同样式的输出

       (list
        (gts-google-engine)
        (gts-google-rpc-engine)
        ;;(gts-deepl-engine :auth-key "3e10bade-88e9-02f2-169f-ab3c445d7984:fx" :pro nil)

        ;;(gts-google-engine :parser (gts-google-summary-parser))
        ;;(gts-google-engine :parser (gts-google-parser))
        (gts-google-rpc-engine :parser (gts-google-rpc-summary-parser))
        ;;(gts-google-rpc-engine :parser (gts-google-rpc-summary-parser))
        )

       :render
       ;; 选定一个渲染器,从而将结果输出到不同目标
       ;; 推荐安装 posframe,并使用 gts-posframe-pop-render 或 gts-posframe-pin-render

       ;;(gts-buffer-render)

       ;;(gts-posframe-pop-render)
       ;;(gts-posframe-pop-render :backcolor "#333333" :forecolor "#ffffff")

       ;;(gts-posframe-pin-render)
       (gts-posframe-pin-render :position (cons 1200 20))
       ;;(gts-posframe-pin-render :width 80 :height 25 :position (cons 1000 20) :forecolor "#ffffff" :backcolor "#111111")

       ;;(gts-kill-ring-render)
       ))

上述配置之后,默认使用 gts-do-translate 命令执行翻译。

1 个赞

2 个赞

@lorniu 请问下原来的在新的buffer 显示翻译的功能还有吗?我这边提示一定要安装 posframe。

有。配置使用 (gts-buffer-render) 即可:

:render (gts-buffer-render)

不过,建议尝试一下 posframe 版本的输出方式。

以前我也喜欢 buffer,觉得 posframe 麻烦。现在写完这个之后,发现 childframe 真香。

多谢,尝试了一下 posframe,在 mac 上会出现屏幕抖动的现象 :sweat_smile:。这也是我尽量不用 posframe 的原因之一。

另外,token 是不是需要加入配置? 我这边一直不返回翻译结果。 目前使用的是这个:

  (setq go-translate-token-current
        (cons 430675 2721866133))

不需要配置其他的,只需要这两句就可以:

(setq gts-translate-list '(("en" "zh")))
(setq gts-default-translator
      (gts-translator
       :picker (gts-prompt-picker)
       :engines (list (gts-google-engine) (gts-google-rpc-engine))
       :render (gts-buffer-render)))

然后通过 gts-do-translate 开始翻译。

我这里测试,电信网络,不开代理,两个翻译引擎都能正常翻译。

刚从github上拉下来的。有问题啊

图片 commit/34ef5de1beeaecfd1d61210988ab5c43fc383129

奇怪,我 -q 打开 emacs,测试几次,没发现问题。

emacs 28, native.

你能不能打开 debug-on-error,然后手动 eval-buffer 下每个文件,定位下问题来源?

我的emacs 是 27.2的。是不是有影响

问题已解决。

这应该是 eieio 在 emacs27 上存在的一个 BUG,会导致 defclass 时改动外部变量。

已修复,请重新再试。

效率确实高。 :+1: 不过我问一下,以前的配置和功能是不兼容了吗? 我使用go-translate和go-translate-popup还是不行。 使用 gts-do-translate 是没有问题的

(use-package go-translate
  :ensure t
  :defer t
  :config
  (setq go-translate-base-url "https://translate.google.cn")
  (setq go-translate-local-language "zh-CN")
  (setq go-translate-token-current (cons 430675 2721866130)))

完全重写,以前的 API 用不着了。

懒得重写一遍英文文档,所以原先的代码保留。旧 API 能用的、想用的就按照以前的用。如果不想用旧的,就用新的。

以后也许有时间可能会将旧的清理掉。

试了一下新版,感觉接口请求的loading时间好长啊,不知道你们有没有这种情况?

我发现一个问题,如果 翻译的内容用 “” 引号,RPC API 就会出错。不用引号就没问题。

报错:

正常的: 图片

我还有一个问题,如果我想不同的配置,做不同的功能怎么办? 比如 通过 buffer 显示结果 是一个功能, 通过 posframe 在当前位置弹出结果 是另一个功能。 就跟旧的 go-translate和go-translate-popup 一样

你说的引号的问题已经在最新的代码中修复。

至于第二个问题,我更新了文档,你可以先看看定制命令那个章节。如果有问题再留言。

给力啊 :+1:

你们免费版本的deepl api 能用么,我用curl 测试没有返回任何内容,在go-translate中也不能用

("http error, make sure your auth_key is correct." . 403)

image

有考虑加上对多行翻译的支持么,当选中多行时,因为换行符的存在,会把一个句子当成多个句子来翻译。

如果只有一个换行符可以把他们当成同一段,多个换行符那就是多段了

你说的多行翻译,其实就是翻译之前,对文本进行预处理。

因为 go-translate 使用 eieio(clos) 实现,所以为翻译引擎增加预处理很简单。比如,想对 gts-google-engine 的文本进行预处理,在配置中添加如下代码即可:

(cl-defmethod gts-translate :before ((o gts-google-engine) task callback)
  (with-slots (text) task
    (setf text [基于text转换完成之后的字符串])))

就拿你说的例子,要实现的就是删除多余的空行。删除单行不删除多行,我尝试写了一下,不知道有没有更好的方案。

这里基于 go-translate 最新的代码,这段过滤规则对所有引擎都起效果:

(cl-defmethod gts-translate :before ((o gts-engine) task callback)
  (with-slots (text) task
    ;; 删除多余行的逻辑,有没有更简单的方法?
    (with-temp-buffer
      (insert text)
      (goto-char (point-min))
      (while (re-search-forward "\n" nil t)
        (if (equal (char-after) ?\n)
            (re-search-forward "[^\n]" nil t)
          (kill-backward-chars 1)
          (insert " ")))
      (setf text (buffer-string)))))
1 个赞