| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 | 1×
1×
1×
1×
1×
1×
1×
1×
350×
25×
325×
325×
325×
325×
1×
417×
417×
1×
54×
1018×
701×
54×
54×
701×
701×
350×
284×
66×
351×
351×
54×
1×
54×
54×
112×
112×
7×
105×
1×
46×
1×
8×
8×
8×
8×
8×
8×
8×
1×
1×
7×
7×
7×
6×
6×
1×
194×
194×
3684×
8×
3684×
194×
8×
8×
2×
2×
194×
1×
| const DocUtils = require("./doc-utils");
const Errors = require("./errors");
function throwRawTagNotInParagraph(options) {
const err = new Errors.XTTemplateError("Raw tag not in paragraph");
const tag = options.part.value;
err.properties = {
id: "raw_tag_outerxml_invalid",
explanation: `The tag "${tag}"`,
rootError: options.rootError,
xtag: tag,
postparsed: options.postparsed,
expandTo: options.expandTo,
index: options.index,
};
throw err;
}
function lastTagIsOpenTag(array, tag) {
if (array.length === 0) {
return false;
}
const lastTag = array[array.length - 1];
const innerLastTag = lastTag.tag.substr(1);
const innerCurrentTag = tag.substr(2, tag.length - 3);
return innerLastTag.indexOf(innerCurrentTag) === 0;
}
function addTag(array, tag) {
array.push({tag});
return array;
}
function getListXmlElements(parts) {
/*
get the different closing and opening tags between two texts (doesn't take into account tags that are opened then closed (those that are closed then opened are returned)):
returns:[{"tag":"</w:r>","offset":13},{"tag":"</w:p>","offset":265},{"tag":"</w:tc>","offset":271},{"tag":"<w:tc>","offset":828},{"tag":"<w:p>","offset":883},{"tag":"<w:r>","offset":1483}]
*/
const tags = parts.filter(function (part) {
return part.type === "tag";
}).map(function (part) {
return part.value;
});
let result = [];
for (let i = 0, tag; i < tags.length; i++) {
tag = tags[i];
// closing tag
if (tag[1] === "/") {
if (lastTagIsOpenTag(result, tag)) {
result.pop();
}
else {
result = addTag(result, tag);
}
}
else Eif (tag[tag.length - 1] !== "/") {
result = addTag(result, tag);
}
}
return result;
}
function getExpandToDefault(parts) {
const xmlElements = getListXmlElements(parts);
for (let i = 0; i < xmlElements.length; i++) {
const xmlElement = xmlElements[i];
if(xmlElement.tag.indexOf("<w:tc") === 0) {
return "w:tr";
}
if(xmlElement.tag.indexOf("<a:tc") === 0) {
return "a:tr";
}
}
return false;
}
function expandOne(part, postparsed, options) {
const expandTo = part.expandTo || options.expandTo;
const index = postparsed.indexOf(part);
Iif (!expandTo) {
return postparsed;
}
let right, left;
try {
right = DocUtils.getRight(postparsed, expandTo, index);
left = DocUtils.getLeft(postparsed, expandTo, index);
}
catch (rootError) {
Eif (rootError instanceof Errors.XTTemplateError) {
throwRawTagNotInParagraph({part, rootError, postparsed, expandTo, index});
}
throw rootError;
}
const leftParts = postparsed.slice(left, index);
const rightParts = postparsed.slice(index + 1, right + 1);
const inner = options.getInner({index, part, leftParts, rightParts, left, right, postparsed});
inner.expanded = [leftParts, rightParts];
return DocUtils.concatArrays([
postparsed.slice(0, left),
[inner],
postparsed.slice(right + 1),
]);
}
function expandToOne(postparsed, options) {
const errors = [];
const expandToElements = postparsed.reduce(function (elements, part) {
if (part.type === "placeholder" && part.module === options.moduleName) {
elements.push(part);
}
return elements;
}, []);
expandToElements.forEach(function (part) {
try {
postparsed = expandOne(part, postparsed, options);
}
catch (error) {
Eif (error instanceof Errors.XTTemplateError) {
errors.push(error);
}
else {
throw error;
}
}
});
return {postparsed, errors};
}
module.exports = {
expandToOne,
getExpandToDefault,
};
|