From 43f3ec306a01cd482e32bdb473e2b167a8a502b2 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Thu, 19 Oct 2023 10:52:03 +0900 Subject: [PATCH 01/33] =?UTF-8?q?AccentDiff=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AE=E8=BF=BD=E5=8A=A0just-pluck-it=E3=83=A9=E3=82=A4?= =?UTF-8?q?=E3=83=96=E3=83=A9=E3=83=AA=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/store/audio.ts | 6 ++ src/store/utility.ts | 128 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 134 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index df8bde5c6c..a6dd442cfd 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "encoding-japanese": "1.0.30", "glob": "8.0.3", "immer": "9.0.2", + "just-pluck-it": "2.3.0", "markdown-it": "12.0.4", "move-file": "3.0.0", "multistream": "4.1.0", diff --git a/src/store/audio.ts b/src/store/audio.ts index 721949f12a..a353a155ed 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -28,6 +28,7 @@ import { DEFAULT_STYLE_NAME, formatCharacterStyleName, joinTextsInAccentPhrases, + AccentDiff, } from "./utility"; import { convertAudioQueryFromEditorToEngine } from "./proxy"; import { createPartialStore } from "./vuex"; @@ -1972,6 +1973,10 @@ export const audioCommandStore = transformCommandStore( if (!state.experimentalSetting.shouldKeepTuningOnTextChange) { newAccentPhrases = accentPhrases; } else { + const mergedDiff: AccentPhrase[] = new AccentDiff( + query.accentPhrases, + accentPhrases + ).mergeAccentPhrases(); /* * # 調整結果の保持の仕組み * 1. 新しいAccentPhraseと古いAccentPhraseのテキスト(モーラのカタカナを結合したもの)を比較する。読点は無視する。(diffからflatDiff) @@ -2032,6 +2037,7 @@ export const audioCommandStore = transformCommandStore( return ap; }); + newAccentPhrases = mergedDiff; } } commit("COMMAND_CHANGE_AUDIO_TEXT", { diff --git a/src/store/utility.ts b/src/store/utility.ts index 28758b0ed7..eb27ffeeec 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -1,7 +1,9 @@ import path from "path"; import { Platform } from "quasar"; +import { Change, diffChars } from "diff"; +import pluck from "just-pluck-it"; import { ToolbarButtonTagType, isMac } from "@/type/preload"; -import { AccentPhrase } from "@/openapi"; +import { AccentPhrase, Mora } from "@/openapi"; export const DEFAULT_STYLE_NAME = "ノーマル"; @@ -173,6 +175,130 @@ function skipMemoText(targettext: string): string { return resolvedText; } +/** + * 新しく変更されるアクセント句に対して、変更前のモーラを適用するクラス + * + * + * まず、与えられた現在と過去のアクセント句のモーラを一つの配列にまとめる。こうして作られた過去と現在のモーラ配列を、 + * それぞれの「変更前モーラパッチ配列」「変更後モーラパッチ配列」と呼ぶことにする。 + * 「変更前モーラパッチ配列」と「変更後モーラパッチ配列」の各文字をテキスト化して、変更前から変更後への変更に対するテキスト差分を検出し、配列にまとめる。この配列を、テキストパッチ配列と呼ぶ。 + * 変更前モーラパッチ配列の中に、変化分の文字列を挿入、または、変更後の状態に合わせて、モーラを削除する操作を行う。 + * こうして作られたモーラ配列を、モーラパッチ配列と呼ぶ。 + * 最後に、変更後のアクセント句全体をモーラに対して走査し、モーラパッチ配列のモーラテキストとアクセント区のモーラテキストを比較して、テキストが一致していれば、 + * 変更後のアクセントモーラに対して、モーラパッチ配列の要素を適用する。 + */ +export class AccentDiff { + beforeAccent: AccentPhrase[]; + afterAccent: AccentPhrase[]; + constructor(beforeAccent: AccentPhrase[], afterAccent: AccentPhrase[]) { + this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); + this.beforeAccent = JSON.parse(JSON.stringify(beforeAccent)); + } + /** + * アクセント句のテキストを配列として返すメンバ関数 + */ + getMorasTextFromAccentPhrases(accent: AccentPhrase[]) { + const result: string[] = []; + accent.forEach((element: AccentPhrase) => { + const plucked = pluck(element.moras, "text"); + const text = plucked.join(""); + result.push(text); + }); + return result.join(""); + } + /** + * パッチモーラ配列を作成するメンバ関数 + */ + createMorasOrMorasTextArray() { + const after = JSON.parse(JSON.stringify(this.afterAccent)); + const before = JSON.parse(JSON.stringify(this.beforeAccent)); + // テキストの差分検出 + const diffed: any = diffChars( + this.getMorasTextFromAccentPhrases(before), + this.getMorasTextFromAccentPhrases(after) + ); + const pluckedBefore = pluck(before, "moras").flat(); // 変更前のアクセント句からモーラ配列を作成 + let pluckedIndex = 0; // 現在のモーラ配列の位置(テキストの位置)を表す。各操作に対して、非常に重要 + for (const diff of diffed) { + if (diff.removed) { + let removeForSmallCounter = 0; // ャ、ュ、ョといった文字を検出するたびに+1加算される + for ( + let removeValueIndex = 0; + removeValueIndex < diff.value.length; + removeValueIndex++ + ) { + if ( + diff.value[removeValueIndex] === "ャ" || + diff.value[removeValueIndex] === "ュ" || + diff.value[removeValueIndex] === "ョ" + ) { + ++removeForSmallCounter; + } + } + pluckedBefore.splice(pluckedIndex, diff.count - removeForSmallCounter); + } else if (diff.added) { + for (let valueIndex = 0; valueIndex < diff.value.length; valueIndex++) { + if ( + diff.value[valueIndex] === "ャ" || + diff.value[valueIndex] === "ュ" || + diff.value[valueIndex] === "ョ" + ) { + pluckedBefore.splice( + pluckedIndex - 1, + 1, + String(diff.value[valueIndex - 1]) + + String(diff.value[valueIndex]) + ); + ++pluckedIndex; + } else { + pluckedBefore.splice(pluckedIndex, 0, diff.value[valueIndex]); + ++pluckedIndex; + } + } + } else { + // 削除も変更もしないfor文を記述 + for (const char of diff.value) { + if (char === "ャ" || char === "ュ" || char === "ョ") continue; + else ++pluckedIndex; + } + } + } + return pluckedBefore; + } + /** + * 変更後のアクセント句に、パッチモーラ配列を適用するメンバ関数 + */ + mergeAccentPhrases() { + const after = JSON.parse(JSON.stringify(this.afterAccent)); + const pluckedBefore = this.createMorasOrMorasTextArray(); + let beforeIndex = 0; // pluckedBeforeのデータの位置 + + // 与えられたアクセント句は、AccentPhrases[ Nmber ][ Object Key][ Number ]の順番で、モーラを操作できるため、二重forで回す + for (let AccentIndex = 0; AccentIndex < after.length; AccentIndex++) { + for ( + let MoraIndex = 0; + MoraIndex < after[AccentIndex]["moras"].length; + MoraIndex++ + ) { + // パッチモーラのある要素が文字列なら次へ + if (typeof pluckedBefore[beforeIndex] === "string") { + ++beforeIndex; + continue; + } + if ( + after[AccentIndex]["moras"][MoraIndex].text === + pluckedBefore[beforeIndex].text + ) { + after[AccentIndex]["moras"][MoraIndex] = pluckedBefore[beforeIndex]; + } + ++beforeIndex; + } + } + + return after; + } +} + /** * 2つのAccentPhrasesのテキスト内容が異なるかどうかを判定 */ From 468d0a298a78e50378297cf3c22c2db735d8fe92 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Thu, 19 Oct 2023 10:58:06 +0900 Subject: [PATCH 02/33] =?UTF-8?q?=E6=97=A2=E5=AD=98=E3=81=AEdiff=E6=A9=9F?= =?UTF-8?q?=E8=83=BD=E3=82=92=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/audio.ts | 61 +--------------------------------------------- 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/src/store/audio.ts b/src/store/audio.ts index a353a155ed..fde09799a9 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -1977,66 +1977,7 @@ export const audioCommandStore = transformCommandStore( query.accentPhrases, accentPhrases ).mergeAccentPhrases(); - /* - * # 調整結果の保持の仕組み - * 1. 新しいAccentPhraseと古いAccentPhraseのテキスト(モーラのカタカナを結合したもの)を比較する。読点は無視する。(diffからflatDiff) - * 例えば、 - * 旧:[ズ ン ダ モ ン ノ] [チョ ウ ショ ク] - * 新:[ズ ン ダ モ ン ノ] [ユ ウ ショ ク] - * という場合、 - * [ズ ン ダ モ ン ノ] - * + [ユ ウ ショ ク] - * - [チョ ウ ショ ク] - * のような変更なしのdiff・追加のdiff・削除のdiffが得られる。 - * - * 2. それぞれのdiffにインデックスを振る。(indexedDiff) - * 3. diffのインデックスと古いAccentPhraseの対応表を作る。(indexToOldAccentPhrase) - * 追加のdiffを抜くと古いAccentPhraseになるので、残ったAccentPhraseのIDを対応させる。 - * [ズ ン ダ モ ン ノ] #0 -> query.accentPhrases[0] - * + [ユ ウ ショ ク] #1 -> (無視) - * - [チョ ウ ショ ク] #2 -> query.accentPhrases[1] - * - * 4. 新しいAccentPhraseの配列を作る。(newAccentPhrases) - * 変更なしのdiffは上の対応表を使って古いAccentPhrase、追加のdiffは新しいAccentPhraseを使い、削除のdiffは無視する。 - * [ズ ン ダ モ ン ノ] #0 -> query.accentPhrases[0] - * + [ユ ウ ショ ク] #1 -> accentPhrases[1] - * - [チョ ウ ショ ク] #2 -> (無視) - */ - const diff = diffArrays( - query.accentPhrases.map(joinTextsInAccentPhrases), - accentPhrases.map(joinTextsInAccentPhrases) - ); - const flatDiff = diff.flatMap((d) => - d.value.map((v) => ({ ...d, value: v })) - ); - const indexedDiff = flatDiff.map((d, i) => ({ - ...d, - index: i, - })); - const indexToOldAccentPhrase = indexedDiff - .filter((d) => !d.added) - .reduce( - (acc, d, i) => ({ - ...acc, - [d.index]: toRaw(query.accentPhrases[i]), - }), - {} as { [index: number]: AccentPhrase } - ); - newAccentPhrases = indexedDiff - .filter((d) => !d.removed) - .map((d, i) => { - const ap = structuredClone( - indexToOldAccentPhrase[d.index] ?? accentPhrases[i] - ); - if (accentPhrases[i].pauseMora !== undefined) { - ap.pauseMora = accentPhrases[i].pauseMora; - } else { - delete ap.pauseMora; - } - ap.isInterrogative = accentPhrases[i].isInterrogative; - - return ap; - }); + newAccentPhrases = mergedDiff; } } From bc126d28eff153b8e1e18150179492c9aeadca84 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Thu, 19 Oct 2023 12:42:36 +0900 Subject: [PATCH 03/33] =?UTF-8?q?package-lock.json=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=82=92=E8=BF=BD=E5=8A=A0(push=E5=BF=98=E3=82=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/package-lock.json b/package-lock.json index e38d463c16..13c933ed31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "encoding-japanese": "1.0.30", "glob": "8.0.3", "immer": "9.0.2", + "just-pluck-it": "2.3.0", "markdown-it": "12.0.4", "move-file": "3.0.0", "multistream": "4.1.0", @@ -9371,6 +9372,11 @@ "setimmediate": "^1.0.5" } }, + "node_modules/just-pluck-it": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/just-pluck-it/-/just-pluck-it-2.3.0.tgz", + "integrity": "sha512-M2UdKR4nsVaOekKqKTikIQXJLhwJfmL8MA6KY2ZbHs60UNTWKnee2Bugo6ExzI8ITLl9xZFYCuBYiZzCnzvxnw==" + }, "node_modules/keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", @@ -21819,6 +21825,11 @@ "setimmediate": "^1.0.5" } }, + "just-pluck-it": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/just-pluck-it/-/just-pluck-it-2.3.0.tgz", + "integrity": "sha512-M2UdKR4nsVaOekKqKTikIQXJLhwJfmL8MA6KY2ZbHs60UNTWKnee2Bugo6ExzI8ITLl9xZFYCuBYiZzCnzvxnw==" + }, "keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", From 07eeca4f6bc14734e9b08dcc6da712f1f4788f63 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Thu, 19 Oct 2023 14:46:49 +0900 Subject: [PATCH 04/33] =?UTF-8?q?diffArrays=E3=82=92=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E3=81=97=E3=80=81=E3=82=BD=E3=83=BC=E3=82=B9=E3=82=B3=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=81=AE=E8=A8=98=E8=BF=B0=E9=87=8F=E3=82=92=E5=89=8A?= =?UTF-8?q?=E6=B8=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 101 +++++++++++++------------------------------ 1 file changed, 29 insertions(+), 72 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index eb27ffeeec..eaeac42e78 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -1,6 +1,6 @@ import path from "path"; import { Platform } from "quasar"; -import { Change, diffChars } from "diff"; +import { diffArrays } from "diff"; import pluck from "just-pluck-it"; import { ToolbarButtonTagType, isMac } from "@/type/preload"; import { AccentPhrase, Mora } from "@/openapi"; @@ -178,14 +178,11 @@ function skipMemoText(targettext: string): string { /** * 新しく変更されるアクセント句に対して、変更前のモーラを適用するクラス * - * - * まず、与えられた現在と過去のアクセント句のモーラを一つの配列にまとめる。こうして作られた過去と現在のモーラ配列を、 - * それぞれの「変更前モーラパッチ配列」「変更後モーラパッチ配列」と呼ぶことにする。 - * 「変更前モーラパッチ配列」と「変更後モーラパッチ配列」の各文字をテキスト化して、変更前から変更後への変更に対するテキスト差分を検出し、配列にまとめる。この配列を、テキストパッチ配列と呼ぶ。 - * 変更前モーラパッチ配列の中に、変化分の文字列を挿入、または、変更後の状態に合わせて、モーラを削除する操作を行う。 - * こうして作られたモーラ配列を、モーラパッチ配列と呼ぶ。 - * 最後に、変更後のアクセント句全体をモーラに対して走査し、モーラパッチ配列のモーラテキストとアクセント区のモーラテキストを比較して、テキストが一致していれば、 - * 変更後のアクセントモーラに対して、モーラパッチ配列の要素を適用する。 + * まず、過去と現在のアクセント句から、モーラ配列を作成する。 + * モーラ配列の各テキストを配列にまとめ、得られた2つの配列より、差分を検出する。 + * 検出した差分の追加、削除、それ以外の状況に応じて、変更前のモーラ配列に対して、文字列の挿入、配列自体の削除 + * を適用し、変更前のモーラ配列のテキストと変更後のアクセント句のモーラ配列のテキストを一致するようにする。 + * 最後に、変更後のアクセント句を走査して、変更前のモーラ配列のオブジェクト部分を変更後のアクセント句のモーラに適用する。 */ export class AccentDiff { beforeAccent: AccentPhrase[]; @@ -194,83 +191,43 @@ export class AccentDiff { this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); this.beforeAccent = JSON.parse(JSON.stringify(beforeAccent)); } + /** - * アクセント句のテキストを配列として返すメンバ関数 - */ - getMorasTextFromAccentPhrases(accent: AccentPhrase[]) { - const result: string[] = []; - accent.forEach((element: AccentPhrase) => { - const plucked = pluck(element.moras, "text"); - const text = plucked.join(""); - result.push(text); - }); - return result.join(""); - } - /** - * パッチモーラ配列を作成するメンバ関数 + * モーラのパッチ配列を作成するメンバ関数 */ - createMorasOrMorasTextArray() { + createDiffPatch() { const after = JSON.parse(JSON.stringify(this.afterAccent)); const before = JSON.parse(JSON.stringify(this.beforeAccent)); - // テキストの差分検出 - const diffed: any = diffChars( - this.getMorasTextFromAccentPhrases(before), - this.getMorasTextFromAccentPhrases(after) + + const pluckedBefore = pluck(before, "moras").flat(); + const pluckedAfter = pluck(after, "moras").flat(); + const diffed = diffArrays( + pluck(JSON.parse(JSON.stringify(pluckedBefore)), "text"), + pluck(JSON.parse(JSON.stringify(pluckedAfter)), "text") ); - const pluckedBefore = pluck(before, "moras").flat(); // 変更前のアクセント句からモーラ配列を作成 - let pluckedIndex = 0; // 現在のモーラ配列の位置(テキストの位置)を表す。各操作に対して、非常に重要 + let pluckedIndex = 0; for (const diff of diffed) { if (diff.removed) { - let removeForSmallCounter = 0; // ャ、ュ、ョといった文字を検出するたびに+1加算される - for ( - let removeValueIndex = 0; - removeValueIndex < diff.value.length; - removeValueIndex++ - ) { - if ( - diff.value[removeValueIndex] === "ャ" || - diff.value[removeValueIndex] === "ュ" || - diff.value[removeValueIndex] === "ョ" - ) { - ++removeForSmallCounter; - } - } - pluckedBefore.splice(pluckedIndex, diff.count - removeForSmallCounter); + pluckedBefore.splice(pluckedIndex, diff.count); } else if (diff.added) { - for (let valueIndex = 0; valueIndex < diff.value.length; valueIndex++) { - if ( - diff.value[valueIndex] === "ャ" || - diff.value[valueIndex] === "ュ" || - diff.value[valueIndex] === "ョ" - ) { - pluckedBefore.splice( - pluckedIndex - 1, - 1, - String(diff.value[valueIndex - 1]) + - String(diff.value[valueIndex]) - ); - ++pluckedIndex; - } else { - pluckedBefore.splice(pluckedIndex, 0, diff.value[valueIndex]); - ++pluckedIndex; - } + for (const insertedText of diff.value) { + pluckedBefore.splice(pluckedIndex, 0, insertedText); + ++pluckedIndex; } } else { - // 削除も変更もしないfor文を記述 - for (const char of diff.value) { - if (char === "ャ" || char === "ュ" || char === "ョ") continue; - else ++pluckedIndex; - } + diff.value.forEach(() => { + ++pluckedIndex; + }); } } return pluckedBefore; } /** - * 変更後のアクセント句に、パッチモーラ配列を適用するメンバ関数 + * 変更後のアクセント句に、モーラパッチ配列を適用するメンバ関数 */ mergeAccentPhrases() { const after = JSON.parse(JSON.stringify(this.afterAccent)); - const pluckedBefore = this.createMorasOrMorasTextArray(); + const MoraPatch = this.createDiffPatch(); let beforeIndex = 0; // pluckedBeforeのデータの位置 // 与えられたアクセント句は、AccentPhrases[ Nmber ][ Object Key][ Number ]の順番で、モーラを操作できるため、二重forで回す @@ -280,16 +237,16 @@ export class AccentDiff { MoraIndex < after[AccentIndex]["moras"].length; MoraIndex++ ) { - // パッチモーラのある要素が文字列なら次へ - if (typeof pluckedBefore[beforeIndex] === "string") { + // 文字列が検出されたとき、何もせず次のモーラへ移動 + if (typeof MoraPatch[beforeIndex] === "string") { ++beforeIndex; continue; } if ( after[AccentIndex]["moras"][MoraIndex].text === - pluckedBefore[beforeIndex].text + MoraPatch[beforeIndex].text ) { - after[AccentIndex]["moras"][MoraIndex] = pluckedBefore[beforeIndex]; + after[AccentIndex]["moras"][MoraIndex] = MoraPatch[beforeIndex]; } ++beforeIndex; } From f35b083e0524ae8563aa5802dbbe6f2e27928c20 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 21 Oct 2023 00:16:16 +0900 Subject: [PATCH 05/33] =?UTF-8?q?just-pluck-it=E3=82=92=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E3=81=97=E3=80=81=E5=90=8C=E3=81=98=E5=BD=B9=E5=89=B2=E3=81=AE?= =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 11 ----------- package.json | 1 - src/store/utility.ts | 26 +++++++++++++++++--------- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 13c933ed31..e38d463c16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,6 @@ "encoding-japanese": "1.0.30", "glob": "8.0.3", "immer": "9.0.2", - "just-pluck-it": "2.3.0", "markdown-it": "12.0.4", "move-file": "3.0.0", "multistream": "4.1.0", @@ -9372,11 +9371,6 @@ "setimmediate": "^1.0.5" } }, - "node_modules/just-pluck-it": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/just-pluck-it/-/just-pluck-it-2.3.0.tgz", - "integrity": "sha512-M2UdKR4nsVaOekKqKTikIQXJLhwJfmL8MA6KY2ZbHs60UNTWKnee2Bugo6ExzI8ITLl9xZFYCuBYiZzCnzvxnw==" - }, "node_modules/keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", @@ -21825,11 +21819,6 @@ "setimmediate": "^1.0.5" } }, - "just-pluck-it": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/just-pluck-it/-/just-pluck-it-2.3.0.tgz", - "integrity": "sha512-M2UdKR4nsVaOekKqKTikIQXJLhwJfmL8MA6KY2ZbHs60UNTWKnee2Bugo6ExzI8ITLl9xZFYCuBYiZzCnzvxnw==" - }, "keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", diff --git a/package.json b/package.json index a6dd442cfd..df8bde5c6c 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ "encoding-japanese": "1.0.30", "glob": "8.0.3", "immer": "9.0.2", - "just-pluck-it": "2.3.0", "markdown-it": "12.0.4", "move-file": "3.0.0", "multistream": "4.1.0", diff --git a/src/store/utility.ts b/src/store/utility.ts index eaeac42e78..30059de8eb 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -1,9 +1,8 @@ import path from "path"; import { Platform } from "quasar"; import { diffArrays } from "diff"; -import pluck from "just-pluck-it"; import { ToolbarButtonTagType, isMac } from "@/type/preload"; -import { AccentPhrase, Mora } from "@/openapi"; +import { AccentPhrase } from "@/openapi"; export const DEFAULT_STYLE_NAME = "ノーマル"; @@ -192,6 +191,15 @@ export class AccentDiff { this.beforeAccent = JSON.parse(JSON.stringify(beforeAccent)); } + createFlatArray(collection: AccentPhrase[], Key: string) { + const targetAccent = JSON.parse(JSON.stringify(collection)); + const result = []; + for (const element of targetAccent) { + result.push(element[Key]); + } + return result.flat(); + } + /** * モーラのパッチ配列を作成するメンバ関数 */ @@ -199,19 +207,19 @@ export class AccentDiff { const after = JSON.parse(JSON.stringify(this.afterAccent)); const before = JSON.parse(JSON.stringify(this.beforeAccent)); - const pluckedBefore = pluck(before, "moras").flat(); - const pluckedAfter = pluck(after, "moras").flat(); + const beforeFlatArray = this.createFlatArray(before, "moras"); + const afterFlatArray = this.createFlatArray(after, "moras"); const diffed = diffArrays( - pluck(JSON.parse(JSON.stringify(pluckedBefore)), "text"), - pluck(JSON.parse(JSON.stringify(pluckedAfter)), "text") + this.createFlatArray(JSON.parse(JSON.stringify(beforeFlatArray)), "text"), + this.createFlatArray(JSON.parse(JSON.stringify(afterFlatArray)), "text") ); let pluckedIndex = 0; for (const diff of diffed) { if (diff.removed) { - pluckedBefore.splice(pluckedIndex, diff.count); + beforeFlatArray.splice(pluckedIndex, diff.count); } else if (diff.added) { for (const insertedText of diff.value) { - pluckedBefore.splice(pluckedIndex, 0, insertedText); + beforeFlatArray.splice(pluckedIndex, 0, insertedText); ++pluckedIndex; } } else { @@ -220,7 +228,7 @@ export class AccentDiff { }); } } - return pluckedBefore; + return beforeFlatArray; } /** * 変更後のアクセント句に、モーラパッチ配列を適用するメンバ関数 From 39a748390a1a3cd19edae4d2e36235d887cd4111 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 21 Oct 2023 23:40:40 +0900 Subject: [PATCH 06/33] =?UTF-8?q?=E8=AA=A4=E5=AD=97=E3=81=AE=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index 30059de8eb..be53d0e2f6 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -218,10 +218,10 @@ export class AccentDiff { if (diff.removed) { beforeFlatArray.splice(pluckedIndex, diff.count); } else if (diff.added) { - for (const insertedText of diff.value) { - beforeFlatArray.splice(pluckedIndex, 0, insertedText); + diff.value.forEach(() => { + beforeFlatArray.splice(pluckedIndex, 0, undefined); ++pluckedIndex; - } + }); } else { diff.value.forEach(() => { ++pluckedIndex; @@ -238,7 +238,7 @@ export class AccentDiff { const MoraPatch = this.createDiffPatch(); let beforeIndex = 0; // pluckedBeforeのデータの位置 - // 与えられたアクセント句は、AccentPhrases[ Nmber ][ Object Key][ Number ]の順番で、モーラを操作できるため、二重forで回す + // 与えられたアクセント句は、AccentPhrases[ Number ][ Object Key ][ Number ]の順番で、モーラを操作できるため、二重forで回す for (let AccentIndex = 0; AccentIndex < after.length; AccentIndex++) { for ( let MoraIndex = 0; @@ -246,7 +246,7 @@ export class AccentDiff { MoraIndex++ ) { // 文字列が検出されたとき、何もせず次のモーラへ移動 - if (typeof MoraPatch[beforeIndex] === "string") { + if (typeof MoraPatch[beforeIndex] === "undefined") { ++beforeIndex; continue; } From d3de6f047392180f443063286213ccb454ca7bde Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 21 Oct 2023 23:43:44 +0900 Subject: [PATCH 07/33] =?UTF-8?q?index=E3=81=AE=E5=8A=A0=E7=AE=97=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=81=A7=E3=80=81for=E6=96=87=E3=82=92=E5=9B=9E?= =?UTF-8?q?=E3=81=95=E3=81=AA=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index be53d0e2f6..3a10b22369 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -223,9 +223,7 @@ export class AccentDiff { ++pluckedIndex; }); } else { - diff.value.forEach(() => { - ++pluckedIndex; - }); + pluckedIndex += diff.value.length; } } return beforeFlatArray; From 49657d9b163f50dec69c2bbe5be2b2169831d7da Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 21 Oct 2023 23:45:20 +0900 Subject: [PATCH 08/33] =?UTF-8?q?=E5=91=BD=E5=90=8D=E8=A6=8F=E5=89=87?= =?UTF-8?q?=E3=81=AB=E6=BA=96=E6=8B=A0=E3=81=97=E3=81=A6=E3=81=84=E3=81=AA?= =?UTF-8?q?=E3=81=84=E5=A4=89=E6=95=B0=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index 3a10b22369..f16873879e 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -237,10 +237,10 @@ export class AccentDiff { let beforeIndex = 0; // pluckedBeforeのデータの位置 // 与えられたアクセント句は、AccentPhrases[ Number ][ Object Key ][ Number ]の順番で、モーラを操作できるため、二重forで回す - for (let AccentIndex = 0; AccentIndex < after.length; AccentIndex++) { + for (let accentIndex = 0; accentIndex < after.length; accentIndex++) { for ( let MoraIndex = 0; - MoraIndex < after[AccentIndex]["moras"].length; + MoraIndex < after[accentIndex]["moras"].length; MoraIndex++ ) { // 文字列が検出されたとき、何もせず次のモーラへ移動 @@ -249,10 +249,10 @@ export class AccentDiff { continue; } if ( - after[AccentIndex]["moras"][MoraIndex].text === + after[accentIndex]["moras"][MoraIndex].text === MoraPatch[beforeIndex].text ) { - after[AccentIndex]["moras"][MoraIndex] = MoraPatch[beforeIndex]; + after[accentIndex]["moras"][MoraIndex] = MoraPatch[beforeIndex]; } ++beforeIndex; } From b9af99a913078412972557cbfe9db5cc2b84aa54 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 21 Oct 2023 23:58:16 +0900 Subject: [PATCH 09/33] =?UTF-8?q?=E5=8F=82=E7=85=A7=E5=A4=96=E3=81=97?= =?UTF-8?q?=E3=82=92=E8=A1=8C=E3=81=86=E7=AE=87=E6=89=80=E3=81=AE=E4=B8=80?= =?UTF-8?q?=E9=83=A8=E3=81=A7structuredClone=E3=82=92=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index f16873879e..016868c19f 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -187,8 +187,8 @@ export class AccentDiff { beforeAccent: AccentPhrase[]; afterAccent: AccentPhrase[]; constructor(beforeAccent: AccentPhrase[], afterAccent: AccentPhrase[]) { - this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); this.beforeAccent = JSON.parse(JSON.stringify(beforeAccent)); + this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); } createFlatArray(collection: AccentPhrase[], Key: string) { @@ -204,14 +204,14 @@ export class AccentDiff { * モーラのパッチ配列を作成するメンバ関数 */ createDiffPatch() { - const after = JSON.parse(JSON.stringify(this.afterAccent)); - const before = JSON.parse(JSON.stringify(this.beforeAccent)); + const before = structuredClone(this.beforeAccent); + const after = structuredClone(this.afterAccent); const beforeFlatArray = this.createFlatArray(before, "moras"); const afterFlatArray = this.createFlatArray(after, "moras"); const diffed = diffArrays( - this.createFlatArray(JSON.parse(JSON.stringify(beforeFlatArray)), "text"), - this.createFlatArray(JSON.parse(JSON.stringify(afterFlatArray)), "text") + this.createFlatArray(structuredClone(beforeFlatArray), "text"), + this.createFlatArray(structuredClone(afterFlatArray), "text") ); let pluckedIndex = 0; for (const diff of diffed) { @@ -232,7 +232,7 @@ export class AccentDiff { * 変更後のアクセント句に、モーラパッチ配列を適用するメンバ関数 */ mergeAccentPhrases() { - const after = JSON.parse(JSON.stringify(this.afterAccent)); + const after = structuredClone(this.afterAccent); const MoraPatch = this.createDiffPatch(); let beforeIndex = 0; // pluckedBeforeのデータの位置 From cf63b0b40b160429d98ec99d0d0f7d4a9c3dd11e Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sun, 22 Oct 2023 00:00:22 +0900 Subject: [PATCH 10/33] =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=82=AF=E3=83=AA?= =?UTF-8?q?=E3=83=A1=E3=83=B3=E3=83=88=E3=81=AE=E8=A8=98=E8=BF=B0=E3=82=92?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index 016868c19f..b9c0c7df99 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -220,7 +220,7 @@ export class AccentDiff { } else if (diff.added) { diff.value.forEach(() => { beforeFlatArray.splice(pluckedIndex, 0, undefined); - ++pluckedIndex; + pluckedIndex++; }); } else { pluckedIndex += diff.value.length; @@ -245,7 +245,7 @@ export class AccentDiff { ) { // 文字列が検出されたとき、何もせず次のモーラへ移動 if (typeof MoraPatch[beforeIndex] === "undefined") { - ++beforeIndex; + beforeIndex++; continue; } if ( @@ -254,7 +254,7 @@ export class AccentDiff { ) { after[accentIndex]["moras"][MoraIndex] = MoraPatch[beforeIndex]; } - ++beforeIndex; + beforeIndex++; } } From bfba65dff6e6b9ff63a3834fe9e8d881d0e64c37 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Tue, 24 Oct 2023 21:42:57 +0900 Subject: [PATCH 11/33] =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE?= =?UTF-8?q?=E7=9B=AE=E7=9A=84=E3=82=92=E7=B0=A1=E6=BD=94=E3=81=AB=E3=81=BE?= =?UTF-8?q?=E3=81=A8=E3=82=81=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index b9c0c7df99..c70d58b86d 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -175,13 +175,8 @@ function skipMemoText(targettext: string): string { } /** - * 新しく変更されるアクセント句に対して、変更前のモーラを適用するクラス - * - * まず、過去と現在のアクセント句から、モーラ配列を作成する。 - * モーラ配列の各テキストを配列にまとめ、得られた2つの配列より、差分を検出する。 - * 検出した差分の追加、削除、それ以外の状況に応じて、変更前のモーラ配列に対して、文字列の挿入、配列自体の削除 - * を適用し、変更前のモーラ配列のテキストと変更後のアクセント句のモーラ配列のテキストを一致するようにする。 - * 最後に、変更後のアクセント句を走査して、変更前のモーラ配列のオブジェクト部分を変更後のアクセント句のモーラに適用する。 + * 2つのアクセント句配列を比べて同じだと思われるモーラの調整結果を転写し + * 変更前のアクセント句の調整結果を変更後のアクセント句に保持する */ export class AccentDiff { beforeAccent: AccentPhrase[]; From 2b4ee7fc44caeb484fd93264e4c22740135c000e Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Tue, 24 Oct 2023 22:13:04 +0900 Subject: [PATCH 12/33] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AA=E5=8F=82?= =?UTF-8?q?=E7=85=A7=E5=9B=9E=E9=81=BF=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index c70d58b86d..cd8cda9efd 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -2,7 +2,7 @@ import path from "path"; import { Platform } from "quasar"; import { diffArrays } from "diff"; import { ToolbarButtonTagType, isMac } from "@/type/preload"; -import { AccentPhrase } from "@/openapi"; +import { AccentPhrase, Mora } from "@/openapi"; export const DEFAULT_STYLE_NAME = "ノーマル"; @@ -186,8 +186,7 @@ export class AccentDiff { this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); } - createFlatArray(collection: AccentPhrase[], Key: string) { - const targetAccent = JSON.parse(JSON.stringify(collection)); + createFlatArray(targetAccent: any[], Key: string) { const result = []; for (const element of targetAccent) { result.push(element[Key]); From 1853237b854b5def7b9acc1f6cd87d20dc42db37 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Tue, 24 Oct 2023 22:22:54 +0900 Subject: [PATCH 13/33] =?UTF-8?q?jsdoc=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index cd8cda9efd..b1bd76d9a3 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -195,7 +195,7 @@ export class AccentDiff { } /** - * モーラのパッチ配列を作成するメンバ関数 + * 変更前と変更後のモーラをフラット化し、変更後のモーラテキストに対応するようにフラット化した変更前のモーラ配列を操作する */ createDiffPatch() { const before = structuredClone(this.beforeAccent); @@ -223,7 +223,7 @@ export class AccentDiff { return beforeFlatArray; } /** - * 変更後のアクセント句に、モーラパッチ配列を適用するメンバ関数 + * 変更後のアクセント句に、createDiffPatchで作成したモーラ配列を適用し、各モーラ配列のテキストが一致したら、変更前のモーラを変更後のモーラに渡す */ mergeAccentPhrases() { const after = structuredClone(this.afterAccent); From 65a351846a62ab136d6a92f825ba483872ec3962 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Tue, 24 Oct 2023 22:25:45 +0900 Subject: [PATCH 14/33] =?UTF-8?q?=E8=AA=A4=E3=81=A3=E3=81=9F=E3=82=B3?= =?UTF-8?q?=E3=83=A1=E3=83=B3=E3=83=88=E3=81=AE=E4=BF=AE=E6=AD=A3=E3=81=A8?= =?UTF-8?q?=E3=80=81=E3=83=95=E3=83=A9=E3=82=B0=E3=81=AE=E8=A8=98=E8=BF=B0?= =?UTF-8?q?=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index b1bd76d9a3..a4711d4c0d 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -237,8 +237,8 @@ export class AccentDiff { MoraIndex < after[accentIndex]["moras"].length; MoraIndex++ ) { - // 文字列が検出されたとき、何もせず次のモーラへ移動 - if (typeof MoraPatch[beforeIndex] === "undefined") { + // undefinedのとき、何もせず次のモーラへ移動 + if (MoraPatch[beforeIndex] == undefined) { beforeIndex++; continue; } From d483506a51b4037afc989b32ab565a4577383c42 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Tue, 24 Oct 2023 22:32:06 +0900 Subject: [PATCH 15/33] =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E5=90=8D?= =?UTF-8?q?=E3=81=AE=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index a4711d4c0d..0381a6550c 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -178,7 +178,7 @@ function skipMemoText(targettext: string): string { * 2つのアクセント句配列を比べて同じだと思われるモーラの調整結果を転写し * 変更前のアクセント句の調整結果を変更後のアクセント句に保持する */ -export class AccentDiff { +export class TuningTranscription { beforeAccent: AccentPhrase[]; afterAccent: AccentPhrase[]; constructor(beforeAccent: AccentPhrase[], afterAccent: AccentPhrase[]) { From 0ca40047d5ec12503546f13b71dc74e542c2060e Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Fri, 27 Oct 2023 23:25:19 +0900 Subject: [PATCH 16/33] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AAimport?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/audio.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/store/audio.ts b/src/store/audio.ts index fde09799a9..774023e05e 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -1,7 +1,6 @@ import path from "path"; import { v4 as uuidv4 } from "uuid"; import Encoding from "encoding-japanese"; -import { diffArrays } from "diff"; import { toRaw } from "vue"; import { createUILockAction, withProgress } from "./ui"; import { @@ -28,7 +27,6 @@ import { DEFAULT_STYLE_NAME, formatCharacterStyleName, joinTextsInAccentPhrases, - AccentDiff, } from "./utility"; import { convertAudioQueryFromEditorToEngine } from "./proxy"; import { createPartialStore } from "./vuex"; From f380d74616fde96b99080c32653584027bcc09cf Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Fri, 27 Oct 2023 23:29:22 +0900 Subject: [PATCH 17/33] =?UTF-8?q?AccentDiff=E3=82=92=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E3=81=97=E3=80=81TuningTranscrption=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/audio.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/store/audio.ts b/src/store/audio.ts index 774023e05e..c0e2e1cf31 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -27,6 +27,7 @@ import { DEFAULT_STYLE_NAME, formatCharacterStyleName, joinTextsInAccentPhrases, + TuningTranscription, } from "./utility"; import { convertAudioQueryFromEditorToEngine } from "./proxy"; import { createPartialStore } from "./vuex"; @@ -1971,10 +1972,10 @@ export const audioCommandStore = transformCommandStore( if (!state.experimentalSetting.shouldKeepTuningOnTextChange) { newAccentPhrases = accentPhrases; } else { - const mergedDiff: AccentPhrase[] = new AccentDiff( + const mergedDiff: AccentPhrase[] = new TuningTranscription( query.accentPhrases, accentPhrases - ).mergeAccentPhrases(); + ).transcribe(); newAccentPhrases = mergedDiff; } From ca80cbf4321a1ed5c32c33c42b94bdf97ed2172c Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Fri, 27 Oct 2023 23:31:40 +0900 Subject: [PATCH 18/33] =?UTF-8?q?=E5=A4=89=E6=95=B0=E5=90=8D=E3=82=92camel?= =?UTF-8?q?Case=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index 0381a6550c..101125b4d4 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -225,28 +225,27 @@ export class TuningTranscription { /** * 変更後のアクセント句に、createDiffPatchで作成したモーラ配列を適用し、各モーラ配列のテキストが一致したら、変更前のモーラを変更後のモーラに渡す */ - mergeAccentPhrases() { + mergeAccentPhrases(moraPatch: any[]) { const after = structuredClone(this.afterAccent); - const MoraPatch = this.createDiffPatch(); let beforeIndex = 0; // pluckedBeforeのデータの位置 // 与えられたアクセント句は、AccentPhrases[ Number ][ Object Key ][ Number ]の順番で、モーラを操作できるため、二重forで回す for (let accentIndex = 0; accentIndex < after.length; accentIndex++) { for ( - let MoraIndex = 0; - MoraIndex < after[accentIndex]["moras"].length; - MoraIndex++ + let moraIndex = 0; + moraIndex < after[accentIndex]["moras"].length; + moraIndex++ ) { // undefinedのとき、何もせず次のモーラへ移動 - if (MoraPatch[beforeIndex] == undefined) { + if (moraPatch[beforeIndex] == undefined) { beforeIndex++; continue; } if ( - after[accentIndex]["moras"][MoraIndex].text === - MoraPatch[beforeIndex].text + after[accentIndex]["moras"][moraIndex].text === + moraPatch[beforeIndex].text ) { - after[accentIndex]["moras"][MoraIndex] = MoraPatch[beforeIndex]; + after[accentIndex]["moras"][moraIndex] = moraPatch[beforeIndex]; } beforeIndex++; } @@ -254,6 +253,11 @@ export class TuningTranscription { return after; } + + transcribe() { + const moraPatch = this.createDiffPatch(); + return this.mergeAccentPhrases(moraPatch); + } } /** From 90d418bab16bc2f89ce11d0500a408398542b4cf Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Fri, 27 Oct 2023 23:36:31 +0900 Subject: [PATCH 19/33] =?UTF-8?q?createFlatArray=E3=81=AE=E5=A4=89?= =?UTF-8?q?=E6=95=B0=E5=90=8D=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index 101125b4d4..a928455bab 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -186,9 +186,9 @@ export class TuningTranscription { this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); } - createFlatArray(targetAccent: any[], Key: string) { + createFlatArray(collection: any[], Key: string) { const result = []; - for (const element of targetAccent) { + for (const element of collection) { result.push(element[Key]); } return result.flat(); From 58b0ab3049af17cf681b3ac09c7d2d2a68f26356 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Wed, 1 Nov 2023 21:25:55 +0900 Subject: [PATCH 20/33] =?UTF-8?q?=E5=9E=8B=E5=AE=A3=E8=A8=80=E3=81=A7any[]?= =?UTF-8?q?=E3=81=AB=E3=81=97=E3=81=A6=E3=81=84=E3=82=8B=E7=AE=87=E6=89=80?= =?UTF-8?q?=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index a928455bab..b55a0c3aa3 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -186,12 +186,17 @@ export class TuningTranscription { this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); } - createFlatArray(collection: any[], Key: string) { - const result = []; + createFlatArray(collection: T[], key: keyof T): T[keyof T][] { + const result: T[keyof T][] = []; for (const element of collection) { - result.push(element[Key]); + const value = element[key]; + if (Array.isArray(value)) { + result.push(...value); + } else { + result.push(value); + } } - return result.flat(); + return result; } /** @@ -225,8 +230,8 @@ export class TuningTranscription { /** * 変更後のアクセント句に、createDiffPatchで作成したモーラ配列を適用し、各モーラ配列のテキストが一致したら、変更前のモーラを変更後のモーラに渡す */ - mergeAccentPhrases(moraPatch: any[]) { - const after = structuredClone(this.afterAccent); + mergeAccentPhrases(moraPatch: (Mora | undefined)[]): AccentPhrase[] { + const after: AccentPhrase[] = structuredClone(this.afterAccent); let beforeIndex = 0; // pluckedBeforeのデータの位置 // 与えられたアクセント句は、AccentPhrases[ Number ][ Object Key ][ Number ]の順番で、モーラを操作できるため、二重forで回す @@ -243,7 +248,7 @@ export class TuningTranscription { } if ( after[accentIndex]["moras"][moraIndex].text === - moraPatch[beforeIndex].text + moraPatch[beforeIndex]?.text ) { after[accentIndex]["moras"][moraIndex] = moraPatch[beforeIndex]; } From 73dbe47b9df0548e90f3cfbf48e4e9000094ed4f Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 4 Nov 2023 22:41:20 +0900 Subject: [PATCH 21/33] =?UTF-8?q?jsdoc=E3=81=AE=E4=BF=AE=E6=AD=A3=E3=81=A8?= =?UTF-8?q?=E3=80=81beforeIndex=20->=20moraPatchIndex=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index b55a0c3aa3..e3cbbd76d6 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -228,11 +228,16 @@ export class TuningTranscription { return beforeFlatArray; } /** - * 変更後のアクセント句に、createDiffPatchで作成したモーラ配列を適用し、各モーラ配列のテキストが一致したら、変更前のモーラを変更後のモーラに渡す + * テキスト: 「こんにちは」 -> 「こんばんは」 のように変更が与えられた場合、にmoraPatch配列とafter(AccentPhrases)を比較する。 + * + * moraPatch = [ {text: "コ"...}, {text: "ン"...}, undefined , undefined , {text: "は"...} ] + * after[...]["moras"] = [ {text: "コ"...}, {text: "ン"...}, {text: "バ"...}, {text: "ン"...}, {text: "は"...} ] + * + * text(key)の値が一致するとき、after[...]["moras"][moraIndex] = moraPatch[moraPatchIndex]と代入することで、モーラを再利用する。 */ mergeAccentPhrases(moraPatch: (Mora | undefined)[]): AccentPhrase[] { const after: AccentPhrase[] = structuredClone(this.afterAccent); - let beforeIndex = 0; // pluckedBeforeのデータの位置 + let moraPatchIndex = 0; // pluckedBeforeのデータの位置 // 与えられたアクセント句は、AccentPhrases[ Number ][ Object Key ][ Number ]の順番で、モーラを操作できるため、二重forで回す for (let accentIndex = 0; accentIndex < after.length; accentIndex++) { @@ -242,17 +247,17 @@ export class TuningTranscription { moraIndex++ ) { // undefinedのとき、何もせず次のモーラへ移動 - if (moraPatch[beforeIndex] == undefined) { - beforeIndex++; + if (moraPatch[moraPatchIndex] == undefined) { + moraPatchIndex++; continue; } if ( after[accentIndex]["moras"][moraIndex].text === - moraPatch[beforeIndex]?.text + moraPatch[moraPatchIndex]?.text ) { - after[accentIndex]["moras"][moraIndex] = moraPatch[beforeIndex]; + after[accentIndex]["moras"][moraIndex] = moraPatch[moraPatchIndex]; } - beforeIndex++; + moraPatchIndex++; } } From ddc4f68659a28e94d2dd0127093a4ed31c020856 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 4 Nov 2023 22:54:24 +0900 Subject: [PATCH 22/33] =?UTF-8?q?jsdoc=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index e3cbbd76d6..c9b83d81b2 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -177,6 +177,10 @@ function skipMemoText(targettext: string): string { /** * 2つのアクセント句配列を比べて同じだと思われるモーラの調整結果を転写し * 変更前のアクセント句の調整結果を変更後のアクセント句に保持する + * 「こんにちは」 -> 「こんばんは」と変更した場合、以下の例において[]に囲まれる部分は、変更前のアクセント句にあるモーラが再利用される。 + * <例> + * + * 「 [こん]ばん[は] 」 */ export class TuningTranscription { beforeAccent: AccentPhrase[]; @@ -228,9 +232,10 @@ export class TuningTranscription { return beforeFlatArray; } /** - * テキスト: 「こんにちは」 -> 「こんばんは」 のように変更が与えられた場合、にmoraPatch配列とafter(AccentPhrases)を比較する。 - * + * テキスト: 「こんにちは」 -> 「こんばんは」 と変更した場合、以下の例のように、moraPatch配列とafter(AccentPhrases)を比較する。 + * <例> (「||」は等号記号を表す) * moraPatch = [ {text: "コ"...}, {text: "ン"...}, undefined , undefined , {text: "は"...} ] + * || || || * after[...]["moras"] = [ {text: "コ"...}, {text: "ン"...}, {text: "バ"...}, {text: "ン"...}, {text: "は"...} ] * * text(key)の値が一致するとき、after[...]["moras"][moraIndex] = moraPatch[moraPatchIndex]と代入することで、モーラを再利用する。 From 56f9a33b1b2bd14d6080112142716bc8f06b416e Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 4 Nov 2023 23:15:14 +0900 Subject: [PATCH 23/33] =?UTF-8?q?=E5=9E=8B=E3=81=AE=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index c9b83d81b2..aff8ac8017 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -190,8 +190,8 @@ export class TuningTranscription { this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); } - createFlatArray(collection: T[], key: keyof T): T[keyof T][] { - const result: T[keyof T][] = []; + createFlatArray(collection: T[], key: K): T[K][] { + const result: T[K][] = []; for (const element of collection) { const value = element[key]; if (Array.isArray(value)) { @@ -212,9 +212,10 @@ export class TuningTranscription { const beforeFlatArray = this.createFlatArray(before, "moras"); const afterFlatArray = this.createFlatArray(after, "moras"); + console.log(beforeFlatArray); const diffed = diffArrays( - this.createFlatArray(structuredClone(beforeFlatArray), "text"), - this.createFlatArray(structuredClone(afterFlatArray), "text") + this.createFlatArray(structuredClone(beforeFlatArray), "text" as never), + this.createFlatArray(structuredClone(afterFlatArray), "text" as never) ); let pluckedIndex = 0; for (const diff of diffed) { From e233502dc788728adce5f68c4e931237274db1b0 Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sat, 4 Nov 2023 23:16:13 +0900 Subject: [PATCH 24/33] =?UTF-8?q?=E5=A4=89=E6=9B=B4=E6=BC=8F=E3=82=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index aff8ac8017..c724635e27 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -223,7 +223,7 @@ export class TuningTranscription { beforeFlatArray.splice(pluckedIndex, diff.count); } else if (diff.added) { diff.value.forEach(() => { - beforeFlatArray.splice(pluckedIndex, 0, undefined); + beforeFlatArray.splice(pluckedIndex, 0, undefined as never); pluckedIndex++; }); } else { From d403b15b523d1730b8294873cdc21a9f96cd8ded Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sun, 5 Nov 2023 00:39:43 +0900 Subject: [PATCH 25/33] =?UTF-8?q?never=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index c724635e27..783dd40015 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -261,7 +261,9 @@ export class TuningTranscription { after[accentIndex]["moras"][moraIndex].text === moraPatch[moraPatchIndex]?.text ) { - after[accentIndex]["moras"][moraIndex] = moraPatch[moraPatchIndex]; + after[accentIndex]["moras"][moraIndex] = moraPatch[ + moraPatchIndex + ] as Mora; } moraPatchIndex++; } @@ -272,7 +274,7 @@ export class TuningTranscription { transcribe() { const moraPatch = this.createDiffPatch(); - return this.mergeAccentPhrases(moraPatch); + return this.mergeAccentPhrases(moraPatch as never); } } From db2be540f3db2a1c9a33d812850e43fb98e8b3aa Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sun, 5 Nov 2023 00:56:32 +0900 Subject: [PATCH 26/33] =?UTF-8?q?jsdoc=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index 783dd40015..a78c979f41 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -204,7 +204,12 @@ export class TuningTranscription { } /** - * 変更前と変更後のモーラをフラット化し、変更後のモーラテキストに対応するようにフラット化した変更前のモーラ配列を操作する + * 変更前の配列を操作してpatchMora配列を作る + * <例> (Uはundefined) + * 変更前: [ "ズ", "ン", "ダ", "モ", "ン", "ナ", "ノ", "ダ" ] + * 変更後: [ "ボ", "ク", "ズ", "ン", "ダ", "ナ", "ノ", "デ", "ス" ] + * ↓ + * patchMora配列: [ U , U , "ズ", "ン", "ダ", "ナ", "ノ", U , U ] */ createDiffPatch() { const before = structuredClone(this.beforeAccent); From 67a522d6b46f57a069f28dedf66286c9a58ab4bf Mon Sep 17 00:00:00 2001 From: wewewe-ok Date: Sun, 5 Nov 2023 00:58:42 +0900 Subject: [PATCH 27/33] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF?= =?UTF-8?q?=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index a78c979f41..cf4a6535be 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -177,7 +177,7 @@ function skipMemoText(targettext: string): string { /** * 2つのアクセント句配列を比べて同じだと思われるモーラの調整結果を転写し * 変更前のアクセント句の調整結果を変更後のアクセント句に保持する - * 「こんにちは」 -> 「こんばんは」と変更した場合、以下の例において[]に囲まれる部分は、変更前のアクセント句にあるモーラが再利用される。 + * 「こんにちは」 -> 「こんばんは」と変更した場合、以下の例において[]に囲まれる部分は、変更前のモーラが再利用される。 * <例> * * 「 [こん]ばん[は] 」 @@ -248,7 +248,7 @@ export class TuningTranscription { */ mergeAccentPhrases(moraPatch: (Mora | undefined)[]): AccentPhrase[] { const after: AccentPhrase[] = structuredClone(this.afterAccent); - let moraPatchIndex = 0; // pluckedBeforeのデータの位置 + let moraPatchIndex = 0; // 与えられたアクセント句は、AccentPhrases[ Number ][ Object Key ][ Number ]の順番で、モーラを操作できるため、二重forで回す for (let accentIndex = 0; accentIndex < after.length; accentIndex++) { From 7b7b1808b085625dd9ad874793060ac20fa330ff Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Mon, 6 Nov 2023 01:37:40 +0900 Subject: [PATCH 28/33] =?UTF-8?q?=E3=82=A2=E3=82=AF=E3=82=BB=E3=83=B3?= =?UTF-8?q?=E3=83=88=E5=8F=A5=E5=86=85=E3=81=AE=E5=B7=AE=E5=88=86=E3=81=AE?= =?UTF-8?q?=E3=83=97=E3=83=AB=E3=83=AA=E3=82=AF=E3=82=A8=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E3=81=84=E3=82=8D=E3=81=84=E3=82=8D=E5=A4=89=E3=81=88?= =?UTF-8?q?=E3=81=A6=E3=81=BF=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 20 +++-- tests/unit/lib/tuningTranscription.spec.ts | 97 ++++++++++++++++++++++ 2 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 tests/unit/lib/tuningTranscription.spec.ts diff --git a/src/store/utility.ts b/src/store/utility.ts index cf4a6535be..c0592ce73d 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -190,8 +190,11 @@ export class TuningTranscription { this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); } - createFlatArray(collection: T[], key: K): T[K][] { - const result: T[K][] = []; + createFlatArray( + collection: T[], + key: K + ): T[K] extends (infer U)[] ? U[] : T[K][] { + const result = []; for (const element of collection) { const value = element[key]; if (Array.isArray(value)) { @@ -200,7 +203,7 @@ export class TuningTranscription { result.push(value); } } - return result; + return result as T[K] extends (infer U)[] ? U[] : T[K][]; } /** @@ -217,25 +220,26 @@ export class TuningTranscription { const beforeFlatArray = this.createFlatArray(before, "moras"); const afterFlatArray = this.createFlatArray(after, "moras"); - console.log(beforeFlatArray); const diffed = diffArrays( - this.createFlatArray(structuredClone(beforeFlatArray), "text" as never), - this.createFlatArray(structuredClone(afterFlatArray), "text" as never) + this.createFlatArray(structuredClone(beforeFlatArray), "text"), + this.createFlatArray(structuredClone(afterFlatArray), "text") ); + + // FIXME: beforeFlatArrayを破壊的に変更しなくても良いようにしてasを不要にする let pluckedIndex = 0; for (const diff of diffed) { if (diff.removed) { beforeFlatArray.splice(pluckedIndex, diff.count); } else if (diff.added) { diff.value.forEach(() => { - beforeFlatArray.splice(pluckedIndex, 0, undefined as never); + beforeFlatArray.splice(pluckedIndex, 0, undefined as never as Mora); pluckedIndex++; }); } else { pluckedIndex += diff.value.length; } } - return beforeFlatArray; + return beforeFlatArray as (Mora | undefined)[]; } /** * テキスト: 「こんにちは」 -> 「こんばんは」 と変更した場合、以下の例のように、moraPatch配列とafter(AccentPhrases)を比較する。 diff --git a/tests/unit/lib/tuningTranscription.spec.ts b/tests/unit/lib/tuningTranscription.spec.ts new file mode 100644 index 0000000000..234395b3e1 --- /dev/null +++ b/tests/unit/lib/tuningTranscription.spec.ts @@ -0,0 +1,97 @@ +import { AccentPhrase, Mora } from "@/openapi"; +import { TuningTranscription } from "@/store/utility"; + +function createDummyMora(text: string): Mora { + return { + text, + vowel: "dummy", + vowelLength: Math.random(), + pitch: Math.random(), + }; +} + +function createDummyAccentPhrase(moraTexts: string[]): AccentPhrase { + return { + moras: moraTexts.map(createDummyMora), + accent: Math.random(), + }; +} + +// AccentPhrasesから特定のmora textを持つものMoraを返す +function findMora( + accentPhrases: AccentPhrase[], + text: string +): Mora | undefined { + let candidate: Mora | undefined; + for (let i = 0; i < accentPhrases.length; i++) { + for (let j = 0; j < accentPhrases[i].moras.length; j++) { + if (accentPhrases[i].moras[j].text === text) { + if (candidate != undefined) { + throw new Error(`AccentPhraseに${text}が複数見つかりました`); + } + candidate = accentPhrases[i].moras[j]; + } + } + } + return candidate; +} + +it("2つ以上のアクセント句でも正しくデータを転写できる", async () => { + const before: AccentPhrase[] = [ + createDummyAccentPhrase(["い", "え"]), + createDummyAccentPhrase(["か", "き", "く", "け", "こ"]), + createDummyAccentPhrase(["さ", "し", "す", "せ", "そ"]), + ]; + const after: AccentPhrase[] = [ + createDummyAccentPhrase(["あ", "い", "う", "え", "お"]), // 最初・真ん中・最後に追加 + createDummyAccentPhrase(["き", "け"]), // 最初・真ん中・最後を消去 + createDummyAccentPhrase(["た", "ち", "つ", "て", "と"]), // すべて置き換え + ]; + const tuningTransctiption = new TuningTranscription(before, after); + const result = tuningTransctiption.transcribe(); + + // モーラ数などは変わっていない + expect(result.length).toEqual(after.length); + for (let i = 0; i < result.length; i++) { + expect(result[i].moras.length).toEqual(after[i].moras.length); + } + + // 転写されている + ["い", "え", "き", "け"].forEach((moraText) => { + expect(findMora(result, moraText)).toEqual(findMora(before, moraText)); + }); + + // 転写されていない + ["あ", "う", "お", "た", "ち", "つ", "て", "と"].forEach((moraText) => { + expect(findMora(result, moraText)).not.toEqual(findMora(before, moraText)); + }); +}); + +it("拗音のあるモーラも正しくデータを転写できる", async () => { + const before = [ + createDummyAccentPhrase(["い", "しぃ", "う", "しゅ", "お", "しょ"]), + ]; + const after = [ + createDummyAccentPhrase(["あ", "しゃ", "き", "きゅ", "お", "しょ"]), + ]; + const tuningTransctiption = new TuningTranscription(before, after); + const result = tuningTransctiption.transcribe(); + + console.log(tuningTransctiption.createDiffPatch()); + + // モーラ数などは変わっていない + expect(result.length).toEqual(after.length); + for (let i = 0; i < result.length; i++) { + expect(result[i].moras.length).toEqual(after[i].moras.length); + } + + // 転写されている + ["お", "しょ"].forEach((moraText) => { + expect(findMora(result, moraText)).toEqual(findMora(before, moraText)); + }); + + // 転写されていない + ["あ", "しゃ", "き", "きゅ"].forEach((moraText) => { + expect(findMora(result, moraText)).not.toEqual(findMora(before, moraText)); + }); +}); From 2ad775e4afee60df48462c22ed9637884e2b3738 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 10 Nov 2023 09:25:03 +0900 Subject: [PATCH 29/33] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=92=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index 67e667e8a7..bdddf5d9b8 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -177,9 +177,9 @@ function skipMemoText(targettext: string): string { /** * 2つのアクセント句配列を比べて同じだと思われるモーラの調整結果を転写し * 変更前のアクセント句の調整結果を変更後のアクセント句に保持する。 - * 「こんにちは」 -> 「こんばんは」と変更した場合、以下の例において[]に囲まれる部分は、変更前のモーラが再利用される。 - * <例> * + * <例> + * 「こんにちは」 -> 「こんばんは」と変更した場合、[]に囲まれる部分で変更前のモーラが転写される。 * 「 [こん]ばん[は] 」 */ export class TuningTranscription { @@ -208,18 +208,16 @@ export class TuningTranscription { /** * 変更前の配列を操作してpatchMora配列を作る。 + * * <例> (Uはundefined) - * 変更前のテキスト差分: [ "ズ", "ン", "ダ", "モ", "ン", "ナ", "ノ", "ダ" ] - * 変更後のテキスト差分: [ "ボ", "ク", "ズ", "ン", "ダ", "ナ", "ノ", "デ", "ス" ] - * ↓ - * ↓ 再利用される文字列とundefinedで構成されたデータを作る。 - * ↓ 比較しやすいように文字列とundefinedを記述しているが、 - * ↓ 実際には"ズ"などの文字列部分が{text: "ズ"...}のようなデータ構造となる。 - * ↓ - * [ U , U , "ズ", "ン", "ダ", "ナ", "ノ", U , U ] + * 変更前 [ ズ, ン, ダ, モ, ン, ナ, ノ, ダ ] + * 変更後 [ ボ, ク, ズ, ン, ダ, ナ, ノ, デ, ス ] * - * したがって、最終的にこちらのようなデータ構造(↓)が出力される。 - * 実際に作られるpatchMora配列: [ U , U , {text: "ズ"...}, {text: "ン"...}, {text: "ダ"...},{text: "ナ"...},{text: "ノ"...}, U , U ] + * 再利用される文字列とundefinedで構成されたデータを作る。 + * [ U, U, ズ, ン, ダ, ナ, ノ, U, U ] + * + * 実際には"ズ"などの文字列部分は{text: "ズ"...}のようなデータ構造になっている。 + * [ U, U, {text: "ズ"...}, {text: "ン"...}, {text: "ダ"...}, {text: "ナ"...}, {text: "ノ"...}, U, U ] */ createDiffPatch() { const before = structuredClone(this.beforeAccent); @@ -250,20 +248,23 @@ export class TuningTranscription { } /** - * 「こんにちは」 -> 「こんばんは」 とテキストを変更した場合、以下の例のように、moraPatch配列とafter(AccentPhrases)を比較し、 - * text(key)の値が一致するとき、after[...]["moras"][moraIndex] = moraPatch[moraPatchIndex]と代入することで、モーラを再利用する。 + * moraPatchとafterAccentを比較し、textが一致するモーラを転写する。 * * <例> (「||」は等号記号を表す) + * 「こんにちは」 -> 「こんばんは」 とテキストを変更した場合、以下の例のように比較する。 + * * moraPatch = [ {text: "コ"...}, {text: "ン"...}, undefined , undefined , {text: "ハ"...} ] * || || || * after[...]["moras"] = [ {text: "コ"...}, {text: "ン"...}, {text: "バ"...}, {text: "ン"...}, {text: "ハ"...} ] * + * あとは一致したモーラを転写するだけ。 + * */ mergeAccentPhrases(moraPatch: (Mora | undefined)[]): AccentPhrase[] { const after: AccentPhrase[] = structuredClone(this.afterAccent); let moraPatchIndex = 0; - // 与えられたアクセント句は、AccentPhrases[ Number ][ Object Key ][ Number ]の順番で、モーラを操作できるため、二重forで回す。 + // AccentPhrasesから[ accentIndex ]["moras"][ moraIndex ]でモーラが得られる。 for (let accentIndex = 0; accentIndex < after.length; accentIndex++) { for ( let moraIndex = 0; From 1b67f74f9813f2e74d4f11aed1e682defa56248c Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 10 Nov 2023 09:28:24 +0900 Subject: [PATCH 30/33] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AAstructuredClon?= =?UTF-8?q?e=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/utility.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index bdddf5d9b8..b3e1dc9be5 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -219,15 +219,15 @@ export class TuningTranscription { * 実際には"ズ"などの文字列部分は{text: "ズ"...}のようなデータ構造になっている。 * [ U, U, {text: "ズ"...}, {text: "ン"...}, {text: "ダ"...}, {text: "ナ"...}, {text: "ノ"...}, U, U ] */ - createDiffPatch() { + private createDiffPatch() { const before = structuredClone(this.beforeAccent); const after = structuredClone(this.afterAccent); const beforeFlatArray = this.createFlatArray(before, "moras"); const afterFlatArray = this.createFlatArray(after, "moras"); const diffed = diffArrays( - this.createFlatArray(structuredClone(beforeFlatArray), "text"), - this.createFlatArray(structuredClone(afterFlatArray), "text") + this.createFlatArray(beforeFlatArray, "text"), + this.createFlatArray(afterFlatArray, "text") ); // FIXME: beforeFlatArrayを破壊的に変更しなくても良いようにしてasを不要にする @@ -260,7 +260,7 @@ export class TuningTranscription { * あとは一致したモーラを転写するだけ。 * */ - mergeAccentPhrases(moraPatch: (Mora | undefined)[]): AccentPhrase[] { + private mergeAccentPhrases(moraPatch: (Mora | undefined)[]): AccentPhrase[] { const after: AccentPhrase[] = structuredClone(this.afterAccent); let moraPatchIndex = 0; From 81841f91ca09c90837d9a02c8b924723051a7a63 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 10 Nov 2023 09:29:18 +0900 Subject: [PATCH 31/33] private --- src/store/utility.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index b3e1dc9be5..e03d9c306b 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -190,7 +190,7 @@ export class TuningTranscription { this.afterAccent = JSON.parse(JSON.stringify(afterAccent)); } - createFlatArray( + private createFlatArray( collection: T[], key: K ): T[K] extends (infer U)[] ? U[] : T[K][] { From da456e20e47cd4338f64e880bdb12aca9f2d36c2 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 10 Nov 2023 09:47:26 +0900 Subject: [PATCH 32/33] currentTextIndex --- src/store/utility.ts | 17 ++++++++++++----- tests/unit/lib/tuningTranscription.spec.ts | 2 -- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index e03d9c306b..61698c914c 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -231,17 +231,21 @@ export class TuningTranscription { ); // FIXME: beforeFlatArrayを破壊的に変更しなくても良いようにしてasを不要にする - let pluckedIndex = 0; + let currentTextIndex = 0; for (const diff of diffed) { if (diff.removed) { - beforeFlatArray.splice(pluckedIndex, diff.count); + beforeFlatArray.splice(currentTextIndex, diff.count); } else if (diff.added) { diff.value.forEach(() => { - beforeFlatArray.splice(pluckedIndex, 0, undefined as never as Mora); - pluckedIndex++; + beforeFlatArray.splice( + currentTextIndex, + 0, + undefined as never as Mora + ); + currentTextIndex++; }); } else { - pluckedIndex += diff.value.length; + currentTextIndex += diff.value.length; } } return beforeFlatArray as (Mora | undefined)[]; @@ -271,6 +275,8 @@ export class TuningTranscription { moraIndex < after[accentIndex]["moras"].length; moraIndex++ ) { + console.log(moraIndex); + // undefinedのとき、何もせず次のモーラへ移動 if (moraPatch[moraPatchIndex] == undefined) { moraPatchIndex++; @@ -283,6 +289,7 @@ export class TuningTranscription { after[accentIndex]["moras"][moraIndex] = moraPatch[ moraPatchIndex ] as Mora; + console.log("copied!"); } moraPatchIndex++; } diff --git a/tests/unit/lib/tuningTranscription.spec.ts b/tests/unit/lib/tuningTranscription.spec.ts index 234395b3e1..d14e5ce4a4 100644 --- a/tests/unit/lib/tuningTranscription.spec.ts +++ b/tests/unit/lib/tuningTranscription.spec.ts @@ -77,8 +77,6 @@ it("拗音のあるモーラも正しくデータを転写できる", async () = const tuningTransctiption = new TuningTranscription(before, after); const result = tuningTransctiption.transcribe(); - console.log(tuningTransctiption.createDiffPatch()); - // モーラ数などは変わっていない expect(result.length).toEqual(after.length); for (let i = 0; i < result.length; i++) { From e2fae752bd20ff5d0fad312b5031c64307fb4e24 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 10 Nov 2023 09:50:08 +0900 Subject: [PATCH 33/33] remove console.log --- src/store/utility.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/store/utility.ts b/src/store/utility.ts index 61698c914c..480a16ff8d 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -275,8 +275,6 @@ export class TuningTranscription { moraIndex < after[accentIndex]["moras"].length; moraIndex++ ) { - console.log(moraIndex); - // undefinedのとき、何もせず次のモーラへ移動 if (moraPatch[moraPatchIndex] == undefined) { moraPatchIndex++; @@ -289,7 +287,6 @@ export class TuningTranscription { after[accentIndex]["moras"][moraIndex] = moraPatch[ moraPatchIndex ] as Mora; - console.log("copied!"); } moraPatchIndex++; }