Merge PR #2437: keep a WebVTT cue whose identifier is a metadata word (#2434)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Palash Debnath
2026-10-01 18:44:09 +05:30
co-authored by Claude Sonnet 5.5
2 changed files with 19 additions and 6 deletions
+5 -1
View File
@@ -83,7 +83,11 @@ function captionBlocks(text, webvtt) {
if (!lines.length) return false;
const first = lines[0];
if (/^WEBVTT(?:[ \t]|$)/.test(first)) return false;
return !isWebVttMetadata(first);
if (!isWebVttMetadata(first)) return true;
// WebVTT's block parser gives a timing line in position two precedence
// over the identifier, so `STYLE`/`REGION`/`NOTE` can name a real cue.
// https://www.w3.org/TR/webvtt1/#file-parsing — mirrors parse_srt.
return lines.length > 1 && isTimingLine(lines[1]);
});
}
+14 -5
View File
@@ -109,11 +109,20 @@ describe('parseSrt', () => {
'00:00:01.000 --> 00:00:02.000\nSpoken text\n';
expect(parseSrt(vtt)).toBe('Spoken text');
});
it('never treats a NOTE block as a cue even when it contains a valid timing line', () => {
const vtt =
'WEBVTT\n\nNOTE\n00:00:01.000 --> 00:00:02.000\nprivate note\n\n' +
'00:00:03.000 --> 00:00:04.000\nSpoken text\n';
expect(parseSrt(vtt)).toBe('Spoken text');
it('lets a timing line in position two outrank a metadata identifier', () => {
for (const identifier of ['STYLE', 'REGION', 'NOTE', 'NOTE identifier']) {
expect(parseSrt(`WEBVTT\n\n${identifier}\n00:01.000 --> 00:02.000\nSpoken text\n`)).toBe(
'Spoken text',
);
}
});
it('keeps a cue whose identifier is STYLE or REGION in a mixed file', () => {
for (const identifier of ['intro', 'STYLE', 'REGION']) {
const vtt =
`WEBVTT\n\n${identifier}\n00:00:01.000 --> 00:00:02.000\nHello world.\n\n` +
'next\n00:00:03.000 --> 00:00:04.000\nStill here.\n';
expect(parseSrt(vtt)).toBe('Hello world.\nStill here.');
}
});
it('keeps NOTE when it is the spoken dialogue', () => {
expect(