1 | const minimatch = require('minimatch')
|
2 | const Metalsmith = require('metalsmith')
|
3 |
|
4 | const { template } = require('../common')
|
5 |
|
6 | const filter = filters => (files, metalsmith, next) => {
|
7 | if (!filters) return next()
|
8 | const metadata = metalsmith.metadata()
|
9 | const filenames = Object.keys(files)
|
10 | Object.keys(filters)
|
11 | .filter(glob => !filters[glob](metadata))
|
12 | .forEach(glob => {
|
13 | const match = minimatch.filter(glob, { dot: true, matchBase: true })
|
14 | filenames.forEach(file => match(file) && delete files[file])
|
15 | })
|
16 | next()
|
17 | }
|
18 |
|
19 | const rename = () => (files, metalsmith, next) => {
|
20 | const metadata = metalsmith.metadata()
|
21 |
|
22 | const filenames = Object.keys(files)
|
23 | filenames.forEach(original => {
|
24 |
|
25 |
|
26 | const current = template.render(original, metadata)
|
27 | if (current === original) return
|
28 |
|
29 | files[current] = files[original]
|
30 | delete files[original]
|
31 | })
|
32 |
|
33 | next()
|
34 | }
|
35 |
|
36 | const render = helpers => (files, metalsmith, next) => {
|
37 | const metadata = metalsmith.metadata()
|
38 |
|
39 | for (const name in files) {
|
40 | let contents = files[name].contents.toString()
|
41 |
|
42 |
|
43 |
|
44 |
|
45 | if (!(/<%([\s\S]+?)%>/.test(contents) || /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/.test(contents))) {
|
46 | continue
|
47 | }
|
48 |
|
49 | contents = template.render(contents, metadata)
|
50 | files[name].contents = Buffer.from(contents)
|
51 | }
|
52 |
|
53 | next()
|
54 | }
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | module.exports = (src, dest, answers, options = {}) => new Promise((resolve, reject) => {
|
64 | const { source, metadata, filters, helpers, plugin } = options
|
65 |
|
66 | const metalsmith = Metalsmith(src)
|
67 |
|
68 | metalsmith.metadata(Object.assign({}, metadata, answers))
|
69 |
|
70 |
|
71 | helpers && template.registerHelpers(helpers)
|
72 |
|
73 |
|
74 | typeof plugin === 'function' && metalsmith.use(plugin)
|
75 |
|
76 |
|
77 | metalsmith.use(filter(filters))
|
78 |
|
79 |
|
80 | metalsmith.use(rename())
|
81 |
|
82 |
|
83 | metalsmith.use(render(helpers))
|
84 |
|
85 | metalsmith.source(source || 'template')
|
86 | metalsmith.destination(dest)
|
87 | metalsmith.clean(false)
|
88 |
|
89 | metalsmith.build((err, files) => {
|
90 | if (err) return reject(err)
|
91 | resolve(files)
|
92 | })
|
93 | })
|