This commit is contained in:
Alex Yatskov 2016-12-17 18:45:19 -08:00
parent 5c94923264
commit d98f4566bc
8 changed files with 74 additions and 78 deletions

View File

@ -117,15 +117,15 @@ class Database {
}
const tagMeta = this.tagMetaCache[dictionary] = {};
const promise = this.db.tagMeta.where('dictionary').equals(dictionary).each(row => {
promises.push(
this.db.tagMeta.where('dictionary').equals(dictionary).each(row => {
tagMeta[row.tag] = {
category: row.category,
notes: row.notes,
order: row.order
};
});
promises.push(promise);
})
);
}
return Promise.all(promises).then(() => this.tagMetaCache);

View File

@ -18,22 +18,22 @@
class Deinflection {
constructor(term, tags=[], rule='') {
constructor(term, rules=[], reason='') {
this.children = [];
this.term = term;
this.tags = tags;
this.rule = rule;
this.rules = rules;
this.reason = reason;
}
validate(validator) {
return validator(this.term).then(sets => {
for (const tags of sets) {
if (this.tags.length === 0) {
for (const rules of sets) {
if (this.rules.length === 0) {
return true;
}
for (const tag of this.tags) {
if (tags.includes(tag)) {
for (const rule of this.rules) {
if (rules.includes(rule)) {
return true;
}
}
@ -43,19 +43,19 @@ class Deinflection {
});
}
deinflect(validator, rules) {
deinflect(validator, reasons) {
const promises = [
this.validate(validator).then(valid => {
const child = new Deinflection(this.term, this.tags);
const child = new Deinflection(this.term, this.rules);
this.children.push(child);
})
];
for (const rule in rules) {
for (const variant of rules[rule]) {
let allowed = this.tags.length === 0;
for (const tag of this.tags) {
if (variant.tagsIn.includes(tag)) {
for (const reason in reasons) {
for (const variant of reasons[reason]) {
let allowed = this.rules.length === 0;
for (const rule of this.rules) {
if (variant.rulesIn.includes(rule)) {
allowed = true;
break;
}
@ -70,9 +70,9 @@ class Deinflection {
continue;
}
const child = new Deinflection(term, variant.tagsOut, rule);
const child = new Deinflection(term, variant.rulesOut, reason);
promises.push(
child.deinflect(validator, rules).then(valid => {
child.deinflect(validator, reasons).then(valid => {
if (valid) {
this.children.push(child);
}
@ -88,14 +88,14 @@ class Deinflection {
gather() {
if (this.children.length === 0) {
return [{root: this.term, tags: this.tags, rules: []}];
return [{root: this.term, rules: this.rules, reasons: []}];
}
const paths = [];
for (const child of this.children) {
for (const path of child.gather()) {
if (this.rule.length > 0) {
path.rules.push(this.rule);
if (this.reason.length > 0) {
path.reasons.push(this.reason);
}
path.source = this.term;
@ -110,15 +110,15 @@ class Deinflection {
class Deinflector {
constructor() {
this.rules = {};
this.reasons = {};
}
setRules(rules) {
this.rules = rules;
setReasons(reasons) {
this.reasons = reasons;
}
deinflect(term, validator) {
const node = new Deinflection(term);
return node.deinflect(validator, this.rules).then(success => success ? node.gather() : []);
return node.deinflect(validator, this.reasons).then(success => success ? node.gather() : []);
}
}

View File

@ -66,11 +66,11 @@ templates['kanji.html'] = template({"1":function(container,depth0,helpers,partia
var helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
return " <span class=\"tag tag-"
+ alias4(((helper = (helper = helpers["class"] || (depth0 != null ? depth0["class"] : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"class","hash":{},"data":data}) : helper)))
+ alias4(((helper = (helper = helpers.category || (depth0 != null ? depth0.category : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"category","hash":{},"data":data}) : helper)))
+ "\" title=\""
+ alias4(((helper = (helper = helpers.desc || (depth0 != null ? depth0.desc : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"desc","hash":{},"data":data}) : helper)))
+ alias4(((helper = (helper = helpers.notes || (depth0 != null ? depth0.notes : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"notes","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ alias4(((helper = (helper = helpers.tag || (depth0 != null ? depth0.tag : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"tag","hash":{},"data":data}) : helper)))
+ "</span>\n";
},"8":function(container,depth0,helpers,partials,data) {
return " <li><span>"
@ -190,11 +190,11 @@ templates['term.html'] = template({"1":function(container,depth0,helpers,partial
var helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
return " <span class=\"tag tag-"
+ alias4(((helper = (helper = helpers["class"] || (depth0 != null ? depth0["class"] : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"class","hash":{},"data":data}) : helper)))
+ alias4(((helper = (helper = helpers.category || (depth0 != null ? depth0.category : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"category","hash":{},"data":data}) : helper)))
+ "\" title=\""
+ alias4(((helper = (helper = helpers.desc || (depth0 != null ? depth0.desc : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"desc","hash":{},"data":data}) : helper)))
+ alias4(((helper = (helper = helpers.notes || (depth0 != null ? depth0.notes : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"notes","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ alias4(((helper = (helper = helpers.tag || (depth0 != null ? depth0.tag : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"tag","hash":{},"data":data}) : helper)))
+ "</span>\n";
},"15":function(container,depth0,helpers,partials,data) {
return " <li><span>"

View File

@ -20,7 +20,7 @@
class Translator {
constructor() {
this.loaded = false;
this.tagMeta = null;
this.ruleMeta = null;
this.database = new Database();
this.deinflector = new Deinflector();
}
@ -31,21 +31,21 @@ class Translator {
}
const promises = [
loadJsonInt('bg/data/rules.json'),
loadJsonInt('bg/data/reasons.json'),
this.database.prepare()
];
return Promise.all(promises).then(([rules]) => {
this.deinflector.setRules(rules);
return Promise.all(promises).then(([reasons]) => {
this.deinflector.setReasons(reasons);
this.loaded = true;
});
}
findTerm(text, dictionaries, enableSoftKatakanaSearch) {
return this.findTermGroups(text, dictionaries).then(groups => {
return this.findDeinflectGroups(text, dictionaries).then(groups => {
const textHiragana = wanakana._katakanaToHiragana(text);
if (text !== textHiragana && enableSoftKatakanaSearch) {
return this.findTermGroups(textHiragana, dictionaries).then(groupsHiragana => {
return this.findDeinflectGroups(textHiragana, dictionaries).then(groupsHiragana => {
for (const key in groupsHiragana) {
groups[key] = groups[key] || groupsHiragana[key];
}
@ -87,25 +87,27 @@ class Translator {
return Promise.all(promises).then(sets => this.processKanji(sets.reduce((a, b) => a.concat(b), [])));
}
findTermGroups(text, dictionaries) {
findDeinflectGroups(text, dictionaries) {
const deinflectGroups = {};
const deinflectPromises = [];
for (let i = text.length; i > 0; --i) {
deinflectPromises.push(
this.deinflector.deinflect(text.slice(0, i), term => {
return this.database.findTerm(term, dictionaries).then(definitions => definitions.map(definition => definition.tags));
return this.database.findTerm(term, dictionaries).then(definitions => definitions.map(definition => definition.rules));
}).then(deinflects => {
const processPromises = [];
for (const deinflect of deinflects) {
processPromises.push(this.processTerm(
processPromises.push(
this.processDeinflection(
deinflectGroups,
deinflect.source,
deinflect.tags,
deinflect.rules,
deinflect.reasons,
deinflect.root,
dictionaries
));
)
);
}
return Promise.all(processPromises);
@ -116,16 +118,16 @@ class Translator {
return Promise.all(deinflectPromises).then(() => deinflectGroups);
}
processTerm(groups, source, tags, rules, root, dictionaries) {
processDeinflection(groups, source, rules, reasons, root, dictionaries) {
return this.database.findTerm(root, dictionaries).then(definitions => {
for (const definition of definitions) {
if (definition.id in groups) {
continue;
}
let matched = tags.length === 0;
for (const tag of tags) {
if (definition.tags.includes(tag)) {
let matched = rules.length === 0;
for (const rule of rules) {
if (definition.rules.includes(rule)) {
matched = true;
break;
}
@ -138,26 +140,20 @@ class Translator {
const tagItems = [];
for (const tag of definition.tags) {
const tagItem = {
name: tag,
class: 'default',
tag,
category: 'default',
order: Number.MAX_SAFE_INTEGER,
score: 0,
desc: definition.entities[tag] || '',
notes: ''
};
applyTagMeta(tagItem, this.tagMeta);
applyTagMeta(tagItem, definition.tagMeta);
tagItems.push(tagItem);
}
let score = 0;
for (const tagItem of tagItems) {
score += tagItem.score;
}
groups[definition.id] = {
score,
source,
rules,
reasons,
score: definition.score,
expression: definition.expression,
reading: definition.reading,
glossary: definition.glossary,
@ -172,13 +168,13 @@ class Translator {
const tagItems = [];
for (const tag of definition.tags) {
const tagItem = {
name: tag,
class: 'default',
tag,
category: 'default',
order: Number.MAX_SAFE_INTEGER,
desc: '',
notes: ''
};
applyTagMeta(tagItem, this.tagMeta);
applyTagMeta(tagItem, definition.tagMeta);
tagItems.push(tagItem);
}

View File

@ -84,8 +84,8 @@ function sortTermDefs(definitions) {
return 1;
}
const rl1 = v1.rules.length;
const rl2 = v2.rules.length;
const rl1 = v1.reasons.length;
const rl2 = v2.reasons.length;
if (rl1 < rl2) {
return -1;
} else if (rl1 > rl2) {

View File

@ -30,7 +30,7 @@
<div class="kanji-tags">
{{#each tags}}
<span class="tag tag-{{class}}" title="{{desc}}">{{name}}</span>
<span class="tag tag-{{category}}" title="{{notes}}">{{tag}}</span>
{{/each}}
</div>

View File

@ -23,7 +23,7 @@
<div class="term-tags">
{{#each tags}}
<span class="tag tag-{{class}}" title="{{desc}}">{{name}}</span>
<span class="tag tag-{{category}}" title="{{notes}}">{{tag}}</span>
{{/each}}
</div>