UNPKG

rtf-stream-parser

Version:

Stream Transform class to tokenize RTF, and another to de-encapsulate text or HTML

189 lines (188 loc) 6.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.handleFonts = void 0; const utils_1 = require("../utils"); const charsetToCpg = { 0: 1252, 2: 42, 77: 10000, 78: 10001, 79: 10003, 80: 10008, 81: 10002, 83: 10005, 84: 10004, 85: 10006, 86: 10081, 87: 10021, 88: 10029, 89: 10007, 128: 932, 129: 949, 130: 1361, 134: 936, 136: 950, 161: 1253, 162: 1254, 163: 1258, 177: 1255, 178: 1256, 186: 1257, 204: 1251, 222: 874, 238: 1250, 254: 437, 255: 850, }; const codepages = { 20127: true, 28591: true, }; for (const charset in charsetToCpg) { const cpg = charsetToCpg[charset]; codepages[cpg] = true; } const handleThemeFont = (global, cw) => { if (global._constructingFontTableEntry) { global._constructingFontTableEntry.themeFont = cw.word.slice(1); } }; const handleFontFamily = (global, cw) => { if (global._constructingFontTableEntry) { global._constructingFontTableEntry.fontFamily = cw.word.slice(1); } }; const fontTokenHandlers = { [0]: global => { if (global._constructingFontTable && global._state.destination === 'fonttbl' && global._state.groupDepth === global._state.destGroupDepth + 1) { global._constructingFontTableEntry = {}; } }, [1]: global => { if (global._constructingFontTable && global._state.destination === 'fonttbl' && global._state.groupDepth === global._state.destGroupDepth) { if (!global._constructingFontTableEntry || !global._constructingFontTableKey) { throw new Error('Finished a font table group but no key?'); } global._fonttbl[global._constructingFontTableKey] = global._constructingFontTableEntry; global._constructingFontTableEntry = undefined; global._constructingFontTableKey = undefined; } if (global._constructingFontTable && global._state.destGroupDepth === 1) { global._constructingFontTable = false; } } }; const fontControlHandlers = { deff: (global, cw) => { if (global._state.destination === 'rtf' && global._state.destDepth > 1 && typeof global._deff !== 'undefined') { return; } if (global._state.destination !== 'rtf' || global._state.destDepth !== 1) throw new Error('\\deff not at root group'); if (typeof global._deff !== 'undefined') throw new Error('\\deff already defined'); global._deff = cw.param + ''; }, fonttbl: global => { if (global._fonttbl && global._state.destGroupDepth > 2) { global._options.warn('Got additional \\fonttbl'); return; } if (global._fonttbl) { throw new Error('fonttbl already created'); } else if (global._state.destDepth !== 2 || global._state.destGroupDepth !== 2) { throw new Error('fonttbl not in header'); } global._constructingFontTable = true; global._fonttbl = {}; }, f: (global, cw) => { if (typeof cw.param === 'undefined') { throw new Error('No param for \\f'); } const f = cw.param + ''; if (global._constructingFontTableEntry && global._constructingFontTableKey) { throw new Error('\\f control word in font group which already has \\f'); } else if (global._constructingFontTableEntry) { global._constructingFontTableKey = f; } else { global._state.font = f; } }, fcharset: (global, cw) => { if (!global._constructingFontTableEntry) { return; } if (!utils_1.isNum(cw.param)) { throw new Error('fcharset with no param'); } if (cw.param !== 1) { let cpg = charsetToCpg[cw.param]; if (!utils_1.isNum(cpg) && codepages[cw.param]) { cpg = cw.param; } if (!utils_1.isNum(cpg)) { global._options.warn('No codepage for charset ' + cw.param); } else { global._constructingFontTableEntry.fcharsetCpg = cpg; } } }, cpg: (global, cw) => { if (!global._constructingFontTableEntry) { return; } const cpg = cw.param; if (!utils_1.isNum(cpg)) { global._options.warn('No codepage given'); } else { global._constructingFontTableEntry.cpg = cpg; } }, flomajor: handleThemeFont, fhimajor: handleThemeFont, fdbmajor: handleThemeFont, fbimajor: handleThemeFont, flominor: handleThemeFont, fhiminor: handleThemeFont, fdbminor: handleThemeFont, fbiminor: handleThemeFont, fnil: handleFontFamily, froman: handleFontFamily, fswiss: handleFontFamily, fmodern: handleFontFamily, fscript: handleFontFamily, fdecor: handleFontFamily, ftech: handleFontFamily, fbidi: handleFontFamily, }; const fontTextHandler = (global, data) => { if (global._constructingFontTableEntry) { if (!utils_1.isStr(data)) { data = data.toString('latin1'); } data = data.replace(/[^\x00-\x7F]/g, c => { const hex = c.charCodeAt(0).toString(16).toUpperCase(); return '\\u' + '0000'.slice(0, 4 - hex.length) + hex; }); let str = (global._constructingFontTableEntry.fontName || '') + data; if (str.endsWith(';')) { str = str.substr(0, str.length - 1); if (str.length > 2 && str.startsWith('"') && str.endsWith('"')) { str = str.substr(1, str.length - 2); } } global._constructingFontTableEntry.fontName = str; return true; } }; exports.handleFonts = { tokenHandlers: fontTokenHandlers, controlHandlers: fontControlHandlers, outputDataFilter: fontTextHandler };