UNPKG

propresenter-parser

Version:

Parses ProPresenter 4, 5, and 6 files to extract the data, and can build ProPresenter 5 and 6 files

117 lines (116 loc) 5.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.normalizeColorToHex = exports.normalizeColorToRgbObj = exports.normalizeColorToRgbaString = exports.hexToRgb = exports.getUniqueID = exports.getIsoDateString = exports.getTextPropsFromRtf = exports.formatRtf = exports.stripRtf = exports.patternRgbaStr = exports.patternRgbaStrAsString = exports.patternHexColor = void 0; exports.patternHexColor = /^#?[a-f\d]{6}$/i; exports.patternRgbaStrAsString = '[10](?:\\.\\d+)? [10](?:\\.\\d+)? [10](?:\\.\\d+)? [10](?:\\.\\d+)?'; exports.patternRgbaStr = new RegExp('^' + exports.patternRgbaStrAsString + '$'); const stripRtf = (str) => { const basicRtfPattern = /\{\*?\\[^{}]+;}|[{}]|\\[A-Za-z]+\n?(?:-?\d+)?[ ]?/g; const newLineSlashesPattern = /\\\n/g; const ctrlCharPattern = /\n\\f[0-9]\s/g; return str.replace(ctrlCharPattern, '').replace(basicRtfPattern, '').replace(newLineSlashesPattern, '\n').trim(); }; exports.stripRtf = stripRtf; const formatRtf = (text, font = 'Arial', size = 60, color = { r: 255, g: 255, b: 255 }) => { return `{\\rtf1\\ansi\\ansicpg1252\\cocoartf1038\\cocoasubrtf320{\\fonttbl\\f0\\fswiss\\fcharset0 ${font};}{\\colortbl;\\red${color.r}\\green${color.g}\\blue${color.b};}\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\qc\\pardirnatural\\f0\\fs${size * 2} \\cf1 ${text.replace(/\r|\n/g, '\\\r')}}`; }; exports.formatRtf = formatRtf; const getTextPropsFromRtf = (str) => { const color = { r: 0, g: 0, b: 0 }; let font = ''; let size = 0; const fontMatches = Array.from(str.matchAll(/\\fcharset0 (.+?);/gi)); if (fontMatches.length > 0) { font = fontMatches[fontMatches.length - 1][1]; } const colorMatch = /\\red(\d+)\\green(\d+)\\blue(\d+);}/i.exec(str); if (colorMatch) { color.r = parseInt(colorMatch[1], 10); color.g = parseInt(colorMatch[2], 10); color.b = parseInt(colorMatch[3], 10); } const sizeMatch = Array.from(str.matchAll(/\\fs(\d+) ?\\/gi)); if (sizeMatch.length > 0) { size = parseInt(sizeMatch[sizeMatch.length - 1][1], 10) / 2; } return { color, font, size, }; }; exports.getTextPropsFromRtf = getTextPropsFromRtf; const getIsoDateString = () => { return new Date().toISOString().replace(/\.\d{3}Z$/, ''); }; exports.getIsoDateString = getIsoDateString; const getUniqueID = () => { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1) .toUpperCase(); } return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`; }; exports.getUniqueID = getUniqueID; const hexToRgb = (hex) => { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); if (result) { return { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16), }; } throw new Error(`Input color '${hex}' could not be parsed! Are you sure this is a hex color?`); }; exports.hexToRgb = hexToRgb; const normalizeColorToRgbaString = (color) => { if (typeof color !== 'string') { return `${color.r / 255} ${color.g / 255} ${color.b / 255} 1`; } if (exports.patternRgbaStr.test(color)) { return color; } if (exports.patternHexColor.test(color)) { return (0, exports.normalizeColorToRgbaString)((0, exports.hexToRgb)(color)); } throw new Error(`Input color '${color}' could not be parsed to an RGBA color string!`); }; exports.normalizeColorToRgbaString = normalizeColorToRgbaString; const normalizeColorToRgbObj = (color) => { if (typeof color !== 'string') { return color; } if (exports.patternRgbaStr.test(color)) { const parts = color.split(' '); return { r: parseFloat(parts[0]) * 255, g: parseFloat(parts[1]) * 255, b: parseFloat(parts[2]) * 255, }; } if (exports.patternHexColor.test(color)) { return (0, exports.hexToRgb)(color); } throw new Error(`Input color '${color}' could not be parsed to an RGB color object!`); }; exports.normalizeColorToRgbObj = normalizeColorToRgbObj; const normalizeColorToHex = (color) => { const to16Bit = (i) => ('00' + i.toString(16)).slice(-2).toUpperCase(); if (typeof color !== 'string') { return to16Bit(color.r) + to16Bit(color.g) + to16Bit(color.b); } if (exports.patternRgbaStr.test(color)) { const parts = color.split(' '); return (to16Bit(Math.round(parseFloat(parts[0]) * 255)) + to16Bit(Math.round(parseFloat(parts[1]) * 255)) + to16Bit(Math.round(parseFloat(parts[2]) * 255))); } if (exports.patternHexColor.test(color)) { return color.replace('#', ''); } throw new Error(`Input color '${color}' could not be parsed to a HEX color!`); }; exports.normalizeColorToHex = normalizeColorToHex;