branch: externals/greader commit 1d9fc00c5aef2066b22894a1bea7536787bbd7f7 Merge: c621404b46 d655f3636c Author: Michelangelo Rodriguez <michelangelo.rodrig...@gmail.com> Commit: Michelangelo Rodriguez <michelangelo.rodrig...@gmail.com>
Merge branch 'personal' into function-get-block --- greader-audiobook.el | 24 ++++++++---- greader-espeak.el | 13 +++++-- greader-translate.el | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++ greader.el | 45 ++++++++++----------- 4 files changed, 157 insertions(+), 33 deletions(-) diff --git a/greader-audiobook.el b/greader-audiobook.el index 6766b66b50..a7258353be 100644 --- a/greader-audiobook.el +++ b/greader-audiobook.el @@ -256,14 +256,16 @@ COUNTER represents the current file name." (filename nil) (counter-chars 0)) (while (< counter-chars (- (length - total-blocks-string)(length counter-string))) + total-blocks-string) + (length counter-string))) (setq filename (concat filename "0")) (setq counter-chars (+ counter-chars 1))) (setq filename (concat filename counter-string ".wav")))) (defun greader-audiobook-compress (book-directory) "Compress given BOOK-DIRECTORY." - (let ((zip-args (append (list "-rj")greader-audiobook-zip-args (list (concat + (let ((zip-args (append (list "-rj")greader-audiobook-zip-args (list + (concat (string-remove-suffix "/" book-directory) @@ -287,7 +289,8 @@ This function will create a directory under buffer without the extension, if any." (interactive "P") - (unless greader-audiobook-buffer-quietly(message "Preparing for conversion (this could take some time...)")) + (unless greader-audiobook-buffer-quietly + (message "Preparing for conversion (this could take some time...)")) (let ((end-position (point-max))) (cond ((not start-position) @@ -314,20 +317,24 @@ buffer without the extension, if any." (total-blocks (greader-audiobook--count-blocks))) (unless (file-exists-p default-directory) (make-directory default-directory)) - (unless greader-audiobook-buffer-quietly(message "Starting conversion of %s ." + (unless greader-audiobook-buffer-quietly + (message "Starting conversion of %s ." book-directory)) (while (greader-audiobook--get-block) (setq output-file-name (greader-audiobook--calculate-file-name output-file-counter total-blocks)) - (unless greader-audiobook-buffer-quietly(message "converting block %d of %d" - output-file-counter total-blocks)) + (unless greader-audiobook-buffer-quietly + (message "converting block %d of %d" + output-file-counter + total-blocks)) (setq output-file-name (greader-audiobook-convert-block output-file-name)) (if output-file-name (progn (when greader-audiobook-transcode-wave-files - (unless greader-audiobook-buffer-quietly(message "Transcoding block to %s..." + (unless greader-audiobook-buffer-quietly + (message "Transcoding block to %s..." greader-audiobook-transcode-format)) (greader-audiobook-transcode-file output-file-name) @@ -338,7 +345,8 @@ buffer without the extension, if any." (error "An error has occurred while converting"))) (when greader-audiobook-compress (setq default-directory greader-audiobook-base-directory) - (unless greader-audiobook-buffer-quietly(message "compressing %s..." book-directory)) + (unless greader-audiobook-buffer-quietly + (message "compressing %s..." book-directory)) (greader-audiobook-compress book-directory) (when greader-audiobook-compress-remove-original (delete-directory book-directory t t) diff --git a/greader-espeak.el b/greader-espeak.el index e8f461073a..138d2eaaef 100644 --- a/greader-espeak.el +++ b/greader-espeak.el @@ -1,5 +1,10 @@ -;; greader-espeak.el -*- lexical-binding: t; -*- +;;; greader-espeak.el --- greader back-end for espeak. -*- lexical-binding: t; -*- ;; Copyright (C) 2017-2024 Free Software Foundation, Inc. + +;;; commentary: + +;;; code: +(require 'ring) (defgroup greader-espeak nil "Back-end of espeak for greader." @@ -57,8 +62,9 @@ LANG must be recognized by espeak or espeak-ng." ;;;###autoload (defun greader-espeak (command &optional arg &rest _) - "Back-end main function of greader-espeak. -COMMAND must be a string suitable for `make-process'." + "Back-end main function for espeak. +COMMAND must be a string suitable for `make-process'. +ARG is applied depending on the command." (pcase command ('executable greader-espeak-executable-name) @@ -98,3 +104,4 @@ COMMAND must be a string suitable for `make-process'." (put 'greader-espeak 'greader-backend-name "greader-espeak") (provide 'greader-espeak) +;;; greader-espeak.el ends here diff --git a/greader-translate.el b/greader-translate.el new file mode 100644 index 0000000000..b05d31e10e --- /dev/null +++ b/greader-translate.el @@ -0,0 +1,108 @@ +;;; greader-translate.el --- translation mode for greader -*- lexical-binding: t; -*- +;; +;; Filename: greader-translate.el +;; Description: On the fly translation for greader. +;; Author: Michelangelo Rodriguez <michelangelo.rodrig...@gmail.com> +;; Created: Mar Giu 11 04:37:23 2024 (+0200) +;; URL: https://gitlab.com/michelangelo-rodriguez/greader +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; With greader-translate-mode it is possible to translate "on the +;; fly" the buffer you are reading. +;; In order to use it, the package `google-translate' must be installed. +;; Also, you have to set the variable `greader-translate-lang-src' +;; properly. +;; Properly means that it must be understood by `google-translate' +;; package. +;; If thinks are set correctly, in order to have the translation you +;; simply must to enable `greader-translate-mode', start your reading +;; with `greader-read', and enjoy. +;; The target language is taken from the function +;; `greader-set-language +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: +(declare-function google-translate-translate nil) +(declare-function greader-get-language nil) +(defgroup greader-translate nil + "On the fly translation mode for greader." + :group 'greader) +(defvar greader-translate-lang-src nil + "language to translate from. +If nil, it will use same language as `lingva-src'.") + +(defcustom greader-translate-timeout 30 + "Timeout for `greader-translate'. +After this timeout, `greader-translate' will generate an error." + :type 'integer) + +(defvar greader-translate-function 'greader-translate-with-google + "Function to use for text translation. +`greader-translate-with-google is provided. +The function should receive the text to translate, and return the +translated text on success, or the original text on failure.") + +(defun greader-translate-with-google (sentence) + "Translate text SENTENCE using `google-translate' library." + (require 'google-translate) + (require 'google-translate-core-ui) + (if (not (string-blank-p sentence)) + (progn + (unless greader-translate-lang-src + (error "Please configure `greader-translate-lang-src' +first")) + (with-timeout (greader-translate-timeout + (greader-translate-mode -1) + (setq sentence nil) + (error "Error while translating. Translation +mode disabled")) + (let ((inhibit-message t) + (ring-length (length kill-ring))) + (google-translate-translate greader-translate-lang-src + (greader-get-language) sentence + 'kill-ring) + (while (equal ring-length (length kill-ring)) + (sit-for 0.1))) + (setq sentence (pop kill-ring)))) + sentence)) + +(defun greader-translate (sentence) + "Translate the text in SENTENCE and return it translated or nil in +case of error." + (funcall greader-translate-function sentence)) + +;;;###autoload +(define-minor-mode greader-translate-mode + nil + :lighter "gr-transl" + (if greader-translate-mode + (progn + (add-hook 'greader-after-get-sentence-functions + #'greader-translate 0 t)) + (remove-hook 'greader-after-get-sentence-functions + #'greader-translate t))) + +(provide 'greader-translate) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; greader-translate.el ends here diff --git a/greader.el b/greader.el index eadf85f357..36b67522a9 100644 --- a/greader.el +++ b/greader.el @@ -6,7 +6,8 @@ ;; Author: Michelangelo Rodriguez <michelangelo.rodrig...@gmail.com> ;; Keywords: tools, accessibility ;; URL: https://www.gitlab.com/michelangelo-rodriguez/greader -;; Version: 0.10.2 +;; package-requires: ((google-translate)) +;; Version: 0.11.0 ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -129,7 +130,7 @@ If all the functions in the hook return nil, this function return nil." (defcustom greader-current-backend - #'greader-espeak + 'greader-espeak "Greader back-end to use." :tag "greader current back-end" :type @@ -266,7 +267,7 @@ if set to t, when you call function `greader-read', that function sets a (define-key map (kbd "<left>") #'greader-backward) (define-key map (kbd "<right>") #'greader-forward) map)) - +(defvar greader-queue-mode) ;;;###autoload (define-minor-mode greader-mode nil @@ -307,9 +308,9 @@ when the buffer is visiting a file." ;; to read and move the point "believe" that that is all the ;; buffer to read. (defvar greader-start-region nil - "start of region.") + "Start of region.") (defvar greader-end-region nil - "end of region.") + "End of region.") (defun greader--active-region-p () "Return t if the region in the current buffer is active. @@ -330,12 +331,12 @@ Active in this context means that the variables "Widen buffer and set greader-region variables to nil." (setq greader-start-region nil) (setq greader-end-region nil) - (greader-region-mode -1) + (greader-region-mode -1) (widen)) ;; This function places the point at the beginning of the active region. (defun greader-set-point-to-start-of-region () - "set the point to the beginning of the active region. + "Set the point to the beginning of the active region. This only happens if the variables `greader-start-region' and `greader-end-region' are set." (when (and greader-start-region greader-end-region) @@ -414,7 +415,7 @@ available backends." (user-error "Not a greader's back-end: %S" backend)))) (backend - (error "backend should be a string or a function: %S" + (error "Backend should be a string or a function: %S" backend)) (t (car (or @@ -570,7 +571,7 @@ mindfullness!)." (greader-mode 1) (greader-read)) (fset 'y-or-n-p (symbol-function 'greader-temp-function)))) - +(defvar greader-continuous-mode) (defun greader-read (&optional goto-marker) "Start reading of current buffer. if `GOTO-MARKER' is t and if you pass a prefix to this @@ -643,7 +644,7 @@ Argument ARG is not used." (insert arg))) (defvar greader-sentence-regexp "[.?!]+[[:space:]]" "Regexp to indicate the end of a sentence in terms of greader.") - +(defvar greader-classic-nav-mode) (defun greader-forward-sentence () "Move the point to next sentence." (let ((result (greader-call-backend 'next-text))) @@ -693,14 +694,12 @@ Optional argument STRING contains the string passed to (if greader-filter-enabled (message string))) (defvar greader-after-change-language-hook nil - "The functions stored in this variable are executed just after new -language is set.") + "The functions in this variable are executed just after new language is set.") + (defun greader-set-language (lang) "Set language of tts. LANG must be in ISO code, for example `en' for English or `fr' for -French. This function sets the language of tts locally for current -buffer, so if you want to set it globally, please use -`M-x customize-option RET greader-language RET'." +French." (interactive (list (let ((result (greader-call-backend 'set-voice nil))) @@ -715,7 +714,7 @@ buffer, so if you want to set it globally, please use (greader-call-backend 'punctuation flag)) (defun greader--get-local-language () - "Returns the language code from the system's locale." + "Return the language code from the system's locale." (let ((locale (or (getenv "LANG") ; First try with the LANG environment variable (getenv "LC_ALL") ; Then with LC_ALL "en"))) @@ -727,7 +726,7 @@ buffer, so if you want to set it globally, please use ; Default to "en" if the locale format is unrecognized (defun greader-get-language () - "return language set in current back-end. + "Return language set in current back-end. if `current-backend' does not implement `get-language' command, try to get the language from the environment." (let ((lang nil)) @@ -738,7 +737,7 @@ get the language from the environment." lang)) (defun greader-get-rate () - "return the numerical value for current back-end rate." + "Return the numerical value for current back-end rate." (let ((result (greader-call-backend 'get-rate))) (if (not (equal result 'not-implemented)) result @@ -962,7 +961,7 @@ In this mode, greader will enter in tired mode at a customizable time (string-to-number (format-time-string "%H"))) (defun greader-convert-time (time) - "Not documented, internal use." + "Return encoded TIME." (let ((current-t (decode-time)) (i (nth 2 (decode-time))) (counter (nth 2 (decode-time)))) @@ -982,7 +981,7 @@ In this mode, greader will enter in tired mode at a customizable time (apply #'encode-time current-t))) (defun greader-current-time-in-interval-p (time1 time2) - "Not documented, internal use." + "Return t if TIME2 is in TIME1." (let ((current-t (current-time))) (if @@ -1116,7 +1115,7 @@ administrator." "Compile espeak voice for a given LANG. when called interactively, compile the espeak-ng definitions for a given language. -By default, greader-compile infers the language from the first two +By default, `greader-compile' infers the language from the first two letters of the file you are visiting. If its LANG parameter is `non-nil', the function will ask for specifying the language to compile, ignoring the current file name @@ -1168,7 +1167,7 @@ function is specifically designed to be executed by a hook." :command command)))) (defun greader-compile--filter (&optional process str) - "Filter process for sudo." + "Filter PROCESS for sudo based on STR." (when (string-match "password" str) (process-send-string process (concat (read-passwd str) "\n"))) (when (string-match "error" str) @@ -1275,6 +1274,7 @@ When called from a function, you should specify SRC and DST, even if :type 'boolean) (defun greader--forward () + "Internal forward sentence." (when (and (equal (point) greader--marker-backward) greader-reading-mode) @@ -1284,6 +1284,7 @@ When called from a function, you should specify SRC and DST, even if (beep)))) (defun greader--set-forward-timer () + "Set the timer for `greader-backward'." (setq greader--timer-backward (run-with-idle-timer greader-backward-seconds nil #'greader--forward)))