-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
102 lines (87 loc) · 2.55 KB
/
index.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
const visitWithParents = require('unist-util-visit-parents');
const path = require('path');
const isRelativeUrl = require('is-relative-url');
const _ = require('lodash');
const sharp = require('gatsby-plugin-sharp');
const Promise = require('bluebird');
const cheerio = require('cheerio');
const slash = require('slash');
module.exports = ({
files, markdownNode, markdownAST, getNode, reporter, cache,
}, pluginOptions) => {
const defaults = {
tag: 'rehype-img',
sharpFunction: 'fluid',
};
const options = _.defaults(pluginOptions, defaults);
const generateImages = async (src) => {
const parentNode = getNode(markdownNode.parent);
let imagePath;
if (parentNode && parentNode.dir) {
imagePath = slash(path.join(parentNode.dir, src));
} else {
return null;
}
const imageNode = _.find(files, (file) => {
if (file && file.absolutePath) {
return file.absolutePath === imagePath;
}
return null;
});
if (!imageNode || !imageNode.absolutePath) {
return null;
}
const result = await sharp[options.sharpFunction]({
file: imageNode,
args: options,
reporter,
cache,
});
return result;
};
// This will allow the use of html image tags
// const rawHtmlNodes = select(markdownAST, `html`)
// vistWithParents does not seem to support async hence the following
const rawNodes = [];
visitWithParents(markdownAST, 'html', (node) => {
rawNodes.push(node);
});
return Promise.all(
rawNodes.map(node => new Promise(async (resolve) => {
if (!node.value) {
return resolve(node);
}
const $ = cheerio.load(node.value);
if ($(options.tag).length === 0) {
return resolve(node);
}
const imageRefs = [];
$(options.tag).each(function () {
imageRefs.push($(this));
});
for (const customComponent of imageRefs) {
const src = customComponent.attr('src');
if (!src) {
return resolve(node);
}
// can do better here!
const fileType = src.slice(-3);
// Ignore gifs and svgs as we can't process them,
if (
isRelativeUrl(src)
&& fileType !== 'gif'
&& fileType !== 'svg'
) {
const props = await generateImages(src);
if (props) {
// Replace the image string
customComponent.attr('rehyped', JSON.stringify(props));
}
}
}
node.type = 'html';
node.value = $('body').html();
return resolve(node);
})),
);
};