Commit 29a69341 by Edgar HIPP

Refactor code

parent bbd2cf6f
"use strict"; "use strict";
const DocUtils = require("docxtemplater").DocUtils; const DocUtils = require("docxtemplater").DocUtils;
DocUtils.convertPixelsToEmus = function (pixel) {
return Math.round(pixel * 9525);
};
module.exports = DocUtils; module.exports = DocUtils;
...@@ -3,43 +3,47 @@ ...@@ -3,43 +3,47 @@
const DocUtils = require("./docUtils"); const DocUtils = require("./docUtils");
const extensionRegex = /[^.]+\.([^.]+)/; const extensionRegex = /[^.]+\.([^.]+)/;
const rels = {
getPrefix(fileType) {
return fileType === "docx" ? "word" : "ppt";
},
getFileTypeName(fileType) {
return fileType === "docx" ? "document" : "presentation";
},
getRelsFileName(fileName) {
return fileName.replace(/^.*?([a-zA-Z0-9]+)\.xml$/, "$1") + ".xml.rels";
},
getRelsFilePath(fileName, fileType) {
const relsFileName = rels.getRelsFileName(fileName);
const prefix = fileType === "pptx" ? "ppt/slides" : "word";
return `${prefix}/_rels/${relsFileName}`;
},
};
module.exports = class ImgManager { module.exports = class ImgManager {
constructor(zip, fileName, xmlDocuments) { constructor(zip, fileName, xmlDocuments, fileType) {
this.fileType = this.getFileType(fileName); this.fileName = fileName;
this.fileTypeName = this.getFileTypeName(fileName); this.prefix = rels.getPrefix(fileType);
this.relsFilePath = this.getRelsFile(fileName);
this.zip = zip; this.zip = zip;
this.xmlDocuments = xmlDocuments; this.xmlDocuments = xmlDocuments;
this.relsDoc = xmlDocuments[this.relsFilePath] || this.createEmptyRelsDoc(xmlDocuments, this.relsFilePath); this.fileTypeName = rels.getFileTypeName(fileType);
} this.mediaPrefix = fileType === "pptx" ? "../media" : "media";
getRelsFile(fileName) { const relsFilePath = rels.getRelsFilePath(fileName, fileType);
let relsFilePath; this.relsDoc = xmlDocuments[relsFilePath] || this.createEmptyRelsDoc(xmlDocuments, relsFilePath);
const relsFileName = this.getRelsFileName(fileName);
const fileType = this.getFileType(fileName);
if (fileType === "ppt") {
relsFilePath = "ppt/slides/_rels/" + relsFileName;
}
else {
relsFilePath = "word/_rels/" + relsFileName;
}
return relsFilePath;
}
getRelsFileName(fileName) {
return fileName.replace(/^.*?([a-z0-9]+)\.xml$/, "$1") + ".xml.rels";
}
getFileType(fileName) {
return (fileName.indexOf("ppt/slides") === 0) ? "ppt" : "word";
}
getFileTypeName(fileName) {
return (fileName.indexOf("ppt/slides") === 0) ? "presentation" : "document";
} }
createEmptyRelsDoc(xmlDocuments, relsFileName) { createEmptyRelsDoc(xmlDocuments, relsFileName) {
const file = this.zip.files[relsFileName] || this.zip.files[this.fileType + "/_rels/" + this.fileTypeName + ".xml.rels"]; const mainRels = this.prefix + "/_rels/" + (this.fileTypeName) + ".xml.rels";
if (!file) { const doc = xmlDocuments[mainRels];
return; if (!doc) {
const err = new Error("Could not copy from empty relsdoc");
err.properties = {
mainRels,
relsFileName,
files: Object.keys(this.zip.files),
};
throw err;
} }
const content = DocUtils.decodeUtf8(file.asText()); const relsDoc = DocUtils.str2xml(DocUtils.xml2str(doc));
const relsDoc = DocUtils.str2xml(content);
const relationships = relsDoc.getElementsByTagName("Relationships")[0]; const relationships = relsDoc.getElementsByTagName("Relationships")[0];
const relationshipChilds = relationships.getElementsByTagName("Relationship"); const relationshipChilds = relationships.getElementsByTagName("Relationship");
for (let i = 0, l = relationshipChilds.length; i < l; i++) { for (let i = 0, l = relationshipChilds.length; i < l; i++) {
...@@ -81,11 +85,12 @@ module.exports = class ImgManager { ...@@ -81,11 +85,12 @@ module.exports = class ImgManager {
i = 0; i = 0;
} }
const realImageName = i === 0 ? imageName : imageName + `(${i})`; const realImageName = i === 0 ? imageName : imageName + `(${i})`;
if (this.zip.files[`${this.fileType}/media/${realImageName}`] != null) { const imagePath = `${this.prefix}/media/${realImageName}`;
if (this.zip.files[imagePath] != null) {
return this.addImageRels(imageName, imageData, i + 1); return this.addImageRels(imageName, imageData, i + 1);
} }
const image = { const image = {
name: `${this.fileType}/media/${realImageName}`, name: imagePath,
data: imageData, data: imageData,
options: { options: {
binary: true, binary: true,
...@@ -100,12 +105,7 @@ module.exports = class ImgManager { ...@@ -100,12 +105,7 @@ module.exports = class ImgManager {
const maxRid = this.loadImageRels() + 1; const maxRid = this.loadImageRels() + 1;
newTag.setAttribute("Id", `rId${maxRid}`); newTag.setAttribute("Id", `rId${maxRid}`);
newTag.setAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"); newTag.setAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
if (this.fileType === "ppt") { newTag.setAttribute("Target", `${this.mediaPrefix}/${realImageName}`);
newTag.setAttribute("Target", `../media/${realImageName}`);
}
else {
newTag.setAttribute("Target", `media/${realImageName}`);
}
relationships.appendChild(newTag); relationships.appendChild(newTag);
return maxRid; return maxRid;
} }
......
module.exports = {
getImageXml(rId, size) {
return `<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="${size[0]}" cy="${size[1]}"/>
<wp:effectExtent l="0" t="0" r="0" b="0"/>
<wp:docPr id="2" name="Image 2" descr="image"/>
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="Picture 1" descr="image"/>
<pic:cNvPicPr>
<a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId${rId}">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
</a:ext>
</a:extLst>
</a:blip>
<a:srcRect/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode="auto">
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="${size[0]}" cy="${size[1]}"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln>
<a:noFill/>
</a:ln>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
`.replace(/\t|\n/g, "");
},
getImageXmlCentered(rId, size) {
return `<w:p>
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr/>
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="${size[0]}" cy="${size[1]}"/>
<wp:docPr id="0" name="Picture" descr=""/>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="Picture" descr=""/>
<pic:cNvPicPr>
<a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId${rId}"/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode="auto">
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="${size[0]}" cy="${size[1]}"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln w="9525">
<a:noFill/>
<a:miter lim="800000"/>
<a:headEnd/>
<a:tailEnd/>
</a:ln>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
</w:r>
</w:p>
`.replace(/\t|\n/g, "");
},
getPptxImageXml(rId, size, offset) {
return `<p:pic>
<p:nvPicPr>
<p:cNvPr id="6" name="Picture 2"/>
<p:cNvPicPr>
<a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
</p:cNvPicPr>
<p:nvPr/>
</p:nvPicPr>
<p:blipFill>
<a:blip r:embed="rId${rId}" cstate="print">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
</a:ext>
</a:extLst>
</a:blip>
<a:srcRect/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</p:blipFill>
<p:spPr bwMode="auto">
<a:xfrm>
<a:off x="${offset.x}" y="${offset.y}"/>
<a:ext cx="${size[0]}" cy="${size[1]}"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln>
<a:noFill/>
</a:ln>
<a:effectLst/>
<a:extLst>
<a:ext uri="{909E8E84-426E-40DD-AFC4-6F175D3DCCD1}">
<a14:hiddenFill xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main">
<a:solidFill>
<a:schemeClr val="accent1"/>
</a:solidFill>
</a14:hiddenFill>
</a:ext>
<a:ext uri="{91240B29-F687-4F45-9708-019B960494DF}">
<a14:hiddenLine xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" w="9525">
<a:solidFill>
<a:schemeClr val="tx1"/>
</a:solidFill>
<a:miter lim="800000"/>
<a:headEnd/>
<a:tailEnd/>
</a14:hiddenLine>
</a:ext>
<a:ext uri="{AF507438-7753-43E0-B8FC-AC1667EBCBE1}">
<a14:hiddenEffects xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main">
<a:effectLst>
<a:outerShdw dist="35921" dir="2700000" algn="ctr" rotWithShape="0">
<a:schemeClr val="bg2"/>
</a:outerShdw>
</a:effectLst>
</a14:hiddenEffects>
</a:ext>
</a:extLst>
</p:spPr>
</p:pic>
`.replace(/\t|\n/g, "");
},
};
...@@ -22,6 +22,8 @@ const fileNames = [ ...@@ -22,6 +22,8 @@ const fileNames = [
"expectedWithoutRels.docx", "expectedWithoutRels.docx",
"tagImage.pptx", "tagImage.pptx",
"expectedTagImage.pptx", "expectedTagImage.pptx",
"tagImageCentered.pptx",
"expectedTagImageCentered.pptx",
]; ];
beforeEach(function () { beforeEach(function () {
...@@ -104,6 +106,13 @@ function testStart() { ...@@ -104,6 +106,13 @@ function testStart() {
this.data = {image: "examples/image.png"}; this.data = {image: "examples/image.png"};
this.loadAndRender(); this.loadAndRender();
}); });
it("should work with PPTX documents centered", function () {
this.name = "tagImageCentered.pptx";
this.expectedName = "expectedTagImageCentered.pptx";
this.data = {image: "examples/image.png"};
this.loadAndRender();
});
}); });
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
"description": "Image Module for docxtemplater", "description": "Image Module for docxtemplater",
"main": "js/index.js", "main": "js/index.js",
"scripts": { "scripts": {
"test:coverage": "istanbul cover _mocha -- es6/test.js",
"compile": "rimraf js && mkdirp js && babel es6 --out-dir js", "compile": "rimraf js && mkdirp js && babel es6 --out-dir js",
"preversion": "npm test && npm run compile && npm run browserify && npm run uglify", "preversion": "npm test && npm run compile && npm run browserify && npm run uglify",
"test:compiled": "mocha js/test.js", "test:compiled": "mocha js/test.js",
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
"jszip": "^2.6.1", "jszip": "^2.6.1",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"mocha": "^3.2.0", "mocha": "^3.2.0",
"istanbul": "^0.4.5",
"rimraf": "^2.5.4", "rimraf": "^2.5.4",
"uglifyjs": "^2.4.10" "uglifyjs": "^2.4.10"
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment