-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathbuild-preview-pages.js
105 lines (96 loc) · 3.47 KB
/
build-preview-pages.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
'use strict'
const asciidoctor = require('asciidoctor.js')()
const fs = require('fs-extra')
const handlebars = require('handlebars')
const { obj: map } = require('through2')
const merge = require('merge-stream')
const ospath = require('path')
const path = ospath.posix
const requireFromString = require('require-from-string')
const vfs = require('vinyl-fs')
const yaml = require('js-yaml')
const ASCIIDOC_ATTRIBUTES = {
experimental: '',
icons: 'font',
sectanchors: '',
'source-highlighter': 'highlight.js',
}
module.exports = (src, previewSrc, previewDest, sink = () => map(), layouts = {}) => () =>
Promise.all([
loadSampleUiModel(previewSrc),
toPromise(
merge(
compileLayouts(src, layouts),
registerPartials(src),
registerHelpers(src),
copyImages(previewSrc, previewDest)
)
),
])
.then(([baseUiModel]) => ({ ...baseUiModel, env: process.env }))
.then((baseUiModel) =>
vfs
.src('**/*.adoc', { base: previewSrc, cwd: previewSrc })
.pipe(
map((file, enc, next) => {
const siteRootPath = path.relative(ospath.dirname(file.path), ospath.resolve(previewSrc))
const uiModel = { ...baseUiModel }
uiModel.page = { ...uiModel.page }
uiModel.siteRootPath = siteRootPath
uiModel.siteRootUrl = path.join(siteRootPath, 'index.html')
uiModel.uiRootPath = path.join(siteRootPath, '_')
if (file.stem === '404') {
uiModel.page = { layout: '404', title: 'Page Not Found' }
} else {
const doc = asciidoctor.load(file.contents, { safe: 'safe', attributes: ASCIIDOC_ATTRIBUTES })
uiModel.page.attributes = Object.entries(doc.getAttributes())
.filter(([name, val]) => name.startsWith('page-'))
.reduce((accum, [name, val]) => {
accum[name.substr(5)] = val
return accum
}, {})
uiModel.page.layout = doc.getAttribute('page-layout', 'default')
uiModel.page.title = doc.getDocumentTitle()
uiModel.page.contents = Buffer.from(doc.convert())
}
file.extname = '.html'
file.contents = Buffer.from(layouts[uiModel.page.layout](uiModel))
next(null, file)
})
)
.pipe(vfs.dest(previewDest))
.pipe(sink())
)
function loadSampleUiModel (src) {
return fs.readFile(ospath.join(src, 'ui-model.yml'), 'utf8').then((contents) => yaml.safeLoad(contents))
}
function registerPartials (src) {
return vfs.src('partials/*.hbs', { base: src, cwd: src }).pipe(
map((file, enc, next) => {
handlebars.registerPartial(file.stem, file.contents.toString())
next()
})
)
}
function registerHelpers (src) {
return vfs.src('helpers/*.js', { base: src, cwd: src }).pipe(
map((file, enc, next) => {
handlebars.registerHelper(file.stem, requireFromString(file.contents.toString()))
next()
})
)
}
function compileLayouts (src, layouts) {
return vfs.src('layouts/*.hbs', { base: src, cwd: src }).pipe(
map((file, enc, next) => {
layouts[file.stem] = handlebars.compile(file.contents.toString(), { preventIndent: true })
next()
})
)
}
function copyImages (src, dest) {
return vfs.src('**/*.{png,svg}', { base: src, cwd: src }).pipe(vfs.dest(dest))
}
function toPromise (stream) {
return new Promise((resolve, reject) => stream.on('error', reject).on('finish', resolve))
}