aboutsummaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/base.ts10
-rw-r--r--api/sentence.ts44
-rw-r--r--api/word.ts76
-rw-r--r--api/yomikun.ts14
4 files changed, 104 insertions, 40 deletions
diff --git a/api/base.ts b/api/base.ts
index e89e76b..28940ef 100644
--- a/api/base.ts
+++ b/api/base.ts
@@ -1,18 +1,12 @@
-import Core from "../core/api.ts";
import Yomikun from "./yomikun.ts";
/** @summary generic class that keeps a reference to parent API reference */
export default abstract class APIBase {
private _resolveAPI: (api: Yomikun) => void = _ => {};
-
- protected api: Promise<Yomikun>;
-
- constructor() {
- this.api = new Promise<Yomikun>(res => this._resolveAPI = res);
- }
+ protected api = new Promise<Yomikun>(res => this._resolveAPI = res);
/** @summary set API reference and return self (for use directly after constructor) */
- withParent(api: Yomikun) {
+ withAPI(api: Yomikun) {
this._resolveAPI(api);
return this;
}
diff --git a/api/sentence.ts b/api/sentence.ts
index 6b1a1e4..2311913 100644
--- a/api/sentence.ts
+++ b/api/sentence.ts
@@ -10,8 +10,8 @@ export default class Sentence extends APIBase {
protected breaks: Array<number> = [];
protected frozen = false;
- public ready: Promise<void>;
private _resolveReady: () => void = () => {};
+ public ready = new Promise<void>(res => this._resolveReady = res);
constructor(input: string) {
super();
@@ -20,7 +20,7 @@ export default class Sentence extends APIBase {
}
first(searchValue: RegExp | string): Word | undefined {
- return this.words[0]; // TODO: implement
+ return this.at(this.original.search(searchValue));
}
private async fetch() {
@@ -28,11 +28,15 @@ export default class Sentence extends APIBase {
}
private async updateWords() {
- this.words.clear();
+ this.words = [];
let token = 0;
let i = 0;
while (i < this.original.length) {
- this.words.push(new Word(this.query!.words[token]).withParent(await this.api));
+ this.words.push(
+ new Word(this.query!.words[token])
+ .withAPI(await this.api)
+ .withParent(this)
+ );
i += this.query!.words[token].source.length;
if (i == this.original.length) break;
@@ -42,7 +46,11 @@ export default class Sentence extends APIBase {
if (this.query!.words[token]?.start == i) continue;
var remainder = this.original.substring(i, this.query!.words[token]?.start);
- this.words.push(new Word(remainder).withParent(await this.api));
+ this.words.push(
+ new Word(remainder)
+ .withAPI(await this.api)
+ .withParent(this)
+ );
i += remainder.length;
}
}
@@ -53,8 +61,7 @@ export default class Sentence extends APIBase {
}, "");
}
- public async update() {
- if (this.frozen) return;
+ public async forceUpdate() {
// unresolve ready
this.ready = new Promise(res => this._resolveReady = res);
@@ -65,12 +72,29 @@ export default class Sentence extends APIBase {
// mark ready again
this._resolveReady();
+ }
+
+ public async update() {
+ if (this.frozen) return;
+ await this.forceUpdate();
}
- public at(term: string) {
- return this.original.indexOf(term);
+ public indexOf(searchString: string, position: number = 0) {
+ return this.original.indexOf(searchString, position);
}
+ public at(indentifier: number | string): Word | undefined {
+ var index = typeof indentifier === "number" ? indentifier : this.indexOf(indentifier);
+ if (index == -1) return;
+ let wordIndex = 0;
+ for (let i = 0; wordIndex < this.words.length; wordIndex++) {
+ var length = this.words[wordIndex].length;
+ if (i + length > index) break;
+ i += length;
+ }
+ return this.words[wordIndex];
+ }
+
public async break(location: number) {
this.breaks.push(location);
await this.update();
@@ -82,6 +106,6 @@ export default class Sentence extends APIBase {
public async unfreeze() {
this.frozen = false;
- await this.update();
+ await this.forceUpdate();
}
}
diff --git a/api/word.ts b/api/word.ts
index 2e07c98..b519789 100644
--- a/api/word.ts
+++ b/api/word.ts
@@ -6,33 +6,33 @@ import "../util/object.ts";
import { Tag, TagGroup, TokenTags } from "../search/tags.ts";
import { SearchWord } from "../search/types.ts";
import { recursiveValues } from "../util/object.ts";
+import Sentence from "./sentence.ts";
+
+// TODO: better irregular reading handling (should also work for counter words / 入る)
// irregular stems taken from <https://en.wikipedia.org/wiki/Japanese_irregular_verbs#suru_and_kuru>
-function irregularSuruStem(tags: TokenTags): string {
+function irregularSuru(tags: TokenTags, conjugation: string): string {
for (let i = 0, tag = tags[i]; i < tags.length; i++, tag = tags[i]) {
if (!recursiveValues(Tag.Inflection).includes(tag)) continue;
if (recursiveValues(Tag.Inflection.Reason).includes(tag)) continue;
if ([
Tag.Inflection.Polite.Masu,
Tag.Inflection.Suffix.Te,
- Tag.Inflection.Tense.Past,
Tag.Inflection.Desirable.Itai, // part of Wikipedia's -ta form
- Tag.Inflection.Negative,
- Tag.Inflection.Desirable.Volitional,
Tag.Inflection.Command,
- ].includes(tag as any)) return "し";
+ ].includes(tag as any)) return "し" + conjugation;
if ([
Tag.Inflection.Passive,
Tag.Inflection.Causative,
- ].includes(tag as any)) return "さ";
+ ].includes(tag as any)) return "さ" + conjugation;
// wikipedia has できる as the potential form for する, but できる here
// means it's already foobar'd
break;
}
- return "す";
+ return conjugation;
}
-function irregularKuruStem(tags: TokenTags): string {
+function irregularKuru(tags: TokenTags, conjugation: string): string {
for (let i = 0, tag = tags[i]; i < tags.length; i++, tag = tags[i]) {
if (!recursiveValues(Tag.Inflection).includes(tag)) continue;
if (recursiveValues(Tag.Inflection.Reason).includes(tag)) continue;
@@ -41,7 +41,7 @@ function irregularKuruStem(tags: TokenTags): string {
Tag.Inflection.Suffix.Te,
Tag.Inflection.Tense.Past,
Tag.Inflection.Desirable.Itai, // part of Wikipedia's -ta form
- ].includes(tag as any)) return "き";
+ ].includes(tag as any)) return "き" + conjugation;
if ([
Tag.Inflection.Negative,
Tag.Inflection.Desirable.Volitional,
@@ -49,10 +49,10 @@ function irregularKuruStem(tags: TokenTags): string {
Tag.Inflection.Causative,
Tag.Inflection.Potential,
Tag.Inflection.Command,
- ].includes(tag as any)) return "こ";
+ ].includes(tag as any)) return "こ" + conjugation;
break;
}
- return "く";
+ return "く" + conjugation;
}
export default class Word extends APIBase {
@@ -60,11 +60,22 @@ export default class Word extends APIBase {
protected base: Japanese;
/** @prop word as written in parent sentence */
protected text: Japanese;
- /** @prop this.furigana should output kanji with reading */
- protected outputKanji: boolean = true;
/** @prop this word represents an unrecognized sentence part between recognized terms */
protected filler: boolean;
+ private _resolveParent: (sentence: Sentence) => void = _ => {};
+ /** @prop parent sentence */
+ protected parent = new Promise<Sentence>(res => this._resolveParent = res);
+
+ /** @prop length of word in sentence */
+ public length: number;
+ /** @prop (conjugated) writing of term (*may* contain kanji) */
+ public writing: string;
+ /** @prop (conjugated) reading of term (kana-only) */
+ public reading: string;
+ /** @prop dictionary id for term */
+ public id: number = -1;
+
constructor(input: string | SearchWord) {
super();
if (typeof input === "string") {
@@ -72,7 +83,6 @@ export default class Word extends APIBase {
input = input as string;
this.base = new Japanese(input, input);
this.text = this.base;
- this.outputKanji = false;
} else {
this.filler = false;
input = input as SearchWord;
@@ -87,26 +97,50 @@ export default class Word extends APIBase {
// special reading for irregular verbs
var reading = input.reading;
- if (input.writing == '来る') reading = irregularKuruStem(input.tags) + conjugation;
- else if (input.writing == '為る') reading = irregularSuruStem(input.tags) + conjugation;
+ if (input.writing == '来る') reading = irregularKuru(input.tags, conjugation);
+ else if (input.writing == '為る') reading = irregularSuru(input.tags, conjugation);
else reading = reading.replaceLast(base, conjugation);
// generate conjugated version of verb with kanji
- this.text = new Japanese(input.writing.replaceLast(base, conjugation), reading);
+ this.text = new Japanese(input.source, reading);
} else {
this.text = this.base;
}
- this.outputKanji = input.source.hasKanji(); // only output kanji if input also uses kanji
+ this.id = input.id;
}
+ this.writing = this.text.writing;
+ this.length = this.text.writing.length;
+ this.reading = this.text.reading;
}
furigana(format: JapaneseFormatter) {
- if (!this.outputKanji) return this.text.reading;
- else return this.text.furigana(format);
+ return this.text.furigana(format);
}
async glossary() {
// TODO: output nothing if this.filler == true
- return new Glossary().withParent(await this.api);
+ return new Glossary().withAPI(await this.api);
}
+
+ /** @summary check if this word is written as ~ */
+ public written(as: string) {
+ return this.text.writing == as || this.base.writing == as;
+ }
+
+ /** @summary check if this word is read as ~ */
+ public read(as: string) {
+ return this.text.reading == as || this.base.reading == as;
+ }
+
+ /** @summary ignore this word for currently logged in user and refresh the sentence */
+ async ignore() {
+ await (await this.api)["setTermPriority"](this.base.writing, this.base.reading, -1);
+ await (await this.parent).update();
+ }
+
+ /** @summary set parent sentence for this word */
+ public withParent(parent: Sentence) {
+ this._resolveParent(parent);
+ return this;
+ }
}
diff --git a/api/yomikun.ts b/api/yomikun.ts
index 696361f..2b102fe 100644
--- a/api/yomikun.ts
+++ b/api/yomikun.ts
@@ -4,6 +4,9 @@ import Sentence from "./sentence.ts";
export default class Yomikun {
protected core: Core;
+ protected user: string = "root";
+ protected uid: number = 0;
+
public ready: Promise<void>;
constructor(core?: Core) {
@@ -16,9 +19,18 @@ export default class Yomikun {
}
async sentence(input: string): Promise<Sentence> {
- var sentence = new Sentence(input).withParent(this);
+ var sentence = new Sentence(input).withAPI(this);
await sentence.ready;
return sentence;
}
+
+ public su(user: string) {
+ this.user = user;
+ // TODO: set this.uid
+ }
+
+ private async setTermPriority(expression: string, reading: string, priority: number) {
+ this.core.user.termPriority(this.uid, expression, reading, priority);
+ }
}