sekka 0.8.8 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/sekka-jisyo +26 -9
- data/emacs/sekka.el +39 -4
- data/lib/sekka/approximatesearch.rb +12 -8
- data/lib/sekka/convert-jisyo.nnd +35 -12
- data/lib/sekka/henkan.nnd +87 -52
- data/lib/sekka/jisyo-db.nnd +63 -42
- data/lib/sekka/kvs.rb +61 -9
- data/lib/sekka/sekkaversion.rb +1 -1
- data/test/approximate-bench.nnd +6 -4
- data/test/henkan-bench.nnd +85 -0
- data/test/henkan-main.nnd +214 -48
- data/test/jisyo.nnd +7 -1
- metadata +127 -28
data/bin/sekka-jisyo
CHANGED
@@ -55,7 +55,10 @@ core.evalStr( <<";;END-OF-SCRIPT" )
|
|
55
55
|
(with-open
|
56
56
|
sekka-file
|
57
57
|
(lambda (f)
|
58
|
-
(load-sekka-jisyo-f
|
58
|
+
(load-sekka-jisyo-f
|
59
|
+
f
|
60
|
+
(target.gsub #/[.]db$/ "") ;; drop ".db" suffix
|
61
|
+
))))
|
59
62
|
|
60
63
|
|
61
64
|
(define (dump-sekka-jisyo sekka-file)
|
@@ -65,9 +68,19 @@ core.evalStr( <<";;END-OF-SCRIPT" )
|
|
65
68
|
(define (display-help)
|
66
69
|
(print "Usage : ")
|
67
70
|
(print " sekka-jisyo convert SKK-JISYO.X > SEKKA-JISYO.X ... output SEKKA-JISYO to STDOUT")
|
68
|
-
(print " sekka-jisyo load SEKKA-JISYO.X SEKKA-JISYO.X.tch ... load SEKKA-JISYO to DB
|
69
|
-
(print " sekka-jisyo
|
71
|
+
(print " sekka-jisyo load SEKKA-JISYO.X SEKKA-JISYO.X.tch ... load SEKKA-JISYO to Tokyo Cabinet DB")
|
72
|
+
(print " sekka-jisyo load SEKKA-JISYO.X SEKKA-JISYO.X.db ... load SEKKA-JISYO to ndbm DB")
|
73
|
+
(print " sekka-jisyo dump SEKKA-JISYO.X.tch ... dump Tokyo Cabinet DB to SEKKA-JISYO(STDOUT)")
|
74
|
+
(print " sekka-jisyo dump SEKKA-JISYO.X.db ... dump ndbm DB to SEKKA-JISYO(STDOUT)"))
|
70
75
|
|
76
|
+
(define (analyze-kvs-type filename)
|
77
|
+
(cond
|
78
|
+
((rxmatch #/[.]tch$/ filename)
|
79
|
+
'tokyocabinet)
|
80
|
+
((rxmatch #/[.]db$/ filename)
|
81
|
+
'dbm)
|
82
|
+
(else
|
83
|
+
(errorf "Error: analyze-kvs-type() got unsupported filename [%s] \n" filename))))
|
71
84
|
|
72
85
|
(define (main argv)
|
73
86
|
(cond
|
@@ -81,13 +94,17 @@ core.evalStr( <<";;END-OF-SCRIPT" )
|
|
81
94
|
(display-help)
|
82
95
|
(convert-skk-jisyo (second argv))))
|
83
96
|
((eq? 'load command)
|
84
|
-
(
|
85
|
-
|
86
|
-
|
97
|
+
(let1 filename (third argv)
|
98
|
+
(set-kvs-type (analyze-kvs-type filename))
|
99
|
+
(if (< (length argv) 3)
|
100
|
+
(display-help)
|
101
|
+
(load-sekka-jisyo (second argv) filename))))
|
87
102
|
((eq? 'dump command)
|
88
|
-
(
|
89
|
-
|
90
|
-
|
103
|
+
(let1 filename (second argv)
|
104
|
+
(set-kvs-type (analyze-kvs-type filename))
|
105
|
+
(if (< (length argv) 2)
|
106
|
+
(display-help)
|
107
|
+
(dump-sekka-jisyo filename))))
|
91
108
|
(else
|
92
109
|
(errorf "Error: no such command [%s] \n" command )))))))
|
93
110
|
|
data/emacs/sekka.el
CHANGED
@@ -104,6 +104,12 @@ non-nil で明示的に呼びだすまでGoogleIMEは起動しない。"
|
|
104
104
|
:type 'boolean
|
105
105
|
:group 'sekka)
|
106
106
|
|
107
|
+
(defcustom sekka-kakutei-with-spacekey t
|
108
|
+
"*Non-nil であれば、リアルタイムガイド表示中のSPACEキーでの確定動作を有効にする"
|
109
|
+
:type 'boolean
|
110
|
+
:group 'sekka)
|
111
|
+
|
112
|
+
|
107
113
|
|
108
114
|
(defface sekka-guide-face
|
109
115
|
'((((class color) (background light)) (:background "#E0E0E0" :foreground "#F03030")))
|
@@ -695,7 +701,7 @@ non-nil で明示的に呼びだすまでGoogleIMEは起動しない。"
|
|
695
701
|
(define-key sekka-select-mode-map "\C-p" 'sekka-select-prev)
|
696
702
|
(define-key sekka-select-mode-map "\C-n" 'sekka-select-next)
|
697
703
|
(define-key sekka-select-mode-map sekka-rK-trans-key 'sekka-select-next)
|
698
|
-
(define-key sekka-select-mode-map
|
704
|
+
(define-key sekka-select-mode-map (kbd "SPC") 'sekka-select-next)
|
699
705
|
(define-key sekka-select-mode-map "\C-u" 'sekka-select-hiragana)
|
700
706
|
(define-key sekka-select-mode-map "\C-i" 'sekka-select-katakana)
|
701
707
|
(define-key sekka-select-mode-map "\C-k" 'sekka-select-katakana)
|
@@ -714,6 +720,7 @@ non-nil で明示的に呼びだすまでGoogleIMEは起動しない。"
|
|
714
720
|
|
715
721
|
(define-key map "\C-n" 'popup-next)
|
716
722
|
(define-key map "\C-j" 'popup-next)
|
723
|
+
(define-key map (kbd "SPC") 'popup-next)
|
717
724
|
(define-key map [down] 'popup-next)
|
718
725
|
(define-key map "\C-p" 'popup-previous)
|
719
726
|
(define-key map [up] 'popup-previous)
|
@@ -978,8 +985,8 @@ non-nil で明示的に呼びだすまでGoogleIMEは起動しない。"
|
|
978
985
|
(lambda (alist)
|
979
986
|
(let ((markers (sekka-assoc-ref 'markers alist nil)))
|
980
987
|
(sekka-debug-print (format "markers=%S\n" markers))
|
981
|
-
(sekka-debug-print (format "marker-position car=%
|
982
|
-
(sekka-debug-print (format "marker-position cdr=%
|
988
|
+
(sekka-debug-print (format "marker-position car=%S\n" (marker-position (car markers))))
|
989
|
+
(sekka-debug-print (format "marker-position cdr=%S\n" (marker-position (cdr markers))))
|
983
990
|
(when (and (marker-position (car markers)) ;; 存在するバッファを指しているか
|
984
991
|
(marker-position (cdr markers)))
|
985
992
|
(if (= (marker-position (car markers))
|
@@ -1287,6 +1294,31 @@ non-nil で明示的に呼びだすまでGoogleIMEは起動しない。"
|
|
1287
1294
|
sticky-list)
|
1288
1295
|
(define-key sticky-map sticky-key '(lambda ()(interactive)(insert sticky-key))))
|
1289
1296
|
|
1297
|
+
|
1298
|
+
(defun sekka-spacekey-init-function ()
|
1299
|
+
(define-key global-map (kbd "SPC")
|
1300
|
+
'(lambda (&optional arg)(interactive "P")
|
1301
|
+
(cond ((and (< 0 sekka-timer-rest)
|
1302
|
+
sekka-kakutei-with-spacekey)
|
1303
|
+
(cond
|
1304
|
+
((string= " " (char-to-string (preceding-char)))
|
1305
|
+
(insert " "))
|
1306
|
+
((eq 10 (preceding-char)) ;; 直前に改行があった
|
1307
|
+
(insert " "))
|
1308
|
+
((string= "/" (char-to-string (preceding-char)))
|
1309
|
+
(delete-region (- (point) 1) (point))
|
1310
|
+
(insert " "))
|
1311
|
+
(t
|
1312
|
+
(sekka-rK-trans))))
|
1313
|
+
(t
|
1314
|
+
(cond
|
1315
|
+
((null arg)
|
1316
|
+
(insert " "))
|
1317
|
+
(t
|
1318
|
+
(dotimes(i arg)
|
1319
|
+
(insert " ")))))))))
|
1320
|
+
|
1321
|
+
|
1290
1322
|
(defun sekka-realtime-guide ()
|
1291
1323
|
"リアルタイムで変換中のガイドを出す
|
1292
1324
|
sekka-modeがONの間中呼び出される可能性がある。"
|
@@ -1410,6 +1442,9 @@ point から行頭方向に同種の文字列が続く間を漢字変換しま
|
|
1410
1442
|
(> (prefix-numeric-value arg) 0))))
|
1411
1443
|
(when sekka-sticky-shift
|
1412
1444
|
(add-hook 'sekka-mode-hook 'sekka-sticky-shift-init-function))
|
1445
|
+
|
1446
|
+
(add-hook 'sekka-mode-hook 'sekka-spacekey-init-function)
|
1447
|
+
|
1413
1448
|
(when sekka-mode (run-hooks 'sekka-mode-hook))
|
1414
1449
|
|
1415
1450
|
(sekka-debug-print "sekka-mode-internal :2\n")
|
@@ -1455,7 +1490,7 @@ point から行頭方向に同種の文字列が続く間を漢字変換しま
|
|
1455
1490
|
(setq default-input-method "japanese-sekka")
|
1456
1491
|
|
1457
1492
|
(defconst sekka-version
|
1458
|
-
"0.
|
1493
|
+
"0.9.0" ;;SEKKA-VERSION
|
1459
1494
|
)
|
1460
1495
|
(defun sekka-version (&optional arg)
|
1461
1496
|
"入力モード変更"
|
@@ -49,19 +49,23 @@ class ApproximateSearch
|
|
49
49
|
}.select { |v| v }.sort_by {|item| 1.0 - item[0]}
|
50
50
|
end
|
51
51
|
|
52
|
-
def search( userid, kvs, keyword,
|
53
|
-
readymade_key =
|
54
|
-
|
52
|
+
def search( userid, kvs, keyword, type )
|
53
|
+
readymade_key = case type
|
54
|
+
when 'k' # okuri nashi kanji entry
|
55
|
+
"(" + keyword.slice( 0, 2 ).downcase + ")"
|
56
|
+
when 'K' # okuri ari kanji entry
|
57
|
+
"(" + keyword.slice( 0, 2 ).upcase + ")"
|
58
|
+
when 'h' # hiragana phrase entry
|
59
|
+
"{" + keyword.slice( 1, 2 ).downcase + "}"
|
55
60
|
else
|
56
|
-
|
61
|
+
raise sprintf( "Error: ApproximateSearch#search unknown type %s ", type )
|
57
62
|
end
|
58
|
-
|
59
|
-
|
63
|
+
|
60
64
|
str = kvs.get( userid + "::" + readymade_key, false )
|
61
|
-
if not str
|
65
|
+
if not str
|
62
66
|
str = kvs.get( "MASTER::" + readymade_key )
|
63
67
|
end
|
64
|
-
|
68
|
+
|
65
69
|
#printf( "#readymade_key %s : %s\n", readymade_key, str )
|
66
70
|
if str
|
67
71
|
filtering( keyword, str.split( /[ ]+/ ))
|
data/lib/sekka/convert-jisyo.nnd
CHANGED
@@ -38,6 +38,17 @@
|
|
38
38
|
(use sekka.roman-lib)
|
39
39
|
|
40
40
|
|
41
|
+
(define (expand-hiragana-phrase-entry key)
|
42
|
+
(let1 roman-list (gen-hiragana->roman-list key)
|
43
|
+
(if (< 1000 (length roman-list))
|
44
|
+
(begin
|
45
|
+
(STDERR.printf " Warning: ignored entry [%s] (hiragana phrase), because too many pattens.\n" key)
|
46
|
+
#f) ;; パターン数が爆発した単語は無視する
|
47
|
+
(map
|
48
|
+
(lambda (x)
|
49
|
+
(cons (+ "=" x) key))
|
50
|
+
roman-list))))
|
51
|
+
|
41
52
|
(define (expand-okuri-nashi-entry key value)
|
42
53
|
(let1 roman-list (gen-hiragana->roman-list key)
|
43
54
|
(if (< 1000 (length roman-list))
|
@@ -79,7 +90,7 @@
|
|
79
90
|
|
80
91
|
(define (display-progress line)
|
81
92
|
(set! current (+ current 1))
|
82
|
-
(when (= 0 (% current
|
93
|
+
(when (= 0 (% current 1000))
|
83
94
|
(STDERR.printf " %7d/%7d (%3.3f%)\n" current total (* (/ current (total.to_f)) 100.0))))
|
84
95
|
|
85
96
|
(define (gen-sekka-entries line)
|
@@ -94,6 +105,13 @@
|
|
94
105
|
((not fields)
|
95
106
|
;; フォーマットエラー
|
96
107
|
#f)
|
108
|
+
((rxmatch #/\;\;/ line)
|
109
|
+
;; フォーマットエラー
|
110
|
+
#f)
|
111
|
+
((and (is-hiragana (first fields))
|
112
|
+
(rxmatch #/^\/$/ (second fields)))
|
113
|
+
;; 平仮名フレーズ
|
114
|
+
(expand-hiragana-phrase-entry (first fields)))
|
97
115
|
((or (is-hiragana (first fields))
|
98
116
|
(rxmatch #/^([>#あ-んー]+)$/ (first fields)))
|
99
117
|
;; 送り仮名なしデータ
|
@@ -113,20 +131,25 @@
|
|
113
131
|
(else
|
114
132
|
(list (cons (first fields) (second fields)))))))
|
115
133
|
|
116
|
-
(let* (
|
134
|
+
(let* ([lines
|
117
135
|
(map
|
118
136
|
(lambda (line)
|
119
137
|
(line.chomp))
|
120
|
-
(f.readlines
|
121
|
-
|
122
|
-
(
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
138
|
+
(f.readlines))]
|
139
|
+
[_ (set! total (lines.size))]
|
140
|
+
[result '#()])
|
141
|
+
(for-each
|
142
|
+
(lambda (x)
|
143
|
+
(let1 entries (gen-sekka-entries x)
|
144
|
+
(when entries
|
145
|
+
(for-each
|
146
|
+
(lambda (entry)
|
147
|
+
(result.push (sprintf "%s %s" (car entry) (cdr entry))))
|
148
|
+
entries))))
|
149
|
+
lines)
|
150
|
+
|
151
|
+
(to-list result)))
|
152
|
+
|
130
153
|
|
131
154
|
|
132
155
|
|
data/lib/sekka/henkan.nnd
CHANGED
@@ -68,40 +68,39 @@
|
|
68
68
|
lst))
|
69
69
|
|
70
70
|
|
71
|
-
(define (
|
72
|
-
(
|
73
|
-
(for-each
|
74
|
-
(lambda (x)
|
75
|
-
(set! result (append result x)))
|
76
|
-
lst)
|
77
|
-
result))
|
71
|
+
(define (flatten-vector vec)
|
72
|
+
(vec.flatten))
|
78
73
|
|
79
74
|
|
80
75
|
;; 曖昧検索
|
81
76
|
;; リストで返す。 (ソート済み検索結果)
|
82
|
-
(define (approximate-search userid kvs keyword
|
83
|
-
(
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
77
|
+
(define (approximate-search userid kvs keyword type limit)
|
78
|
+
(let ([jarow-threshold
|
79
|
+
(if (= "h" type)
|
80
|
+
0.975
|
81
|
+
0.94)])
|
82
|
+
|
83
|
+
(let* ((a-search (ApproximateSearch.new jarow-threshold))
|
84
|
+
(lst (to-list
|
85
|
+
(flatten-vector
|
86
|
+
(map
|
87
|
+
(lambda (x)
|
88
|
+
(let* ((val (vector-ref x 0))
|
89
|
+
(k (vector-ref x 1))
|
90
|
+
(v (dict-get userid kvs k ""))
|
91
|
+
(v-pair (string-split-first-and-rest v))
|
92
|
+
(v-first (car v-pair))
|
93
|
+
(v-rest (cdr v-pair)))
|
94
|
+
(map
|
95
|
+
(lambda (element)
|
96
|
+
(list val k (+ v-first element)))
|
97
|
+
(v-rest.split "/"))))
|
98
|
+
(a-search.search userid kvs keyword type)))))
|
99
|
+
(nn-heuristics-result (nn-heuristics keyword lst))
|
100
|
+
(sorted-lst (sort-by nn-heuristics-result (lambda (item) (- 1.0 (car item))))))
|
101
|
+
(if (= limit 0)
|
102
|
+
sorted-lst
|
103
|
+
(take* sorted-lst limit)))))
|
105
104
|
|
106
105
|
|
107
106
|
;; 厳密検索
|
@@ -143,7 +142,7 @@
|
|
143
142
|
|
144
143
|
;; 送り仮名なしの変換
|
145
144
|
(define (henkan-okuri-nashi userid kvs keyword limit)
|
146
|
-
(let* ((result (approximate-search userid kvs keyword
|
145
|
+
(let* ((result (approximate-search userid kvs keyword "k" limit))
|
147
146
|
(kouho (uniq (map
|
148
147
|
(lambda (x)
|
149
148
|
(third x))
|
@@ -204,7 +203,7 @@
|
|
204
203
|
(+ (rxmatch-substring m 1)
|
205
204
|
(rxmatch-substring m 2)
|
206
205
|
(rxmatch-substring m 3))
|
207
|
-
|
206
|
+
"K"
|
208
207
|
limit))
|
209
208
|
(okurigana-lst (gen-roman->hiragana (sekka-downcase
|
210
209
|
(+
|
@@ -236,19 +235,45 @@
|
|
236
235
|
(take* lst limit)))))))
|
237
236
|
|
238
237
|
|
238
|
+
;; 平仮名フレーズ辞書を使った曖昧検索
|
239
|
+
(define (henkan-hiragana-phrase userid kvs keyword limit roman-method)
|
240
|
+
(let* ([result (approximate-search userid kvs
|
241
|
+
(+ "=" (sekka-downcase keyword))
|
242
|
+
"h"
|
243
|
+
limit)]
|
244
|
+
[uniq-result
|
245
|
+
(delete-duplicates
|
246
|
+
(map
|
247
|
+
(lambda (x) (third x))
|
248
|
+
result))]
|
249
|
+
|
250
|
+
[lst (map
|
251
|
+
(lambda (x)
|
252
|
+
(list x #f keyword 'h))
|
253
|
+
uniq-result)])
|
254
|
+
|
255
|
+
(if (= limit 0)
|
256
|
+
lst
|
257
|
+
(take* lst limit))))
|
258
|
+
|
259
|
+
|
260
|
+
|
239
261
|
;; 平仮名の変換
|
240
|
-
(define (henkan-hiragana kvs keyword roman-method)
|
241
|
-
(let* (
|
242
|
-
(
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
262
|
+
(define (henkan-hiragana userid kvs keyword roman-method)
|
263
|
+
(let* ([phrase-limit 3]
|
264
|
+
[str (sekka-downcase keyword)]
|
265
|
+
[hira (gen-roman->hiragana str roman-method)]
|
266
|
+
[kata (gen-roman->katakana str roman-method)])
|
267
|
+
(append
|
268
|
+
(henkan-hiragana-phrase userid kvs keyword phrase-limit roman-method)
|
269
|
+
(if (null? hira)
|
270
|
+
`((,keyword #f ,keyword j))
|
271
|
+
(append-map (lambda (h k)
|
272
|
+
`(
|
273
|
+
(,h #f ,keyword h)
|
274
|
+
(,k #f ,keyword k)))
|
275
|
+
hira
|
276
|
+
kata)))))
|
252
277
|
|
253
278
|
|
254
279
|
;; アルファベットの単純変換
|
@@ -303,23 +328,21 @@
|
|
303
328
|
(cond
|
304
329
|
((rxmatch #/[a-z][A-Z`+]/ k)
|
305
330
|
;; 送りあり
|
306
|
-
;;(let1 result (approximate-search db k #t) (disp-search-result result))
|
307
331
|
(append
|
308
332
|
(append
|
309
333
|
(henkan-okuri-ari userid kvs k limit roman-method)
|
310
334
|
(if (null? (gen-roman->hiragana (sekka-downcase k) roman-method))
|
311
335
|
'()
|
312
|
-
(henkan-hiragana kvs (sekka-downcase k) roman-method)))
|
336
|
+
(henkan-hiragana userid kvs (sekka-downcase k) roman-method)))
|
313
337
|
(henkan-alphabet kvs keyword)))
|
314
338
|
(else
|
315
339
|
;; 送りなし
|
316
|
-
;;(let1 result (approximate-search db k #f) (disp-search-result result))
|
317
340
|
(append
|
318
341
|
(append
|
319
342
|
(henkan-okuri-nashi userid kvs k limit)
|
320
343
|
(if (null? (gen-roman->hiragana (sekka-downcase k) roman-method))
|
321
344
|
'()
|
322
|
-
(henkan-hiragana kvs (sekka-downcase k) roman-method)))
|
345
|
+
(henkan-hiragana userid kvs (sekka-downcase k) roman-method)))
|
323
346
|
(henkan-alphabet kvs keyword))))))
|
324
347
|
;; 10進数数値のみで構成されるキーワード
|
325
348
|
((rxmatch #/^[0-9]+$/ keyword)
|
@@ -332,7 +355,7 @@
|
|
332
355
|
((not (null? (gen-roman->hiragana keyword roman-method)))
|
333
356
|
(append
|
334
357
|
(append
|
335
|
-
(henkan-hiragana kvs keyword roman-method)
|
358
|
+
(henkan-hiragana userid kvs keyword roman-method)
|
336
359
|
(henkan-alphabet kvs keyword))
|
337
360
|
(henkan-okuri-nashi userid kvs keyword limit)))
|
338
361
|
(else
|
@@ -468,7 +491,8 @@
|
|
468
491
|
|
469
492
|
(define (_create-ready-made-keylist keylist)
|
470
493
|
(receive (okuri-ari-hash
|
471
|
-
okuri-nashi-hash
|
494
|
+
okuri-nashi-hash
|
495
|
+
hiragana-phrase-hash)
|
472
496
|
(create-2char-hash keylist)
|
473
497
|
|
474
498
|
;; OKURI-ARI
|
@@ -491,8 +515,19 @@
|
|
491
515
|
(string-join (uniq (sort (append (to-list (fetched.split #/[ ]+/))
|
492
516
|
(hash-table-get okuri-nashi-hash key))))
|
493
517
|
" "))))
|
494
|
-
(hash-table-keys okuri-nashi-hash))
|
495
|
-
|
518
|
+
(hash-table-keys okuri-nashi-hash))
|
519
|
+
|
520
|
+
;; HIRAGANA-PHRASE
|
521
|
+
(for-each
|
522
|
+
(lambda (key)
|
523
|
+
(let1 fetched (kvs.get (+ userid "::" "{" (sekka-downcase key) "}")
|
524
|
+
(kvs.get (+ masterid "::" "{" (sekka-downcase key) "}") ""))
|
525
|
+
(kvs.put! (+ userid "::" "{" (sekka-downcase key) "}")
|
526
|
+
(string-join (uniq (sort (append (to-list (fetched.split #/[ ]+/))
|
527
|
+
(hash-table-get hiragana-phrase-hash key))))
|
528
|
+
" "))))
|
529
|
+
(hash-table-keys hiragana-phrase-hash))))
|
530
|
+
|
496
531
|
;; "ユーザー語彙を"(stored)"にpush!する"
|
497
532
|
(define (kvs-push! userid kvs entry-str)
|
498
533
|
(let* ((orig (kvs.get (+ userid "::(stored)") "()"))
|
data/lib/sekka/jisyo-db.nnd
CHANGED
@@ -72,21 +72,29 @@
|
|
72
72
|
opt)))
|
73
73
|
|
74
74
|
(define (create-2char-hash keylist)
|
75
|
-
(define okuri-ari-hash
|
76
|
-
(define okuri-nashi-hash
|
75
|
+
(define okuri-ari-hash (make-hash-table))
|
76
|
+
(define okuri-nashi-hash (make-hash-table))
|
77
|
+
(define hiragana-phrase-hash (make-hash-table))
|
77
78
|
(define (create-hash keylist)
|
78
79
|
(for-each
|
79
80
|
(lambda (k)
|
80
|
-
(when (rxmatch #/^[a-zA-Z#^>-@`\;+:'\-]+$/ k)
|
81
|
-
(
|
82
|
-
|
83
|
-
(
|
84
|
-
|
85
|
-
(hash-table-push!
|
81
|
+
(when (rxmatch #/^[=a-zA-Z#^>-@`\;+:'\-]+$/ k)
|
82
|
+
(if (rxmatch #/^=/ k)
|
83
|
+
;; HIRAGANA-PHRASE
|
84
|
+
(let1 sliced (sekka-downcase (k.slice 1 2))
|
85
|
+
(when (= 2 sliced.size)
|
86
|
+
(hash-table-push! hiragana-phrase-hash sliced k)))
|
87
|
+
;; OKURI-ARI and OKURI-NASHI
|
88
|
+
(let1 sliced (sekka-downcase (k.slice 0 2))
|
89
|
+
(when (= 2 sliced.size)
|
90
|
+
(if (rxmatch #/[A-Z`+]$/ k)
|
91
|
+
(hash-table-push! okuri-ari-hash sliced k)
|
92
|
+
(hash-table-push! okuri-nashi-hash sliced k)))))))
|
86
93
|
keylist))
|
87
94
|
(create-hash keylist)
|
88
95
|
(values okuri-ari-hash
|
89
|
-
okuri-nashi-hash
|
96
|
+
okuri-nashi-hash
|
97
|
+
hiragana-phrase-hash))
|
90
98
|
|
91
99
|
(define (setup-ready-made-keylist kvs keylist)
|
92
100
|
(for-each
|
@@ -97,7 +105,8 @@
|
|
97
105
|
alphabet-pairs)
|
98
106
|
|
99
107
|
(receive (okuri-ari-hash
|
100
|
-
okuri-nashi-hash
|
108
|
+
okuri-nashi-hash
|
109
|
+
hiragana-phrase-hash)
|
101
110
|
(create-2char-hash keylist)
|
102
111
|
|
103
112
|
;; OKURI-ARI
|
@@ -112,49 +121,61 @@
|
|
112
121
|
(lambda (key)
|
113
122
|
(kvs.put! (+ masterid "::" "(" (sekka-downcase key) ")")
|
114
123
|
(string-join (uniq (sort (hash-table-get okuri-nashi-hash key))) " ")))
|
115
|
-
(hash-table-keys okuri-nashi-hash))
|
116
|
-
|
117
|
-
|
118
|
-
(
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
(
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
124
|
+
(hash-table-keys okuri-nashi-hash))
|
125
|
+
|
126
|
+
;; HIRAGANA-PHRASE
|
127
|
+
(for-each
|
128
|
+
(lambda (key)
|
129
|
+
(kvs.put! (+ masterid "::" "{" (sekka-downcase key) "}")
|
130
|
+
(string-join (uniq (sort (hash-table-get hiragana-phrase-hash key))) " ")))
|
131
|
+
(hash-table-keys hiragana-phrase-hash))))
|
132
|
+
|
133
|
+
|
134
|
+
(define (append-entry userid kvs _key value)
|
135
|
+
(let1 key (+ userid "::" _key)
|
136
|
+
(cond
|
137
|
+
((rxmatch #/^=/ _key)
|
138
|
+
;; hiragana-phrase entry
|
139
|
+
(kvs.put! key value))
|
140
|
+
(else
|
141
|
+
(if-let1 got (kvs.get key #f)
|
142
|
+
(let* ((trimmed-a-first1 (car (string-split-first-and-rest got)))
|
143
|
+
(trimmed-a (if-let1 m (rxmatch #/^[C\/](.+)$/ got)
|
144
|
+
(rxmatch-substring m 1)
|
145
|
+
got))
|
146
|
+
(trimmed-b-first1 (car (string-split-first-and-rest value)))
|
147
|
+
(trimmed-b (if-let1 m (rxmatch #/^[C\/](.+)$/ value)
|
148
|
+
(rxmatch-substring m 1)
|
149
|
+
value))
|
150
|
+
(lst (delete-duplicates (append (to-list (trimmed-a.split "/"))
|
151
|
+
(to-list (trimmed-b.split "/"))))))
|
152
|
+
(if (= trimmed-a-first1 trimmed-b-first1)
|
153
|
+
(kvs.put! key (+ trimmed-a-first1 (string-join lst "/")))
|
154
|
+
(begin
|
155
|
+
;; "/" よりも "C" を優先する
|
156
|
+
(cond
|
157
|
+
((= "C" trimmed-a-first1) ;; aを優先
|
158
|
+
(kvs.put! key got))
|
159
|
+
((= "C" trimmed-b-first1) ;; bを優先
|
160
|
+
(kvs.put! key value))
|
161
|
+
(else
|
162
|
+
(errorf "Error: [%s][%s] entry is wrong format" key value))))))
|
163
|
+
(kvs.put! key value))))))
|
143
164
|
|
144
165
|
|
145
166
|
(define (load-sekka-jisyo-f f filename)
|
146
167
|
(define keylist '())
|
147
|
-
(define (create-keylist kvs
|
168
|
+
(define (create-keylist kvs f)
|
148
169
|
(for-each
|
149
170
|
(lambda (line)
|
150
171
|
(let1 fields (split-dict-line line)
|
151
172
|
(set! keylist (cons (first fields) keylist))
|
152
173
|
(append-entry masterid kvs (first fields) (second fields))))
|
153
|
-
|
174
|
+
(f.readlines)))
|
154
175
|
(let1 kvs (Kvs.new (get-kvs-type))
|
155
176
|
(kvs.open filename)
|
156
177
|
(kvs.clear)
|
157
|
-
(create-keylist kvs
|
178
|
+
(create-keylist kvs f)
|
158
179
|
(setup-ready-made-keylist kvs keylist)
|
159
180
|
(kvs.close)))
|
160
181
|
|
@@ -165,7 +186,7 @@
|
|
165
186
|
(for-each
|
166
187
|
(lambda (key)
|
167
188
|
(f.puts (+ key " " (kvs.get key))))
|
168
|
-
(
|
189
|
+
(kvs.keys.sort))
|
169
190
|
(kvs.close)))
|
170
191
|
|
171
192
|
|