[F] Space between English words

This commit is contained in:
2025-11-29 13:22:13 +08:00
parent cf02921078
commit 0bb68ae554
4 changed files with 20 additions and 5 deletions
+1
View File
@@ -88,6 +88,7 @@ export const typingSettingsDefault = {
showRomaji: false, showRomaji: false,
showRomajiOnError: true, showRomajiOnError: true,
hideRepeated: false, hideRepeated: false,
ignoreEnglish: false,
}; };
export type TypingSettings = typeof typingSettingsDefault; export type TypingSettings = typeof typingSettingsDefault;
+3 -1
View File
@@ -49,4 +49,6 @@ export function dedupLines(lrc: LyricLine[], hide: boolean) {
seen.add(key); seen.add(key);
return true; return true;
}); });
} }
export const isEnglish = (str: string | undefined) => str && /^[a-zA-Z\s.,'!?]+$/.test(str)
+10 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { tick } from "svelte" import { tick } from "svelte"
import { isKana, isKanji, toKatakana, toRomaji } from "wanakana" import { isKana, isKanji, toKatakana, toRomaji } from "wanakana"
import type { ProcLrcLine, ProcLrcSeg } from "./IMEHelper" import { isEnglish, type ProcLrcLine, type ProcLrcSeg } from "./IMEHelper"
import type { TypingSettings } from "$lib/types" import type { TypingSettings } from "$lib/types"
import { animateCaret } from "./animation" import { animateCaret } from "./animation"
@@ -31,8 +31,11 @@
const _preprocessKana = (kana: string) => settings.allKata ? toKatakana(kana) : kana const _preprocessKana = (kana: string) => settings.allKata ? toKatakana(kana) : kana
const preprocessKana = (kana: string, state?: string) => (settings.showRomaji || (settings.showRomajiOnError && state === 'wrong')) ? `<ruby>${_preprocessKana(kana)}<rt>${toRomaji(kana)}</rt></ruby>` : _preprocessKana(kana) const preprocessKana = (kana: string, state?: string) => (settings.showRomaji || (settings.showRomajiOnError && state === 'wrong')) ? `<ruby>${_preprocessKana(kana)}<rt>${toRomaji(kana)}</rt></ruby>` : _preprocessKana(kana)
const allStates = (l: number, seg: ProcLrcSeg) => states[l]?.slice(seg.swi, seg.swi + seg.kana.length) ?? [] const allStates = (l: number, seg: ProcLrcSeg) => states[l]?.slice(seg.swi, seg.swi + seg.kana.length) ?? []
const getKanjiState = (l: number, seg: ProcLrcSeg) => { const getKanjiState = (l: number, seg: ProcLrcSeg) => {
if (settings.ignoreEnglish && isEnglish(seg.kanji)) return 'ignored'
let sts = allStates(l, seg) let sts = allStates(l, seg)
if (sts.every(s => s === 'right')) return 'right' if (sts.every(s => s === 'right')) return 'right'
if (sts.some(s => s === 'wrong')) return 'wrong' if (sts.some(s => s === 'wrong')) return 'wrong'
@@ -73,7 +76,7 @@
<div class="lrc p-content text-center m3-font-body-large" class:active={l === currentLineIndex} role="button" tabindex="0" <div class="lrc p-content text-center m3-font-body-large" class:active={l === currentLineIndex} role="button" tabindex="0"
onclick={() => onLineClick?.()} onclick={() => onLineClick?.()}
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onLineClick?.() } }}> onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onLineClick?.() } }}>
{#each line.parts as seg} {#each line.parts as seg, i}
{#if !seg.kanji} {#if !seg.kanji}
{#each seg.kana as char, c} {#each seg.kana as char, c}
<span class="{states[l]?.[seg.swi + c] ?? ''}" class:here={l === currentLineIndex && currentWordIndex === seg.swi + c} <span class="{states[l]?.[seg.swi + c] ?? ''}" class:here={l === currentLineIndex && currentWordIndex === seg.swi + c}
@@ -90,6 +93,9 @@
</rt>{/if} </rt>{/if}
</ruby> </ruby>
{/if} {/if}
{#if line.parts[i+1] && (isEnglish(seg.kanji ?? seg.kana) || isEnglish(line.parts[i+1].kanji ?? line.parts[i+1].kana))}
&nbsp;
{/if}
{/each} {/each}
</div> </div>
{/each} {/each}
@@ -125,4 +131,6 @@
color: #7b78c2 color: #7b78c2
.punctuation .punctuation
opacity: 0.5 opacity: 0.5
.ignored
opacity: 0.5
</style> </style>
+6 -2
View File
@@ -4,7 +4,7 @@
import { onMount } from "svelte" import { onMount } from "svelte"
import { typingSettingsDefault } from "$lib/types.ts" import { typingSettingsDefault } from "$lib/types.ts"
import { isKana, isKanji, toHiragana } from "wanakana" import { isKana, isKanji, toHiragana } from "wanakana"
import { composeList, fuzzyEquals, processLrcLine, dedupLines, type ProcLrcLine } from "$lib/ui/player/IMEHelper.ts" import { composeList, fuzzyEquals, processLrcLine, dedupLines, isEnglish, type ProcLrcLine } from "$lib/ui/player/IMEHelper.ts"
import "$lib/ext.ts" import "$lib/ext.ts"
import { API } from "$lib/client.ts" import { API } from "$lib/client.ts"
import { goto } from '$app/navigation' import { goto } from '$app/navigation'
@@ -129,7 +129,11 @@
} }
// Check next expected character, if it's neither kana nor kanji, skip it // Check next expected character, if it's neither kana nor kanji, skip it
while (findLoc().let(({ exp, cLine }) => !isKana(exp) && !isKanji(exp) && incr(cLine))) {} while (findLoc().let(({ exp, cLine, cSeg }) => {
const isPunctuation = !isKana(exp) && !isKanji(exp)
const isIgnoredEnglish = ud.settings.ignoreEnglish && isEnglish(cSeg.kanji)
return (isPunctuation || isIgnoredEnglish) && incr(cLine)
})) {}
} }
$effect(() => inputChanged(inp, false)) $effect(() => inputChanged(inp, false))