From 90701914d065512f20a2818278cccc0d1f921bdb Mon Sep 17 00:00:00 2001 From: wareya Date: Sun, 4 Nov 2018 06:56:12 -0500 Subject: [PATCH] add support for importing a new deconjugator ruleset and overriding the built-in one --- background-script.js | 285 +---------- dict/deconjugator.json | 1020 ++++++++++++++++++++++++++++++++++++++++ manifest.json | 1 + options.html | 4 - options.js | 50 +- 5 files changed, 1093 insertions(+), 267 deletions(-) create mode 100644 dict/deconjugator.json diff --git a/background-script.js b/background-script.js index 42a9f88..8adcf9f 100644 --- a/background-script.js +++ b/background-script.js @@ -7,7 +7,8 @@ let settings = { reader_width: 800, -reader_height: 300 +reader_height: 300, +deconjugator_rules_json: "", }; async function settings_init() @@ -23,6 +24,7 @@ async function settings_init() } getvar("reader_width", 800); getvar("reader_height", 300); + getvar("deconjugator_rules_json", ""); } catch(err) {} // options not stored yet } @@ -350,263 +352,25 @@ function search(text) // deconjugation rules let rules = []; -// TODO: load rules from an underlay +function load_deconjugation_rules(filename) +{ + let req = new XMLHttpRequest(); + req.addEventListener("load", () => + { + if (req.readyState === 4) + { + if (req.status === 200) + rules = JSON.parse(req.responseText); + else + console.error(req.statusText); + } + }); + req.open("GET", browser.extension.getURL(filename)); + req.send(); + return req; +} -//////////////////// -// verb stems -//////////////////// - -// "e" stem used for potential and ba -rules.push({type: "neverfinalrule" -, dec_end: -["く","す","つ","う","る","ぐ","ぶ","ぬ","む","る","う","く"] -, con_end: -["け","せ","て","え","れ","げ","べ","ね","め","れ","え","け"] -, dec_tag: -["v5k","v5s","v5t","v5u","v5r","v5g","v5b","v5n","v5m","v1","v5u-s","v5k-s"] -, con_tag:"stem-izenkei", detail:"(izenkei)"}); -// the potential of v5r-i verbs does not use a simple e ending, it uses the ren'youkei (infinitive) followed by える, thus ありえる -rules.push({type: "neverfinalrule", dec_end:"る", con_end:"れ", dec_tag: "v5r-i", con_tag:"stem-e", detail:"(izenkei)"}); -rules.push({type: "neverfinalrule", dec_end:"", con_end:"", dec_tag: "stem-izenkei", con_tag:"stem-e", detail:""}); - -// true imperative -rules.push({type: "onlyfinalrule" -, dec_end: -["く","す","つ","う","る","る","ぐ","ぶ","ぬ","む","る","る","う","く"] -, con_end: -["け","せ","て","え","れ","れ","げ","べ","ね","め","ろ","よ","え","け"] // ichidan has two imperatives FIXME: don't let potential conjugate to よ -, dec_tag: -["v5k","v5s","v5t","v5u","v5r","v5r-i","v5g","v5b","v5n","v5m","v1","v1","v5u-s","v5k-s"] -, con_tag:"uninflectable", detail:"imperative"}); - -// ~a stem -rules.push({type: "neverfinalrule" -, dec_end: -["く","す","つ","う","る","ぐ","ぶ","ぬ","む","う","く"] -, con_end: -["か","さ","た","わ","ら","が","ば","な","ま","わ","か"] -, dec_tag: -["v5k","v5s","v5t","v5u","v5r","v5g","v5b","v5n","v5m","v5u-s","v5k-s"] // TODO: support あらへん, あらぬ, etc -, con_tag:"stem-a", detail:"('a' stem)"}); - -// unvoiced past stems -rules.push({type: "neverfinalrule" -, dec_end: -["く","す","つ","う","る","る","る","う","く"] -, con_end: -["い","し","っ","っ","っ","っ","","う","っ"] -, dec_tag: -["v5k","v5s","v5t","v5u","v5r","v5r-i","v1","v5u-s","v5k-s"] -, con_tag:"stem-ren-less", detail:"(unstressed infinitive)"}); -// voiced past stems -rules.push({type: "neverfinalrule" -, dec_end: -["ぐ","ぶ","ぬ","む"] -, con_end: -["い","ん","ん","ん"] -, dec_tag: -["v5g","v5b","v5n","v5m"] -, con_tag:"stem-ren-less-v", detail:"(unstressed infinitive)"}); - -// infinitives (ren'youkei) that are different than the corresponding past stem -rules.push({type: "stdrule" -, dec_end: -["く","つ","う","る","る","ぐ","ぶ","ぬ","む","う","く"] -, con_end: -["き","ち","い","り","り","ぎ","び","に","み","い","き"] -, dec_tag: -["v5k","v5t","v5u","v5r","v5r-i","v5g","v5b","v5n","v5m","v5u-s","v5k-s"] -, con_tag:"stem-ren", detail:"(infinitive)"}); -// ones that need the te trap -rules.push({type: "contextrule", contextrule:"tetrap" -, dec_end: -["す","る"] -, con_end: -["し",""] -, dec_tag: -["v5s","v1"] -, con_tag:"stem-ren", detail:"(infinitive)"}); - -// stem for negatives proper -rules.push({type: "neverfinalrule" -, dec_end: -["","る"] -, con_end: -["",""] -, dec_tag: -["stem-a","v1"] -, con_tag:"stem-mizenkei", detail:"(mizenkei)"}); - -// ~a stem -rules.push({type: "stdrule" -, dec_end: -["く","す","つ","う","る","る","ぐ","ぶ","ぬ","む","る","う","く"] -, con_end: -["こう","そう","とう","おう","ろう","ろう","ごう","ぼう","のう","もう","よう","おう","こう"] -, dec_tag: -["v5k","v5s","v5t","v5u","v5r","v5r-i","v5g","v5b","v5n","v5m","v1","v5u-s","v5k-s"] -, con_tag:"form-volition", detail:"volitional"}); - -//////////////////// -// adjective stems -//////////////////// - -rules.push({type: "stdrule", dec_end:"い", con_end:"く", dec_tag:"adj-i", con_tag:"stem-ku", detail:"(adverbial stem)"}); -rules.push({type: "stdrule", dec_end:"い", con_end:"か", dec_tag:"adj-i", con_tag:"stem-ka", detail:"(ka stem)"}); -rules.push({type: "stdrule", dec_end:"い", con_end:"け", dec_tag:"adj-i", con_tag:"stem-ke", detail:"(ke stem)"}); -rules.push({type: "stdrule", dec_end:"い", con_end:"", dec_tag:"adj-i", con_tag:"stem-adj-base", detail:"(stem)"}); - -// TODO move these -// Forms based on the bare adjective stem -rules.push({type: "stdrule", dec_end:"", con_end:"すぎる", dec_tag:"stem-adj-base", con_tag:"v1", detail:"excess"}); -rules.push({type: "stdrule", dec_end:"", con_end:"そう", dec_tag:"stem-adj-base", con_tag:"adj-na", detail:"seemingness"}); -rules.push({type: "stdrule", dec_end:"", con_end:"がる", dec_tag:"stem-adj-base", con_tag:"v5r", detail:"garu"}); -rules.push({type: "stdrule", dec_end:"", con_end:"さ", dec_tag:"stem-adj-base", con_tag:"n", detail:"noun form"}); - -//////////////////// -// common forms -//////////////////// - -// rules.push({type: "stdrule", dec_end:"", con_end:"た", dec_tag:"stem-ren", con_tag:"stem-past", detail:"past"}); // unusual but real but don't necessarily want it yet -rules.push({type: "stdrule", dec_end:"", con_end:"た", dec_tag:"stem-ren-less", con_tag:"stem-past", detail:"past"}); -rules.push({type: "stdrule", dec_end:"", con_end:"だ", dec_tag:"stem-ren-less-v", con_tag:"stem-past", detail:"past"}); -// rules.push({type: "stdrule", dec_end:"", con_end:"て", dec_tag:"stem-ren", con_tag:"stem-te", detail:"(te form)"}); // unusual but real but don't necessarily want it yet -rules.push({type: "stdrule", dec_end:"", con_end:"った", dec_tag:"stem-ka", con_tag:"stem-past", detail:"past"}); - -// we may want some te forms to only apply to verbs, not adjectives -// FIXME: need a way to not break ~ないでください, ~ないでいく, etc before we actually do it -rules.push({type: "stdrule", dec_end:"", con_end:"て", dec_tag:"stem-ren-less", con_tag:"stem-te-verbal", detail:"(te form)"}); -rules.push({type: "stdrule", dec_end:"", con_end:"で", dec_tag:"stem-ren-less-v", con_tag:"stem-te-verbal", detail:"(te form)"}); -// tag alias -rules.push({type: "stdrule", dec_end:"", con_end:"", dec_tag:"stem-te-verbal", con_tag:"stem-te", detail:""}); -// now the te form for adjectives -// adjectives have two te forms, one of which is not used synthetically -rules.push({type: "stdrule", dec_end:"", con_end:"で", dec_tag:"adj-i", con_tag:"stem-te", detail:"(te form)"}); -rules.push({type: "stdrule", dec_end:"", con_end:"で", dec_tag:"stem-ku", con_tag:"stem-te-defective", detail:"(te form)"}); - -// doesn't have anywhere else to go -rules.push({type: "rewriterule", dec_end:"です", con_end:"でした", dec_tag:"exp", con_tag:"stem-past", detail:"past"}); -rules.push({type: "rewriterule", dec_end:"です", con_end:"でして", dec_tag:"exp", con_tag:"stem-te-verbal", detail:"(te form)"}); -// TODO: add te form of です? or would it be too confusing to have? -// e.g. it would let people find "でしている" in "自分でしている" as です instead of で + conjugated する - -// negatives -rules.push({type: "contextrule", contextrule: "adjspecial", dec_end:"", con_end:"ない", dec_tag:"stem-mizenkei", con_tag:"adj-i", detail:"negative"}); -rules.push({type: "stdrule", dec_end:"", con_end:"ん", dec_tag:"stem-mizenkei", con_tag:"adj-i", detail:"slurred negative"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ず", dec_tag:"stem-mizenkei", con_tag:"uninflectable", detail:"adverbial negative"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ずに", dec_tag:"stem-mizenkei", con_tag:"uninflectable", detail:"without doing so"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ぬ", dec_tag:"stem-mizenkei", con_tag:"uninflectable", detail:"archaic negative"}); - -rules.push({type: "contextrule", contextrule: "adjspecial", dec_end:"", con_end:"ない", dec_tag:"stem-ku", con_tag:"adj-i", detail:"negative"}); - -// special negative inflections where the intermediate stage (e.g. 赤くある) is not a synthetic phrase like the end result (e.g. 赤くありません) is -// FIXME: don't allow conjugating ~ない to this? -rules.push({type: "stdrule", dec_end:"", con_end:"ありません", dec_tag:"stem-ku", con_tag:"uninflectable", detail:"formal negative"}); -rules.push({type: "stdrule", dec_end:"", con_end:"ありませんでした", dec_tag:"stem-ku", con_tag:"uninflectable", detail:"formal negative past"}); - - -// masu and its conjugations (allowing it to conjugate recursively causes problems because its grammar is unlike typical declarative verbs) -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ます", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"polite"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ません", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"negative polite"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ました", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"past polite"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"まして", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"te polite"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ませんでした", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"past negative polite"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ましょう", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"polite volitional"}); - -//////////////////// -// conditional forms -//////////////////// - -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"たら", dec_tag:"stem-ren-less", con_tag:"uninflectable", detail:"conditional"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"だら", dec_tag:"stem-ren-less-v", con_tag:"uninflectable", detail:"conditional"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ったら", dec_tag:"stem-ka", con_tag:"uninflectable", detail:"conditional"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"たらば", dec_tag:"stem-ren-less", con_tag:"uninflectable", detail:"formal conditional"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"だらば", dec_tag:"stem-ren-less-v", con_tag:"uninflectable", detail:"formal conditional"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ったらば", dec_tag:"stem-ka", con_tag:"uninflectable", detail:"formal conditional"}); - -rules.push({type: "stdrule", dec_end:"", con_end:"ば", dec_tag:"stem-e", con_tag:"uninflectable", detail:"provisional conditional"}); -rules.push({type: "stdrule", dec_end:"", con_end:"れば", dec_tag:"stem-ke", con_tag:"uninflectable", detail:"provisional conditional"}); - -//////////////////// -// non-analytical forms -//////////////////// - -//passive and potential -rules.push({type: "stdrule", dec_end:"", con_end:"る", dec_tag:"stem-izenkei", con_tag:"v1", detail:"potential"}); // FIXME don't allow to attach to the short causative -rules.push({type: "stdrule", dec_end:"る", con_end:"りえる", dec_tag:"v5r-i", con_tag:"v1", detail:"potential"}); // v5r-i verbs have an irregular potential -// note: ichidan (i.e. v1) verbs cannot conjugate to stem-a -rules.push({type: "stdrule", dec_end:"", con_end:"れる", dec_tag:"stem-a", con_tag:"v1", detail:"passive"}); -rules.push({type: "stdrule", dec_end:"る", con_end:"られる", dec_tag:"v1", con_tag:"v1", detail:"passive/potential"}); - -// causative -rules.push({type: "stdrule", dec_end:"", con_end:"せる", dec_tag:"stem-a", con_tag:"v1", detail:"causative"}); -rules.push({type: "stdrule", dec_end:"る", con_end:"させる", dec_tag:"v1", con_tag:"v1", detail:"causative"}); -rules.push({type: "contextrule", contextrule: "saspecial", dec_end:"", con_end:"す", dec_tag:"stem-a", con_tag:"v5s", detail:"short causative"}); - -//////////////////// -// te-based forms -//////////////////// - -// mere te auxiliaries -rules.push({type: "stdrule", dec_end:"", con_end:"しまう", dec_tag:"stem-te", con_tag:"v5u", detail:"finish/completely/end up"}); -// personal te auxiliaries -rules.push({type: "stdrule", dec_end:"", con_end:"ください", dec_tag:"stem-te", con_tag:"adj-i", detail:"polite request"}); -rules.push({type: "stdrule", dec_end:"", con_end:"あげる", dec_tag:"stem-te", con_tag:"v5r", detail:"do for someone"}); -// grammatical aspect forms -// FIXME: add the てる とる etc. conjugations; though the てる conjugation needs a bunch of annoying traps -rules.push({type: "stdrule", dec_end:"", con_end:"いる", dec_tag:"stem-te", con_tag:"v1", detail:"teiru"}); -rules.push({type: "stdrule", dec_end:"", con_end:"おる", dec_tag:"stem-te", con_tag:"v5r", detail:"teoru"}); -rules.push({type: "stdrule", dec_end:"", con_end:"ある", dec_tag:"stem-te", con_tag:"v5r-i", detail:"tearu"}); -rules.push({type: "stdrule", dec_end:"", con_end:"いく", dec_tag:"stem-te", con_tag:"v5k-s", detail:"teiku"}); -rules.push({type: "stdrule", dec_end:"", con_end:"くる", dec_tag:"stem-te", con_tag:"vk", detail:"tekuru"}); -rules.push({type: "stdrule", dec_end:"", con_end:"おく", dec_tag:"stem-te", con_tag:"v5k", detail:"for now"}); -// nonverbal functions of the te form -rules.push({type: "stdrule", dec_end:"", con_end:"は", dec_tag:"stem-te", con_tag:"uninflectable", detail:"topic"}); -rules.push({type: "stdrule", dec_end:"", con_end:"は", dec_tag:"stem-te-defective", con_tag:"uninflectable", detail:"topic"}); -// TODO: ても too? - -//////////////////// -// ren'youkei based forms -//////////////////// - -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"なさい", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"kind request"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"な", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"casual kind request"}); - -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ながら", dec_tag:"stem-ren", con_tag:"uninflectable", detail:"while"}); - -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"たり", dec_tag:"stem-ren-less", con_tag:"uninflectable", detail:"tari"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"だり", dec_tag:"stem-ren-less-v", con_tag:"uninflectable", detail:"tari"}); -rules.push({type: "onlyfinalrule", dec_end:"", con_end:"ったり", dec_tag:"stem-ka", con_tag:"uninflectable", detail:"tari"}); - -rules.push({type: "contextrule", contextrule:"adjspecial", dec_end:"", con_end:"たい", dec_tag:"stem-ren", con_tag:"adj-i", detail:"want"}); - -rules.push({type: "stdrule", dec_end:"", con_end:"すぎる", dec_tag:"stem-ren", con_tag:"v1", detail:"too much"}); - -//////////////////// -// transparent contractions -//////////////////// -rules.push({type: "stdrule", dec_end:"てしまう", con_end:"ちゃう", dec_tag:"v5u", con_tag:"v5u", detail:"(contraction)"}); -rules.push({type: "stdrule", dec_end:"でしまう", con_end:"じゃう", dec_tag:"v5u", con_tag:"v5u", detail:"(contraction)"}); -rules.push({type: "stdrule", dec_end:"てしまう", con_end:"ちまう", dec_tag:"v5u", con_tag:"v5u", detail:"(contraction)"}); -rules.push({type: "stdrule", dec_end:"でしまう", con_end:"じまう", dec_tag:"v5u", con_tag:"v5u", detail:"(contraction)"}); - -rules.push({type: "stdrule", dec_end:"ては", con_end:"ちゃ", dec_tag:"stem-te", con_tag:"uninflectable", detail:"(contraction)"}); -rules.push({type: "stdrule", dec_end:"では", con_end:"じゃ", dec_tag:"stem-te", con_tag:"uninflectable", detail:"(contraction)"}); - -rules.push({type: "onlyfinalrule", dec_end:"ければ", con_end:"けりゃ", dec_tag:"uninflectable", con_tag:"uninflectable", detail:"(contraction)"}); -rules.push({type: "onlyfinalrule", dec_end:"ければ", con_end:"きゃ", dec_tag:"uninflectable", con_tag:"uninflectable", detail:"(contraction)"}); - -// other -rules.push({type: "onlyfinalrule", dec_end:"る", con_end:"ん", dec_tag:"v1", con_tag:"uninflectable", detail:"slurred"}); -rules.push({type: "onlyfinalrule", dec_end:"る", con_end:"ん", dec_tag:"v5r", con_tag:"uninflectable", detail:"slurred"}); -rules.push({type: "onlyfinalrule", dec_end:"る", con_end:"ん", dec_tag:"v5aru", con_tag:"uninflectable", detail:"slurred"}); -rules.push({type: "onlyfinalrule", dec_end:"る", con_end:"ん", dec_tag:"vk", con_tag:"uninflectable", detail:"slurred"}); // FIXME: ? - -// TODO: a bunch of missing contractions, vk, vs_i, v5aru, v4r, - -//rules.push({type: "stdrule", dec_end:"", con_end:"たい", dec_tag:"stem-ren", con_tag:"adj-i", detail:"want"}); - -// FIXME implement un-deconjugation to show the actual reading of the deconjugated word e.g. of 来る or 得る - this is what furigana rules are for +load_deconjugation_rules("dict/deconjugator.json"); // return deconjugated form if stdrule applies to form, return otherwise function stdrule_deconjugate_inner(my_form, my_rule) @@ -794,9 +558,10 @@ function deconjugate(mytext) let new_novel = new Set(); for(let form of novel) { - for(let i = 0; i < rules.length; i++) + for(let rule of rules) { - let rule = rules[i]; + if(!(rule instanceof Object)) + continue; let newform = rule_functions[rule.type](form, rule); @@ -821,7 +586,7 @@ function deconjugate(mytext) // takes deconjugated forms and looks them up in a dictionary // building a list of all matches -function build_lookup_comb (forms) +function build_lookup_comb(forms) { // FIXME: dumpster fire that shouldn't be anywhere near as complicated as I made it diff --git a/dict/deconjugator.json b/dict/deconjugator.json new file mode 100644 index 0000000..0c96425 --- /dev/null +++ b/dict/deconjugator.json @@ -0,0 +1,1020 @@ +[ + "This file is public domain data.", + "===verb stems===", + "'e' stem used for potential and ba", + { + "type": "neverfinalrule", + "dec_end": [ + "く", + "す", + "つ", + "う", + "る", + "ぐ", + "ぶ", + "ぬ", + "む", + "る", + "う", + "く" + ], + "con_end": [ + "け", + "せ", + "て", + "え", + "れ", + "げ", + "べ", + "ね", + "め", + "れ", + "え", + "け" + ], + "dec_tag": [ + "v5k", + "v5s", + "v5t", + "v5u", + "v5r", + "v5g", + "v5b", + "v5n", + "v5m", + "v1", + "v5u-s", + "v5k-s" + ], + "con_tag": "stem-izenkei", + "detail": "(izenkei)" + }, + "the potential of v5r-i verbs does not use a simple e ending, it uses the ren'youkei (infinitive) followed by える, thus ありえる", + { + "type": "neverfinalrule", + "dec_end": "る", + "con_end": "れ", + "dec_tag": "v5r-i", + "con_tag": "stem-e", + "detail": "(izenkei)" + }, + { + "type": "neverfinalrule", + "dec_end": "", + "con_end": "", + "dec_tag": "stem-izenkei", + "con_tag": "stem-e", + "detail": "" + }, + "true imperative", + { + "type": "onlyfinalrule", + "dec_end": [ + "く", + "す", + "つ", + "う", + "る", + "る", + "ぐ", + "ぶ", + "ぬ", + "む", + "る", + "る", + "う", + "く" + ], + "con_end": [ + "け", + "せ", + "て", + "え", + "れ", + "れ", + "げ", + "べ", + "ね", + "め", + "ろ", + "よ", + "え", + "け" + ], + "dec_tag": [ + "v5k", + "v5s", + "v5t", + "v5u", + "v5r", + "v5r-i", + "v5g", + "v5b", + "v5n", + "v5m", + "v1", + "v1", + "v5u-s", + "v5k-s" + ], + "con_tag": "uninflectable", + "detail": "imperative" + }, + "~a stem", + { + "type": "neverfinalrule", + "dec_end": [ + "く", + "す", + "つ", + "う", + "る", + "ぐ", + "ぶ", + "ぬ", + "む", + "う", + "く" + ], + "con_end": [ + "か", + "さ", + "た", + "わ", + "ら", + "が", + "ば", + "な", + "ま", + "わ", + "か" + ], + "dec_tag": [ + "v5k", + "v5s", + "v5t", + "v5u", + "v5r", + "v5g", + "v5b", + "v5n", + "v5m", + "v5u-s", + "v5k-s" + ], + "con_tag": "stem-a", + "detail": "('a' stem)" + }, + "unvoiced past stems", + { + "type": "neverfinalrule", + "dec_end": [ + "く", + "す", + "つ", + "う", + "る", + "る", + "る", + "う", + "く" + ], + "con_end": [ + "い", + "し", + "っ", + "っ", + "っ", + "っ", + "", + "う", + "っ" + ], + "dec_tag": [ + "v5k", + "v5s", + "v5t", + "v5u", + "v5r", + "v5r-i", + "v1", + "v5u-s", + "v5k-s" + ], + "con_tag": "stem-ren-less", + "detail": "(unstressed infinitive)" + }, + "voiced past stems", + { + "type": "neverfinalrule", + "dec_end": [ + "ぐ", + "ぶ", + "ぬ", + "む" + ], + "con_end": [ + "い", + "ん", + "ん", + "ん" + ], + "dec_tag": [ + "v5g", + "v5b", + "v5n", + "v5m" + ], + "con_tag": "stem-ren-less-v", + "detail": "(unstressed infinitive)" + }, + "infinitives (ren'youkei) that are different than the corresponding past stem", + { + "type": "stdrule", + "dec_end": [ + "く", + "つ", + "う", + "る", + "る", + "ぐ", + "ぶ", + "ぬ", + "む", + "う", + "く" + ], + "con_end": [ + "き", + "ち", + "い", + "り", + "り", + "ぎ", + "び", + "に", + "み", + "い", + "き" + ], + "dec_tag": [ + "v5k", + "v5t", + "v5u", + "v5r", + "v5r-i", + "v5g", + "v5b", + "v5n", + "v5m", + "v5u-s", + "v5k-s" + ], + "con_tag": "stem-ren", + "detail": "(infinitive)" + }, + "ones that need the te trap", + { + "type": "contextrule", + "contextrule": "tetrap", + "dec_end": [ + "す", + "る" + ], + "con_end": [ + "し", + "" + ], + "dec_tag": [ + "v5s", + "v1" + ], + "con_tag": "stem-ren", + "detail": "(infinitive)" + }, + "stem for negatives proper", + { + "type": "neverfinalrule", + "dec_end": [ + "", + "る" + ], + "con_end": [ + "", + "" + ], + "dec_tag": [ + "stem-a", + "v1" + ], + "con_tag": "stem-mizenkei", + "detail": "(mizenkei)" + }, + "volitional/hortative form", + { + "type": "stdrule", + "dec_end": [ + "く", + "す", + "つ", + "う", + "る", + "る", + "ぐ", + "ぶ", + "ぬ", + "む", + "る", + "う", + "く" + ], + "con_end": [ + "こう", + "そう", + "とう", + "おう", + "ろう", + "ろう", + "ごう", + "ぼう", + "のう", + "もう", + "よう", + "おう", + "こう" + ], + "dec_tag": [ + "v5k", + "v5s", + "v5t", + "v5u", + "v5r", + "v5r-i", + "v5g", + "v5b", + "v5n", + "v5m", + "v1", + "v5u-s", + "v5k-s" + ], + "con_tag": "form-volition", + "detail": "volitional" + }, + "===adjectives stems===", + { + "type": "stdrule", + "dec_end": "い", + "con_end": "く", + "dec_tag": "adj-i", + "con_tag": "stem-ku", + "detail": "(adverbial stem)" + }, + { + "type": "stdrule", + "dec_end": "い", + "con_end": "か", + "dec_tag": "adj-i", + "con_tag": "stem-ka", + "detail": "(ka stem)" + }, + { + "type": "stdrule", + "dec_end": "い", + "con_end": "け", + "dec_tag": "adj-i", + "con_tag": "stem-ke", + "detail": "(ke stem)" + }, + { + "type": "stdrule", + "dec_end": "い", + "con_end": "", + "dec_tag": "adj-i", + "con_tag": "stem-adj-base", + "detail": "(stem)" + }, + "Forms based on the bare adjective stem", + { + "type": "stdrule", + "dec_end": "", + "con_end": "すぎる", + "dec_tag": "stem-adj-base", + "con_tag": "v1", + "detail": "excess" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "そう", + "dec_tag": "stem-adj-base", + "con_tag": "adj-na", + "detail": "seemingness" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "がる", + "dec_tag": "stem-adj-base", + "con_tag": "v5r", + "detail": "garu" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "さ", + "dec_tag": "stem-adj-base", + "con_tag": "n", + "detail": "noun form" + }, + "===common forms===", + { + "type": "stdrule", + "dec_end": "", + "con_end": "た", + "dec_tag": "stem-ren-less", + "con_tag": "stem-past", + "detail": "past" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "だ", + "dec_tag": "stem-ren-less-v", + "con_tag": "stem-past", + "detail": "past" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "った", + "dec_tag": "stem-ka", + "con_tag": "stem-past", + "detail": "past" + }, + "we may want some te forms to only apply to verbs, not adjectives", + "FIXME: need a way to not break ~ないでください, ~ないでいく, etc before we actually do it", + { + "type": "stdrule", + "dec_end": "", + "con_end": "て", + "dec_tag": "stem-ren-less", + "con_tag": "stem-te-verbal", + "detail": "(te form)" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "で", + "dec_tag": "stem-ren-less-v", + "con_tag": "stem-te-verbal", + "detail": "(te form)" + }, + "tag alias", + { + "type": "stdrule", + "dec_end": "", + "con_end": "", + "dec_tag": "stem-te-verbal", + "con_tag": "stem-te", + "detail": "" + }, + "now the te form for adjectives", + "adjectives have two te forms, one of which is not used synthetically", + { + "type": "stdrule", + "dec_end": "", + "con_end": "で", + "dec_tag": "adj-i", + "con_tag": "stem-te", + "detail": "(te form)" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "で", + "dec_tag": "stem-ku", + "con_tag": "stem-te-defective", + "detail": "(te form)" + }, + "nowhere else to put this", + { + "type": "rewriterule", + "dec_end": "です", + "con_end": "でした", + "dec_tag": "exp", + "con_tag": "stem-past", + "detail": "past" + }, + { + "type": "rewriterule", + "dec_end": "です", + "con_end": "でして", + "dec_tag": "exp", + "con_tag": "stem-te-verbal", + "detail": "(te form)" + }, + "negatives", + { + "type": "contextrule", + "contextrule": "adjspecial", + "dec_end": "", + "con_end": "ない", + "dec_tag": "stem-mizenkei", + "con_tag": "adj-i", + "detail": "negative" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "ん", + "dec_tag": "stem-mizenkei", + "con_tag": "adj-i", + "detail": "slurred negative" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ず", + "dec_tag": "stem-mizenkei", + "con_tag": "uninflectable", + "detail": "adverbial negative" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ずに", + "dec_tag": "stem-mizenkei", + "con_tag": "uninflectable", + "detail": "without doing so" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ぬ", + "dec_tag": "stem-mizenkei", + "con_tag": "uninflectable", + "detail": "archaic negative" + }, + { + "type": "contextrule", + "contextrule": "adjspecial", + "dec_end": "", + "con_end": "ない", + "dec_tag": "stem-ku", + "con_tag": "adj-i", + "detail": "negative" + }, + "special negative inflections where the intermediate stage (e.g. 赤くある) is not a valid synthetic phrase like the end result (e.g. 赤くありません) is", + { + "type": "stdrule", + "dec_end": "", + "con_end": "ありません", + "dec_tag": "stem-ku", + "con_tag": "uninflectable", + "detail": "formal negative" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "ありませんでした", + "dec_tag": "stem-ku", + "con_tag": "uninflectable", + "detail": "formal negative past" + }, + "masu and its conjugations (allowing it to conjugate recursively causes problems because its grammar is unlike typical declarative verbs)", + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ます", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "polite" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ません", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "negative polite" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ました", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "past polite" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "まして", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "te polite" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ませんでした", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "past negative polite" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ましょう", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "polite volitional" + }, + "===conditional forms===", + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "たら", + "dec_tag": "stem-ren-less", + "con_tag": "uninflectable", + "detail": "conditional" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "だら", + "dec_tag": "stem-ren-less-v", + "con_tag": "uninflectable", + "detail": "conditional" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ったら", + "dec_tag": "stem-ka", + "con_tag": "uninflectable", + "detail": "conditional" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "たらば", + "dec_tag": "stem-ren-less", + "con_tag": "uninflectable", + "detail": "formal conditional" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "だらば", + "dec_tag": "stem-ren-less-v", + "con_tag": "uninflectable", + "detail": "formal conditional" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ったらば", + "dec_tag": "stem-ka", + "con_tag": "uninflectable", + "detail": "formal conditional" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "ば", + "dec_tag": "stem-e", + "con_tag": "uninflectable", + "detail": "provisional conditional" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "れば", + "dec_tag": "stem-ke", + "con_tag": "uninflectable", + "detail": "provisional conditional" + }, + "===non-analytical forms===", + "passive and potential", + { + "type": "stdrule", + "dec_end": "", + "con_end": "る", + "dec_tag": "stem-izenkei", + "con_tag": "v1", + "detail": "potential" + }, + { + "type": "stdrule", + "dec_end": "る", + "con_end": "りえる", + "dec_tag": "v5r-i", + "con_tag": "v1", + "detail": "potential" + }, + "note: ichidan (i.e. v1) verbs cannot conjugate to stem-a", + { + "type": "stdrule", + "dec_end": "", + "con_end": "れる", + "dec_tag": "stem-a", + "con_tag": "v1", + "detail": "passive" + }, + { + "type": "stdrule", + "dec_end": "る", + "con_end": "られる", + "dec_tag": "v1", + "con_tag": "v1", + "detail": "passive/potential" + }, + "causative", + { + "type": "stdrule", + "dec_end": "", + "con_end": "せる", + "dec_tag": "stem-a", + "con_tag": "v1", + "detail": "causative" + }, + { + "type": "stdrule", + "dec_end": "る", + "con_end": "させる", + "dec_tag": "v1", + "con_tag": "v1", + "detail": "causative" + }, + { + "type": "contextrule", + "contextrule": "saspecial", + "dec_end": "", + "con_end": "す", + "dec_tag": "stem-a", + "con_tag": "v5s", + "detail": "short causative" + }, + "===te-based forms===", + "mere te auxiliaries", + { + "type": "stdrule", + "dec_end": "", + "con_end": "しまう", + "dec_tag": "stem-te", + "con_tag": "v5u", + "detail": "finish/completely/end up" + }, + "personal te auxiliaries", + { + "type": "stdrule", + "dec_end": "", + "con_end": "ください", + "dec_tag": "stem-te", + "con_tag": "adj-i", + "detail": "polite request" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "あげる", + "dec_tag": "stem-te", + "con_tag": "v5r", + "detail": "do for someone" + }, + "grammatical aspect forms", + "FIXME: add the てる とる etc. conjugations; though the てる conjugation needs a bunch of annoying traps", + { + "type": "stdrule", + "dec_end": "", + "con_end": "いる", + "dec_tag": "stem-te", + "con_tag": "v1", + "detail": "teiru" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "おる", + "dec_tag": "stem-te", + "con_tag": "v5r", + "detail": "teoru" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "ある", + "dec_tag": "stem-te", + "con_tag": "v5r-i", + "detail": "tearu" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "いく", + "dec_tag": "stem-te", + "con_tag": "v5k-s", + "detail": "teiku" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "くる", + "dec_tag": "stem-te", + "con_tag": "vk", + "detail": "tekuru" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "おく", + "dec_tag": "stem-te", + "con_tag": "v5k", + "detail": "for now" + }, + "nonverbal functions of the te form", + { + "type": "stdrule", + "dec_end": "", + "con_end": "は", + "dec_tag": "stem-te", + "con_tag": "uninflectable", + "detail": "topic" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "は", + "dec_tag": "stem-te-defective", + "con_tag": "uninflectable", + "detail": "topic" + }, + "TODO: ても too?", + "===ren'youkei based forms===", + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "なさい", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "kind request" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "な", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "casual kind request" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ながら", + "dec_tag": "stem-ren", + "con_tag": "uninflectable", + "detail": "while" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "たり", + "dec_tag": "stem-ren-less", + "con_tag": "uninflectable", + "detail": "tari" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "だり", + "dec_tag": "stem-ren-less-v", + "con_tag": "uninflectable", + "detail": "tari" + }, + { + "type": "onlyfinalrule", + "dec_end": "", + "con_end": "ったり", + "dec_tag": "stem-ka", + "con_tag": "uninflectable", + "detail": "tari" + }, + { + "type": "contextrule", + "contextrule": "adjspecial", + "dec_end": "", + "con_end": "たい", + "dec_tag": "stem-ren", + "con_tag": "adj-i", + "detail": "want" + }, + { + "type": "stdrule", + "dec_end": "", + "con_end": "すぎる", + "dec_tag": "stem-ren", + "con_tag": "v1", + "detail": "too much" + }, + "===transparent contractions===", + { + "type": "stdrule", + "dec_end": "てしまう", + "con_end": "ちゃう", + "dec_tag": "v5u", + "con_tag": "v5u", + "detail": "(contraction)" + }, + { + "type": "stdrule", + "dec_end": "でしまう", + "con_end": "じゃう", + "dec_tag": "v5u", + "con_tag": "v5u", + "detail": "(contraction)" + }, + { + "type": "stdrule", + "dec_end": "てしまう", + "con_end": "ちまう", + "dec_tag": "v5u", + "con_tag": "v5u", + "detail": "(contraction)" + }, + { + "type": "stdrule", + "dec_end": "でしまう", + "con_end": "じまう", + "dec_tag": "v5u", + "con_tag": "v5u", + "detail": "(contraction)" + }, + { + "type": "stdrule", + "dec_end": "ては", + "con_end": "ちゃ", + "dec_tag": "stem-te", + "con_tag": "uninflectable", + "detail": "(contraction)" + }, + { + "type": "stdrule", + "dec_end": "では", + "con_end": "じゃ", + "dec_tag": "stem-te", + "con_tag": "uninflectable", + "detail": "(contraction)" + }, + { + "type": "onlyfinalrule", + "dec_end": "ければ", + "con_end": "けりゃ", + "dec_tag": "uninflectable", + "con_tag": "uninflectable", + "detail": "(contraction)" + }, + { + "type": "onlyfinalrule", + "dec_end": "ければ", + "con_end": "きゃ", + "dec_tag": "uninflectable", + "con_tag": "uninflectable", + "detail": "(contraction)" + }, + "other", + { + "type": "onlyfinalrule", + "dec_end": "る", + "con_end": "ん", + "dec_tag": "v1", + "con_tag": "uninflectable", + "detail": "slurred" + }, + { + "type": "onlyfinalrule", + "dec_end": "る", + "con_end": "ん", + "dec_tag": "v5r", + "con_tag": "uninflectable", + "detail": "slurred" + }, + { + "type": "onlyfinalrule", + "dec_end": "る", + "con_end": "ん", + "dec_tag": "v5aru", + "con_tag": "uninflectable", + "detail": "slurred" + }, + { + "type": "onlyfinalrule", + "dec_end": "る", + "con_end": "ん", + "dec_tag": "vk", + "con_tag": "uninflectable", + "detail": "slurred" + }, + "// TODO: a bunch of missing contractions, and suppoer for other verb types like vk, vs_i, v5aru, v4r, ..." +] diff --git a/manifest.json b/manifest.json index 7a7182e..473e15f 100644 --- a/manifest.json +++ b/manifest.json @@ -41,6 +41,7 @@ "dict/JMdict10.json", "dict/JMdict11.json", "dict/jdic audio.txt", + "dict/deconjugator.json", "reader.js", "reader.html", "mining.js", diff --git a/options.html b/options.html index c8181bd..7a458d2 100644 --- a/options.html +++ b/options.html @@ -17,10 +17,6 @@ -
-

-
-

About

This extension uses JMdict, which is Copyright © 2018 The Electronic Dictionary Research and Development Group and licensed under the CC BY-SA 3.0 license.

diff --git a/options.js b/options.js index 4bdbbe0..c0a6bdb 100644 --- a/options.js +++ b/options.js @@ -436,11 +436,53 @@ function buildpage() optionsection.appendChild(container); } - let livemininglink = document.getElementById("livemininglink"); - livemininglink.onclick = function(e){browser.windows.create({url:browser.extension.getURL('livemining.html'),type:'popup'}); e.preventDefault();}; + // mining + + let liveminingbutton = document.createElement("button"); + liveminingbutton.type = "button"; + liveminingbutton.innerText = "Configure live mining"; + liveminingbutton.onclick = function(e){browser.windows.create({url:browser.extension.getURL('livemining.html'),type:'popup'}); e.preventDefault();}; + optionsection.appendChild(liveminingbutton); optionsection.appendChild(document.createElement("hr")); + // deconjugation rules + + let decon_file = document.createElement("input"); + decon_file.type = "file"; + decon_file.id = "decon_file"; + decon_file.addEventListener("change", () => + { + let fname = document.querySelector("#epwing_file").files[0]; + let reader = new FileReader(); + reader.onload = async(e) => + { + try + { + browser.storage.local.set({"deconjugator_rules_json":JSON.stringify(JSON.parse(e.target.result))}); + browser.runtime.sendMessage({type:"refreshepwing"}); + document.querySelector("#import_label").textContent = "Imported. Might take a few seconds to apply."; + } + catch(except) + { + console.log(except.stack); + } + }; + reader.readAsText(fname); + }); + let decon_label = document.createElement("label"); + decon_label.for = decon_file.id; + decon_label.id = "import_label"; + decon_label.textContent = "Import deconjugation ruleset. Overrides default deconjugation ruleset. Importing a blank file and restarting your browser will restore the default ruleset."; + decon_label.style.display = "block"; + + optionsection.appendChild(decon_file); + optionsection.appendChild(decon_label); + + optionsection.appendChild(document.createElement("hr")); + + // json dictionary + let file = document.createElement("input"); file.type = "file"; file.id = "epwing_file"; @@ -513,6 +555,8 @@ This format can be extended in the future if it becomes desirable to include mor optionsection.appendChild(document.createElement("hr")); + // backup + let backup_save = document.createElement("button"); backup_save.type = "button"; backup_save.innerText = "Save Backup"; @@ -560,7 +604,7 @@ This format can be extended in the future if it becomes desirable to include mor let backup_load_label = document.createElement("label"); backup_load_label.for = backup_save.id; backup_load_label.id = "backup_load_label"; - backup_load_label.textContent = "Import Backup."; + backup_load_label.textContent = "Import Backup. WARNING: Overwrites ALMOST EVERYTHING, INCLUDING MINED CARDS."; backup_load_label.style.display = "block"; optionsection.appendChild(backup_load); optionsection.appendChild(backup_load_label);