list.scm
1 | ;;; Nani Project website |
2 | ;;; Copyright © 2020 Julien Lepiller <julien@lepiller.eu> |
3 | ;;; |
4 | ;;; This file is part of the Nani Project website. |
5 | ;;; |
6 | ;;; The Nani Project website is free software; you can redistribute it and/or modify it |
7 | ;;; under the terms of the GNU Affero General Public License as published by |
8 | ;;; the Free Software Foundation; either version 3 of the License, or (at |
9 | ;;; your option) any later version. |
10 | ;;; |
11 | ;;; The Nani Project website is distributed in the hope that it will be useful, but |
12 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | ;;; GNU Affero General Public License for more details. |
15 | ;;; |
16 | ;;; You should have received a copy of the GNU Affero General Public License |
17 | ;;; along with the Nani Project website. If not, see <http://www.gnu.org/licenses/>. |
18 | |
19 | (use-modules (tools i18n)) |
20 | (use-modules (nani kanji kanjidic)) |
21 | (use-modules ((nani kanji radk) #:prefix radk:)) |
22 | (use-modules (nani kanji kanjivg)) |
23 | (use-modules (nani result result)) |
24 | (use-modules (nani pitch pitch)) |
25 | (use-modules (nani sentence sentence)) |
26 | (use-modules (gcrypt hash)) |
27 | (use-modules (ice-9 match)) |
28 | (use-modules (ice-9 format)) |
29 | (use-modules (ice-9 binary-ports)) |
30 | |
31 | (define* (description dico #:key (long? #f) (lang "en")) |
32 | (define radk-synopsis |
33 | `(_ "Radical to Kanji dictionary from the Electronic Dictionary Research and Development Group.")) |
34 | (define radk-description |
35 | `(_ "This dictionary allows you to enter kanji by selecting some of its |
36 | components. Tap the water component button on the bottom of the screen to |
37 | access the kanji selection by component view")) |
38 | |
39 | (define ksvg-synopsis |
40 | `(_ "Kanji writing visual help by the Kanjivg project.")) |
41 | (define ksvg-description |
42 | `(_ "This dictionary allows you to see how a kanji is written, what it is |
43 | composed of, and the order in which strokes are written.")) |
44 | |
45 | (define wadoku-synopsis |
46 | `(_ "Japanese/German dictionary from Wadoku.")) |
47 | (define wadoku-description |
48 | `(_ "This dictionary allows you to do searches on the main view of this app. |
49 | Failing to download one of these dictionaries will make the app unusable |
50 | as you can't search for anything. This dictionary can be searched for |
51 | by kanji, reading (kana) and by German translation.")) |
52 | |
53 | (define wadoku-pitch-synopsis |
54 | `(_ "Pitch accent dictionary from Wadoku.")) |
55 | (define wadoku-pitch-description |
56 | `(_ "This dictionary allows you to augment search results on the main view |
57 | with pitch accent (pronunciation) information. Japanese is not flat, |
58 | and this dictionary will add information that will help you pronounce |
59 | words better, with a standard Japanese pitch accent.")) |
60 | |
61 | (define jibiki-synopsis |
62 | `(_ "Japanese/French dictionary from the Jibiki project.")) |
63 | (define jibiki-description |
64 | `(_ "This dictionary allows you to do searches on the main view of this app. |
65 | Failing to download one of these dictionaries will make the app unusable |
66 | as you can't search for anything. This dictionary can be searched for |
67 | by kanji, reading (kana) and by French translation.")) |
68 | |
69 | (define (tatoeba-synopsis lang) |
70 | (match lang |
71 | ("eng" `(_ "Japanese/english aligned sentences from the Tatoeba project.")) |
72 | ("fra" `(_ "Japanese/French aligned sentences from the Tatoeba project.")) |
73 | ("rus" `(_ "Japanese/Russian aligned sentences from the Tatoeba project.")) |
74 | ("spa" `(_ "Japanese/Spanish aligned sentences from the Tatoeba project.")) |
75 | ("ukr" `(_ "Japanese/Ukrainian aligned sentences from the Tatoeba project.")))) |
76 | (define (tatoeba-description lang) |
77 | `(_ "Tatoeba is a collection of sentences and translations. This |
78 | dictionary contains pairs of sentences that are direct translations of |
79 | one another, which allows you to see example sentences in search |
80 | results.")) |
81 | |
82 | (define (jmdict-synopsis lang) |
83 | (match lang |
84 | ("e" `(_ "Japanese/English dictionary from the Electronic Dictionary Research and Development Group.")) |
85 | ("dut" `(_ "Japanese/Dutch dictionary from the Electronic Dictionary Research and Development Group.")) |
86 | ("fre" `(_ "Japanese/French dictionary from the Electronic Dictionary Research and Development Group.")) |
87 | ("ger" `(_ "Japanese/German dictionary from the Electronic Dictionary Research and Development Group.")) |
88 | ("hun" `(_ "Japanese/Hungarian dictionary from the Electronic Dictionary Research and Development Group.")) |
89 | ("rus" `(_ "Japanese/Russian dictionary from the Electronic Dictionary Research and Development Group.")) |
90 | ("slv" `(_ "Japanese/Slovenian dictionary from the Electronic Dictionary Research and Development Group.")) |
91 | ("spa" `(_ "Japanese/Spanish dictionary from the Electronic Dictionary Research and Development Group.")) |
92 | ("swe" `(_ "Japanese/Swedish dictionary from the Electronic Dictionary Research and Development Group.")))) |
93 | (define (jmdict-description lang) |
94 | `(_ "This dictionary allows you to do searches on the main view of this app. |
95 | Failing to download one of these dictionaries will make the app unusable |
96 | as you can't search for anything. This dictionary can be searched for by |
97 | kanji, reading (kana) and by meaning in the languages you selected.")) |
98 | |
99 | (define (kanjidic-synopsis lang) |
100 | (match lang |
101 | ("en" `(_ "Kanji dictionary with English meanings.")) |
102 | ("es" `(_ "Kanji dictionary with Spanish meanings.")) |
103 | ("fr" `(_ "Kanji dictionary with French meanings.")) |
104 | ("pt" `(_ "Kanji dictionary with Portuguese meanings.")))) |
105 | (define (kanjidic-description lang) |
106 | `(_ "This dictionary allows you to search for kanji and view kanji information |
107 | such as number of strokes, pronunciations and meanings.")) |
108 | |
109 | (let* ((english |
110 | (cond |
111 | ((equal? (dico-type dico) "radk") |
112 | (if long? |
113 | radk-description |
114 | radk-synopsis)) |
115 | ((equal? (dico-type dico) "ksvg") |
116 | (if long? |
117 | ksvg-description |
118 | ksvg-synopsis)) |
119 | ((equal? (dico-type dico) "kanjidic") |
120 | (let ((dico-lang (substring dico 9))) |
121 | (if long? |
122 | (kanjidic-description dico-lang) |
123 | (kanjidic-synopsis dico-lang)))) |
124 | ((equal? (dico-type dico) "wadoku") |
125 | (if long? |
126 | wadoku-description |
127 | wadoku-synopsis)) |
128 | ((equal? (dico-type dico) "wadoku_pitch") |
129 | (if long? |
130 | wadoku-pitch-description |
131 | wadoku-pitch-synopsis)) |
132 | ((equal? (dico-type dico) "jibiki") |
133 | (if long? |
134 | jibiki-description |
135 | jibiki-synopsis)) |
136 | ((equal? (dico-type dico) "jmdict") |
137 | (let ((dico-lang (substring dico 7))) |
138 | (if long? |
139 | (jmdict-description dico-lang) |
140 | (jmdict-synopsis dico-lang)))) |
141 | ((equal? (dico-type dico) "tatoeba") |
142 | (let ((dico-lang (substring dico 8))) |
143 | (if long? |
144 | (tatoeba-description dico-lang) |
145 | (tatoeba-synopsis dico-lang)))))) |
146 | (translated (translate english lang))) |
147 | (if (and (equal? english translated) (not (equal? lang "en"))) |
148 | #f |
149 | translated))) |
150 | |
151 | (define (filesize file) |
152 | (stat:size (stat file))) |
153 | |
154 | (define (sha256 file) |
155 | (define hash (file-sha256 file)) |
156 | (apply |
157 | string-append |
158 | (map |
159 | (lambda (n) |
160 | (format #f "~2,'0x" n)) |
161 | (array->list hash)))) |
162 | |
163 | (define (dico-type file) |
164 | (cond |
165 | ((equal? file "radicals") "radk") |
166 | ((equal? file "kanjivg") "ksvg") |
167 | ((and (> (string-length file) 8) (equal? (substring file 0 8) "kanjidic")) |
168 | "kanjidic") |
169 | ((and (> (string-length file) 6) (equal? (substring file 0 6) "JMdict")) |
170 | "jmdict") |
171 | ((and (> (string-length file) 7) (equal? (substring file 0 7) "tatoeba")) |
172 | "tatoeba") |
173 | ((equal? file "jibiki_fre") "jibiki") |
174 | ((equal? file "wadoku_ger") "wadoku") |
175 | ((equal? file "wadoku_pitch") "wadoku_pitch"))) |
176 | |
177 | (define (entries file) |
178 | (cond |
179 | ((equal? (dico-type (dico-name file)) "radk") |
180 | (radk:kanji-count file)) |
181 | ((equal? (dico-type (dico-name file)) "ksvg") |
182 | (kanjivg-entry-count file)) |
183 | ((equal? (dico-type (dico-name file)) "kanjidic") |
184 | (kanjidic-entry-count file)) |
185 | ((member (dico-type (dico-name file)) '("jmdict" "wadoku" "jibiki")) |
186 | (dictionary-entry-count file)) |
187 | ((equal? (dico-type (dico-name file)) "tatoeba") |
188 | (sentence-dictionary-entry-count file)) |
189 | ((equal? (dico-type (dico-name file)) "wadoku_pitch") |
190 | (pitch-entry-count file)))) |
191 | |
192 | (define (dico-name file) |
193 | (basename file ".nani")) |
194 | |
195 | (define (dico-lang name) |
196 | (cond |
197 | ((equal? name "radicals") "") |
198 | ((equal? name "kanjivg") "") |
199 | ((equal? name "wadoku_pitch") "") |
200 | ((and (> (string-length name) 8) (equal? (substring name 0 8) "kanjidic")) |
201 | (substring name 9)) |
202 | ((and (> (string-length name) 6) (equal? (substring name 0 6) "JMdict")) |
203 | (let ((lang (substring name 7))) |
204 | (match lang |
205 | ("e" "en") |
206 | ("dut" "nl") |
207 | ("fre" "fr") |
208 | ("ger" "de") |
209 | ("hun" "hu") |
210 | ("rus" "ru") |
211 | ("slv" "sl") |
212 | ("spa" "es") |
213 | ("swe" "sv")))) |
214 | ((equal? name "jibiki_fre") "fr") |
215 | ((equal? name "wadoku_ger") "de"))) |
216 | |
217 | (match (command-line) |
218 | ((_ output dicos ...) |
219 | (with-output-to-file output |
220 | (lambda _ |
221 | (for-each |
222 | (lambda (dico) |
223 | (let* ((sha256 (sha256 dico)) |
224 | (size (filesize dico)) |
225 | (name (dico-name dico)) |
226 | (lang (dico-lang name)) |
227 | (type (dico-type name)) |
228 | (entry-count (entries dico))) |
229 | (format #t "[~a]~%" name) |
230 | (for-each |
231 | (lambda (lang) |
232 | (let ((synopsis (description name #:lang lang)) |
233 | (description (description name #:lang lang #:long? #t))) |
234 | (when synopsis |
235 | (format #t "synopsis=~a=~a~%" lang synopsis)) |
236 | (when description |
237 | (format #t "description=~a=~a~%" lang description)))) |
238 | (filter (lambda (lang) (not (equal? lang ""))) languages)) |
239 | (format #t "lang=~a~%" lang) |
240 | (format #t "sha256=~a~%" sha256) |
241 | (format #t "size=~a~%" size) |
242 | (format #t "type=~a~%" type) |
243 | (format #t "entries=~a~%" entry-count) |
244 | (format #t "url=~a~%" (string-append "https://nani.lepiller.eu/" dico)) |
245 | (format #t "~%"))) |
246 | dicos))))) |
247 |