Skip to content

Commit 377dbf4

Browse files
committed
Support dynamic picture placement in docx's description field
1 parent 2158681 commit 377dbf4

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

lib/postprocessor.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,17 @@ class FileStore {
3131
}
3232
}
3333

34+
const allframes = /<draw:frame (.*?)<\/draw:frame>/g;
35+
3436
class OdtPostProcessor {
35-
allframes = /<draw:frame (.*?)<\/draw:frame>/g;
3637

3738
constructor(template, data, options, filestore) {
3839
const contentXml = template.files.find((f) => f.name === "content.xml");
3940
if (!contentXml) return;
4041
const manifestXml = template.files.find(f => f.name === "META-INF/manifest.xml");
4142

4243
// Use base64 data to create new file and update references
43-
contentXml.data = contentXml.data.replaceAll(this.allframes, function (drawFrame) {
44+
contentXml.data = contentXml.data.replaceAll(allframes, function (drawFrame) {
4445
const [,,mime,content] = /<svg:title>(data:([^;]+);base64,(.*?))<\/svg:title>/.exec(drawFrame) || [];
4546
if (!content || !mime) return drawFrame;
4647
const [,extension] = mime.split("/");
@@ -63,17 +64,19 @@ class OdtPostProcessor {
6364
}
6465
}
6566

67+
const alldrawings = /<w:drawing>(.*?)<\/w:drawing>/g;
68+
const allrels = /<Relationship (.*?)\/>/g;
69+
6670
class DocxPostProcessor {
67-
alldrawings = /<w:drawing>(.*?)<\/w:drawing>/g;
6871
pattern = /(<w:drawing>.*<wp:docPr.*title=)("data:image\/(.*);base64,(.+?)")(.*:embed=")(.*?)(".*<\/w:drawing>)/g;
6972

7073
constructor(template, data, options, filestore) {
7174
const documentXmlFile = template.files.find(f => f.name === "word/document.xml");
7275
if (!documentXmlFile) return;
7376
const documentXmlRelsFile = template.files.find(f => f.name === "word/_rels/document.xml.rels");
7477

75-
documentXmlFile.data = documentXmlFile.data.replaceAll(this.alldrawings, function (drawing) {
76-
const [,,mime,content ] = /title="(data:([^;]+);base64,(.*?))"/.exec(drawing) || [];
78+
documentXmlFile.data = documentXmlFile.data.replaceAll(alldrawings, function (drawing) {
79+
const [,,,mime,content ] = /(title|descr)="(data:([^;]+);base64,(.*?))"/.exec(drawing) || [];
7780
const [,relationshipId] = /embed="(.*?)"/.exec(drawing) || [];
7881
if (!content || !mime || !relationshipId) return drawing;
7982
const [,extension] = mime.split("/");
@@ -83,12 +86,13 @@ class DocxPostProcessor {
8386
if (newfile) {
8487
template.files.push({ name: imgFile, isMarked: false, data: Buffer.from(content, "base64"), parent: ""});
8588
// Update corresponding entry in word/_rels/document.xml.rels file
86-
const regex = new RegExp(`(.*Target=")(.*)(".*Id="${relationshipId}".*\/>.*<\/Relationships>)`,"g");
87-
documentXmlRelsFile.data = documentXmlRelsFile.data.replaceAll(regex, function (_match, p1, _p2, p3) {
88-
return [p1, `/${imgFile}`, p3].join("")
89+
documentXmlRelsFile.data = documentXmlRelsFile.data.replaceAll(allrels, function (relationship) {
90+
const [,id] = /Id="(.*?)"/.exec(relationship) || [];
91+
if (id != relationshipId) return relationship;
92+
return relationship.replace(/Target=".*?"/g, `Target="/${imgFile}"`);
8993
});
9094
}
91-
return drawing.replace(/title="data:[^"]+"/, 'title=""');
95+
return drawing.replace(/(title|descr)="data:[^;]+;base64,.*?"/g, '$1=""');
9296
});
9397
}
9498
}

0 commit comments

Comments
 (0)