youtube-cue/src/parser.js

114 lines
3.6 KiB
JavaScript
Raw Normal View History

2017-06-07 20:47:10 +00:00
/*jshint esversion: 6 */
2021-05-30 14:07:09 +00:00
/**
2021-06-28 09:23:41 +00:00
* https://regex101.com/r/XwBLUH/2
2021-05-30 14:07:09 +00:00
* This regex parses out the following groups:
2021-06-28 09:23:41 +00:00
* trackl track number at the left of the timestamp, optional and optionally enclosed in square brackets or parantheses
* trackr track number at the of the timestamp, optional and optionally enclosed in square brackets or parantheses
*
2021-05-30 14:07:09 +00:00
* start_ts: complete track start timestamp (hh:mm:ss) (mm:ss is minimum)
* start_hh: starting hh, optional
* start_mm: starting minutes, required
* start_ss: starting seconds, required
*
* end_ts: complete track end timestamp (hh:mm:ss) (mm:ss is minimum to match). optional
* end:hh: track end hour, optional
* end:mm: track end minute, optional
* end:ss: track end seconds, optional
*
2021-06-28 09:23:41 +00:00
* text_1: text found to the left of the timestamp, ignoring the track number
* text_2: text found to the right of the timestamp, ignoring the track number
2021-05-30 14:07:09 +00:00
*
* It is suggested to check their lengths and pick one to parse as the Track Title
*/
2021-06-28 09:23:41 +00:00
const TS_REGEX = /^((?<trackl>\d{1,3})\.)? *(?<text_1>.*?) *[\(\[]?(?<start_ts>((?<start_hh>\d{1,2}):)?(?<start_mm>\d{1,2}):(?<start_ss>\d{1,2})) *-? *[\)\]]?(?<end_ts>(?<end_hh>\d{1,2}:)?(?<end_mm>\d{1,2}):(?<end_ss>\d{1,2}))? *((?<trackr>\d{1,3})\.)? *(?<text_2>.*?)$/;
2021-05-30 15:31:27 +00:00
import getArtistTitle from 'get-artist-title'
2017-06-10 20:23:12 +00:00
var _options = {};
2017-06-07 20:14:09 +00:00
2021-05-30 15:31:27 +00:00
function convertTime(h,m,s) {
return (+h) * 60 * 60 + (+m) * 60 + (+s)
}
2017-06-07 20:14:09 +00:00
var filterTimestamp = function(line) {
2021-05-30 14:07:09 +00:00
return TS_REGEX.test(line)
2017-06-07 20:14:09 +00:00
};
2021-05-30 15:31:27 +00:00
var firstPass = function(line) {
2017-06-07 20:14:09 +00:00
let matches = line.match(TS_REGEX);
2021-06-28 09:23:41 +00:00
let track = matches.groups['trackl'] ? +matches.groups['trackl'] : (matches.groups['trackr'] ? +matches.groups['trackr'] : null)
2017-06-07 20:14:09 +00:00
return {
2021-06-28 09:23:41 +00:00
track: track,
2021-05-30 14:07:09 +00:00
start: {
2021-05-30 15:31:27 +00:00
ts: matches.groups['start_ts'].length<6 ? `00:${matches.groups['start_ts']}` : matches.groups['start_ts'],
2021-05-30 14:07:09 +00:00
hh: matches.groups['start_hh'] ? +matches.groups['start_hh'] : 0,
// These 2 are always set
mm: +matches.groups['start_mm'],
ss: +matches.groups['start_ss'],
},
end: (matches.groups['end_ts']!==undefined ? {
ts: matches.groups['end_ts']? matches.groups['end_ts'] : null,
hh: matches.groups['end_hh']? +matches.groups['end_hh'] : null,
mm: matches.groups['end_mm']? +matches.groups['end_mm'] : null,
ss: matches.groups['end_ss']? +matches.groups['end_ss'] : null,
} : null),
_: {
left_text: matches.groups['text_1'],
right_text: matches.groups['text_2']
}
}
2017-06-07 20:14:09 +00:00
};
2021-05-30 14:07:09 +00:00
var calcTimestamp = function(obj) {
if(obj.end) {
2021-05-30 15:31:27 +00:00
obj.end.calc = convertTime(obj.end.hh,obj.end.mm,obj.end.ss)
2021-05-30 14:07:09 +00:00
}
2021-05-30 15:31:27 +00:00
obj.start.calc = convertTime(obj.start.hh,obj.start.mm,obj.start.ss)
2021-05-30 14:07:09 +00:00
return obj
}
2017-06-07 20:14:09 +00:00
2021-05-30 14:07:09 +00:00
var parseTitle = function(obj) {
2021-06-28 09:23:41 +00:00
obj.title = obj._.left_text.length > obj._.right_text.length
2021-05-30 14:07:09 +00:00
? obj._.left_text : obj._.right_text;
2021-06-28 09:23:41 +00:00
return obj
2021-05-30 14:07:09 +00:00
}
2017-06-07 20:14:09 +00:00
2017-06-10 20:23:12 +00:00
var parseArtist = function(obj) {
let [artist, title] = getArtistTitle(obj.title, {
defaultArtist: _options.artist,
2021-05-30 15:31:27 +00:00
defaultTitle: obj.title
2017-06-10 20:23:12 +00:00
});
2021-06-28 09:23:41 +00:00
obj.artist = artist
obj.title = title
return obj
2017-06-10 20:23:12 +00:00
};
2021-05-30 15:31:27 +00:00
var addTrack = function(obj, index) {
if (obj.track==null) {
obj.track = index+1
}
return obj
}
var addEnd = function(obj, index, arr) {
if (!obj.end) {
if(arr.length!=index+1) {
let next = arr[index+1]
obj.end = next.start
return obj
}
}
return obj
}
export function parse (text, options = { artist: 'Unknown' }) {
_options = options;
return text
.split('\n')
.filter(filterTimestamp)
.map(firstPass)
.map(calcTimestamp)
.map(parseTitle)
.map(parseArtist)
.map(addTrack)
.map(addEnd)
}