Skip to content

Commit

Permalink
Merge pull request #19 from abstractvector/master
Browse files Browse the repository at this point in the history
Support parsing metadata from input
  • Loading branch information
osk authored Mar 15, 2019
2 parents 104ca8a + ebbb8dd commit 52dea41
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 3 deletions.
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,48 @@ For the above example we'd get:
}
```

### Metadata

Some WebVTT strings may also contain lines of metadata after the initial `WEBVTT` line, for example:

```
WEBVTT
Kind: captions
Language: en
00:00:00.000 --> 00:00:01.000
Hello world!
```

By passing `{ meta: true }` to the `parse` method, these metadata will be returned as an object called `meta`. For example, parsing the above example:

```js
parse(webvtt, { meta: true });
```

would return the following:

```json
{
"valid":true,
"meta":{
"Kind": "captions",
"Language": "en"
},
"cues":[
{
"identifier":"",
"start":0,
"end":1,
"text":"Hello world!",
"styles":""
}
]
}
```

If no metadata is available, `meta` will be set to `null` in the result if the option is specified.

### Compiling

Compiles JSON from the above format back into a WebVTT string.
Expand Down
27 changes: 24 additions & 3 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ ParserError.prototype = Object.create(Error.prototype);

const TIMESTAMP_REGEXP = /([0-9]{1,2})?:?([0-9]{2}):([0-9]{2}\.[0-9]{3})/;

function parse (input) {
function parse (input, options) {
if (!options) options = {};

options = {
meta: options.meta === true
};

if (typeof input !== 'string') {
throw new ParserError('Input must be a string');
Expand Down Expand Up @@ -46,13 +51,29 @@ function parse (input) {
return { valid: true };
}

if (headerParts.length > 1 && headerParts[1] !== '') {
if (!options.meta && headerParts.length > 1 && headerParts[1] !== '') {
throw new ParserError('Missing blank line after signature');
}

const cues = parseCues(parts);
const meta = options.meta ? parseMeta(headerParts) : null;

const result = { valid: true, cues };

if (options.meta) {
result.meta = meta;
}

return result;
}

return { valid: true, cues };
function parseMeta (headerParts) {
const meta = {};
headerParts.slice(1).forEach(header => {
const [key, value] = header.split(':').map(t => t.trim());
meta[key] = value;
});
return Object.keys(meta).length > 0 ? meta : null;
}

function parseCues (cues) {
Expand Down
73 changes: 73 additions & 0 deletions test/parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,77 @@ Chapter 17`;

parse(input).cues.should.have.length(3);
});

it('should not return meta by default', () => {
const input = `WEBVTT
1
00:00.000 --> 00:00.001`;

parse(input).should.have.property('valid').be.true;
parse(input).should.not.have.property('meta');
});

it('should accept an options object', () => {
const input = `WEBVTT
1
00:00.000 --> 00:00.001`;
const options = { meta: true };

parse(input, options).cues[0].start.should.equal(0);
parse(input, options).cues[0].end.should.equal(0.001);
});

it('should fail if metadata exists but the meta option is not set', () => {
const input = `WEBVTT
Kind: captions
Language: en
1
00:00.000 --> 00:00.001`;
const options = { };

(() => { parse(input, options); })
.should.throw(parserError, /Missing blank line after signature/);
});

it('should fail if metadata exists but the meta option is false', () => {
const input = `WEBVTT
Kind: captions
Language: en
1
00:00.000 --> 00:00.001`;
const options = { meta: false };

(() => { parse(input, options); })
.should.throw(parserError, /Missing blank line after signature/);
});

it('should return meta if meta option is true', () => {
const input = `WEBVTT
Kind: captions
Language: en
1
00:00.000 --> 00:00.001`;
const options = { meta: true };

parse(input, options).should.have.property('valid').be.true;
parse(input, options).should.have.property('meta').be.deep.equal(
{ Kind: 'captions', Language: 'en' }
);
});

it('should return null if meta option is true but no meta', () => {
const input = `WEBVTT
1
00:00.000 --> 00:00.001`;
const options = { meta: true };

parse(input, options).should.have.property('valid').be.true;
parse(input, options).should.have.property('meta').be.equal(null);
});
});

0 comments on commit 52dea41

Please sign in to comment.