Skip to content

Commit

Permalink
メモとルビ機能を設定で変更可能にし、デフォルトをオフにする (#1700)
Browse files Browse the repository at this point in the history
* メモとルビ機能を設定で変更可能にし、デフォルトをオフにする

* 少しドキュメントを足した
  • Loading branch information
Hiroshiba authored Jan 12, 2024
1 parent 97ebf38 commit 577cd93
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 54 deletions.
106 changes: 75 additions & 31 deletions src/components/SettingDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,56 @@
</template>
</q-btn-toggle>
</q-card-actions>
<q-card-actions class="q-px-md q-py-sm bg-surface">
<div>メモ機能</div>
<div
aria-label="ONの場合、テキストを [] で囲むことで、テキスト中にメモを書けます。"
>
<q-icon name="help_outline" size="sm" class="help-hover-icon">
<q-tooltip
:delay="500"
anchor="center right"
self="center left"
transition-show="jump-right"
transition-hide="jump-left"
>
ONの場合、テキストを []
で囲むことで、テキスト中にメモを書けます。
</q-tooltip>
</q-icon>
</div>
<q-space />
<q-toggle
:model-value="enableMemoNotation"
@update:model-value="changeEnableMemoNotation($event)"
>
</q-toggle>
</q-card-actions>
<q-card-actions class="q-px-md q-py-sm bg-surface">
<div>ルビ機能</div>
<div
aria-label="ONの場合、テキストに {ルビ対象|よみかた} と書くことで、テキストの読み方を変えられます。"
>
<q-icon name="help_outline" size="sm" class="help-hover-icon">
<q-tooltip
:delay="500"
anchor="center right"
self="center left"
transition-show="jump-right"
transition-hide="jump-left"
>
ONの場合、テキストに {ルビ対象|よみかた}
と書くことで、テキストの読み方を変えられます。
</q-tooltip>
</q-icon>
</div>
<q-space />
<q-toggle
:model-value="enableRubyNotation"
@update:model-value="changeEnableRubyNotation($event)"
>
</q-toggle>
</q-card-actions>
<q-card-actions class="q-px-md q-py-sm bg-surface">
<div>非表示にしたヒントを全て再表示</div>
<div
Expand Down Expand Up @@ -952,12 +1002,23 @@ import {
ExperimentalSettingType,
ActivePointScrollMode,
SplitTextWhenPasteType,

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / lint

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-test

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (windows-cpu-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (linux-cpu-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (windows-directml-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (macos-cpu-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (linux-nvidia-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (windows-nvidia-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (linux-cpu-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (linux-nvidia-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (windows-directml-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (windows-nvidia-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (windows-cpu-prepackage)

'SplitTextWhenPasteType' is defined but never used

Check warning on line 1004 in src/components/SettingDialog.vue

View workflow job for this annotation

GitHub Actions / build-and-upload (macos-cpu-prepackage)

'SplitTextWhenPasteType' is defined but never used
EditorFontType,
RootMiscSettingType,
EngineId,
} from "@/type/preload";
type SamplingRateOption = EngineSettingType["outputSamplingRate"];
// ルート直下にある雑多な設定値を簡単に扱えるようにする
const useRootMiscSetting = <T extends keyof RootMiscSettingType>(key: T) => {
const state = computed(() => store.state[key]);
const setter = (value: RootMiscSettingType[T]) => {
// Vuexの型処理でUnionが解かれてしまうのを迂回している
// FIXME: このワークアラウンドをなくす
store.dispatch("SET_ROOT_MISC_SETTING", { key: key as never, value });
};
return [state, setter] as const;
};
const props =
defineProps<{
modelValue: boolean;
Expand Down Expand Up @@ -1039,29 +1100,13 @@ const availableThemeNameComputed = computed(() => {
});
});
const editorFont = computed(() => store.state.editorFont);
const changeEditorFont = (editorFont: EditorFontType) => {
store.dispatch("SET_ROOT_MISC_SETTING", {
key: "editorFont",
value: editorFont,
});
};
const [editorFont, changeEditorFont] = useRootMiscSetting("editorFont");
const enableMultiEngine = computed(() => store.state.enableMultiEngine);
const setEnableMultiEngine = (enableMultiEngine: boolean) => {
store.dispatch("SET_ROOT_MISC_SETTING", {
key: "enableMultiEngine",
value: enableMultiEngine,
});
};
const [enableMultiEngine, setEnableMultiEngine] =
useRootMiscSetting("enableMultiEngine");
const showTextLineNumber = computed(() => store.state.showTextLineNumber);
const changeShowTextLineNumber = (showTextLineNumber: boolean) => {
store.dispatch("SET_ROOT_MISC_SETTING", {
key: "showTextLineNumber",
value: showTextLineNumber,
});
};
const [showTextLineNumber, changeShowTextLineNumber] =
useRootMiscSetting("showTextLineNumber");
// エディタの+ボタン表示設定
const showAddAudioItemButton = computed(
Expand Down Expand Up @@ -1092,6 +1137,12 @@ const changeShowAddAudioItemButton = async (
}
};
const [enableMemoNotation, changeEnableMemoNotation] =
useRootMiscSetting("enableMemoNotation");
const [enableRubyNotation, changeEnableRubyNotation] =
useRootMiscSetting("enableRubyNotation");
const canSetAudioOutputDevice = computed(() => {
return !!HTMLAudioElement.prototype.setSinkId;
});
Expand Down Expand Up @@ -1277,15 +1328,8 @@ const openFileExplore = async () => {
}
};
const splitTextWhenPaste = computed(() => store.state.splitTextWhenPaste);
const changeSplitTextWhenPaste = (
splitTextWhenPaste: SplitTextWhenPasteType
) => {
store.dispatch("SET_ROOT_MISC_SETTING", {
key: "splitTextWhenPaste",
value: splitTextWhenPaste,
});
};
const [splitTextWhenPaste, changeSplitTextWhenPaste] =
useRootMiscSetting("splitTextWhenPaste");
const showsFilePatternEditDialog = ref(false);
Expand Down
23 changes: 19 additions & 4 deletions src/store/audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,10 @@ export const audioStore = createPartialStore<AudioStoreTypes>({

if (state.savingSetting.exportText) {
await writeTextFile({
text: extractExportText(state.audioItems[audioKey].text),
text: extractExportText(state.audioItems[audioKey].text, {
enableMemoNotation: state.enableMemoNotation,
enableRubyNotation: state.enableRubyNotation,
}),
filePath: filePath.replace(/\.wav$/, ".txt"),
encoding: state.savingSetting.fileEncoding,
}).then(getValueOrThrow);
Expand Down Expand Up @@ -1608,7 +1611,12 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
return { result: "WRITE_ERROR", path: filePath };
}
labs.push(lab);
texts.push(extractExportText(state.audioItems[audioKey].text));
texts.push(
extractExportText(state.audioItems[audioKey].text, {
enableMemoNotation: state.enableMemoNotation,
enableRubyNotation: state.enableRubyNotation,
})
);
// 最終音素の終了時刻を取得する
const splitLab = lab.split(" ");
labOffset = Number(splitLab[splitLab.length - 2]);
Expand Down Expand Up @@ -1715,7 +1723,11 @@ export const audioStore = createPartialStore<AudioStoreTypes>({
: "";

const skippedText = extractExportText(
state.audioItems[audioKey].text
state.audioItems[audioKey].text,
{
enableMemoNotation: state.enableMemoNotation,
enableRubyNotation: state.enableRubyNotation,
}
);
texts.push(speakerName + skippedText);
}
Expand Down Expand Up @@ -1946,7 +1958,10 @@ export const audioCommandStore = transformCommandStore(
const engineId = state.audioItems[audioKey].voice.engineId;
const styleId = state.audioItems[audioKey].voice.styleId;
const query = state.audioItems[audioKey].query;
const skippedText = extractYomiText(text);
const skippedText = extractYomiText(text, {
enableMemoNotation: state.enableMemoNotation,
enableRubyNotation: state.enableRubyNotation,
});

try {
if (query != undefined) {
Expand Down
4 changes: 4 additions & 0 deletions src/store/setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export const settingStoreState: SettingStoreState = {
},
engineSettings: {},
enableMultiEngine: false,
enableMemoNotation: false,
enableRubyNotation: false,
};

export const settingStore = createPartialStore<SettingStoreTypes>({
Expand Down Expand Up @@ -140,6 +142,8 @@ export const settingStore = createPartialStore<SettingStoreTypes>({
"splitTextWhenPaste",
"splitterPosition",
"enableMultiEngine",
"enableRubyNotation",
"enableMemoNotation",
] as const;

// rootMiscSettingKeysに値を足し忘れていたときに型エラーを出す検出用コード
Expand Down
47 changes: 39 additions & 8 deletions src/store/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,24 +154,55 @@ function replaceTag(
return result;
}

export function extractExportText(text: string): string {
return skipReadingPart(skipMemoText(text));
/**
* テキスト書き出し用のテキストを生成する。
*/
export function extractExportText(
text: string,
{
enableMemoNotation,
enableRubyNotation,
}: { enableMemoNotation: boolean; enableRubyNotation: boolean }
): string {
if (enableMemoNotation) {
text = skipMemoText(text);
}
if (enableRubyNotation) {
text = skipRubyReadingPart(text);
}
return text;
}
export function extractYomiText(text: string): string {
return skipWritingPart(skipMemoText(text));

/**
* 読み用のテキストを生成する。
*/
export function extractYomiText(
text: string,
{
enableMemoNotation,
enableRubyNotation,
}: { enableMemoNotation: boolean; enableRubyNotation: boolean }
): string {
if (enableMemoNotation) {
text = skipMemoText(text);
}
if (enableRubyNotation) {
text = skipRubyWritingPart(text);
}
return text;
}
function skipReadingPart(text: string): string {

function skipRubyReadingPart(text: string): string {
// テキスト内の全ての{漢字|かんじ}パターンを探し、漢字部分だけを残す
return text.replace(/\{([^|]*)\|([^}]*)\}/g, "$1");
}
function skipWritingPart(text: string): string {
function skipRubyWritingPart(text: string): string {
// テキスト内の全ての{漢字|かんじ}パターンを探し、かんじ部分だけを残す
return text.replace(/\{([^|]*)\|([^}]*)\}/g, "$2");
}
function skipMemoText(targettext: string): string {
// []をスキップ
const resolvedText = targettext.replace(/\[.*?\]/g, "");
return resolvedText;
return targettext.replace(/\[.*?\]/g, "");
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/type/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,8 @@ export const rootMiscSettingSchema = z.object({
.default("PERIOD_AND_NEW_LINE"),
splitterPosition: splitterPositionSchema.default({}),
enableMultiEngine: z.boolean().default(false),
enableMemoNotation: z.boolean().default(false), // メモ記法を有効にするか
enableRubyNotation: z.boolean().default(false), // ルビ記法を有効にするか
});
export type RootMiscSettingType = z.infer<typeof rootMiscSettingSchema>;

Expand Down
2 changes: 2 additions & 0 deletions tests/unit/store/Vuex.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ describe("store/vuex.js test", () => {
notifyOnGenerate: false,
},
enableMultiEngine: false,
enableMemoNotation: false,
enableRubyNotation: false,
progress: -1,
isVuexReady: false,
defaultPresetKeys: {},
Expand Down
67 changes: 56 additions & 11 deletions tests/unit/store/utility.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,63 @@ test("currentDateString", () => {
expect(currentDateString()).toMatch(/\d{4}\d{2}\d{2}/);
});

test("extractExportText", () => {
const input = "{漢字|かんじ}[半角記号メモ]";
const expected = "漢字";
const result = extractExportText(input);
expect(result).toEqual(expected);
});
describe("extractExportTextとextractYomiText", () => {
const memoText = "ダミー]ダミー[メモ]ダミー[ダミー";
const rubyText = "ダミー|}ダミー{漢字|読み}ダミー{|ダミー";

const text = memoText + rubyText;

const expectedSkippedMemoText = "ダミー]ダミーダミー[ダミー";
const expectedSkippedRubyExportText = "ダミー|}ダミー読みダミー{|ダミー";
const expectedSkippedRubyYomiText = "ダミー|}ダミー漢字ダミー{|ダミー";

it("無指定の場合はそのまま", () => {
const param = {
enableMemoNotation: false,
enableRubyNotation: false,
};
expect(extractExportText(text, param)).toBe(text);
expect(extractYomiText(text, param)).toBe(text);
});

test("extractYomiText", () => {
const input = "{漢字|かんじ}[メモ]";
const expected = "かんじ";
const result = extractYomiText(input);
expect(result).toEqual(expected);
it("メモをスキップ", () => {
const param = {
enableMemoNotation: true,
enableRubyNotation: false,
};
expect(extractExportText(text, param)).toBe(
expectedSkippedMemoText + rubyText
);
expect(extractYomiText(text, param)).toBe(
expectedSkippedMemoText + rubyText
);
});

it("ルビをスキップ", () => {
const param = {
enableMemoNotation: false,
enableRubyNotation: true,
};
expect(extractExportText(text, param)).toBe(
memoText + expectedSkippedRubyYomiText
);
expect(extractYomiText(text, param)).toBe(
memoText + expectedSkippedRubyExportText
);
});

it("メモとルビをスキップ", () => {
const param = {
enableMemoNotation: true,
enableRubyNotation: true,
};
expect(extractExportText(text, param)).toBe(
expectedSkippedMemoText + expectedSkippedRubyYomiText
);
expect(extractYomiText(text, param)).toBe(
expectedSkippedMemoText + expectedSkippedRubyExportText
);
});
});

describe("TuningTranscription", () => {
Expand Down

0 comments on commit 577cd93

Please sign in to comment.