-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
preview.ts
113 lines (100 loc) · 3.32 KB
/
preview.ts
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
111
112
113
import { stringify } from '@vivliostyle/vfm';
import chalk from 'chalk';
import chokidar from 'chokidar';
import fs from 'fs';
import getPort from 'get-port';
import http from 'http';
import path, { basename, dirname, join, relative, resolve } from 'path';
import resolvePkg from 'resolve-pkg';
import serve from 'serve-handler';
import { Command } from 'commander';
async function preview(argv: any, input: string[]) {
const stylePath = input[0];
if (!stylePath) {
console.log(
'vivliostyle-theme-scripts <stylePath> [--layout <layout.html>]',
);
process.exit(1);
}
const layout = argv.layout;
const baseDir = process.cwd();
// asset server
const assetPort = await getPort();
const assetRoot = path.resolve(__dirname, '../assets');
const assetPrefix = `http://localhost:${assetPort}`;
const assetServer = http
.createServer(async function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
await serve(req, res, {
public: assetRoot,
});
})
.listen(assetPort);
// vivliostyle viewer
const viewerPort = await getPort();
const viewerPkg = resolvePkg('@vivliostyle/viewer', { cwd: baseDir })!;
const viewerRoot = join(viewerPkg, 'lib');
const viewerPrefix = `http://localhost:${viewerPort}`;
const viewerServer = http
.createServer(async function (req, res) {
await serve(req, res, {
public: viewerRoot,
});
})
.listen(viewerPort);
// source server
const sourcePort = await getPort();
const sourceRoot = baseDir;
const sourcePrefix = `http://localhost:${sourcePort}`;
const sourceServer = http
.createServer(async function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Cache-Control', 'no-store');
await serve(req, res, {
public: sourceRoot,
});
})
.listen(sourcePort);
let layoutURL = layout
? `${sourcePrefix}/${layout}`
: `${assetPrefix}/default.html`;
const styleURL = `${sourcePrefix}/${stylePath}`;
function recompile(tmpHTMLPath: string) {
const convertedHTML = stringify(fs.readFileSync(layout, 'utf8'));
fs.writeFileSync(tmpHTMLPath, convertedHTML);
console.log(`${chalk.yellow('[vfm]')} compiled`, tmpHTMLPath);
}
const isVFM = layout && layout.endsWith('.md');
if (isVFM) {
const layoutDir = dirname(resolve(layout));
const tmpHTMLName = basename(layout, '.md') + '.html';
const tmpHTMLPath = relative(baseDir, join(layoutDir, tmpHTMLName));
chokidar
.watch('**', {
ignored: (p: string) => {
return /node_modules|\.git/.test(p);
},
cwd: layoutDir,
})
.on('change', (path) => {
if (!path || !/\.(md|markdown)$/i.test(path)) return;
recompile(tmpHTMLPath);
});
recompile(tmpHTMLPath);
layoutURL = `${sourcePrefix}/${tmpHTMLPath}`;
}
const entrypoint = `${viewerPrefix}/#src=${layoutURL}&style=${styleURL}&bookMode=true&spread=false`;
console.log(
`open preview in the browser and test your theme ([ctrl+c] to quit)
${chalk.bold.green(entrypoint)}
`,
);
}
export default function makeCommand() {
const command = new Command('preview');
command
.description('clone a repository into a newly created directory')
.option('-l, --layout <layout>', 'HTML Layout')
.action(preview);
return command;
}