UNPKG

webvtt2ass

Version:
101 lines (91 loc) 3.74 kB
"use strict"; const he = require("he"); const TimeSpan = require("./timespan"); const default_font = "Arial"; function assHeader(font) { font = font || default_font; const header = [ "[Script Info]\n; Script generated by webvtt2ass\nScriptType: v4.00+\nWrapStyle: 0\nScaledBorderAndShadow: yes\nYCbCr Matrix: None\nPlayResX: 1920\nPlayResY: 1080\n", "[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding", `Style: Default,${font},50,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0.5,2,10,10,10,1`, `Style: Ruby,${font},50,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0.5,2,10,10,10,1`, "[Events]\nFormat: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text", "Comment: 0,00:00:00.00,00:00:00.00,Ruby,,0,0,0,template furi,{\\pos(!line.left+syl.center!,!line.middle-line.height!)\\an5}", "Comment: 0,00:00:00.00,00:00:00.00,Ruby,,0,0,0,template syl,{\\pos(!line.left+syl.center!,!line.middle!)\\an5}" ]; return header.join("\n") + "\n"; } function html2assColor(color) { if (color.startsWith("color")) { return `&H${color.substr(9, 2)}${color.substr(7, 2)}${color.substr(5, 2)}&`; } // todo: cast red to &H0000FF& return color; } //src: <ruby>明日<rt>あした</tr></ruby>また<ruby>会<rt>あう</rt></ruby><ruby>時<rt>とき</rt></ruby> //tgt: {\k}明日|あした{\k}また{\k}会|あう{\k}時|とき //ref: http://docs.aegisub.org/manual/Furigana_karaoke function parseTreeRuby(tree) { let ret = "{\\k}"; tree.children.forEach((item) => { if (item.type === "text") { ret += item.value; } else if (item.type === "object") { if (item.name === "rt") { ret += "|" + parseTreeInner(item, true).text; ret += "{\\k}"; } } }); return ret; } function parseTreeInner(tree, noTag) { const nodes = tree.children; let ret = {text: ""}; if (tree.name === "ruby") { ret.text += parseTreeRuby(tree); ret.style = "Ruby"; } else { if (tree.name === "v") { ret.voice = tree.value; } nodes.forEach((item) => { if (item.type === "object") { const temp = parseTreeInner(item); ret.text += temp.text; ret.style = temp.style; if (ret.voice === undefined) { ret.voice = temp.voice; } } else { ret.text += item.value; } }); if (tree.name !== undefined && noTag === undefined) { if (tree.name !== "v") { // handle class if (tree.name === "c") { const classes = tree.classes // TODO: handle style info } else { ret.text = "{\\" + tree.name + "1}" + ret.text + "{\\" + tree.name + "0}"; } } } } return ret; } function parseSegment(line) { let ret = parseTreeInner(line.tree); if (ret.voice === undefined) { ret.voice = ""; } if (ret.style === undefined) { ret.style = "Default"; } ret.text = he.decode(ret.text).replace(/\n/g, "\\N"); ret.begin = new TimeSpan(line.startTime).toString(); ret.end = new TimeSpan(line.endTime).toString(); return ret; } module.exports = {parseSegment: parseSegment, assHeader: assHeader};