-
Notifications
You must be signed in to change notification settings - Fork 0
/
.eleventy.js
110 lines (102 loc) · 3.62 KB
/
.eleventy.js
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
const mammoth = require("mammoth");
const cheerio = require("cheerio");
const lodashMerge = require("lodash.merge");
const path = require("path");
const fs = require("fs");
const md5 = require("js-md5");
const fsPromises = require("fs/promises");
module.exports = function (eleventyConfig, suppliedOptions) {
const defaultOptions = {
layout: "layouts/docx.njk",
outputDir: eleventyConfig.dir?.output || "_site",
imageDir: "images",
useGlobalLayout: true,
cheerioTransform: null,
mammothConfig: {},
};
// Return your Object options:
let options = lodashMerge({}, defaultOptions, suppliedOptions);
eleventyConfig.addTemplateFormats("docx");
// ignore temporary files
eleventyConfig.ignores.add("**/~*.docx");
eleventyConfig.addExtension("docx", {
getData: function () {
if (options.useGlobalLayout) {
// Set layout for all docx files
return {
layout: options.layout,
};
} else {
// The layout must be set elsewhere in the data cascade (eg. directory data files)
return {};
}
},
compile: function (str, inputPath) {
return async (data) => {
// This checks the data cascade for specific mammothConfig and cheerioTransform
// If they're not in the cascade, we use the global options (set when adding plugin to .eleventy.js)
const mammothConfig = data.mammothConfig
? data.mammothConfig
: options.mammothConfig;
const cheerioTransform = data.cheerioTransform
? data.cheerioTransform
: options.cheerioTransform;
const imageSubfolderName = data.page.fileSlug;
const imageNamePrefix = data.page.fileSlug;
var imageCounter = 1;
var imageSrcByHash = {};
mammothConfig.convertImage = mammoth.images.imgElement(async function (
image
) {
const imageBuffer = await image.read();
const imageHash = md5(imageBuffer);
// check if image hash is already in our saved hashes.
// if it is, we return the saved src
if (imageSrcByHash[imageHash]) {
return {
src: imageSrcByHash[imageHash],
};
}
// no saved image hash - write new image file
const imageExt = image.contentType.split("/").pop();
const imageDir = path.join(
options.outputDir,
imageSubfolderName,
options.imageDir
);
if (!fs.existsSync(imageDir)) {
await fsPromises.mkdir(imageDir, { recursive: true });
}
const imageFilename = `${
imageNamePrefix ? imageNamePrefix + "_" : ""
}image${imageCounter}.${imageExt}`;
const imageFilePath = path.join(imageDir, imageFilename);
fs.writeFile(imageFilePath, imageBuffer, "base64", function (err) {
if (err) {
console.log(err);
} else {
console.log(`Saved image file: ${imageFilePath}`);
}
});
imageCounter++;
// save this src and hash to our saved hashes
const src = `${options.imageDir}/${imageFilename}`;
imageSrcByHash[imageHash] = src;
return {
src,
};
});
const rawHtml = await mammoth
.convertToHtml({ path: inputPath }, mammothConfig)
.then((result) => result.value);
if (typeof cheerioTransform === "function") {
const $ = cheerio.load(rawHtml);
cheerioTransform($);
return $("body").html();
} else {
return rawHtml;
}
};
},
});
};