-
Notifications
You must be signed in to change notification settings - Fork 3
/
jplookup.ts
108 lines (91 loc) · 2.31 KB
/
jplookup.ts
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
// looks up words in the subtitle containing a kanji on a J-E dictionary
import { mecab, MecabPOSComplete, isKanji } from './mecab';
import { isNotBlackListed } from './blacklist';
import { toHiragana } from './kana';
import { jisho } from './jisho';
const showLoading = false;
const defaultOptions = {
fs: 14,
border: 1.0,
color: 'FFFFFF',
borderColor: '000000',
};
function clearass() {
mp.set_osd_ass(0, 0, '{}');
}
function ass(message: string, opts: Partial<typeof defaultOptions>) {
const options = { ...defaultOptions, ...opts };
const style = [
`{\\fs${options.fs}}`,
`{\\1c&H${options.color}&}`,
`{\\bord${options.border}}`,
`{\\3c&H${options.borderColor}&}`,
].join('');
mp.set_osd_ass(0, 0, `${style}${message}`);
}
function handler(_prop: string, text: string) {
if (!text) {
clearass();
return;
}
if (showLoading) {
ass('読み込み中・・・', { fs: 10 });
}
const result = lookup(text).map(
x => `${x.lemma} (${x.reading}) - ${x.definition}`,
);
if (result.length > 0) {
ass(`${result.join('\\N')}`, {});
} else {
clearass();
}
}
let active = false;
function removeSpeaker(text: string): string {
return text
.replace(/([^()]*)/, '')
.replace(/\([^()]*\)/, '')
.trim();
}
type LookupResult = {
lemma: string;
reading: string;
definition: string;
};
function lookup(text: string): LookupResult[] {
return mecab(removeSpeaker(text))
.filter(isNotBlackListed)
.filter((x): x is MecabPOSComplete => x.t === 'POSC')
.filter(isKanji)
.map(x => {
const jr = jisho(x.lemma);
return jr
? {
lemma: x.lemma,
reading: jr.lemmaReading,
definition: jr.definition,
}
: {
lemma: x.lemma,
reading: toHiragana(x.reading),
definition: '',
};
});
}
function subanalyze() {
if (active) {
mp.unobserve_property(handler);
clearass();
active = false;
} else {
mp.observe_property('sub-text', 'string', handler);
active = true;
}
}
mp.add_key_binding('x', 'toggle', subanalyze);
// call this function for testing the parsing and lookup function
export function testhandler() {
lookup('小さな約束だった').forEach(x =>
mp.msg.error(`${x.lemma}: ${x.definition}`),
);
}