go-translate 更新到 v3

可以手动对调目标语言与源语言吗?或者强制在配置中指定。

我这边是遇到上下文同时存在中英文时,会自动识别翻译目标语言为英文,导致英文没能翻译,中文译为英文。

加一个这个在配置中就可以正常解析 pdf 了。

(cl-defmethod gt-text :around ((taker gt-taker) translator)
      "Extend the original gt-text method to handle pdf-view-mode."
      (if (eq major-mode 'pdf-view-mode)
          (gt-text-at-point nil 'pdf-view-mode)
        (cl-call-next-method)))

1 个赞

用pdf-tools查看PDF?

对 紫薯布丁

如果用的是 DeepL 的 Pro 的 api 的话,需要写成 (gt-deepl-engine :pro t) 需要加 :pro t,这个 README 当中没有写,只有源码中提了一句。

发现个小问题,这个下面出现 processing 的时候光标就无法正常跳转到翻译处。但是已经正常翻译了。

我觉得人名或者专业名词不翻译,也是一些人的需求,不知道是否有人已经做了 hack

go-translate 经常出现错误:Keyword argument :filter not one of (:headers :body :else :finally :noquery :as :then :body-type :decode :connect-timeout :timeout)

gt-log 如下:

2351.2 gt-start (gt-translator)
2351.2 gt-init (gt-translator)
2351.2 gt-reset (gt-translator)
2351.2 gt-take (gt-taker gt-translator)
2351.5 [translator] version: 1729132351.190346
                    target: (en zh)
                    bounds: (Hands On RTOS with Microcontrollers Building real time embedded systems using FreeRTOS, STM32 MCUs, and SEGGER debug tools.pdf)
                    text: (Contributors
                    About the author
                    Brian Amos is an embedded system engineer who has been programming with FreeRTOS
                    since 2012. He is currently a senior firmware engineer in the telecom industry creating
                    embedded systems used in ground stations for satellite communication. In the past, he led a
                    team of engineers creating a flexible architecture to rapidly develop high-precision
                    laboratory test equipment. Prior to this, he worked with early mesh networked energy
                    harvesting sensors used to help predict when industrial machinery needed maintenance.
                    )
                    taker: gt-taker, engines: (ChatGPT), render: gt-buffer-render
2351.5 [1] add task task-346: (gt-chatgpt-engine/gt-buffer-render)
2351.5 [translator] <1> all tasks added
2351.5 gt-init (gt-buffer-render gt-translator)
2351.5 [translator] <2> gt-buffer-render prepared
2351.5 gt-translate (gt-chatgpt-engine task-346)
2351.5 gt-init (gt-chatgpt-engine task-346)
2351.5 [next] task-346: gt-chatgpt-engine prepare to translate
2351.6 [gt-plz-http-client] > #s(gt-plz-http-client nil eieio--unbound)
                            > https://api.deepseek.com/v1/chat/completions
                            > HEADER: ((User-Agent . Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36) (Content-Type . application/json) (Authorization . Bearer sk-5953eec93a7d4c6f8cff9739000d1bae))
                            > DATA:   {"model":"deepseek-chat","temperature":0.8,"stream":null,"messages":[{"role":"system","content":"You are a translation assistant"},{"role":"user","content":"Translate the text to Chinese, text is: \nContributors\nAbout the author\nBrian Amos is an embedded system engineer who has been programming with FreeRTOS\nsince 2012. He is currently a senior firmware engineer in the telecom industry creating\nembedded systems used in ground stations for satellite communication. In the past, he led a\nteam of engineers creating a flexible architecture to rapidly develop high-precision\nlaboratory test equipment. Prior to this, he worked with early mesh networked energy\nharvesting sensors used to help predict when industrial machinery needed maintenance.\n"}]}
                            > EXTRA: (--silent --compressed --location)
2351.6 gt-fail (task-346)
2351.6 [translator] <3> all result parsed
2351.6 gt-output (gt-buffer-render gt-translator) 3
2351.6 [next] task-346: [----- error -----] (error Keyword argument :filter not one of (:headers :body :else :finally :noquery :as :then :body-type :decode :connect-timeout :timeout))

   backtrace()
   gt-fail(#<gt-task gt-task-1ffb7e956812> (error "Keyword argument :filter not one of (:headers :bod..."))
   gt-start(#<gt-translator gt-translator-1ffb83694494>)
   gt-do-translate(nil)
   funcall-interactively(gt-do-translate nil)
   call-interactively(gt-do-translate nil nil)
   command-execute(gt-do-translate)

我尝试过删除 go-translate 安装目录下的所有 elc,重启无效。

只能将 go-translate 删除,重新安装 go-translate,才能使用。但是在重装后下一次重启 emacs,就又出现该错误,非常痛苦。不知道是哪里的问题?

发现 Emacs 中的 plz 版本是 0.7.1 将其升级为 0.9.1 后支持 :filter 后解决问题。

最近用 mastodon.el 比较多,不想用 mastodon.el 自己实现的翻译插件,逻辑比较简单,于是自己写了 go-translate 的版本,可以同时翻译 profile 和 toots。

(defun find-text-bounds (get-text-fn)
      "Find the bounds of the text content returned by GET-TEXT-FN in the current buffer."
      (let ((text-content (funcall get-text-fn)))
        (when text-content
          (save-excursion
            (goto-char (point-min))
            ;; Search for the exact text content
            (when (search-forward text-content nil t)
              (let ((start (match-beginning 0))
                    (end (match-end 0)))
                (list (cons start end))))))))

    (defun find-toot-text-bounds ()
      "Find the bounds of the text content of the toot at point, excluding media."
      (find-text-bounds
       (lambda ()
         (let ((toot (mastodon-tl--property 'item-json)))
           (when toot
             (mastodon-tl--render-text (mastodon-tl--field 'content toot) toot))))))

    (defun find-profile-note-bounds ()
      "Find the bounds of the profile note of the user in the current buffer."
      (find-text-bounds
       (lambda ()
         (let ((profile-json (mastodon-profile--profile-json)))
           (when profile-json
             (mastodon-tl--render-text (alist-get 'note profile-json) profile-json))))))

    (defun mastodon-translate-text (bounds-fn)
      "Translate text using BOUNDS-FN to find the bounds in the current buffer."
      (let ((bounds (funcall bounds-fn)))
        (if bounds
            (gt-start (gt-translator :taker (list (gt-taker :pick (lambda (&rest _) bounds) :langs '(en zh))
                                                  (gt-taker :pick (lambda (&rest _) bounds) :langs '(ja zh))
                                                  (gt-taker :pick (lambda (&rest _) bounds) :langs '(fr zh))
                                                  (gt-taker :pick (lambda (&rest _) bounds) :langs '(de zh)))
                                     :engines (gt-chatgpt-engine)
                                     :render (gt-overlay-render :type 'after
                                                                :rfmt "\n--- Translation ---\n%s"
                                                                :sface nil
                                                                :rface '(:foreground "grey"))))
          (message "No text content to translate."))))

    (defun mastodon-detect-and-translate ()
      "Detect the content type under the cursor and translate it using `go-translate`."
      (interactive)
      (cond
       ;; Check if the current line is a toot
       ((get-text-property (point) 'item-json)
        (message "Toot detected at point.")
        (mastodon-translate-text #'find-toot-text-bounds))
       ;; Otherwise, assume we are dealing with a profile
       ((mastodon-tl--profile-buffer-p)
        (message "Profile detected.")
        (mastodon-translate-text #'find-profile-note-bounds))
       (t
        (user-error "Not in a recognizable Mastodon buffer"))))

他提供的示例函数是直接返回了 toot 的内容,这样利用 go-translate 翻译的话结果是在 echo 当中的,我想要 overlay 的效果(更加贴近 telega 的翻译效果)。所以写了上面的函数获取了 bounds 传入 gt-taker 当中。感谢作者提供了这么好用的包。

1 个赞

作者最新的 commit 修复了这个问题,不需要这个了。

已经支持 osx-dictionary.

(setq gt-osxdict-program "osx-dictionary")
...
:engines (gt-osxdict-engine)

这段代码貌似可以简化。大致:

(cl-defmethod gt-thing-at-point ((_ (eql 'xxx)) (_ (eql 'mastodon-mode)))
  (cond
   ;; Check if the current line is a toot
   ((get-text-property (point) 'item-json)
    (message "Toot detected at point.")
    (mastodon-translate-text #'find-toot-text-bounds))
   ;; Otherwise, assume we are dealing with a profile
   ((mastodon-tl--profile-buffer-p)
    (message "Profile detected.")
    (mastodon-translate-text #'find-profile-note-bounds))
   (t
    (user-error "Not in a recognizable Mastodon buffer"))))

(defun mastodon-detect-and-translate ()
  "Detect the content type under the cursor and translate it using `go-translate`."
  (interactive)
  (gt-start
   (gt-translator :taker (list (gt-taker :text 'xxx :langs '(zh en ja fr de)))
                  :engines (gt-chatgpt-engine)
                  :render (gt-overlay-render :type 'after
                                             :rfmt "\n--- Translation ---\n%s"
                                             :sface nil
                                             :rface '(:foreground "grey")))))

未测试,仅是思路。

谢谢!osx-dictionary 支持的是哪里下载的命令?

我试了下,是可以的,但是 :rfmt 会在每个段落前添加。

(defun mastodon-translate-text (bounds-fn)
  "Translate text using BOUNDS-FN to find the bounds in the current buffer."
  (funcall bounds-fn))

(cl-defmethod gt-thing-at-point ((_ (eql 'xxx)) (_ (eql 'mastodon-mode)))
  (let (bds)
    (cond
     ;; Check if the current line is a toot
     ((get-text-property (point) 'item-json)
      (message "Toot detected at point.")
      (mastodon-translate-text #'find-toot-text-bounds))
     ;; Otherwise, assume we are dealing with a profile
     ((mastodon-tl--profile-buffer-p)
      (message "Profile detected.")
      (mastodon-translate-text #'find-profile-note-bounds))
     (t
      (user-error "Not in a recognizable Mastodon buffer")))))

(defun mastodon-detect-and-translate ()
  "Detect the content type under the cursor and translate it using `go-translate`."
  (interactive)
  (gt-start
   (gt-translator :taker (list (gt-taker :text 'xxx :langs '(zh en ja fr de)))
                  :engines (gt-chatgpt-engine)
                  :render (gt-overlay-render :type 'after
                           :rfmt "\n--- Translation ---\n%s"
                           :sface nil
                           :rface '(:foreground "grey")))))

不过这样也不错,可以对照原文来看。

# Source:
https://github.com/itchyny/dictionary.vim/tree/master/autoload/dictionary.m

# Build: 
clang -framework CoreServices -framework Foundation dictionary.m -o osx-dictionary

谢谢!也就是和osx-dictionary 用的同一个binary

很好的插件

请问楼主可以为 gpt 引擎增加一个可选的请求参数 reasoning_format 吗?调用推理模型来翻译的时候,此参数控制是否在返回结果中包含 <think> 块。一旦包含这个块,就会造成 overlay 显示段落错位

目前观察到 groq 的接口有这个参数

如果认为此参数仅限于 groq 而不愿修改,那么请问有什么方便的覆盖的接口吗?除了重写 (cl-defmethod gt-translate ((engine gt-chatgpt-engine) task next)

开放一个变量,允许用户往 (json-encode 中新增请求字段,或许是一个不错的途径。


最新的 gptel 上已提供了一个变量 gptel-include-reasoning 来控制推理模型是否输出原因