@@ -420,10 +420,10 @@ If LAMBDA is non-nil, call it after creating the download process."
420
420
:type 'string )
421
421
422
422
423
- (defvar paw-say-word-english-functions '(paw-say-word-cambridge paw-youdao-say-word))
423
+ (defvar paw-say-word-english-functions '(paw-say-word-cambridge paw-say-word-oxford paw- youdao-say-word))
424
424
(defvar paw-say-word-japanese-functions '(paw-say-word-jpod101-alternate))
425
425
426
- (defcustom paw-say-word-functions '(paw-say-word-cambridge paw-say-word-jpod101-alternate paw-edge-tts-say-word paw-youdao-say-word paw-say-word-forvo)
426
+ (defcustom paw-say-word-functions '(paw-say-word-cambridge paw-say-word-oxford paw-say-word- jpod101-alternate paw-edge-tts-say-word paw-youdao-say-word paw-say-word-forvo)
427
427
" The functions to download and play sound file one by one, used in `paw-say-word' if arg is nil. If any one success, it will break."
428
428
:type 'list
429
429
:group 'paw )
@@ -474,71 +474,39 @@ will prompt you every first time when download the audio file. "
474
474
(source (plist-get args :source ))
475
475
(word-hash (md5 word))
476
476
(mp3-file (concat (expand-file-name word-hash paw-tts-cache-dir) " .mp3" ))
477
- (mp3-file-edge-tts (concat (expand-file-name (concat word-hash " +edge-tts" ) paw-tts-cache-dir) " .mp3" ))
478
- (mp3-file-youdao (concat (expand-file-name (concat word-hash " +youdao" ) paw-tts-cache-dir) " .mp3" ))
479
- (mp3-file-jisho (concat (expand-file-name (concat word-hash " +jisho" ) paw-tts-cache-dir) " .mp3" ))
480
- (mp3-file-jpod101 (concat (expand-file-name (concat word-hash " +jpod101" ) paw-tts-cache-dir) " .mp3" ))
481
- (mp3-file-jpod101-alternate (concat (expand-file-name (concat word-hash " +jpod101-alternate" ) paw-tts-cache-dir) " .mp3" ))
482
- (subtitle-file (concat (expand-file-name word-hash paw-tts-cache-dir) " .vtt" ))
483
- (audio-url))
477
+ (audio-url)
478
+ (lambda (lambda (file)
479
+ (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
480
+ (copy-file file mp3-file t )))))
484
481
(make-directory paw-tts-cache-dir t ) ; ; ensure cache directory exists
485
482
(if refresh
486
483
(message " Re-Downloading the audio file... " ))
487
- (when (or (and refresh (file-exists-p mp3-file))
488
- (and (file-exists-p mp3-file) (= (file-attribute-size (file-attributes mp3-file)) 0 ) ))
489
- (delete-file mp3-file))
490
- (when (or (and refresh (file-exists-p subtitle-file))
491
- (and (file-exists-p subtitle-file) (= (file-attribute-size (file-attributes subtitle-file)) 0 ) ))
492
- (delete-file subtitle-file))
493
- (when (or (and refresh (file-exists-p mp3-file-edge-tts))
494
- (and (file-exists-p mp3-file-edge-tts) (= (file-attribute-size (file-attributes mp3-file-edge-tts)) 0 ) ))
495
- (delete-file mp3-file-edge-tts))
496
- (when (or (and refresh (file-exists-p mp3-file-jisho))
497
- (and (file-exists-p mp3-file-jisho) (= (file-attribute-size (file-attributes mp3-file-jisho)) 0 ) ))
498
- (delete-file mp3-file-jisho))
499
- (when (or (and refresh (file-exists-p mp3-file-youdao))
500
- (and (file-exists-p mp3-file-youdao) (= (file-attribute-size (file-attributes mp3-file-youdao)) 0 ) ))
501
- (delete-file mp3-file-youdao))
502
- (when (or (and refresh (file-exists-p mp3-file-jpod101))
503
- (and (file-exists-p mp3-file-jpod101) (= (file-attribute-size (file-attributes mp3-file-jpod101)) 0 ) ))
504
- (delete-file mp3-file-jpod101))
505
- (when (or (and refresh (file-exists-p mp3-file-jpod101-alternate))
506
- (and (file-exists-p mp3-file-jpod101-alternate) (= (file-attribute-size (file-attributes mp3-file-jpod101-alternate)) 0 ) ))
507
- (delete-file mp3-file-jpod101-alternate))
508
- (let ((source (if source (completing-read (format " Select Audio Playback Source (%s ): " word) '(" edge-tts" " forvo" " youdao" " cambridge" " jisho" " jpod101" " jpod101-alternate" ) nil t ) " default" )))
484
+ (paw-say-word-delete-mp3-file (concat word-hash " +edge-tts" ) refresh)
485
+ (paw-say-word-delete-mp3-file (concat word-hash " +youdao" ) refresh)
486
+ (paw-say-word-delete-mp3-file (concat word-hash " +jisho" ) refresh)
487
+ (paw-say-word-delete-mp3-file (concat word-hash " +jpod101" ) refresh)
488
+ (paw-say-word-delete-mp3-file (concat word-hash " +jpod101-alternate" ) refresh)
489
+ (paw-say-word-delete-mp3-file (concat word-hash " +frovo" ) refresh)
490
+ (paw-say-word-delete-mp3-file (concat word-hash " +cambridge" ) refresh)
491
+ (paw-say-word-delete-mp3-file (concat word-hash " +oxford" ) refresh)
492
+ (let ((source (if source (completing-read (format " Select Audio Playback Source (%s ): " word) '(" edge-tts" " forvo" " youdao" " cambridge" " oxford" " jisho" " jpod101" " jpod101-alternate" ) nil t ) " default" )))
509
493
(pcase source
510
494
(" default"
511
495
(if (file-exists-p mp3-file)
512
496
(setq audio-url mp3-file)
513
497
(setq audio-url mp3-file)
514
- (paw-say-word-function paw-say-word-functions word
515
- (lambda (file )
516
- (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
517
- (copy-file file mp3-file t ))))))
518
-
498
+ (paw-say-word-function paw-say-word-functions word lambda)))
519
499
(" edge-tts"
520
500
(paw-edge-tts-say-word word
521
501
:lang (completing-read (format " Select TTS Sound Engine (%s ): " word) '(" en" " ja" " zh" " zh-Hant" " ko" " Multilingual" ) nil t )
522
- :lambda (lambda (file )
523
- (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
524
- (copy-file file mp3-file t )))))
502
+ :lambda lambda))
525
503
(" forvo"
526
504
(paw-say-word-forvo word
527
505
:lang (completing-read (format " Select TTS Sound Engine (%s ): " word) '(" en" " ja" " zh" " ko" ) nil t )
528
- :lambda (lambda (file )
529
- (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
530
- (copy-file file mp3-file t )))))
531
-
532
- (" youdao"
533
- (paw-youdao-say-word word :lambda (lambda (file )
534
- (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
535
- (copy-file file mp3-file t )))))
536
-
537
- (" cambridge"
538
- (paw-say-word-cambridge word :lambda (lambda (file )
539
- (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
540
- (copy-file file mp3-file t )))))
541
-
506
+ :lambda lambda))
507
+ (" youdao" (paw-youdao-say-word word :lambda lambda))
508
+ (" cambridge" (paw-say-word-cambridge word :lambda lambda))
509
+ (" oxford" (paw-say-word-oxford word :lambda lambda))
542
510
(" jisho"
543
511
(paw-say-word-jisho word
544
512
; ; have to provide a reading
@@ -549,10 +517,7 @@ will prompt you every first time when download the audio file. "
549
517
(if (string= input paw-play-source-button)
550
518
word
551
519
input)))
552
- :lambda (lambda (file )
553
- (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
554
- (copy-file file mp3-file t )))))
555
-
520
+ :lambda lambda))
556
521
(" jpod101"
557
522
(paw-say-word-jpod101 word
558
523
; ; have to provide a reading
@@ -563,20 +528,18 @@ will prompt you every first time when download the audio file. "
563
528
(if (string= input paw-play-source-button)
564
529
word
565
530
input)))
566
- :lambda (lambda (file )
567
- (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
568
- (copy-file file mp3-file t )))))
569
-
570
- (" jpod101-alternate"
571
- (paw-say-word-jpod101-alternate word
572
- :lambda (lambda (file )
573
- (if (and (file-exists-p file) (> (file-attribute-size (file-attributes file)) 0 ) )
574
- (copy-file file mp3-file t )))))))
575
-
531
+ :lambda lambda))
532
+ (" jpod101-alternate" (paw-say-word-jpod101-alternate word :lambda lambda))))
576
533
(if (and audio-url (file-exists-p audio-url) )
577
534
(setq paw-say-word-running-process (start-process " *paw say word*" nil " mpv" audio-url)))
578
535
(if (and audio-url (file-exists-p audio-url) ) audio-url )))
579
536
537
+ (defun paw-say-word-delete-mp3-file (hash refresh )
538
+ (let* ((mp3-file (concat (expand-file-name hash paw-tts-cache-dir) " .mp3" )))
539
+ (when (or (and refresh (file-exists-p mp3-file))
540
+ (and (file-exists-p mp3-file) (= (file-attribute-size (file-attributes mp3-file)) 0 ) ))
541
+ (delete-file mp3-file))))
542
+
580
543
(defun paw-play-mp3-process-sentiel (process event mp3-file )
581
544
; ; When process "finished", then begin playback
582
545
(when (string= event " finished\n " )
@@ -1148,7 +1111,11 @@ if `paw-detect-language-p' is t, or return as `paw-non-ascii-language' if
1148
1111
(funcall select-func items)) )
1149
1112
(if lambda (funcall lambda nil ) ))
1150
1113
1151
- )))) )))
1114
+ )))
1115
+ :error
1116
+ (cl-function (lambda (&rest args &key error-thrown &allow-other-keys )
1117
+ (if lambda (funcall lambda nil ) )
1118
+ (message " Failed to find audio URL, %s " error-thrown)))) )))
1152
1119
1153
1120
; ; (paw-say-word-jpod101-alternate "日本" "") ;; all sounds
1154
1121
; ; (paw-say-word-jpod101-alternate "日本" "日本") ;; all sounds
@@ -1242,7 +1209,106 @@ if `paw-detect-language-p' is t, or return as `paw-non-ascii-language' if
1242
1209
(" us" (funcall select-func (list us-voice-url)))
1243
1210
(" uk" (funcall select-func (list uk-voice-url)))
1244
1211
(_ (funcall select-func items))) )
1245
- (if lambda (funcall lambda nil ) )))))) )))
1212
+ (if lambda (funcall lambda nil ) )))))
1213
+ :error
1214
+ (cl-function (lambda (&rest args &key error-thrown &allow-other-keys )
1215
+ (if lambda (funcall lambda nil ) )
1216
+ (message " Failed to find audio URL, %s " error-thrown)))) )))
1217
+
1218
+
1219
+ (defvar pay-say-word-oxford-audio-list nil )
1220
+
1221
+
1222
+ (defcustom paw-say-word-oxford-voice " us"
1223
+ " The voice of the oxford dictionary, either us or uk."
1224
+ :group 'paw
1225
+ :type 'string )
1226
+
1227
+ (defun paw-say-word-oxford (term &rest args )
1228
+ (let* ((reading (or (plist-get args :reading ) " " ))
1229
+ (lambda (plist-get args :lambda ))
1230
+ (download-only (plist-get args :download-only ))
1231
+ (select-func (lambda (items )
1232
+ (if-let* ((choice (if (> (length items) 1 )
1233
+ (completing-read " Select sound: " items)
1234
+ (caar items)))
1235
+ (audio-url (car (assoc-default choice items) )))
1236
+ (paw-download-and-say-word
1237
+ :source-name " oxford"
1238
+ :word term
1239
+ :audio-url audio-url
1240
+ :lambda lambda
1241
+ :download-only download-only)
1242
+ (message " No valid audio url " )))))
1243
+ (if (and (stringp (caar pay-say-word-oxford-audio-list ))
1244
+ (string-match-p term (caar pay-say-word-oxford-audio-list )) )
1245
+
1246
+ (pcase paw-say-word-oxford-voice
1247
+ (" us" (funcall select-func (list (cl-find-if (lambda (item )
1248
+ (string-match-p " \\ [us\\ ]" (car item)))
1249
+ pay-say-word-oxford-audio-list))))
1250
+ (" uk" (funcall select-func (list (cl-find-if (lambda (item )
1251
+ (string-match-p " \\ [uk\\ ]" (car item)))
1252
+ pay-say-word-oxford-audio-list))))
1253
+ (_ (funcall select-func pay-say-word-oxford-audio-list)))
1254
+
1255
+ (request (format " https://www.oxfordlearnersdictionaries.com/definition/english/%s " (downcase term ))
1256
+ :parser 'buffer-string
1257
+ :headers '((" User-Agent" . " Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36" )
1258
+ (" Content-Type" . " application/x-www-form-urlencoded" ))
1259
+ :success (cl-function
1260
+ (lambda (&key data &allow-other-keys )
1261
+ ; ; Parse HTML
1262
+
1263
+ ; ; (with-temp-file "~/test.html"
1264
+ ; ; (insert data))
1265
+ (let* ((parsed-html (with-temp-buffer
1266
+ (insert data)
1267
+ (libxml-parse-html-region (point-min ) (point-max ))))
1268
+ ; ; Get all 'dc-result-row' elements
1269
+ (uk-voice (dom-by-class parsed-html " phons_br" ))
1270
+ (us-voice (dom-by-class parsed-html " phons_n_am" ))
1271
+ (items)
1272
+ (us-voice-url)
1273
+ (uk-voice-url))
1274
+
1275
+ ; ; (with-temp-file "~/test.html"
1276
+ ; ; (insert data))
1277
+ (when-let* ((audio-elem (dom-by-class us-voice " pron-us" ))
1278
+ (audio-url (dom-attr audio-elem 'data-src-mp3 )))
1279
+ (setq us-voice-url (list (format " %s [us]" (propertize term 'face 'paw-file-face )) audio-url))
1280
+ (push us-voice-url items))
1281
+
1282
+ ; ; (pp us-voice-url)
1283
+
1284
+ (when-let* ((audio-elem (dom-by-class uk-voice " pron-uk" ))
1285
+ (audio-url (dom-attr audio-elem 'data-src-mp3 )))
1286
+ (setq uk-voice-url (list (format " %s [uk]" (propertize term 'face 'paw-file-face )) audio-url))
1287
+ (push uk-voice-url items))
1288
+
1289
+ ; ; (pp uk-voice-url)
1290
+ (if items
1291
+ (progn
1292
+ (setq pay-say-word-oxford-audio-list items)
1293
+ (pcase paw-say-word-oxford-voice
1294
+ (" us" (funcall select-func (list us-voice-url)))
1295
+ (" uk" (funcall select-func (list uk-voice-url)))
1296
+ (_ (funcall select-func items))) )
1297
+ (if lambda (funcall lambda nil ) ))
1298
+ )
1299
+
1300
+
1301
+ ))
1302
+
1303
+ :error
1304
+ (cl-function (lambda (&rest args &key error-thrown &allow-other-keys )
1305
+ (if lambda (funcall lambda nil ) )
1306
+ (message " Failed to find audio URL, %s " error-thrown)))
1307
+ ) )))
1308
+
1309
+
1310
+ ; ; (paw-say-word-oxford "hello")
1311
+ ; ; (paw-say-word-oxford "world")
1246
1312
1247
1313
1248
1314
@@ -1296,10 +1362,17 @@ if `paw-detect-language-p' is t, or return as `paw-non-ascii-language' if
1296
1362
(info (string-trim (dom-texts (dom-by-class res " ofLink" )) )))
1297
1363
; ; (message "%s %s %s" term username audio-url)
1298
1364
(push (list (format " %s Pronunciation by %s %s " (propertize term 'face 'paw-file-face ) info username) audio-url) list-play)))
1299
- (when list-play
1300
- (setq list-play (nreverse list-play))
1301
- (setq paw-say-word-forvo-audio-list list-play)
1302
- (funcall select-func list-play)))))))))
1365
+ (if list-play
1366
+ (progn
1367
+ (setq list-play (nreverse list-play))
1368
+ (setq paw-say-word-forvo-audio-list list-play)
1369
+ (funcall select-func list-play) )
1370
+ (if lambda (funcall lambda nil ) )))))
1371
+ :error
1372
+ (cl-function (lambda (&rest args &key error-thrown &allow-other-keys )
1373
+ (if lambda (funcall lambda nil ) )
1374
+ (message " Failed to find audio URL, %s " error-thrown)))
1375
+ ))))
1303
1376
1304
1377
; ; (paw-say-word-forvo "hello")
1305
1378
0 commit comments