docxtemplater
Version:
.docx generator working with templates and data (like Mustache)
282 lines (281 loc) • 8.78 kB
HTML
<html lang="en">
<head>
<title>Code coverage report for es6/xmlMatcher.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../prettify.css" />
<link rel="stylesheet" href="../base.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>
<a href="../index.html">all files</a> / <a href="index.html">es6/</a> xmlMatcher.js
</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Statements</span>
<span class='fraction'>46/46</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Branches</span>
<span class='fraction'>4/4</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Functions</span>
<span class='fraction'>5/5</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Lines</span>
<span class='fraction'>44/44</span>
</div>
</div>
</div>
<div class='status-line high'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet">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</td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-yes">661×</span>
<span class="cline-any cline-yes">661×</span>
<span class="cline-any cline-yes">51×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">63×</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">"use strict";
// res class responsibility is to parse the XML.
const DocUtils = require("./docUtils");
const memoize = require("memoizejs");
function handleRecursiveCase(res) {
/*
Because xmlTemplater is recursive (meaning it can call it self), we need to handle special cases where the XML is not valid:
For example with res string "I am</w:t></w:r></w:p><w:p><w:r><w:t>sleeping",
- we need to match also the string that is inside an implicit <w:t> (that's the role of replacerUnshift) (in res case 'I am')
- we need to match the string that is at the right of a <w:t> (that's the role of replacerPush) (in res case 'sleeping')
the test: describe "scope calculation" it "should compute the scope between 2 <w:t>" makes sure that res part of code works
It should even work if they is no XML at all, for example if the code is just "I am sleeping", in res case however, they should only be one match
*/
function replacerUnshift() {
const pn = {array: Array.prototype.slice.call(arguments)};
pn.array.shift();
const match = pn.array[0] + pn.array[1];
// add match so that pn[0] = whole match, pn[1]= first parenthesis,...
pn.array.unshift(match);
pn.array.pop();
const offset = pn.array.pop();
pn.offset = offset;
pn.first = true;
// add at the beginning
res.matches.unshift(pn);
res.charactersAdded.unshift(0);
return res.charactersAddedCumulative.unshift(0);
}
if (res.content.indexOf("<") === -1 && res.content.indexOf(">") === -1) {
res.content.replace(/^()([^<>]*)$/, replacerUnshift);
}
let r = new RegExp(`^()([^<]+)<\/(?:${res.tagsXmlArrayJoined})>`);
res.content.replace(r, replacerUnshift);
function replacerPush() {
const pn = {array: Array.prototype.slice.call(arguments)};
pn.array.pop();
const offset = pn.array.pop();
pn.offset = offset;
pn.last = true;
// add at the end
res.matches.push(pn);
res.charactersAdded.push(0);
return res.charactersAddedCumulative.push(0);
}
r = new RegExp(`(<(?:${res.tagsXmlArrayJoined})[^>]*>)([^>]+)$`);
res.content.replace(r, replacerPush);
return res;
}
function xmlMatcher(content, tagsXmlArray) {
const res = {};
res.content = content;
res.tagsXmlArray = tagsXmlArray;
res.tagsXmlArrayJoined = res.tagsXmlArray.join("|");
const regexp = new RegExp(`(<(?:${res.tagsXmlArrayJoined})[^>]*>)([^<>]*)</(?:${res.tagsXmlArrayJoined})>`, "g");
res.matches = DocUtils.pregMatchAll(regexp, res.content);
res.charactersAddedCumulative = res.matches.map(() => 0);
res.charactersAdded = res.matches.map(() => 0);
return handleRecursiveCase(res);
}
const memoized = memoize(xmlMatcher);
module.exports = function (content, tagsXmlArray) {
return DocUtils.cloneDeep(memoized(content, tagsXmlArray));
};
</pre></td></tr>
</table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage
generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Sat Jun 18 2016 12:59:17 GMT+0200 (CEST)
</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>