UNPKG

ass-compiler

Version:

Parses and compiles ASS subtitle format to easy-to-use data structure.

90 lines (84 loc) 2.7 kB
import { compileDrawing } from './drawing.js'; import { compileTag } from './tag.js'; const a2an = [ null, 1, 2, 3, null, 7, 8, 9, null, 4, 5, 6, ]; const globalTags = ['r', 'a', 'an', 'pos', 'org', 'move', 'fade', 'fad', 'clip']; function inheritTag(pTag) { return JSON.parse(JSON.stringify(Object.assign({}, pTag, { k: undefined, kf: undefined, ko: undefined, kt: undefined, }))); } export function compileText({ styles, style, parsed, start, end }) { let alignment; let q = { q: styles[style].tag.q }; let pos; let org; let move; let fade; let clip; const slices = []; let slice = { style, fragments: [] }; let prevTag = {}; for (let i = 0; i < parsed.length; i++) { const { tags, text, drawing } = parsed[i]; let reset; for (let j = 0; j < tags.length; j++) { const tag = tags[j]; reset = tag.r === undefined ? reset : tag.r; } const fragment = { tag: reset === undefined ? inheritTag(prevTag) : {}, text, drawing: drawing.length ? compileDrawing(drawing) : null, }; for (let j = 0; j < tags.length; j++) { const tag = tags[j]; alignment = alignment || a2an[tag.a || 0] || tag.an; q = compileTag(tag, 'q') || q; if (!move) { pos = pos || compileTag(tag, 'pos'); } org = org || compileTag(tag, 'org'); if (!pos) { move = move || compileTag(tag, 'move'); } fade = fade || compileTag(tag, 'fade') || compileTag(tag, 'fad'); clip = compileTag(tag, 'clip') || clip; const key = Object.keys(tag)[0]; if (key && !~globalTags.indexOf(key)) { const sliceTag = styles[style].tag; const { c1, c2, c3, c4 } = sliceTag; const fs = prevTag.fs || sliceTag.fs; const compiledTag = compileTag(tag, key, { start, end, c1, c2, c3, c4, fs }); if (key === 't') { fragment.tag.t = fragment.tag.t || []; fragment.tag.t.push(compiledTag.t); } else { Object.assign(fragment.tag, compiledTag); } } } prevTag = fragment.tag; if (reset !== undefined) { slices.push(slice); slice = { style: styles[reset] ? reset : style, fragments: [] }; } if (fragment.text || fragment.drawing) { const prev = slice.fragments[slice.fragments.length - 1] || {}; if (prev.text && fragment.text && !Object.keys(fragment.tag).length) { // merge fragment to previous if its tag is empty prev.text += fragment.text; } else { slice.fragments.push(fragment); } } } slices.push(slice); return Object.assign({ alignment, slices }, q, pos, org, move, fade, clip); }