1064 lines
50 KiB
JavaScript
1064 lines
50 KiB
JavaScript
"use strict";
|
|
var __assign = (this && this.__assign) || function () {
|
|
__assign = Object.assign || function(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
function step(op) {
|
|
if (f) throw new TypeError("Generator is already executing.");
|
|
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
switch (op[0]) {
|
|
case 0: case 1: t = op; break;
|
|
case 4: _.label++; return { value: op[1], done: false };
|
|
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
default:
|
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
if (t[2]) _.ops.pop();
|
|
_.trys.pop(); continue;
|
|
}
|
|
op = body.call(thisArg, _);
|
|
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
}
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.splitCommand = exports.getCommand = exports.walkTemplate = exports.findHighestImgId = exports.produceJsReport = exports.extractQuery = exports.newContext = void 0;
|
|
var reportUtils_1 = require("./reportUtils");
|
|
var jsSandbox_1 = require("./jsSandbox");
|
|
var types_1 = require("./types");
|
|
var errors_1 = require("./errors");
|
|
var debug_1 = require("./debug");
|
|
function newContext(options, imageAndShapeIdIncrement) {
|
|
if (imageAndShapeIdIncrement === void 0) { imageAndShapeIdIncrement = 0; }
|
|
return {
|
|
gCntIf: 0,
|
|
gCntEndIf: 0,
|
|
level: 1,
|
|
fCmd: false,
|
|
cmd: '',
|
|
fSeekQuery: false,
|
|
buffers: {
|
|
'w:p': { text: '', cmds: '', fInsertedText: false },
|
|
'w:tr': { text: '', cmds: '', fInsertedText: false },
|
|
'w:tc': { text: '', cmds: '', fInsertedText: false },
|
|
},
|
|
imageAndShapeIdIncrement: imageAndShapeIdIncrement,
|
|
images: {},
|
|
linkId: 0,
|
|
links: {},
|
|
htmlId: 0,
|
|
htmls: {},
|
|
vars: {},
|
|
loops: [],
|
|
fJump: false,
|
|
shorthands: {},
|
|
options: options,
|
|
// To verfiy we don't have a nested if within the same p or tr tag
|
|
pIfCheckMap: new Map(),
|
|
trIfCheckMap: new Map(),
|
|
};
|
|
}
|
|
exports.newContext = newContext;
|
|
// Go through the document until the query string is found (normally at the beginning)
|
|
function extractQuery(template, options) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var ctx, nodeIn, fFound, parent_1, nextSibling, parent_2;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
ctx = newContext(options);
|
|
// ensure no command will be processed, except QUERY
|
|
ctx.fSeekQuery = true;
|
|
nodeIn = template;
|
|
_a.label = 1;
|
|
case 1:
|
|
if (!true) return [3 /*break*/, 4];
|
|
// Move down
|
|
if (nodeIn._children.length)
|
|
nodeIn = nodeIn._children[0];
|
|
else {
|
|
fFound = false;
|
|
while (nodeIn._parent != null) {
|
|
parent_1 = nodeIn._parent;
|
|
nextSibling = (0, reportUtils_1.getNextSibling)(nodeIn);
|
|
if (nextSibling) {
|
|
nodeIn = nextSibling;
|
|
fFound = true;
|
|
break;
|
|
}
|
|
nodeIn = parent_1;
|
|
}
|
|
if (!fFound)
|
|
return [3 /*break*/, 4];
|
|
}
|
|
if (!nodeIn)
|
|
return [3 /*break*/, 4];
|
|
parent_2 = nodeIn._parent;
|
|
if (!(nodeIn._fTextNode &&
|
|
parent_2 &&
|
|
!parent_2._fTextNode &&
|
|
parent_2._tag === 'w:t')) return [3 /*break*/, 3];
|
|
return [4 /*yield*/, processText(null, nodeIn, ctx, processCmd)];
|
|
case 2:
|
|
_a.sent();
|
|
_a.label = 3;
|
|
case 3:
|
|
if (ctx.query != null)
|
|
return [3 /*break*/, 4];
|
|
return [3 /*break*/, 1];
|
|
case 4: return [2 /*return*/, ctx.query];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
exports.extractQuery = extractQuery;
|
|
function produceJsReport(data, template, ctx) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
return __generator(this, function (_a) {
|
|
return [2 /*return*/, walkTemplate(data, template, ctx, processCmd)];
|
|
});
|
|
});
|
|
}
|
|
exports.produceJsReport = produceJsReport;
|
|
function findHighestImgId(mainDoc) {
|
|
var doc_ids = [];
|
|
var search = function (n) {
|
|
for (var _i = 0, _a = n._children; _i < _a.length; _i++) {
|
|
var c = _a[_i];
|
|
var tag = c._fTextNode ? null : c._tag;
|
|
if (tag == null)
|
|
continue;
|
|
if (tag === 'wp:docPr') {
|
|
if (c._fTextNode)
|
|
continue;
|
|
var raw = c._attrs.id;
|
|
if (typeof raw !== 'string')
|
|
continue;
|
|
var id = Number.parseInt(raw, 10);
|
|
if (Number.isSafeInteger(id))
|
|
doc_ids.push(id);
|
|
}
|
|
if (c._children.length > 0)
|
|
search(c);
|
|
}
|
|
};
|
|
search(mainDoc);
|
|
if (doc_ids.length > 0)
|
|
return Math.max.apply(Math, doc_ids);
|
|
return 0;
|
|
}
|
|
exports.findHighestImgId = findHighestImgId;
|
|
var debugPrintNode = function (node) {
|
|
return JSON.stringify(node._fTextNode
|
|
? {
|
|
_ifName: node._ifName,
|
|
_fTextNode: node._fTextNode,
|
|
_text: node === null || node === void 0 ? void 0 : node._text,
|
|
}
|
|
: {
|
|
_ifName: node._ifName,
|
|
_fTextNode: node._fTextNode,
|
|
_tag: node === null || node === void 0 ? void 0 : node._tag,
|
|
_attrs: node === null || node === void 0 ? void 0 : node._attrs,
|
|
});
|
|
};
|
|
var findParentPorTrNode = function (node) {
|
|
var parentNode = node._parent;
|
|
var resultNode = null;
|
|
while (parentNode != null && resultNode == null) {
|
|
var parentNodeTag = parentNode._fTextNode ? null : parentNode._tag;
|
|
if (parentNodeTag === 'w:p') {
|
|
// check also for w:tr tag
|
|
var grandParentNode = parentNode._parent != null ? parentNode._parent._parent : null;
|
|
if (grandParentNode != null &&
|
|
!grandParentNode._fTextNode &&
|
|
grandParentNode._tag === 'w:tr') {
|
|
resultNode = grandParentNode;
|
|
}
|
|
else {
|
|
resultNode = parentNode;
|
|
}
|
|
}
|
|
parentNode = parentNode._parent;
|
|
}
|
|
return resultNode;
|
|
};
|
|
function walkTemplate(data, template, ctx, processor) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var out, nodeIn, nodeOut, move, deltaJump, errors, loopCount, maximumWalkingDepth, curLoop, nextSibling, parent_3, tag, fRemoveNode, buffers, nodeOutParent, imgNode, captionNodes, parent_4, linkNode, parent_5, htmlNode, parent_6, tag, newNode, newNodeTag, parent_7, result, err, innermost_loop, err;
|
|
var _a;
|
|
var _b;
|
|
return __generator(this, function (_c) {
|
|
switch (_c.label) {
|
|
case 0:
|
|
out = (0, reportUtils_1.cloneNodeWithoutChildren)(template);
|
|
nodeIn = template;
|
|
nodeOut = out;
|
|
deltaJump = 0;
|
|
errors = [];
|
|
loopCount = 0;
|
|
maximumWalkingDepth = ((_b = ctx.options) === null || _b === void 0 ? void 0 : _b.maximumWalkingDepth) || 1000000;
|
|
_c.label = 1;
|
|
case 1:
|
|
if (!true) return [3 /*break*/, 5];
|
|
curLoop = (0, reportUtils_1.getCurLoop)(ctx);
|
|
nextSibling = null;
|
|
// =============================================
|
|
// Move input node pointer
|
|
// =============================================
|
|
if (ctx.fJump) {
|
|
if (!curLoop)
|
|
throw new errors_1.InternalError('jumping while curLoop is null');
|
|
// TODO: comment debug statements back out, as creating the debug string creates overhead.
|
|
debug_1.logger.debug("Jumping to level ".concat(curLoop.refNodeLevel, "..."), debugPrintNode(curLoop.refNode));
|
|
deltaJump = ctx.level - curLoop.refNodeLevel;
|
|
nodeIn = curLoop.refNode;
|
|
ctx.level = curLoop.refNodeLevel;
|
|
ctx.fJump = false;
|
|
move = 'JUMP';
|
|
// Down (only if he haven't just moved up)
|
|
}
|
|
else if (nodeIn._children.length && move !== 'UP') {
|
|
nodeIn = nodeIn._children[0];
|
|
ctx.level += 1;
|
|
move = 'DOWN';
|
|
// Sideways
|
|
}
|
|
else if ((nextSibling = (0, reportUtils_1.getNextSibling)(nodeIn))) {
|
|
nodeIn = nextSibling;
|
|
move = 'SIDE';
|
|
// Up
|
|
}
|
|
else {
|
|
parent_3 = nodeIn._parent;
|
|
if (parent_3 == null) {
|
|
debug_1.logger.debug("=== parent is null, breaking after ".concat(loopCount, " loops..."));
|
|
return [3 /*break*/, 5];
|
|
}
|
|
else if (loopCount > maximumWalkingDepth) {
|
|
// adding a emergency exit to avoid infit loops
|
|
debug_1.logger.debug("=== parent is still not null after ".concat(loopCount, " loops, something must be wrong ..."), debugPrintNode(parent_3));
|
|
throw new errors_1.InternalError('infinite loop or massive dataset detected. Please review and try again');
|
|
}
|
|
nodeIn = parent_3;
|
|
ctx.level -= 1;
|
|
move = 'UP';
|
|
}
|
|
debug_1.logger.debug("Next node [".concat(move, ", level ").concat(ctx.level, "]"), debugPrintNode(nodeIn));
|
|
// =============================================
|
|
// Process input node
|
|
// =============================================
|
|
// Delete the last generated output node in several special cases
|
|
// --------------------------------------------------------------
|
|
if (move !== 'DOWN') {
|
|
tag = nodeOut._fTextNode ? null : nodeOut._tag;
|
|
fRemoveNode = false;
|
|
// Delete last generated output node if we're skipping nodes due to an empty FOR loop
|
|
if ((tag === 'w:p' ||
|
|
tag === 'w:tbl' ||
|
|
tag === 'w:tr' ||
|
|
tag === 'w:tc') &&
|
|
(0, reportUtils_1.isLoopExploring)(ctx)) {
|
|
fRemoveNode = true;
|
|
// Delete last generated output node if the user inserted a paragraph
|
|
// (or table row) with just a command
|
|
}
|
|
else if (tag === 'w:p' || tag === 'w:tr' || tag === 'w:tc') {
|
|
buffers = ctx.buffers[tag];
|
|
fRemoveNode =
|
|
buffers.text === '' && buffers.cmds !== '' && !buffers.fInsertedText;
|
|
// If the last generated output node is a table row, and it is set to be deleted,
|
|
// don't delete if it has exactly one nested row (i.e. within nested table)
|
|
if (tag === 'w:tr' && fRemoveNode) {
|
|
fRemoveNode =
|
|
nodeIn._children.filter(function (child) { return !child._fTextNode && child._tag === 'w:tr'; }).length !== 1;
|
|
}
|
|
// If the last generated output node is a table column, and it is set to be deleted,
|
|
// don't delete if it has a table as a child
|
|
if (tag === 'w:tc' && fRemoveNode) {
|
|
fRemoveNode = !(nodeOut._children.filter(function (child) { return !child._fTextNode && child._tag === 'w:tbl'; }).length > 0);
|
|
}
|
|
}
|
|
// Execute removal, if needed. The node will no longer be part of the output, but
|
|
// the parent will be accessible from the child (so that we can still move up the tree)
|
|
if (fRemoveNode && nodeOut._parent != null) {
|
|
nodeOut._parent._children.pop();
|
|
}
|
|
}
|
|
// Handle an UP movement
|
|
// ---------------------
|
|
if (move === 'UP') {
|
|
// Loop exploring? Update the reference node for the current loop
|
|
if ((0, reportUtils_1.isLoopExploring)(ctx) &&
|
|
curLoop &&
|
|
nodeIn === curLoop.refNode._parent) {
|
|
curLoop.refNode = nodeIn;
|
|
curLoop.refNodeLevel -= 1;
|
|
debug_1.logger.debug("Updated loop '".concat(curLoop.varName, "' refNode: ") + debugPrintNode(nodeIn));
|
|
}
|
|
nodeOutParent = nodeOut._parent;
|
|
if (nodeOutParent == null)
|
|
throw new errors_1.InternalError('node parent is null');
|
|
// Execute the move in the output tree
|
|
nodeOut = nodeOutParent;
|
|
// If an image was generated, replace the parent `w:t` node with
|
|
// the image node
|
|
if (ctx.pendingImageNode &&
|
|
!nodeOut._fTextNode &&
|
|
nodeOut._tag === 'w:t') {
|
|
imgNode = ctx.pendingImageNode.image;
|
|
captionNodes = ctx.pendingImageNode.caption;
|
|
parent_4 = nodeOut._parent;
|
|
if (parent_4) {
|
|
imgNode._parent = parent_4;
|
|
parent_4._children.pop();
|
|
parent_4._children.push(imgNode);
|
|
if (captionNodes) {
|
|
(_a = parent_4._children).push.apply(_a, captionNodes);
|
|
}
|
|
// Prevent containing paragraph or table row from being removed
|
|
ctx.buffers['w:p'].fInsertedText = true;
|
|
ctx.buffers['w:tr'].fInsertedText = true;
|
|
ctx.buffers['w:tc'].fInsertedText = true;
|
|
}
|
|
delete ctx.pendingImageNode;
|
|
}
|
|
// If a link was generated, replace the parent `w:r` node with
|
|
// the link node
|
|
if (ctx.pendingLinkNode &&
|
|
!nodeOut._fTextNode &&
|
|
nodeOut._tag === 'w:r') {
|
|
linkNode = ctx.pendingLinkNode;
|
|
parent_5 = nodeOut._parent;
|
|
if (parent_5) {
|
|
linkNode._parent = parent_5;
|
|
parent_5._children.pop();
|
|
parent_5._children.push(linkNode);
|
|
// Prevent containing paragraph or table row from being removed
|
|
ctx.buffers['w:p'].fInsertedText = true;
|
|
ctx.buffers['w:tr'].fInsertedText = true;
|
|
ctx.buffers['w:tc'].fInsertedText = true;
|
|
}
|
|
delete ctx.pendingLinkNode;
|
|
}
|
|
// If a html page was generated, replace the parent `w:p` node with
|
|
// the html node
|
|
if (ctx.pendingHtmlNode &&
|
|
!nodeOut._fTextNode &&
|
|
nodeOut._tag === 'w:p') {
|
|
htmlNode = ctx.pendingHtmlNode;
|
|
parent_6 = nodeOut._parent;
|
|
if (parent_6) {
|
|
htmlNode._parent = parent_6;
|
|
parent_6._children.pop();
|
|
parent_6._children.push(htmlNode);
|
|
// Prevent containing paragraph or table row from being removed
|
|
ctx.buffers['w:p'].fInsertedText = true;
|
|
ctx.buffers['w:tr'].fInsertedText = true;
|
|
ctx.buffers['w:tc'].fInsertedText = true;
|
|
}
|
|
delete ctx.pendingHtmlNode;
|
|
}
|
|
// `w:tc` nodes shouldn't be left with no `w:p` or 'w:altChunk' children; if that's the
|
|
// case, add an empty `w:p` inside
|
|
if (!nodeOut._fTextNode &&
|
|
nodeOut._tag === 'w:tc' &&
|
|
!nodeOut._children.filter(function (o) { return !o._fTextNode && (o._tag === 'w:p' || o._tag === 'w:altChunk'); }).length) {
|
|
nodeOut._children.push({
|
|
_parent: nodeOut,
|
|
_children: [],
|
|
_fTextNode: false,
|
|
_tag: 'w:p',
|
|
_attrs: {},
|
|
});
|
|
}
|
|
// Save latest `w:rPr` node that was visited (for LINK properties)
|
|
if (!nodeOut._fTextNode && nodeOut._tag === 'w:rPr') {
|
|
ctx.textRunPropsNode = nodeOut;
|
|
}
|
|
if (!nodeIn._fTextNode && nodeIn._tag === 'w:r') {
|
|
delete ctx.textRunPropsNode;
|
|
}
|
|
}
|
|
if (!(move === 'DOWN' || move === 'SIDE')) return [3 /*break*/, 4];
|
|
// Move nodeOut to point to the new node's parent
|
|
if (move === 'SIDE') {
|
|
if (nodeOut._parent == null)
|
|
throw new errors_1.InternalError('node parent is null');
|
|
nodeOut = nodeOut._parent;
|
|
}
|
|
tag = nodeIn._fTextNode ? null : nodeIn._tag;
|
|
if (tag === 'w:p' || tag === 'w:tr' || tag === 'w:tc') {
|
|
ctx.buffers[tag] = { text: '', cmds: '', fInsertedText: false };
|
|
}
|
|
newNode = (0, reportUtils_1.cloneNodeWithoutChildren)(nodeIn);
|
|
newNode._parent = nodeOut;
|
|
nodeOut._children.push(newNode);
|
|
newNodeTag = newNode._tag;
|
|
if (!(0, reportUtils_1.isLoopExploring)(ctx) &&
|
|
(newNodeTag === 'wp:docPr' || newNodeTag === 'v:shape')) {
|
|
debug_1.logger.debug('detected a - ', debugPrintNode(newNode));
|
|
updateID(newNode, ctx);
|
|
}
|
|
parent_7 = nodeIn._parent;
|
|
if (!(nodeIn._fTextNode &&
|
|
parent_7 &&
|
|
!parent_7._fTextNode &&
|
|
parent_7._tag === 'w:t')) return [3 /*break*/, 3];
|
|
return [4 /*yield*/, processText(data, nodeIn, ctx, processor)];
|
|
case 2:
|
|
result = _c.sent();
|
|
if (typeof result === 'string') {
|
|
// TODO: improve typesafety of conversion Node to TextNode.
|
|
newNode._text = result;
|
|
debug_1.logger.debug("Inserted command result string into node. Updated node: " +
|
|
debugPrintNode(newNode));
|
|
}
|
|
else {
|
|
errors.push.apply(errors, result);
|
|
}
|
|
_c.label = 3;
|
|
case 3:
|
|
// Execute the move in the output tree
|
|
nodeOut = newNode;
|
|
_c.label = 4;
|
|
case 4:
|
|
// JUMP to the target level of the tree.
|
|
// -------------------------------------------
|
|
if (move === 'JUMP') {
|
|
while (deltaJump > 0) {
|
|
if (nodeOut._parent == null)
|
|
throw new errors_1.InternalError('node parent is null');
|
|
nodeOut = nodeOut._parent;
|
|
deltaJump -= 1;
|
|
}
|
|
}
|
|
loopCount++;
|
|
return [3 /*break*/, 1];
|
|
case 5:
|
|
if (ctx.gCntIf !== ctx.gCntEndIf) {
|
|
err = new errors_1.IncompleteConditionalStatementError();
|
|
if (ctx.options.failFast) {
|
|
throw err;
|
|
}
|
|
else {
|
|
errors.push(err);
|
|
}
|
|
}
|
|
if (ctx.loops.filter(function (l) { return !l.isIf; }).length > 0) {
|
|
innermost_loop = ctx.loops[ctx.loops.length - 1];
|
|
err = new errors_1.UnterminatedForLoopError(innermost_loop);
|
|
if (ctx.options.failFast) {
|
|
throw err;
|
|
}
|
|
else {
|
|
errors.push(err);
|
|
}
|
|
}
|
|
if (errors.length > 0)
|
|
return [2 /*return*/, {
|
|
status: 'errors',
|
|
errors: errors,
|
|
}];
|
|
return [2 /*return*/, {
|
|
status: 'success',
|
|
report: out,
|
|
images: ctx.images,
|
|
links: ctx.links,
|
|
htmls: ctx.htmls,
|
|
}];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
exports.walkTemplate = walkTemplate;
|
|
var processText = function (data, node, ctx, onCommand) { return __awaiter(void 0, void 0, void 0, function () {
|
|
var _a, cmdDelimiter, failFast, text, segments, outText, errors, idx, segment, cmdResultText;
|
|
return __generator(this, function (_b) {
|
|
switch (_b.label) {
|
|
case 0:
|
|
_a = ctx.options, cmdDelimiter = _a.cmdDelimiter, failFast = _a.failFast;
|
|
text = node._text;
|
|
if (text == null || text === '')
|
|
return [2 /*return*/, ''];
|
|
segments = text
|
|
.split(cmdDelimiter[0])
|
|
.map(function (s) { return s.split(cmdDelimiter[1]); })
|
|
.reduce(function (x, y) { return x.concat(y); });
|
|
outText = '';
|
|
errors = [];
|
|
idx = 0;
|
|
_b.label = 1;
|
|
case 1:
|
|
if (!(idx < segments.length)) return [3 /*break*/, 5];
|
|
// Include the separators in the `buffers` field (used for deleting paragraphs if appropriate)
|
|
if (idx > 0)
|
|
appendTextToTagBuffers(cmdDelimiter[0], ctx, { fCmd: true });
|
|
segment = segments[idx];
|
|
// logger.debug(`Token: '${segment}' (${ctx.fCmd})`);
|
|
if (ctx.fCmd)
|
|
ctx.cmd += segment;
|
|
else if (!(0, reportUtils_1.isLoopExploring)(ctx))
|
|
outText += segment;
|
|
appendTextToTagBuffers(segment, ctx, { fCmd: ctx.fCmd });
|
|
if (!(idx < segments.length - 1)) return [3 /*break*/, 4];
|
|
if (!ctx.fCmd) return [3 /*break*/, 3];
|
|
return [4 /*yield*/, onCommand(data, node, ctx)];
|
|
case 2:
|
|
cmdResultText = _b.sent();
|
|
if (cmdResultText != null) {
|
|
if (typeof cmdResultText === 'string') {
|
|
outText += cmdResultText;
|
|
appendTextToTagBuffers(cmdResultText, ctx, {
|
|
fCmd: false,
|
|
fInsertedText: true,
|
|
});
|
|
}
|
|
else {
|
|
if (failFast)
|
|
throw cmdResultText;
|
|
errors.push(cmdResultText);
|
|
}
|
|
}
|
|
_b.label = 3;
|
|
case 3:
|
|
ctx.fCmd = !ctx.fCmd;
|
|
_b.label = 4;
|
|
case 4:
|
|
idx++;
|
|
return [3 /*break*/, 1];
|
|
case 5:
|
|
if (errors.length > 0)
|
|
return [2 /*return*/, errors];
|
|
return [2 /*return*/, outText];
|
|
}
|
|
});
|
|
}); };
|
|
// ==========================================
|
|
// Command processor
|
|
// ==========================================
|
|
var processCmd = function (data, node, ctx) { return __awaiter(void 0, void 0, void 0, function () {
|
|
var cmd, _a, cmdName, cmdRest, aliasMatch, aliasName, fullCmd, result, nerr, str, literalXmlDelimiter, splitByLineBreak, LINE_BREAK, END_OF_TEXT, START_OF_TEXT, img, pars, html, err_1;
|
|
return __generator(this, function (_b) {
|
|
switch (_b.label) {
|
|
case 0:
|
|
cmd = getCommand(ctx.cmd, ctx.shorthands, ctx.options.fixSmartQuotes);
|
|
ctx.cmd = ''; // flush the context
|
|
_b.label = 1;
|
|
case 1:
|
|
_b.trys.push([1, 28, , 29]);
|
|
_a = splitCommand(cmd), cmdName = _a.cmdName, cmdRest = _a.cmdRest;
|
|
if (cmdName !== 'CMD_NODE')
|
|
debug_1.logger.debug("Processing cmd: ".concat(cmd));
|
|
// Seeking query?
|
|
if (ctx.fSeekQuery) {
|
|
if (cmdName === 'QUERY')
|
|
ctx.query = cmdRest;
|
|
return [2 /*return*/];
|
|
}
|
|
if (!(cmdName === 'QUERY' || cmdName === 'CMD_NODE')) return [3 /*break*/, 2];
|
|
return [3 /*break*/, 27];
|
|
case 2:
|
|
if (!(cmdName === 'ALIAS')) return [3 /*break*/, 3];
|
|
aliasMatch = /^(\S+)\s+(.+)/.exec(cmdRest);
|
|
if (!aliasMatch)
|
|
throw new errors_1.InvalidCommandError('Invalid ALIAS command', cmd);
|
|
aliasName = aliasMatch[1];
|
|
fullCmd = aliasMatch[2];
|
|
ctx.shorthands[aliasName] = fullCmd;
|
|
debug_1.logger.debug("Defined alias '".concat(aliasName, "' for: ").concat(fullCmd));
|
|
return [3 /*break*/, 27];
|
|
case 3:
|
|
if (!(cmdName === 'FOR' || cmdName === 'IF')) return [3 /*break*/, 5];
|
|
return [4 /*yield*/, processForIf(data, node, ctx, cmd, cmdName, cmdRest)];
|
|
case 4:
|
|
_b.sent();
|
|
return [3 /*break*/, 27];
|
|
case 5:
|
|
if (!(cmdName === 'END-FOR' || cmdName === 'END-IF')) return [3 /*break*/, 6];
|
|
processEndForIf(node, ctx, cmd, cmdName, cmdRest);
|
|
return [3 /*break*/, 27];
|
|
case 6:
|
|
if (!(cmdName === 'INS')) return [3 /*break*/, 12];
|
|
if (!!(0, reportUtils_1.isLoopExploring)(ctx)) return [3 /*break*/, 11];
|
|
return [4 /*yield*/, (0, jsSandbox_1.runUserJsAndGetRaw)(data, cmdRest, ctx)];
|
|
case 7:
|
|
result = _b.sent();
|
|
if (result == null) {
|
|
return [2 /*return*/, ''];
|
|
}
|
|
if (!(typeof result === 'object' && !Array.isArray(result))) return [3 /*break*/, 10];
|
|
nerr = new errors_1.ObjectCommandResultError(cmdRest, result);
|
|
if (!(ctx.options.errorHandler != null)) return [3 /*break*/, 9];
|
|
return [4 /*yield*/, ctx.options.errorHandler(nerr, cmdRest)];
|
|
case 8:
|
|
result = _b.sent();
|
|
return [3 /*break*/, 10];
|
|
case 9: throw nerr;
|
|
case 10:
|
|
str = String(result);
|
|
if (ctx.options.processLineBreaks) {
|
|
literalXmlDelimiter = ctx.options.literalXmlDelimiter;
|
|
if (ctx.options.processLineBreaksAsNewText) {
|
|
splitByLineBreak = str.split('\n');
|
|
LINE_BREAK = "".concat(literalXmlDelimiter, "<w:br/>").concat(literalXmlDelimiter);
|
|
END_OF_TEXT = "".concat(literalXmlDelimiter, "</w:t>").concat(literalXmlDelimiter);
|
|
START_OF_TEXT = "".concat(literalXmlDelimiter, "<w:t xml:space=\"preserve\">").concat(literalXmlDelimiter);
|
|
str = splitByLineBreak.join("".concat(END_OF_TEXT).concat(LINE_BREAK).concat(START_OF_TEXT));
|
|
}
|
|
else {
|
|
str = str.replace(/\n/g, "".concat(literalXmlDelimiter, "<w:br/>").concat(literalXmlDelimiter));
|
|
}
|
|
}
|
|
return [2 /*return*/, str];
|
|
case 11: return [3 /*break*/, 27];
|
|
case 12:
|
|
if (!(cmdName === 'EXEC')) return [3 /*break*/, 15];
|
|
if (!!(0, reportUtils_1.isLoopExploring)(ctx)) return [3 /*break*/, 14];
|
|
return [4 /*yield*/, (0, jsSandbox_1.runUserJsAndGetRaw)(data, cmdRest, ctx)];
|
|
case 13:
|
|
_b.sent();
|
|
_b.label = 14;
|
|
case 14: return [3 /*break*/, 27];
|
|
case 15:
|
|
if (!(cmdName === 'IMAGE')) return [3 /*break*/, 18];
|
|
if (!!(0, reportUtils_1.isLoopExploring)(ctx)) return [3 /*break*/, 17];
|
|
return [4 /*yield*/, (0, jsSandbox_1.runUserJsAndGetRaw)(data, cmdRest, ctx)];
|
|
case 16:
|
|
img = _b.sent();
|
|
if (img != null) {
|
|
try {
|
|
processImage(ctx, img);
|
|
}
|
|
catch (e) {
|
|
if (!(0, errors_1.isError)(e))
|
|
throw e;
|
|
throw new errors_1.ImageError(e, cmd);
|
|
}
|
|
}
|
|
_b.label = 17;
|
|
case 17: return [3 /*break*/, 27];
|
|
case 18:
|
|
if (!(cmdName === 'LINK')) return [3 /*break*/, 22];
|
|
if (!!(0, reportUtils_1.isLoopExploring)(ctx)) return [3 /*break*/, 21];
|
|
return [4 /*yield*/, (0, jsSandbox_1.runUserJsAndGetRaw)(data, cmdRest, ctx)];
|
|
case 19:
|
|
pars = _b.sent();
|
|
if (!(pars != null)) return [3 /*break*/, 21];
|
|
return [4 /*yield*/, processLink(ctx, pars)];
|
|
case 20:
|
|
_b.sent();
|
|
_b.label = 21;
|
|
case 21: return [3 /*break*/, 27];
|
|
case 22:
|
|
if (!(cmdName === 'HTML')) return [3 /*break*/, 26];
|
|
if (!!(0, reportUtils_1.isLoopExploring)(ctx)) return [3 /*break*/, 25];
|
|
return [4 /*yield*/, (0, jsSandbox_1.runUserJsAndGetRaw)(data, cmdRest, ctx)];
|
|
case 23:
|
|
html = _b.sent();
|
|
if (!(html != null)) return [3 /*break*/, 25];
|
|
return [4 /*yield*/, processHtml(ctx, html)];
|
|
case 24:
|
|
_b.sent();
|
|
_b.label = 25;
|
|
case 25: return [3 /*break*/, 27];
|
|
case 26: throw new errors_1.CommandSyntaxError(cmd);
|
|
case 27: return [2 /*return*/];
|
|
case 28:
|
|
err_1 = _b.sent();
|
|
if (!(0, errors_1.isError)(err_1))
|
|
throw err_1;
|
|
if (ctx.options.errorHandler != null) {
|
|
return [2 /*return*/, ctx.options.errorHandler(err_1)];
|
|
}
|
|
return [2 /*return*/, err_1];
|
|
case 29: return [2 /*return*/];
|
|
}
|
|
});
|
|
}); };
|
|
var builtInRegexes = types_1.BUILT_IN_COMMANDS.map(function (word) { return new RegExp("^".concat(word, "\\b")); });
|
|
var notBuiltIns = function (cmd) {
|
|
return !builtInRegexes.some(function (r) { return r.test(cmd.toUpperCase()); });
|
|
};
|
|
function getCommand(command, shorthands, fixSmartQuotes) {
|
|
// Get a cleaned version of the command
|
|
var cmd = command.trim();
|
|
if (cmd[0] === '*') {
|
|
var aliasName = cmd.slice(1).trim();
|
|
if (!shorthands[aliasName])
|
|
throw new errors_1.InvalidCommandError('Unknown alias', cmd);
|
|
cmd = shorthands[aliasName];
|
|
debug_1.logger.debug("Alias for: ".concat(cmd));
|
|
}
|
|
else if (cmd[0] === '=') {
|
|
cmd = "INS ".concat(cmd.slice(1).trim());
|
|
}
|
|
else if (cmd[0] === '!') {
|
|
cmd = "EXEC ".concat(cmd.slice(1).trim());
|
|
}
|
|
else if (notBuiltIns(cmd)) {
|
|
cmd = "INS ".concat(cmd.trim());
|
|
}
|
|
//replace 'smart' quotes with straight quotes
|
|
if (fixSmartQuotes) {
|
|
cmd = cmd
|
|
.replace(/[\u201C\u201D\u201E]/g, '"')
|
|
.replace(/[\u2018\u2019\u201A]/g, "'");
|
|
}
|
|
return cmd.trim();
|
|
}
|
|
exports.getCommand = getCommand;
|
|
function splitCommand(cmd) {
|
|
// Extract command name
|
|
var cmdNameMatch = /^(\S+)\s*/.exec(cmd);
|
|
var cmdName;
|
|
var cmdRest = '';
|
|
if (cmdNameMatch != null) {
|
|
cmdName = cmdNameMatch[1].toUpperCase();
|
|
cmdRest = cmd.slice(cmdName.length).trim();
|
|
}
|
|
return { cmdName: cmdName, cmdRest: cmdRest };
|
|
}
|
|
exports.splitCommand = splitCommand;
|
|
// ==========================================
|
|
// Individual commands
|
|
// ==========================================
|
|
var processForIf = function (data, node, ctx, cmd, cmdName, cmdRest) { return __awaiter(void 0, void 0, void 0, function () {
|
|
var isIf, forMatch, varName, curLoop, parentPorTrNode, parentPorTrNodeTag, parentLoopLevel, fParentIsExploring, loopOver, shouldRun;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
isIf = cmdName === 'IF';
|
|
forMatch = null;
|
|
varName = undefined;
|
|
if (isIf) {
|
|
if (!node._ifName) {
|
|
node._ifName = "__if_".concat(ctx.gCntIf);
|
|
ctx.gCntIf += 1;
|
|
}
|
|
varName = node._ifName;
|
|
}
|
|
else {
|
|
forMatch = /^(\S+)\s+IN\s+(.+)/i.exec(cmdRest);
|
|
if (!forMatch)
|
|
throw new errors_1.InvalidCommandError('Invalid FOR command', cmd);
|
|
varName = forMatch[1];
|
|
}
|
|
curLoop = (0, reportUtils_1.getCurLoop)(ctx);
|
|
if (!!(curLoop && curLoop.varName === varName)) return [3 /*break*/, 6];
|
|
// Check whether we already started a nested IF without and END-IF for this p or tr tag
|
|
if (isIf) {
|
|
parentPorTrNode = findParentPorTrNode(node);
|
|
parentPorTrNodeTag = parentPorTrNode != null
|
|
? parentPorTrNode._fTextNode
|
|
? null
|
|
: parentPorTrNode._tag
|
|
: null;
|
|
if (parentPorTrNode != null) {
|
|
if (parentPorTrNodeTag === 'w:p') {
|
|
if (ctx.pIfCheckMap.has(parentPorTrNode) &&
|
|
ctx.pIfCheckMap.get(parentPorTrNode) !== cmd)
|
|
throw new errors_1.InvalidCommandError('Invalid IF command nested into another IF command on the same line', cmd);
|
|
else
|
|
ctx.pIfCheckMap.set(parentPorTrNode, cmd);
|
|
}
|
|
else if (parentPorTrNodeTag === 'w:tr') {
|
|
if (ctx.trIfCheckMap.has(parentPorTrNode) &&
|
|
ctx.trIfCheckMap.get(parentPorTrNode) !== cmd)
|
|
throw new errors_1.InvalidCommandError('Invalid IF command nested into another IF command on the same table row', cmd);
|
|
else
|
|
ctx.trIfCheckMap.set(parentPorTrNode, cmd);
|
|
}
|
|
}
|
|
}
|
|
parentLoopLevel = ctx.loops.length - 1;
|
|
fParentIsExploring = parentLoopLevel >= 0 && ctx.loops[parentLoopLevel].idx === -1;
|
|
loopOver = void 0;
|
|
if (!fParentIsExploring) return [3 /*break*/, 1];
|
|
loopOver = [];
|
|
return [3 /*break*/, 5];
|
|
case 1:
|
|
if (!isIf) return [3 /*break*/, 3];
|
|
return [4 /*yield*/, (0, jsSandbox_1.runUserJsAndGetRaw)(data, cmdRest, ctx)];
|
|
case 2:
|
|
shouldRun = !!(_a.sent());
|
|
loopOver = shouldRun ? [1] : [];
|
|
return [3 /*break*/, 5];
|
|
case 3:
|
|
if (!forMatch)
|
|
throw new errors_1.InvalidCommandError('Invalid FOR command', cmd);
|
|
return [4 /*yield*/, (0, jsSandbox_1.runUserJsAndGetRaw)(data, forMatch[2], ctx)];
|
|
case 4:
|
|
loopOver = _a.sent();
|
|
if (!Array.isArray(loopOver))
|
|
throw new errors_1.InvalidCommandError('Invalid FOR command (can only iterate over Array)', cmd);
|
|
_a.label = 5;
|
|
case 5:
|
|
ctx.loops.push({
|
|
refNode: node,
|
|
refNodeLevel: ctx.level,
|
|
varName: varName,
|
|
loopOver: loopOver,
|
|
isIf: isIf,
|
|
// run through the loop once first, without outputting anything
|
|
// (if we don't do it like this, we could not run empty loops!)
|
|
idx: -1,
|
|
});
|
|
_a.label = 6;
|
|
case 6:
|
|
(0, reportUtils_1.logLoop)(ctx.loops);
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
}); };
|
|
var processEndForIf = function (node, ctx, cmd, cmdName, cmdRest) {
|
|
var isIf = cmdName === 'END-IF';
|
|
var curLoop = (0, reportUtils_1.getCurLoop)(ctx);
|
|
if (!curLoop)
|
|
throw new errors_1.InvalidCommandError("Unexpected ".concat(cmdName, " outside of ").concat(isIf ? 'IF statement' : 'FOR loop', " context"), cmd);
|
|
// Reset the if check flag for the corresponding p or tr parent node
|
|
var parentPorTrNode = findParentPorTrNode(node);
|
|
var parentPorTrNodeTag = parentPorTrNode != null
|
|
? parentPorTrNode._fTextNode
|
|
? null
|
|
: parentPorTrNode._tag
|
|
: null;
|
|
if (parentPorTrNodeTag === 'w:p') {
|
|
ctx.pIfCheckMap.delete(parentPorTrNode);
|
|
}
|
|
else if (parentPorTrNodeTag === 'w:tr') {
|
|
ctx.trIfCheckMap.delete(parentPorTrNode);
|
|
}
|
|
// First time we visit an END-IF node, we assign it the arbitrary name
|
|
// generated when the IF was processed
|
|
if (isIf && !node._ifName) {
|
|
node._ifName = curLoop.varName;
|
|
ctx.gCntEndIf += 1;
|
|
}
|
|
// Check if this is the expected END-IF/END-FOR. If not:
|
|
// - If it's one of the nested varNames, throw
|
|
// - If it's not one of the nested varNames, ignore it; we find
|
|
// cases in which an END-IF/FOR is found that belongs to a previous
|
|
// part of the paragraph of the current loop.
|
|
var varName = isIf ? node._ifName : cmdRest;
|
|
if (curLoop.varName !== varName) {
|
|
if (ctx.loops.find(function (o) { return o.varName === varName; }) == null) {
|
|
debug_1.logger.debug("Ignoring ".concat(cmd, " (").concat(varName, ", but we're expecting ").concat(curLoop.varName, ")"));
|
|
return;
|
|
}
|
|
throw new errors_1.InvalidCommandError('Invalid command', cmd);
|
|
}
|
|
// Get the next item in the loop
|
|
var nextIdx = curLoop.idx + 1;
|
|
var nextItem = curLoop.loopOver[nextIdx];
|
|
if (nextItem != null) {
|
|
// next iteration
|
|
ctx.vars[varName] = nextItem;
|
|
ctx.fJump = true;
|
|
curLoop.idx = nextIdx;
|
|
}
|
|
else {
|
|
// loop finished
|
|
ctx.loops.pop();
|
|
}
|
|
};
|
|
var imageToContext = function (ctx, img) {
|
|
validateImage(img);
|
|
ctx.imageAndShapeIdIncrement += 1;
|
|
var id = String(ctx.imageAndShapeIdIncrement);
|
|
var relId = "img".concat(id);
|
|
ctx.images[relId] = img;
|
|
return relId;
|
|
};
|
|
function validateImage(img) {
|
|
if (!(img.data instanceof Uint8Array ||
|
|
img.data instanceof ArrayBuffer ||
|
|
typeof img.data === 'string')) {
|
|
throw new Error('image .data property needs to be provided as Uint8Array (e.g. Buffer), ArrayBuffer, or as a base64-encoded string');
|
|
}
|
|
if (!types_1.ImageExtensions.includes(img.extension)) {
|
|
throw new Error("An extension (one of ".concat(types_1.ImageExtensions, ") needs to be provided when providing an image or a thumbnail."));
|
|
}
|
|
}
|
|
function validateImagePars(pars) {
|
|
if (!Number.isFinite(pars.width))
|
|
throw new Error("invalid image width: ".concat(pars.width, " (in cm)"));
|
|
if (!Number.isFinite(pars.height))
|
|
throw new Error("invalid image height: ".concat(pars.height, " (in cm)"));
|
|
validateImage(pars);
|
|
if (pars.thumbnail)
|
|
validateImage(pars.thumbnail);
|
|
}
|
|
var processImage = function (ctx, imagePars) {
|
|
var _a;
|
|
validateImagePars(imagePars);
|
|
var cx = (imagePars.width * 360e3).toFixed(0);
|
|
var cy = (imagePars.height * 360e3).toFixed(0);
|
|
var imgRelId = imageToContext(ctx, getImageData(imagePars));
|
|
var id = String(ctx.imageAndShapeIdIncrement);
|
|
var alt = imagePars.alt || 'desc';
|
|
var node = reportUtils_1.newNonTextNode;
|
|
var extNodes = [];
|
|
extNodes.push(node('a:ext', { uri: '{28A0092B-C50C-407E-A947-70E740481C1C}' }, [
|
|
node('a14:useLocalDpi', {
|
|
'xmlns:a14': 'http://schemas.microsoft.com/office/drawing/2010/main',
|
|
val: '0',
|
|
}),
|
|
]));
|
|
// http://officeopenxml.com/drwSp-rotate.php
|
|
// Values are in 60,000ths of a degree, with positive angles moving clockwise or towards the positive y-axis.
|
|
var rot = imagePars.rotation
|
|
? (imagePars.rotation * 60e3).toString()
|
|
: undefined;
|
|
if (ctx.images[imgRelId].extension === '.svg') {
|
|
// Default to an empty thumbnail, as it is not critical and just part of the docx standard's scaffolding.
|
|
// Without a thumbnail, the svg won't render (even in newer versions of Word that don't need the thumbnail).
|
|
var thumbnail = (_a = imagePars.thumbnail) !== null && _a !== void 0 ? _a : {
|
|
data: 'bm90aGluZwo=',
|
|
extension: '.png',
|
|
};
|
|
var thumbRelId = imageToContext(ctx, thumbnail);
|
|
extNodes.push(node('a:ext', { uri: '{96DAC541-7B7A-43D3-8B79-37D633B846F1}' }, [
|
|
node('asvg:svgBlip', {
|
|
'xmlns:asvg': 'http://schemas.microsoft.com/office/drawing/2016/SVG/main',
|
|
'r:embed': imgRelId,
|
|
}),
|
|
]));
|
|
// For SVG the thumb is placed where the image normally goes.
|
|
imgRelId = thumbRelId;
|
|
}
|
|
var pic = node('pic:pic', { 'xmlns:pic': 'http://schemas.openxmlformats.org/drawingml/2006/picture' }, [
|
|
node('pic:nvPicPr', {}, [
|
|
node('pic:cNvPr', { id: '0', name: "Picture ".concat(id), descr: alt }),
|
|
node('pic:cNvPicPr', {}, [
|
|
node('a:picLocks', { noChangeAspect: '1', noChangeArrowheads: '1' }),
|
|
]),
|
|
]),
|
|
node('pic:blipFill', {}, [
|
|
node('a:blip', { 'r:embed': imgRelId, cstate: 'print' }, [
|
|
node('a:extLst', {}, extNodes),
|
|
]),
|
|
node('a:srcRect'),
|
|
node('a:stretch', {}, [node('a:fillRect')]),
|
|
]),
|
|
node('pic:spPr', { bwMode: 'auto' }, [
|
|
node('a:xfrm', rot ? { rot: rot } : {}, [
|
|
node('a:off', { x: '0', y: '0' }),
|
|
node('a:ext', { cx: cx, cy: cy }),
|
|
]),
|
|
node('a:prstGeom', { prst: 'rect' }, [node('a:avLst')]),
|
|
node('a:noFill'),
|
|
node('a:ln', {}, [node('a:noFill')]),
|
|
]),
|
|
]);
|
|
var drawing = node('w:drawing', {}, [
|
|
node('wp:inline', { distT: '0', distB: '0', distL: '0', distR: '0' }, [
|
|
node('wp:extent', { cx: cx, cy: cy }),
|
|
node('wp:docPr', { id: id, name: "Picture ".concat(id), descr: alt }),
|
|
node('wp:cNvGraphicFramePr', {}, [
|
|
node('a:graphicFrameLocks', {
|
|
'xmlns:a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
|
|
noChangeAspect: '1',
|
|
}),
|
|
]),
|
|
node('a:graphic', { 'xmlns:a': 'http://schemas.openxmlformats.org/drawingml/2006/main' }, [
|
|
node('a:graphicData', { uri: 'http://schemas.openxmlformats.org/drawingml/2006/picture' }, [pic]),
|
|
]),
|
|
]),
|
|
]);
|
|
ctx.pendingImageNode = { image: drawing };
|
|
if (imagePars.caption) {
|
|
ctx.pendingImageNode.caption = [
|
|
node('w:br'),
|
|
node('w:t', {}, [(0, reportUtils_1.newTextNode)(imagePars.caption)]),
|
|
];
|
|
}
|
|
};
|
|
function getImageData(imagePars) {
|
|
var data = imagePars.data, extension = imagePars.extension;
|
|
if (!extension) {
|
|
throw new Error('If you return image `data`, make sure you return an extension as well!');
|
|
}
|
|
return { extension: extension, data: data };
|
|
}
|
|
var processLink = function (ctx, linkPars) { return __awaiter(void 0, void 0, void 0, function () {
|
|
var url, _a, label, id, relId, node, textRunPropsNode, link;
|
|
return __generator(this, function (_b) {
|
|
url = linkPars.url, _a = linkPars.label, label = _a === void 0 ? url : _a;
|
|
ctx.linkId += 1;
|
|
id = String(ctx.linkId);
|
|
relId = "link".concat(id);
|
|
ctx.links[relId] = { url: url };
|
|
node = reportUtils_1.newNonTextNode;
|
|
textRunPropsNode = ctx.textRunPropsNode;
|
|
link = node('w:hyperlink', { 'r:id': relId, 'w:history': '1' }, [
|
|
node('w:r', {}, [
|
|
textRunPropsNode ||
|
|
node('w:rPr', {}, [node('w:u', { 'w:val': 'single' })]),
|
|
node('w:t', {}, [(0, reportUtils_1.newTextNode)(label)]),
|
|
]),
|
|
]);
|
|
ctx.pendingLinkNode = link;
|
|
return [2 /*return*/];
|
|
});
|
|
}); };
|
|
var processHtml = function (ctx, data) { return __awaiter(void 0, void 0, void 0, function () {
|
|
var id, relId, node, html;
|
|
return __generator(this, function (_a) {
|
|
ctx.htmlId += 1;
|
|
id = String(ctx.htmlId);
|
|
relId = "html".concat(id);
|
|
ctx.htmls[relId] = data;
|
|
node = reportUtils_1.newNonTextNode;
|
|
html = node('w:altChunk', { 'r:id': relId });
|
|
ctx.pendingHtmlNode = html;
|
|
return [2 /*return*/];
|
|
});
|
|
}); };
|
|
// ==========================================
|
|
// Helpers
|
|
// ==========================================
|
|
var BufferKeys = ['w:p', 'w:tr', 'w:tc'];
|
|
var appendTextToTagBuffers = function (text, ctx, options) {
|
|
if (ctx.fSeekQuery)
|
|
return;
|
|
var fCmd = options.fCmd, fInsertedText = options.fInsertedText;
|
|
var type = fCmd ? 'cmds' : 'text';
|
|
BufferKeys.forEach(function (key) {
|
|
var buf = ctx.buffers[key];
|
|
buf[type] += text;
|
|
if (fInsertedText)
|
|
buf.fInsertedText = true;
|
|
});
|
|
};
|
|
function updateID(newNode, ctx) {
|
|
ctx.imageAndShapeIdIncrement += 1;
|
|
var id = String(ctx.imageAndShapeIdIncrement);
|
|
newNode._attrs = __assign(__assign({}, newNode._attrs), { id: "".concat(id) });
|
|
}
|