aboutsummaryrefslogtreecommitdiff
path: root/ext/jp
diff options
context:
space:
mode:
authorAlex Yatskov <alex@foosoft.net>2016-03-26 14:21:51 -0700
committerAlex Yatskov <alex@foosoft.net>2016-03-26 14:21:51 -0700
commitced7bf5f27c72b98fae3b2d24f1820e0083c22bf (patch)
tree3b6e88f5ed32b1cebfd20035c44fde6d947bf9bf /ext/jp
parent12696d3e6b3d7f1b92923ed625fdb3dc5ec660f2 (diff)
File reorg
Diffstat (limited to 'ext/jp')
-rw-r--r--ext/jp/deinflector.js126
-rw-r--r--ext/jp/dictionary.js84
-rw-r--r--ext/jp/translator.js151
-rw-r--r--ext/jp/yomichan.js73
4 files changed, 0 insertions, 434 deletions
diff --git a/ext/jp/deinflector.js b/ext/jp/deinflector.js
deleted file mode 100644
index 03f9d40a..00000000
--- a/ext/jp/deinflector.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
- * Author: Alex Yatskov <alex@foosoft.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-class Deinflection {
- constructor(term, tags=[], rule='') {
- this.children = [];
- this.term = term;
- this.tags = tags;
- this.rule = rule;
- }
-
- validate(validator) {
- for (const tags of validator(this.term)) {
- if (this.tags.length === 0) {
- return true;
- }
-
- for (const tag of this.tags) {
- if (this.searchTags(tag, tags)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- deinflect(validator, rules) {
- if (this.validate(validator)) {
- const child = new Deinflection(this.term);
- this.children.push(child);
- }
-
- for (const rule in rules) {
- const variants = rules[rule];
- for (const v of variants) {
- let allowed = this.tags.length === 0;
- for (const tag of this.tags) {
- if (this.searchTags(tag, v.tagsIn)) {
- allowed = true;
- break;
- }
- }
-
- if (!allowed || !this.term.endsWith(v.kanaIn)) {
- continue;
- }
-
- const term = this.term.slice(0, -v.kanaIn.length) + v.kanaOut;
- const child = new Deinflection(term, v.tagsOut, rule);
- if (child.deinflect(validator, rules)) {
- this.children.push(child);
- }
- }
- }
-
- return this.children.length > 0;
- }
-
- searchTags(tag, tags) {
- for (const t of tags) {
- const re = new RegExp(tag);
- if (re.test(t)) {
- return true;
- }
- }
-
- return false;
- }
-
- gather() {
- if (this.children.length === 0) {
- return [{root: this.term, rules: []}];
- }
-
- const paths = [];
- for (const child of this.children) {
- for (const path of child.gather()) {
- if (this.rule.length > 0) {
- path.rules.push(this.rule);
- }
-
- path.source = this.term;
- paths.push(path);
- }
- }
-
- return paths;
- }
-}
-
-
-class Deinflector {
- constructor() {
- this.rules = {};
- }
-
- setRules(rules) {
- this.rules = rules;
- }
-
- deinflect(term, validator) {
- const node = new Deinflection(term);
- if (node.deinflect(validator, this.rules)) {
- return node.gather();
- }
-
- return null;
- }
-}
diff --git a/ext/jp/dictionary.js b/ext/jp/dictionary.js
deleted file mode 100644
index eff54890..00000000
--- a/ext/jp/dictionary.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
- * Author: Alex Yatskov <alex@foosoft.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-class Dictionary {
- constructor() {
- this.termDicts = [];
- this.kanjiDicts = [];
- }
-
- addTermDict(termDict) {
- this.termDicts.push(termDict);
- }
-
- addKanjiDict(kanjiDict) {
- this.kanjiDicts.push(kanjiDict);
- }
-
-
- findTerm(term) {
- let results = [];
- for (let dict of this.termDicts) {
- results = results.concat(this.findTermInDict(term, dict));
- }
-
- return results;
- }
-
- findKanji(kanji) {
- const results = [];
- for (let dict of this.kanjiDicts) {
- const result = this.findKanjiInDict(kanji, dict);
- if (result !== null) {
- results.push(result);
- }
- }
-
- return results;
- }
-
- findTermInDict(term, dict) {
- return (dict.indices[term] || []).map(index => {
- const [e, r, g, t] = dict.defs[index];
- return {
- id: index,
- expression: e,
- reading: r,
- glossary: g,
- tags: t.split(' ')
- };
- });
- }
-
- findKanjiInDict(kanji, dict) {
- const def = dict.defs[kanji];
- if (def === null) {
- return null;
- }
-
- const [c, k, o, g] = def;
- return {
- id: kanji.charCodeAt(0),
- character: c,
- kunyomi: k,
- onyomi: o,
- glossary: g
- };
- }
-}
diff --git a/ext/jp/translator.js b/ext/jp/translator.js
deleted file mode 100644
index 7a610377..00000000
--- a/ext/jp/translator.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
- * Author: Alex Yatskov <alex@foosoft.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-class Translator {
- constructor() {
- this.dictionary = new Dictionary();
- this.deinflector = new Deinflector();
- this.initialized = false;
- }
-
- loadData(paths, callback) {
- if (this.initialized) {
- callback();
- return;
- }
-
- const loaders = [];
- for (const key of ['rules', 'edict', 'enamdict', 'kanjidic']) {
- loaders.push(
- $.getJSON(chrome.extension.getURL(paths[key]))
- );
- }
-
- $.when.apply($, loaders).done((rules, edict, enamdict, kanjidic) => {
- this.deinflector.setRules(rules[0]);
-
- this.dictionary.addTermDict(edict[0]);
- this.dictionary.addTermDict(enamdict[0]);
- this.dictionary.addKanjiDict(kanjidic[0]);
-
- this.initialized = true;
-
- if (callback) {
- callback();
- }
- });
- }
-
- findTerm(text) {
- const groups = {};
- for (let i = text.length; i > 0; --i) {
- const term = text.slice(0, i);
-
- const dfs = this.deinflector.deinflect(term, t => {
- const tags = [];
- for (const d of this.dictionary.findTerm(t)) {
- tags.push(d.tags);
- }
-
- return tags;
- });
-
- if (dfs === null) {
- this.processTerm(groups, term);
- } else {
- for (const df of dfs) {
- this.processTerm(groups, df.source, df.rules, df.root);
- }
- }
- }
-
- let results = [];
- for (const key in groups) {
- results.push(groups[key]);
- }
-
- results = results.sort(this.resultSorter);
-
- let length = 0;
- for (const result of results) {
- length = Math.max(length, result.source.length);
- }
-
- return {results: results, length: length};
- }
-
- findKanji(text) {
- let results = [];
-
- const processed = {};
- for (const c of text) {
- if (!processed.has(c)) {
- results = results.concat(this.dictionary.findKanji(c));
- processed[c] = true;
- }
- }
-
- return results;
- }
-
- processTerm(groups, source, rules=[], root='') {
- for (const entry of this.dictionary.findTerm(root || source)) {
- if (entry.id in groups) {
- continue;
- }
-
- groups[entry.id] = {
- expression: entry.expression,
- reading: entry.reading,
- glossary: entry.glossary,
- tags: entry.tags,
- source: source,
- rules: rules
- };
- }
- }
-
- resultSorter(v1, v2) {
- const sl1 = v1.source.length;
- const sl2 = v2.source.length;
- if (sl1 > sl2) {
- return -1;
- } else if (sl1 < sl2) {
- return 1;
- }
-
- const p1 = v1.tags.indexOf('P') >= 0;
- const p2 = v2.tags.indexOf('P') >= 0;
- if (p1 && !p2) {
- return -1;
- } else if (!p1 && p2) {
- return 1;
- }
-
- const rl1 = v1.rules.length;
- const rl2 = v2.rules.length;
- if (rl1 < rl2) {
- return -1;
- } else if (rl2 > rl1) {
- return 1;
- }
-
- return 0;
- }
-}
diff --git a/ext/jp/yomichan.js b/ext/jp/yomichan.js
deleted file mode 100644
index 5c2b579f..00000000
--- a/ext/jp/yomichan.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
- * Author: Alex Yatskov <alex@foosoft.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-class Yomichan {
- constructor() {
- this.translator = new Translator();
- this.res = {
- rules: 'jp/data/rules.json',
- edict: 'jp/data/edict.json',
- enamdict: 'jp/data/enamdict.json',
- kanjidic: 'jp/data/kanjidic.json'
- };
-
- this.updateState('disabled');
-
- chrome.runtime.onMessage.addListener(this.onMessage.bind(this));
- chrome.browserAction.onClicked.addListener(this.onBrowserAction.bind(this));
- }
-
- onFindTerm({term}) {
- return this.translator.findTerm(term);
- }
-
- onMessage(request, sender, callback) {
- const {action, data} = request;
- const handler = {
- findTerm: this.onFindTerm
- }[action];
-
- if (handler !== null) {
- const result = handler.call(this, data);
- if (callback !== null) {
- callback(result);
- }
- }
- }
-
- onBrowserAction(tab) {
- switch (this.state) {
- case 'disabled':
- this.updateState('loading');
- this.translator.loadData(this.res, () => this.updateState('enabled'));
- break;
- case 'enabled':
- this.updateState('disabled');
- break;
- }
- }
-
- updateState(state) {
- const text = {'disabled': '', 'enabled': 'on', 'loading': '...'}[state];
- chrome.browserAction.setBadgeText({text: text});
- this.state = state;
- }
-}
-
-window.yomichan = new Yomichan();