blob: 5871b180b5c0588acc17f72e85c0ed3fa2614de5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
(require 'cl-macs)
(require 'ht)
(require 'seq)
(require 's)
;; Type definitions for Russian structures
(cl-defstruct russian-word
"Definition and metadata of a single Russian word."
(word nil :type string)
(translations :type list
:documentation "List of lists of strings, each a set of translations.")
(notes nil :type list ;; of string
:documentation "free-form notes about this word")
(roots nil :type list ;; of string
:documentation "list of strings that correspond with roots (exact string match)"))
(defun russian--merge-words (previous new)
"Merge two Russian word definitions together. If no previous
definition exists, only the new one will be returned."
(if (not previous) new
(assert (equal (russian-word-word previous)
(russian-word-word new))
"different words passed into merge function")
(make-russian-word :word (russian-word-word previous)
:translations (-concat (russian-word-translations previous)
(russian-word-translations new))
:notes (-concat (russian-word-notes previous)
(russian-word-notes new))
:roots (-concat (russian-word-roots previous)
(russian-word-roots new)))))
;; Definitions for creating a data structure of all Russian words.
(defvar russian-words (make-hash-table)
"Table of all Russian words in the corpus.")
(defun russian--define-word (word)
"Define a single word in the corpus, optionally merging it with
another entry."
(let ((key (russian-word-word word)))
(ht-set russian-words key (russian--merge-words
(ht-get russian-words key)
word))))
(defmacro define-russian-words (&rest words)
"Define the list of all available words. There may be more than
one entry for a word in some cases."
(declare (indent defun))
;; Clear the table before proceeding with insertion
(setq russian-words (make-hash-table))
(seq-map
(lambda (word)
(russian--define-word (make-russian-word :word (car word)
:translations (cadr word)
:notes (caddr word)
:roots (cadddr word))))
words)
'(message "Defined %s unique words." (ht-size russian-words)))
;; Helpers to train Russian words when Emacs is idling.
(defun russian--format-word (word)
"Format a Russian word suitable for echo display."
(apply #'s-concat
(-flatten
(list (russian-word-word word)
" - "
(s-join ", " (russian-word-translations word))
(when-let ((roots (russian-word-roots word)))
(list " [" (s-join ", " roots) "]"))
(when-let ((notes (russian-word-notes word)))
(list " (" (s-join "; " notes) ")"))))))
(defvar russian--last-word nil
"Last randomly displayed Russian word")
(defun display-random-russian-word ()
(interactive)
(let* ((word (seq-random-elt (ht-values russian-words))))
(while (ht-contains? russian--known-words (russian-word-word word))
(setq word (seq-random-elt (ht-values russian-words))))
(setq russian--last-word word)
(message (russian--format-word word))))
(defvar russian--display-timer
(run-with-idle-timer 5 t #'display-random-russian-word))
;; Ability to filter out known words
(defvar russian--known-words (make-hash-table)
"Table of words that are already known.")
(defun persist-known-russian-words ()
"Persist all known Russian words."
(let ((file "/persist/tazjin/known-russian-words.el"))
(with-temp-file file
(insert (prin1-to-string russian--known-words)))))
(defun load-known-russian-words ()
"Load all known Russian words."
(let ((file "/persist/tazjin/known-russian-words.el"))
(with-temp-buffer
(insert-file-contents file)
(setq russian--known-words (read (current-buffer))))))
(defun mark-last-russian-word-known ()
"Mark the last Russian word that appeared as known."
(interactive)
(let ((word (russian-word-word russian--last-word)))
(ht-set russian--known-words word t)
(persist-known-russian-words)
(message "Marked '%s' as known" word)))
(provide 'russian)
|