feat(subtitles): add regex subtitle filters with built-in presets (#318)

- Add `subtitleFilter` config with four presets: parentheses, brackets, speaker prefix and music symbols. Custom regex rules run after the presets.
- Filter primary text where it enters the app (live `sub-text` and parsed cues), so the overlay, sidebar, mining and stats all get the same filtered text.
- Changes hot-reload: the current line is read again and the active track is parsed again, using the filter config as the prefetch parse key.
- Add a custom rule editor in Settings under Behavior → Subtitle Filters that checks patterns as you type.
- Update the config example, the configuration docs and the architecture domains doc, and add a changelog fragment.
This commit is contained in:
sudacode authored and GitHub committed 2026-11-03 00:33:58 -08:00
1 parent 848a6c4021
commit fa3051f9cb
28 files changed
+740 -11

No files matched your search

+4
View File
@@ -36,9 +36,11 @@ import type {
FrequencyDictionaryMatchMode,
FrequencyDictionaryMode,
NPlusOneMatchMode,
ResolvedSubtitleFilterConfig,
ResolvedSubtitleSidebarConfig,
SecondarySubConfig,
SubtitlePosition,
SubtitleFilterConfig,
SubtitleSidebarConfig,
SubtitleStyleConfig,
} from './subtitle';
@@ -170,6 +172,7 @@ export interface Config {
startupWarmups?: StartupWarmupsConfig;
subtitleStyle?: SubtitleStyleConfig;
subtitleSidebar?: SubtitleSidebarConfig;
subtitleFilter?: SubtitleFilterConfig;
auto_start_overlay?: boolean;
jimaku?: JimakuConfig;
/** @deprecated Use tsukihime. */
@@ -344,6 +347,7 @@ export interface ResolvedConfig {
};
};
subtitleSidebar: ResolvedSubtitleSidebarConfig;
subtitleFilter: ResolvedSubtitleFilterConfig;
auto_start_overlay: boolean;
jimaku: JimakuConfig & {
apiBaseUrl: string;
+2 -1
View File
@@ -28,7 +28,8 @@ export type ConfigSettingsControl =
| 'anki-field'
| 'mpv-keybindings'
| 'color-list'
| 'css-declarations';
| 'css-declarations'
| 'subtitle-filter-rules';
export type ConfigSettingsRestartBehavior = 'hot-reload' | 'restart';
+21
View File
@@ -84,6 +84,27 @@ export interface SecondarySubConfig {
defaultMode?: SecondarySubMode;
}
/** Built-in subtitle text filters; `subtitle-text-filter.ts` holds their patterns. */
export type SubtitleFilterPresetId = 'parentheses' | 'brackets' | 'speakerPrefix' | 'musicSymbols';
/** A user regex rule. Patterns compile with the `gmu` flags, so `^`/`$` match per line. */
export interface SubtitleFilterRule {
name: string;
pattern: string;
replacement: string;
enabled: boolean;
}
export interface SubtitleFilterConfig {
presets?: Partial<Record<SubtitleFilterPresetId, boolean>>;
customRules?: Partial<SubtitleFilterRule>[];
}
export interface ResolvedSubtitleFilterConfig {
presets: Record<SubtitleFilterPresetId, boolean>;
customRules: SubtitleFilterRule[];
}
export type NPlusOneMatchMode = 'headword' | 'surface';
export type FrequencyDictionaryMatchMode = 'headword' | 'surface';