docgen-tool 2.1.3 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +35 -33
- package/{docgen → dist/docgen.js} +13 -24
- package/{source → dist/source}/docgen.js +380 -357
- package/dist/source/require/docgen.css +138 -0
- package/dist/source/require/katexInjector.js +18 -0
- package/dist/source/require/print.css +26 -0
- package/{source → dist/source}/templates/main.html +93 -93
- package/package.json +50 -20
- package/.npmignore +0 -2
- package/docs/advanced-content.html +0 -239
- package/docs/commonmark.html +0 -225
- package/docs/docgen.pdf +0 -0
- package/docs/files/images/logo.png +0 -0
- package/docs/files/images/overview.png +0 -0
- package/docs/files/images/pdf.png +0 -0
- package/docs/files/images/svg/icon.svg +0 -845
- package/docs/files/images/svg/overview.svg +0 -1345
- package/docs/files/images/text.png +0 -0
- package/docs/files/images/web.png +0 -0
- package/docs/index.html +0 -333
- package/docs/installation.html +0 -121
- package/docs/ownership.html +0 -164
- package/docs/release-notes.html +0 -148
- package/docs/require/docgen.css +0 -131
- package/docs/require/katexInjector.js +0 -22
- package/docs/require/print.css +0 -19
- package/docs/running.html +0 -123
- package/docs/troubleshooting.html +0 -105
- package/docs/upgrading.html +0 -124
- package/docs/version-control.html +0 -102
- package/docs/writing-content.html +0 -305
- package/index.html +0 -10
- package/source/example/contents.json +0 -12
- package/source/example/files/images/logo.png +0 -0
- package/source/example/index.txt +0 -4
- package/source/example/parameters.json +0 -37
- package/source/example/release-notes.txt +0 -1
- package/source/optional/katex/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Main-Bold.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Main-Italic.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Main-Regular.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Math-Italic.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Math-Regular.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/source/optional/katex/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/source/optional/katex/katex.min.css +0 -1
- package/source/optional/katex/katex.min.js +0 -6
- package/source/pdf-stylesheet.css +0 -53
- package/source/release-checklist.txt +0 -27
- package/source/require/docgen.css +0 -131
- package/source/require/katexInjector.js +0 -22
- package/source/require/print.css +0 -19
- package/source/require/webknife/fonts/DroidSansMono.woff +0 -0
- package/source/require/webknife/fonts/OpenSans.woff +0 -0
- package/source/require/webknife/fonts/OpenSansBold.woff +0 -0
- package/source/require/webknife/fonts/OpenSansBoldItalic.woff +0 -0
- package/source/require/webknife/fonts/OpenSansItalic.woff +0 -0
- package/source/require/webknife/framework.icons.js +0 -82
- package/source/require/webknife/framework.min.css +0 -3
- package/source/require/webknife/framework.min.js +0 -14
- package/source/require/webknife/highlight.min.css +0 -1
- package/source/require/webknife/highlight.min.js +0 -6
- package/source/user-guide/advanced-content.txt +0 -171
- package/source/user-guide/commonmark.txt +0 -156
- package/source/user-guide/contents.json +0 -57
- package/source/user-guide/files/images/logo.png +0 -0
- package/source/user-guide/files/images/overview.png +0 -0
- package/source/user-guide/files/images/pdf.png +0 -0
- package/source/user-guide/files/images/svg/icon.svg +0 -845
- package/source/user-guide/files/images/svg/overview.svg +0 -1345
- package/source/user-guide/files/images/text.png +0 -0
- package/source/user-guide/files/images/web.png +0 -0
- package/source/user-guide/index.txt +0 -245
- package/source/user-guide/installation.txt +0 -49
- package/source/user-guide/parameters.json +0 -37
- package/source/user-guide/release-notes.txt +0 -64
- package/source/user-guide/running.txt +0 -47
- package/source/user-guide/troubleshooting.txt +0 -32
- package/source/user-guide/upgrading.txt +0 -25
- package/source/user-guide/version-control.txt +0 -13
- package/source/user-guide/writing-content.txt +0 -269
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_AMS-Regular.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Main-Bold.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Main-Italic.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Main-Regular.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Math-Italic.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Math-Regular.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Size1-Regular.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Size2-Regular.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Size3-Regular.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/fonts/KaTeX_Size4-Regular.woff +0 -0
- /package/{docs/require → dist/source/optional}/katex/katex.min.css +0 -0
- /package/{docs/require → dist/source/optional}/katex/katex.min.js +0 -0
- /package/{source → dist/source}/pdf-contents.xsl +0 -0
- /package/{docs → dist/source}/require/webknife/fonts/DroidSansMono.woff +0 -0
- /package/{docs → dist/source}/require/webknife/fonts/OpenSans.woff +0 -0
- /package/{docs → dist/source}/require/webknife/fonts/OpenSansBold.woff +0 -0
- /package/{docs → dist/source}/require/webknife/fonts/OpenSansBoldItalic.woff +0 -0
- /package/{docs → dist/source}/require/webknife/fonts/OpenSansItalic.woff +0 -0
- /package/{docs → dist/source}/require/webknife/framework.icons.js +0 -0
- /package/{docs → dist/source}/require/webknife/framework.min.css +0 -0
- /package/{docs → dist/source}/require/webknife/framework.min.js +0 -0
- /package/{docs → dist/source}/require/webknife/highlight.min.css +0 -0
- /package/{docs → dist/source}/require/webknife/highlight.min.js +0 -0
- /package/{source → dist/source}/templates/pdfCover.html +0 -0
- /package/{source → dist/source}/templates/pdfFooter.html +0 -0
- /package/{source → dist/source}/templates/pdfHeader.html +0 -0
- /package/{source → dist/source}/templates/redirect.html +0 -0
- /package/{source → dist/source}/templates/webCover.html +0 -0
|
@@ -1,172 +1,160 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
3
|
var rsvp = require('rsvp');
|
|
3
4
|
var fs = require('fs-extra');
|
|
4
5
|
var path = require('path');
|
|
5
6
|
var cheerio = require('cheerio');
|
|
6
|
-
var markdown = require('markdown-it')('commonmark').enable('table')
|
|
7
|
+
var markdown = require('markdown-it')('commonmark').enable('table');
|
|
7
8
|
var moment = require('moment');
|
|
8
|
-
var
|
|
9
|
-
var schemaValidator = require(
|
|
9
|
+
var child_process_1 = require("child_process");
|
|
10
|
+
var schemaValidator = require('z-schema');
|
|
10
11
|
var chalk = require('chalk');
|
|
11
12
|
var spawnArgs = require('spawn-args');
|
|
12
13
|
var cliSpinner = require('cli-spinner').Spinner;
|
|
13
14
|
var imageSizeOf = require('image-size');
|
|
14
|
-
|
|
15
15
|
//Allow CommonMark links that use other protocols, such as file:///
|
|
16
16
|
//The markdown-it implementation is more restrictive than the CommonMark spec
|
|
17
17
|
//See https://github.com/markdown-it/markdown-it/issues/108
|
|
18
|
-
markdown.validateLink = function () {
|
|
19
|
-
|
|
18
|
+
markdown.validateLink = function () {
|
|
19
|
+
return true;
|
|
20
|
+
};
|
|
20
21
|
/**
|
|
21
|
-
* DocGen class
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
function DocGen (process)
|
|
25
|
-
{
|
|
22
|
+
* DocGen class
|
|
23
|
+
*/
|
|
24
|
+
function DocGen(process) {
|
|
26
25
|
var mainProcess = process;
|
|
27
|
-
var version = '
|
|
28
|
-
var wkhtmltopdfVersion = 'wkhtmltopdf 0.12.
|
|
26
|
+
var version = '3.0.1';
|
|
27
|
+
var wkhtmltopdfVersion = 'wkhtmltopdf 0.12.6 (with patched qt)'; //output from wkhtmltopdf -V
|
|
29
28
|
var options;
|
|
30
29
|
var templates = {};
|
|
31
30
|
var meta = {};
|
|
32
31
|
var pages = {};
|
|
33
32
|
var sortedPages = {};
|
|
34
|
-
|
|
35
33
|
this.getVersion = function () {
|
|
36
34
|
return version;
|
|
37
|
-
}
|
|
38
|
-
|
|
35
|
+
};
|
|
39
36
|
this.setOptions = function (userOptions) {
|
|
40
37
|
options = userOptions;
|
|
41
38
|
//all user-specified paths must be normalized
|
|
42
39
|
if (options.input) {
|
|
43
|
-
options.input = path.normalize(options.input+'/');
|
|
40
|
+
options.input = path.normalize(options.input + '/');
|
|
44
41
|
}
|
|
45
42
|
if (options.output) {
|
|
46
|
-
options.output = path.normalize(options.output+'/');
|
|
43
|
+
options.output = path.normalize(options.output + '/');
|
|
47
44
|
}
|
|
48
|
-
|
|
49
45
|
//wkhtmltopdf path does not need a trailing slash
|
|
50
46
|
if (options.wkhtmltopdfPath && options.wkhtmltopdfPath !== '') {
|
|
51
47
|
options.wkhtmltopdfPath = path.normalize(options.wkhtmltopdfPath);
|
|
52
48
|
}
|
|
53
|
-
}
|
|
54
|
-
|
|
49
|
+
};
|
|
55
50
|
/*
|
|
56
|
-
|
|
51
|
+
copy the example source files (template) to any directory, when scaffold command is invoked
|
|
57
52
|
*/
|
|
58
|
-
|
|
59
53
|
this.scaffold = function () {
|
|
60
54
|
console.log(chalk.green('Creating scaffold template directory'));
|
|
61
|
-
copyDirSync(__dirname+'/example', options.output);
|
|
62
|
-
}
|
|
63
|
-
|
|
55
|
+
copyDirSync(__dirname + '/example', options.output);
|
|
56
|
+
};
|
|
64
57
|
this.run = function () {
|
|
65
|
-
console.log(chalk.green.bold('DocGen version '+version));
|
|
58
|
+
console.log(chalk.green.bold('DocGen version ' + version));
|
|
66
59
|
//delete and recreate the output directory
|
|
67
60
|
remakeDirSync(options.output);
|
|
68
61
|
loadTemplates();
|
|
69
|
-
}
|
|
70
|
-
|
|
62
|
+
};
|
|
71
63
|
/*
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
read any file (async)
|
|
65
|
+
*/
|
|
75
66
|
var readFile = function (path) {
|
|
76
67
|
return new rsvp.Promise(function (resolve, reject) {
|
|
77
|
-
fs.readFile
|
|
68
|
+
fs.readFile(path, 'utf8', function (error, data) {
|
|
78
69
|
if (error) {
|
|
79
|
-
console.log(chalk.red('Error reading file: '+path));
|
|
70
|
+
console.log(chalk.red('Error reading file: ' + path));
|
|
80
71
|
reject(error);
|
|
81
|
-
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
82
74
|
data = data.replace(/^\uFEFF/, ''); //remove the BOM (byte-order-mark) from UTF-8 files, if present
|
|
83
75
|
resolve(data);
|
|
84
76
|
}
|
|
85
77
|
});
|
|
86
78
|
});
|
|
87
|
-
}
|
|
88
|
-
|
|
79
|
+
};
|
|
89
80
|
/*
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
81
|
+
write any file (async)
|
|
82
|
+
*/
|
|
93
83
|
var writeFile = function (path, data) {
|
|
94
84
|
return new rsvp.Promise(function (resolve, reject) {
|
|
95
85
|
fs.writeFile(path, data, function (error) {
|
|
96
86
|
if (error) {
|
|
97
|
-
console.log(chalk.red('Error writing file: '+path));
|
|
87
|
+
console.log(chalk.red('Error writing file: ' + path));
|
|
98
88
|
reject(error);
|
|
99
|
-
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
100
91
|
resolve(true);
|
|
101
92
|
}
|
|
102
93
|
});
|
|
103
94
|
});
|
|
104
|
-
}
|
|
105
|
-
|
|
95
|
+
};
|
|
106
96
|
/*
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
97
|
+
copy any directory (sync)
|
|
98
|
+
*/
|
|
110
99
|
var copyDirSync = function (source, destination) {
|
|
111
100
|
try {
|
|
112
101
|
fs.copySync(source, destination);
|
|
113
|
-
}
|
|
114
|
-
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.log(chalk.red('Error copying directory: ' + source + ' to ' + destination));
|
|
115
105
|
if (options.verbose === true) {
|
|
116
106
|
console.log(chalk.red(error));
|
|
117
107
|
mainProcess.exit(1);
|
|
118
108
|
}
|
|
119
109
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
110
|
+
};
|
|
122
111
|
/*
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
112
|
+
remake a directory (sync) ... remove and then mkdir in one operation
|
|
113
|
+
*/
|
|
126
114
|
var remakeDirSync = function (path) {
|
|
127
115
|
try {
|
|
128
116
|
fs.removeSync(path);
|
|
129
117
|
fs.mkdirpSync(path);
|
|
130
|
-
}
|
|
131
|
-
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.log(chalk.red('Error recreating directory: ' + path));
|
|
132
121
|
if (options.verbose === true) {
|
|
133
122
|
console.log(chalk.red(error));
|
|
134
123
|
mainProcess.exit(1);
|
|
135
124
|
}
|
|
136
125
|
}
|
|
137
|
-
}
|
|
138
|
-
|
|
126
|
+
};
|
|
139
127
|
/*
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
128
|
+
remove any directory (sync)
|
|
129
|
+
*/
|
|
143
130
|
var removeDirSync = function (path) {
|
|
144
131
|
try {
|
|
145
132
|
fs.removeSync(path);
|
|
146
|
-
}
|
|
147
|
-
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.log(chalk.red('Error removing directory: ' + path));
|
|
148
136
|
if (options.verbose === true) {
|
|
149
137
|
console.log(chalk.red(error));
|
|
150
138
|
mainProcess.exit(1);
|
|
151
139
|
}
|
|
152
140
|
}
|
|
153
|
-
}
|
|
154
|
-
|
|
141
|
+
};
|
|
155
142
|
/*
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
143
|
+
load all HTML template files
|
|
144
|
+
*/
|
|
159
145
|
var loadTemplates = function () {
|
|
160
146
|
console.log(chalk.green('Loading templates'));
|
|
161
147
|
var files = {
|
|
162
|
-
main: readFile(__dirname+'/templates/main.html'),
|
|
163
|
-
redirect: readFile(__dirname+'/templates/redirect.html'),
|
|
164
|
-
webCover: readFile(__dirname+'/templates/webCover.html'),
|
|
165
|
-
pdfCover: readFile(__dirname+'/templates/pdfCover.html'),
|
|
166
|
-
pdfHeader: readFile(__dirname+'/templates/pdfHeader.html'),
|
|
167
|
-
pdfFooter: readFile(__dirname+'/templates/pdfFooter.html'),
|
|
148
|
+
main: readFile(__dirname + '/templates/main.html'),
|
|
149
|
+
redirect: readFile(__dirname + '/templates/redirect.html'),
|
|
150
|
+
webCover: readFile(__dirname + '/templates/webCover.html'),
|
|
151
|
+
pdfCover: readFile(__dirname + '/templates/pdfCover.html'),
|
|
152
|
+
pdfHeader: readFile(__dirname + '/templates/pdfHeader.html'),
|
|
153
|
+
pdfFooter: readFile(__dirname + '/templates/pdfFooter.html'),
|
|
168
154
|
};
|
|
169
|
-
rsvp
|
|
155
|
+
rsvp
|
|
156
|
+
.hash(files)
|
|
157
|
+
.then(function (files) {
|
|
170
158
|
for (var key in files) {
|
|
171
159
|
if (files.hasOwnProperty(key)) {
|
|
172
160
|
var file = files[key];
|
|
@@ -175,163 +163,180 @@ function DocGen (process)
|
|
|
175
163
|
}
|
|
176
164
|
}
|
|
177
165
|
loadMeta();
|
|
178
|
-
})
|
|
166
|
+
})
|
|
167
|
+
.catch(function (error) {
|
|
179
168
|
console.log(chalk.red('Error loading templates'));
|
|
180
169
|
if (options.verbose === true) {
|
|
181
170
|
console.log(chalk.red(error));
|
|
182
171
|
}
|
|
183
172
|
mainProcess.exit(1);
|
|
184
173
|
});
|
|
185
|
-
}
|
|
186
|
-
|
|
174
|
+
};
|
|
187
175
|
/*
|
|
188
|
-
|
|
176
|
+
JSON schema validation
|
|
189
177
|
*/
|
|
190
|
-
|
|
191
178
|
var schemas = {
|
|
192
|
-
|
|
193
|
-
title:
|
|
194
|
-
type:
|
|
179
|
+
parameters: {
|
|
180
|
+
title: 'DocGen Parameters Schema',
|
|
181
|
+
type: 'object',
|
|
195
182
|
required: [
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
183
|
+
'title',
|
|
184
|
+
'name',
|
|
185
|
+
'version',
|
|
186
|
+
'date',
|
|
187
|
+
'organization',
|
|
188
|
+
'author',
|
|
189
|
+
'owner',
|
|
190
|
+
'contributors',
|
|
191
|
+
'website',
|
|
192
|
+
'module',
|
|
193
|
+
'id',
|
|
194
|
+
'summary',
|
|
195
|
+
'marking',
|
|
196
|
+
'legalese',
|
|
210
197
|
],
|
|
211
198
|
properties: {
|
|
212
|
-
title: { type:
|
|
213
|
-
name: { type:
|
|
214
|
-
version: { type:
|
|
215
|
-
date: { type:
|
|
199
|
+
title: { type: 'string' },
|
|
200
|
+
name: { type: 'string' },
|
|
201
|
+
version: { type: 'string' },
|
|
202
|
+
date: { type: 'string' },
|
|
216
203
|
organization: {
|
|
217
|
-
type
|
|
218
|
-
required: [
|
|
204
|
+
type: 'object',
|
|
205
|
+
required: ['name', 'url'],
|
|
219
206
|
properties: {
|
|
220
|
-
name: { type:
|
|
221
|
-
url: { type:
|
|
222
|
-
}
|
|
207
|
+
name: { type: 'string' },
|
|
208
|
+
url: { type: 'string' },
|
|
209
|
+
},
|
|
223
210
|
},
|
|
224
211
|
author: {
|
|
225
|
-
type
|
|
226
|
-
required: [
|
|
212
|
+
type: 'object',
|
|
213
|
+
required: ['name', 'url'],
|
|
227
214
|
properties: {
|
|
228
|
-
name: { type:
|
|
229
|
-
url: { type:
|
|
230
|
-
}
|
|
215
|
+
name: { type: 'string' },
|
|
216
|
+
url: { type: 'string' },
|
|
217
|
+
},
|
|
231
218
|
},
|
|
232
219
|
owner: {
|
|
233
|
-
type
|
|
234
|
-
required: [
|
|
220
|
+
type: 'object',
|
|
221
|
+
required: ['name', 'url'],
|
|
235
222
|
properties: {
|
|
236
|
-
name: { type:
|
|
237
|
-
url: { type:
|
|
238
|
-
}
|
|
223
|
+
name: { type: 'string' },
|
|
224
|
+
url: { type: 'string' },
|
|
225
|
+
},
|
|
239
226
|
},
|
|
240
227
|
contributors: {
|
|
241
|
-
type
|
|
242
|
-
items: {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
228
|
+
type: 'array',
|
|
229
|
+
items: {
|
|
230
|
+
oneOf: [
|
|
231
|
+
{
|
|
232
|
+
type: 'object',
|
|
233
|
+
required: ['name', 'url'],
|
|
234
|
+
properties: {
|
|
235
|
+
name: { type: 'string' },
|
|
236
|
+
url: { type: 'string' },
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
},
|
|
250
241
|
},
|
|
251
242
|
website: {
|
|
252
|
-
type
|
|
253
|
-
required: [
|
|
243
|
+
type: 'object',
|
|
244
|
+
required: ['name', 'url'],
|
|
254
245
|
properties: {
|
|
255
|
-
name: { type:
|
|
256
|
-
url: { type:
|
|
257
|
-
}
|
|
246
|
+
name: { type: 'string' },
|
|
247
|
+
url: { type: 'string' },
|
|
248
|
+
},
|
|
258
249
|
},
|
|
259
250
|
backlink: {
|
|
260
|
-
type
|
|
261
|
-
required: [
|
|
251
|
+
type: 'object',
|
|
252
|
+
required: ['name', 'url'],
|
|
262
253
|
properties: {
|
|
263
|
-
name: { type:
|
|
264
|
-
url: { type:
|
|
265
|
-
}
|
|
254
|
+
name: { type: 'string' },
|
|
255
|
+
url: { type: 'string' },
|
|
256
|
+
},
|
|
266
257
|
},
|
|
267
|
-
module: { type:
|
|
268
|
-
id: { type:
|
|
269
|
-
summary: { type:
|
|
270
|
-
marking: { type:
|
|
271
|
-
legalese: { type:
|
|
272
|
-
}
|
|
258
|
+
module: { type: 'string' },
|
|
259
|
+
id: { type: 'string' },
|
|
260
|
+
summary: { type: 'string' },
|
|
261
|
+
marking: { type: 'string' },
|
|
262
|
+
legalese: { type: 'string' },
|
|
263
|
+
},
|
|
273
264
|
},
|
|
274
|
-
|
|
275
|
-
title:
|
|
276
|
-
type
|
|
277
|
-
items: {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
265
|
+
contents: {
|
|
266
|
+
title: 'DocGen Table of Contents Schema',
|
|
267
|
+
type: 'array',
|
|
268
|
+
items: {
|
|
269
|
+
oneOf: [
|
|
270
|
+
{
|
|
271
|
+
type: 'object',
|
|
272
|
+
required: ['heading', 'column', 'pages'],
|
|
273
|
+
properties: {
|
|
274
|
+
name: { type: 'string' },
|
|
275
|
+
column: { type: 'integer', minimum: 1, maximum: 4 },
|
|
276
|
+
pages: {
|
|
277
|
+
type: 'array',
|
|
278
|
+
items: {
|
|
279
|
+
oneOf: [
|
|
280
|
+
{
|
|
281
|
+
type: 'object',
|
|
282
|
+
required: ['title', 'source'],
|
|
283
|
+
properties: {
|
|
284
|
+
title: { type: 'string' },
|
|
285
|
+
source: { type: 'string' },
|
|
286
|
+
html: { type: 'boolean' },
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
},
|
|
294
293
|
},
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
}
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
},
|
|
298
297
|
};
|
|
299
|
-
|
|
300
298
|
var validateJSON = function (key, data) {
|
|
301
299
|
var schema = schemas[key];
|
|
302
300
|
var validator = new schemaValidator();
|
|
303
301
|
var valid = validator.validate(data, schema);
|
|
304
302
|
if (!valid) {
|
|
305
|
-
console.log(chalk.red('Error parsing required file: '+
|
|
303
|
+
console.log(chalk.red('Error parsing required file: ' +
|
|
304
|
+
key +
|
|
305
|
+
'.json (failed schema validation)'));
|
|
306
306
|
if (options.verbose === true) {
|
|
307
307
|
console.log(chalk.red(validator.getLastError()));
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
310
|
return valid;
|
|
311
|
-
}
|
|
312
|
-
|
|
311
|
+
};
|
|
313
312
|
/*
|
|
314
|
-
|
|
313
|
+
load all metadata files (JSON)
|
|
315
314
|
*/
|
|
316
|
-
|
|
317
315
|
var loadMeta = function () {
|
|
318
316
|
console.log(chalk.green('Loading required JSON metadata files'));
|
|
319
317
|
var files = {
|
|
320
|
-
parameters: readFile(options.input+'/parameters.json'),
|
|
321
|
-
contents: readFile(options.input+'/contents.json'),
|
|
318
|
+
parameters: readFile(options.input + '/parameters.json'),
|
|
319
|
+
contents: readFile(options.input + '/contents.json'),
|
|
322
320
|
};
|
|
323
|
-
rsvp
|
|
324
|
-
|
|
325
|
-
|
|
321
|
+
rsvp
|
|
322
|
+
.hash(files)
|
|
323
|
+
.then(function (files) {
|
|
324
|
+
for (var key in files) {
|
|
325
|
+
if (files.hasOwnProperty(key)) {
|
|
326
|
+
//ignore prototype
|
|
326
327
|
try {
|
|
327
328
|
var file = JSON.parse(files[key]);
|
|
328
329
|
if (validateJSON(key, file)) {
|
|
329
330
|
meta[key] = file;
|
|
330
|
-
}
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
331
333
|
mainProcess.exit(1);
|
|
332
334
|
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
console.log(chalk.red('Error parsing required file: ' +
|
|
338
|
+
key +
|
|
339
|
+
'.json (invalid JSON)'));
|
|
335
340
|
if (options.verbose === true) {
|
|
336
341
|
console.log(chalk.red(error));
|
|
337
342
|
}
|
|
@@ -340,102 +345,106 @@ function DocGen (process)
|
|
|
340
345
|
}
|
|
341
346
|
}
|
|
342
347
|
//add the release notes to the contents list
|
|
343
|
-
var extra = {
|
|
344
|
-
heading: 'Extra',
|
|
348
|
+
var extra = {
|
|
349
|
+
heading: 'Extra',
|
|
345
350
|
column: 5,
|
|
346
|
-
pages: [
|
|
347
|
-
{ title: 'Release notes', source: 'release-notes.txt' }
|
|
348
|
-
]
|
|
351
|
+
pages: [{ title: 'Release notes', source: 'release-notes.txt' }],
|
|
349
352
|
};
|
|
350
353
|
meta.contents.push(extra);
|
|
351
354
|
loadMarkdown();
|
|
352
|
-
})
|
|
355
|
+
})
|
|
356
|
+
.catch(function (error) {
|
|
353
357
|
console.log(chalk.red('Error loading required JSON metadata files'));
|
|
354
358
|
if (options.verbose === true) {
|
|
355
359
|
console.log(chalk.red(error));
|
|
356
360
|
}
|
|
357
361
|
mainProcess.exit(1);
|
|
358
362
|
});
|
|
359
|
-
}
|
|
360
|
-
|
|
363
|
+
};
|
|
361
364
|
/*
|
|
362
|
-
|
|
365
|
+
load all markdown files (source)
|
|
363
366
|
*/
|
|
364
|
-
|
|
365
367
|
var loadMarkdown = function () {
|
|
366
368
|
console.log(chalk.green('Loading source files'));
|
|
367
369
|
var keys = [];
|
|
368
370
|
var files = [];
|
|
369
|
-
meta.contents.forEach(
|
|
370
|
-
section.pages.forEach(
|
|
371
|
+
meta.contents.forEach(function (section) {
|
|
372
|
+
section.pages.forEach(function (page) {
|
|
371
373
|
keys.push(page);
|
|
372
|
-
files.push(options.input+'/'+page.source);
|
|
374
|
+
files.push(options.input + '/' + page.source);
|
|
373
375
|
});
|
|
374
376
|
});
|
|
375
377
|
//add the release notes page
|
|
376
378
|
keys.push('ownership');
|
|
377
|
-
files.push(options.input+'/release-notes.txt');
|
|
378
|
-
rsvp
|
|
379
|
-
files.
|
|
380
|
-
|
|
379
|
+
files.push(options.input + '/release-notes.txt');
|
|
380
|
+
rsvp
|
|
381
|
+
.all(files.map(readFile))
|
|
382
|
+
.then(function (files) {
|
|
383
|
+
files.forEach(function (page, index) {
|
|
384
|
+
try {
|
|
381
385
|
var key = keys[index];
|
|
382
|
-
if (key.html === true) {
|
|
386
|
+
if (key.html === true) {
|
|
387
|
+
//allow raw HTML input pages
|
|
383
388
|
pages[key.source] = page;
|
|
384
|
-
}
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
//otherwise parse input from Markdown into HTML
|
|
385
392
|
var html = markdown.render(page);
|
|
386
393
|
pages[key.source] = html;
|
|
387
394
|
}
|
|
388
|
-
}
|
|
389
|
-
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
console.log(chalk.red('Error parsing Markdown file: ' + file.source));
|
|
390
398
|
if (options.verbose === true) {
|
|
391
399
|
console.log(chalk.red(error));
|
|
392
400
|
}
|
|
393
401
|
mainProcess.exit(1);
|
|
394
402
|
}
|
|
395
403
|
});
|
|
396
|
-
|
|
397
|
-
})
|
|
404
|
+
processContent();
|
|
405
|
+
})
|
|
406
|
+
.catch(function (error) {
|
|
407
|
+
console.log(error);
|
|
398
408
|
console.log(chalk.red('Error loading source files'));
|
|
399
409
|
if (options.verbose === true) {
|
|
400
410
|
console.log(chalk.red(error));
|
|
401
411
|
}
|
|
402
412
|
mainProcess.exit(1);
|
|
403
413
|
});
|
|
404
|
-
}
|
|
405
|
-
|
|
414
|
+
};
|
|
406
415
|
var sortPages = function () {
|
|
407
416
|
//sort the contents by heading
|
|
408
|
-
var headings = {1: [], 2: [], 3: [], 4: [], 5: []};
|
|
409
|
-
meta.contents.forEach(
|
|
417
|
+
var headings = { 1: [], 2: [], 3: [], 4: [], 5: [] };
|
|
418
|
+
meta.contents.forEach(function (section) {
|
|
410
419
|
if (headings.hasOwnProperty(section.column)) {
|
|
411
420
|
headings[section.column].push(section);
|
|
412
421
|
}
|
|
413
|
-
|
|
414
422
|
});
|
|
415
423
|
sortedPages = headings;
|
|
416
|
-
}
|
|
417
|
-
|
|
424
|
+
};
|
|
418
425
|
/*
|
|
419
|
-
|
|
426
|
+
build the HTML for the table of contents
|
|
420
427
|
*/
|
|
421
|
-
|
|
422
428
|
var webToc = function () {
|
|
423
429
|
sortPages();
|
|
424
|
-
var pdfName = meta.parameters.name.toLowerCase()+'.pdf';
|
|
430
|
+
var pdfName = meta.parameters.name.toLowerCase() + '.pdf';
|
|
425
431
|
var $ = templates.main;
|
|
426
432
|
var html = [], i = -1;
|
|
427
433
|
html[++i] = '<div><table class="unstyled"><tr>';
|
|
428
434
|
//build the contents HTML
|
|
429
435
|
for (var key in sortedPages) {
|
|
430
436
|
if (sortedPages.hasOwnProperty(key)) {
|
|
431
|
-
if (key != 5) {
|
|
437
|
+
if (key != 5) {
|
|
438
|
+
//skip the extra column
|
|
432
439
|
html[++i] = '<td class="dg-tocGroup">';
|
|
433
|
-
sortedPages[key].forEach(
|
|
434
|
-
html[++i] =
|
|
435
|
-
|
|
440
|
+
sortedPages[key].forEach(function (section) {
|
|
441
|
+
html[++i] =
|
|
442
|
+
'<ul><li class="dg-tocHeading">' + section.heading + '</li>';
|
|
443
|
+
section.pages.forEach(function (page) {
|
|
436
444
|
var name = page.source.substr(0, page.source.lastIndexOf('.'));
|
|
437
|
-
var path = name+'.html';
|
|
438
|
-
html[++i] =
|
|
445
|
+
var path = name + '.html';
|
|
446
|
+
html[++i] =
|
|
447
|
+
'<li><a href="' + path + '">' + page.title + '</a></li>';
|
|
439
448
|
});
|
|
440
449
|
html[++i] = '</li></ul>';
|
|
441
450
|
});
|
|
@@ -443,14 +452,18 @@ function DocGen (process)
|
|
|
443
452
|
}
|
|
444
453
|
}
|
|
445
454
|
}
|
|
446
|
-
|
|
447
455
|
//fixed-width column at end
|
|
448
456
|
html[++i] = '<td class="dg-tocGroup" id="dg-tocFixedColumn"><ul>';
|
|
449
|
-
html[++i] =
|
|
450
|
-
|
|
457
|
+
html[++i] =
|
|
458
|
+
'<li><span class="w-icon dg-tocIcon" data-name="person_group" title="archive"></span><a href="ownership.html">Ownership</a></li>';
|
|
459
|
+
html[++i] =
|
|
460
|
+
'<li><span class="w-icon dg-tocIcon" data-name="refresh" title="archive"></span><a href="release-notes.html">Release Notes</a></li>';
|
|
451
461
|
html[++i] = '</ul><div>';
|
|
452
462
|
if (options.pdf) {
|
|
453
|
-
html[++i] =
|
|
463
|
+
html[++i] =
|
|
464
|
+
'<button class="w-icon-button" onclick="window.location=\'' +
|
|
465
|
+
pdfName +
|
|
466
|
+
'\';">';
|
|
454
467
|
html[++i] = '<span class="w-icon" data-name="document"></span>';
|
|
455
468
|
html[++i] = '<span>PDF copy</span>';
|
|
456
469
|
html[++i] = '</button>';
|
|
@@ -459,39 +472,34 @@ function DocGen (process)
|
|
|
459
472
|
html[++i] = '</tr></table></div>';
|
|
460
473
|
$('#dg-toc').html(html.join(''));
|
|
461
474
|
templates.main = $;
|
|
462
|
-
}
|
|
463
|
-
|
|
475
|
+
};
|
|
464
476
|
/*
|
|
465
|
-
|
|
477
|
+
insert the parameters into all templates
|
|
466
478
|
*/
|
|
467
|
-
|
|
468
479
|
var insertParameters = function () {
|
|
469
|
-
|
|
470
480
|
//------------------------------------------------------------------------------------------------------
|
|
471
481
|
//logo dimensions
|
|
472
482
|
var hasLogo = false;
|
|
473
483
|
var logoWidth = 0;
|
|
474
484
|
var logoHeight = 0;
|
|
475
485
|
try {
|
|
476
|
-
var logo = imageSizeOf(options.input+'/files/images/logo.png');
|
|
486
|
+
var logo = imageSizeOf(options.input + '/files/images/logo.png');
|
|
477
487
|
logoWidth = logo.width;
|
|
478
488
|
logoHeight = logo.height;
|
|
479
489
|
hasLogo = true;
|
|
480
|
-
}
|
|
490
|
+
}
|
|
491
|
+
catch (error) {
|
|
481
492
|
//do nothing. If logo file cannot be read, logo is simply not shown
|
|
482
493
|
}
|
|
483
|
-
|
|
484
494
|
//------------------------------------------------------------------------------------------------------
|
|
485
|
-
|
|
486
495
|
//the homepage is the first link in the first heading
|
|
487
496
|
var homelink = meta.contents[0].pages[0];
|
|
488
|
-
|
|
489
|
-
|
|
497
|
+
homelink =
|
|
498
|
+
homelink.source.substr(0, homelink.source.lastIndexOf('.')) + '.html';
|
|
490
499
|
var date = moment().format('DD/MM/YYYY');
|
|
491
500
|
var time = moment().format('HH:mm:ss');
|
|
492
501
|
var year = moment().format('YYYY');
|
|
493
|
-
var attribution = 'Created by DocGen '+version+' on '+date+' at '+time+'.';
|
|
494
|
-
|
|
502
|
+
var attribution = 'Created by DocGen ' + version + ' on ' + date + ' at ' + time + '.';
|
|
495
503
|
var releaseVersion = meta.parameters.version;
|
|
496
504
|
if (options.setVersion !== false) {
|
|
497
505
|
releaseVersion = options.setVersion;
|
|
@@ -500,70 +508,93 @@ function DocGen (process)
|
|
|
500
508
|
if (options.setReleaseDate !== false) {
|
|
501
509
|
releaseDate = options.setReleaseDate;
|
|
502
510
|
}
|
|
503
|
-
|
|
504
511
|
var author = '';
|
|
505
512
|
if (meta.parameters.author.url !== '') {
|
|
506
|
-
author +=
|
|
507
|
-
|
|
513
|
+
author +=
|
|
514
|
+
'<a href="' +
|
|
515
|
+
meta.parameters.author.url +
|
|
516
|
+
'">' +
|
|
517
|
+
meta.parameters.author.name +
|
|
518
|
+
'</a>';
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
508
521
|
author += meta.parameters.author.name;
|
|
509
522
|
}
|
|
510
|
-
|
|
511
523
|
var owner = '';
|
|
512
524
|
if (meta.parameters.owner.url !== '') {
|
|
513
|
-
owner +=
|
|
514
|
-
|
|
525
|
+
owner +=
|
|
526
|
+
'<a href="' +
|
|
527
|
+
meta.parameters.owner.url +
|
|
528
|
+
'">' +
|
|
529
|
+
meta.parameters.owner.name +
|
|
530
|
+
'</a>';
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
515
533
|
owner += meta.parameters.owner.name;
|
|
516
534
|
}
|
|
517
|
-
|
|
518
535
|
var organization = '';
|
|
519
536
|
if (meta.parameters.organization.url !== '') {
|
|
520
|
-
organization +=
|
|
521
|
-
|
|
537
|
+
organization +=
|
|
538
|
+
'<a href="' +
|
|
539
|
+
meta.parameters.organization.url +
|
|
540
|
+
'">' +
|
|
541
|
+
meta.parameters.organization.name +
|
|
542
|
+
'</a>';
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
522
545
|
organization += meta.parameters.organization.name;
|
|
523
546
|
}
|
|
524
|
-
|
|
525
547
|
var website = '';
|
|
526
548
|
if (meta.parameters.website.url !== '') {
|
|
527
|
-
website +=
|
|
528
|
-
|
|
549
|
+
website +=
|
|
550
|
+
'<a href="' +
|
|
551
|
+
meta.parameters.website.url +
|
|
552
|
+
'">' +
|
|
553
|
+
meta.parameters.website.name +
|
|
554
|
+
'</a>';
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
529
557
|
website += meta.parameters.website.name;
|
|
530
558
|
}
|
|
531
|
-
|
|
532
559
|
var backlink = '';
|
|
533
560
|
if (meta.parameters.backlink.url !== '') {
|
|
534
|
-
backlink +=
|
|
535
|
-
|
|
561
|
+
backlink +=
|
|
562
|
+
'<a href="' +
|
|
563
|
+
meta.parameters.backlink.url +
|
|
564
|
+
'">' +
|
|
565
|
+
meta.parameters.backlink.name +
|
|
566
|
+
'</a>';
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
536
569
|
backlink += meta.parameters.backlink.name;
|
|
537
570
|
}
|
|
538
|
-
|
|
539
571
|
var contributors = '';
|
|
540
|
-
meta.parameters.contributors.forEach
|
|
572
|
+
meta.parameters.contributors.forEach(function (contributor) {
|
|
541
573
|
if (contributor.url !== '') {
|
|
542
|
-
contributors +=
|
|
543
|
-
|
|
544
|
-
|
|
574
|
+
contributors +=
|
|
575
|
+
'<a href="' + contributor.url + '">' + contributor.name + '</a>, ';
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
contributors += contributor.name + ', ';
|
|
545
579
|
}
|
|
546
580
|
});
|
|
547
|
-
contributors = contributors.replace(/,\s*$/,
|
|
548
|
-
|
|
549
|
-
var
|
|
550
|
-
|
|
551
|
-
var webTitle = meta.parameters.title
|
|
552
|
-
|
|
553
|
-
var webFooter = 'Version '+releaseVersion+' released on '+releaseDate+'.';
|
|
554
|
-
|
|
581
|
+
contributors = contributors.replace(/,\s*$/, ''); //remove trailing commas
|
|
582
|
+
var copyright = '© ' + year + ' ' + organization;
|
|
583
|
+
var webTitle = meta.parameters.title;
|
|
584
|
+
var webFooter = 'Version ' + releaseVersion + ' released on ' + releaseDate + '.';
|
|
555
585
|
for (var key in templates) {
|
|
556
586
|
if (templates.hasOwnProperty(key)) {
|
|
557
|
-
$ = templates[key];
|
|
587
|
+
var $ = templates[key];
|
|
558
588
|
//logo
|
|
559
589
|
if (hasLogo === true) {
|
|
560
590
|
var logoUrl = 'files/images/logo.png';
|
|
561
591
|
$('#dg-logo').css('background-image', 'url(' + logoUrl + ')');
|
|
562
|
-
$('#dg-logo').css('height', logoHeight+'px');
|
|
563
|
-
$('#dg-logo').css('line-height', logoHeight+'px');
|
|
564
|
-
$('#dg-logo').css('padding-left',
|
|
565
|
-
}
|
|
566
|
-
|
|
592
|
+
$('#dg-logo').css('height', logoHeight + 'px');
|
|
593
|
+
$('#dg-logo').css('line-height', logoHeight + 'px');
|
|
594
|
+
$('#dg-logo').css('padding-left', logoWidth + 25 + 'px');
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
$('#dg-logo').css('padding-left', '0');
|
|
567
598
|
}
|
|
568
599
|
//parameters
|
|
569
600
|
$('title').text(meta.parameters.title);
|
|
@@ -571,7 +602,7 @@ function DocGen (process)
|
|
|
571
602
|
$('#dg-title').text(meta.parameters.title);
|
|
572
603
|
$('#dg-owner').html(owner);
|
|
573
604
|
$('#dg-version').text(releaseVersion);
|
|
574
|
-
$('#dg-web-title-version').text('('+releaseVersion+')');
|
|
605
|
+
$('#dg-web-title-version').text('(' + releaseVersion + ')');
|
|
575
606
|
$('#dg-release-date').text(releaseDate);
|
|
576
607
|
$('#dg-web-footer').text(webFooter);
|
|
577
608
|
$('#dg-author').html(author);
|
|
@@ -588,38 +619,38 @@ function DocGen (process)
|
|
|
588
619
|
}
|
|
589
620
|
}
|
|
590
621
|
if (options.mathKatex === true) {
|
|
591
|
-
$ = templates.main;
|
|
622
|
+
var $ = templates.main;
|
|
592
623
|
//support for KaTeX (bundled with DocGen)
|
|
593
624
|
$('head').append('<link rel="stylesheet" href="require/katex/katex.min.css" type="text/css">');
|
|
594
625
|
$('head').append('<script type="text/javascript" src="require/katex/katex.min.js"></script>');
|
|
595
626
|
$('head').append('<script type="text/javascript" src="require/katexInjector.js"></script>');
|
|
596
|
-
|
|
597
627
|
}
|
|
598
628
|
if (options.mathMathjax === true) {
|
|
599
629
|
//support for MathJax (only supported via CDN due to very large size)
|
|
600
630
|
//MathJax configuration is the same as used by math.stackexchange.com
|
|
601
|
-
|
|
631
|
+
//Note - wkhtmlpdf //cdn urls - see https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1634
|
|
602
632
|
$('head').append('<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full"></script>');
|
|
603
633
|
}
|
|
604
|
-
}
|
|
605
|
-
|
|
634
|
+
};
|
|
606
635
|
/*
|
|
607
|
-
|
|
636
|
+
process each input into an output
|
|
608
637
|
*/
|
|
609
|
-
|
|
610
|
-
var process = function () {
|
|
638
|
+
var processContent = function () {
|
|
611
639
|
console.log(chalk.green('Generating the static web content'));
|
|
612
640
|
webToc();
|
|
613
641
|
insertParameters();
|
|
614
|
-
meta.contents.forEach(
|
|
615
|
-
section.pages.forEach(
|
|
642
|
+
meta.contents.forEach(function (section) {
|
|
643
|
+
section.pages.forEach(function (page) {
|
|
616
644
|
var $ = cheerio.load(templates.main.html()); //clone
|
|
617
645
|
var key = page.source;
|
|
618
646
|
var content = pages[key];
|
|
619
647
|
//add relevant container
|
|
620
|
-
if (page.html === true) {
|
|
648
|
+
if (page.html === true) {
|
|
649
|
+
//raw HTML pages should not be confined to the fixed width
|
|
621
650
|
$('#dg-content').html('<div id="dg-innerContent"></div>');
|
|
622
|
-
}
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
//Markdown pages should be confined to the fixed width
|
|
623
654
|
$('#dg-content').html('<div class="w-fixed-width"><div id="dg-innerContent"></div></div>');
|
|
624
655
|
}
|
|
625
656
|
$('#dg-innerContent').html(content);
|
|
@@ -631,11 +662,11 @@ function DocGen (process)
|
|
|
631
662
|
if (headings.length > 0) {
|
|
632
663
|
html[++i] = '<ul class="dg-pageToc">';
|
|
633
664
|
}
|
|
634
|
-
headings.each(function(
|
|
665
|
+
headings.each(function () {
|
|
635
666
|
var label = $(this).text();
|
|
636
|
-
var anchor = label.toLowerCase().replace(/\s+/g,
|
|
667
|
+
var anchor = label.toLowerCase().replace(/\s+/g, '-');
|
|
637
668
|
$(this).attr('id', anchor);
|
|
638
|
-
html[++i] = '<li><a href="#'+anchor+'">'+label+'</a></li>';
|
|
669
|
+
html[++i] = '<li><a href="#' + anchor + '">' + label + '</a></li>';
|
|
639
670
|
});
|
|
640
671
|
if (headings.length > 0) {
|
|
641
672
|
html[++i] = '</ul>';
|
|
@@ -645,7 +676,7 @@ function DocGen (process)
|
|
|
645
676
|
}
|
|
646
677
|
//------------------------------------------------------------------------------------------------------
|
|
647
678
|
//prepend the auto heading (which makes the PDF table of contents match the web TOC)
|
|
648
|
-
$('#dg-innerContent').prepend('<h1 id="dg-autoTitle">'+page.title+'</h1>');
|
|
679
|
+
$('#dg-innerContent').prepend('<h1 id="dg-autoTitle">' + page.title + '</h1>');
|
|
649
680
|
if (page.html === true) {
|
|
650
681
|
$('#dg-autoTitle').addClass('dg-hiddenTitle');
|
|
651
682
|
}
|
|
@@ -662,53 +693,52 @@ function DocGen (process)
|
|
|
662
693
|
$('#dg-innerContent').html(templates.webCover.html());
|
|
663
694
|
templates.webCover = $;
|
|
664
695
|
writePages();
|
|
665
|
-
}
|
|
666
|
-
|
|
696
|
+
};
|
|
667
697
|
/*
|
|
668
|
-
|
|
698
|
+
write each html page
|
|
669
699
|
*/
|
|
670
|
-
|
|
671
700
|
var writePages = function () {
|
|
672
701
|
console.log(chalk.green('Writing the web page files'));
|
|
673
702
|
var promises = {};
|
|
674
|
-
meta.contents.forEach(
|
|
675
|
-
section.pages.forEach(
|
|
703
|
+
meta.contents.forEach(function (section) {
|
|
704
|
+
section.pages.forEach(function (page) {
|
|
676
705
|
var key = page.source;
|
|
677
706
|
var name = key.substr(0, page.source.lastIndexOf('.'));
|
|
678
|
-
var path = options.output+name+'.html';
|
|
707
|
+
var path = options.output + name + '.html';
|
|
679
708
|
var html = pages[key].html();
|
|
680
709
|
promises[key] = writeFile(path, html);
|
|
681
710
|
});
|
|
682
711
|
});
|
|
683
712
|
//add extra files
|
|
684
|
-
promises['ownership'] = writeFile(options.output+'ownership.html', templates.webCover.html());
|
|
713
|
+
promises['ownership'] = writeFile(options.output + 'ownership.html', templates.webCover.html());
|
|
685
714
|
if (options.pdf === true) {
|
|
686
|
-
var pdfTempDir = options.output+'temp/';
|
|
715
|
+
var pdfTempDir = options.output + 'temp/';
|
|
687
716
|
fs.mkdirsSync(pdfTempDir);
|
|
688
|
-
promises['docgenPdfCover'] = writeFile(pdfTempDir+'pdfCover.html', templates.pdfCover.html());
|
|
689
|
-
promises['docgenPdfHeader'] = writeFile(pdfTempDir+'pdfHeader.html', templates.pdfHeader.html());
|
|
690
|
-
promises['docgenPdfFooter'] = writeFile(pdfTempDir+'pdfFooter.html', templates.pdfFooter.html());
|
|
717
|
+
promises['docgenPdfCover'] = writeFile(pdfTempDir + 'pdfCover.html', templates.pdfCover.html());
|
|
718
|
+
promises['docgenPdfHeader'] = writeFile(pdfTempDir + 'pdfHeader.html', templates.pdfHeader.html());
|
|
719
|
+
promises['docgenPdfFooter'] = writeFile(pdfTempDir + 'pdfFooter.html', templates.pdfFooter.html());
|
|
691
720
|
}
|
|
692
|
-
rsvp
|
|
693
|
-
|
|
694
|
-
|
|
721
|
+
rsvp
|
|
722
|
+
.hash(promises)
|
|
723
|
+
.then(function () {
|
|
724
|
+
copyDirSync(__dirname + '/require', options.output + 'require'); //CSS, JavaScript
|
|
725
|
+
copyDirSync(options.input + '/files', options.output + 'files'); //user-attached files and images
|
|
695
726
|
if (options.mathKatex === true) {
|
|
696
|
-
copyDirSync(__dirname+'/optional/katex', options.output+'require/katex');
|
|
727
|
+
copyDirSync(__dirname + '/optional/katex', options.output + 'require/katex');
|
|
697
728
|
}
|
|
698
729
|
checkPdfVersion();
|
|
699
|
-
})
|
|
730
|
+
})
|
|
731
|
+
.catch(function (error) {
|
|
700
732
|
console.log(chalk.red('Error writing the web page files'));
|
|
701
733
|
if (options.verbose === true) {
|
|
702
734
|
console.log(chalk.red(error));
|
|
703
735
|
}
|
|
704
736
|
mainProcess.exit(1);
|
|
705
737
|
});
|
|
706
|
-
}
|
|
707
|
-
|
|
738
|
+
};
|
|
708
739
|
/*
|
|
709
|
-
|
|
740
|
+
wkthmltopdf options
|
|
710
741
|
*/
|
|
711
|
-
|
|
712
742
|
var pdfOptions = [
|
|
713
743
|
' --zoom 1.0',
|
|
714
744
|
' --image-quality 100',
|
|
@@ -723,51 +753,51 @@ function DocGen (process)
|
|
|
723
753
|
' --footer-spacing 5',
|
|
724
754
|
' --no-stop-slow-scripts',
|
|
725
755
|
];
|
|
726
|
-
|
|
727
756
|
var getPdfArguments = function () {
|
|
728
|
-
var pdfName = meta.parameters.name.toLowerCase()+'.pdf';
|
|
729
|
-
pdfOptions.push(' --
|
|
730
|
-
pdfOptions.push(' --
|
|
731
|
-
pdfOptions.push(' --
|
|
732
|
-
pdfOptions.push(' --
|
|
733
|
-
pdfOptions.push('
|
|
734
|
-
pdfOptions.push('
|
|
757
|
+
var pdfName = meta.parameters.name.toLowerCase() + '.pdf';
|
|
758
|
+
pdfOptions.push(' --enable-local-file-access');
|
|
759
|
+
pdfOptions.push(' --javascript-delay ' + options.pdfDelay); //code syntax highlight in wkhtmltopdf 0.12.2.1 fails without a delay (but why doesn't --no-stop-slow-scripts work?)
|
|
760
|
+
pdfOptions.push(' --user-style-sheet ' + __dirname + '/pdf-stylesheet.css');
|
|
761
|
+
pdfOptions.push(' --header-html ' + options.output + 'temp/pdfHeader.html');
|
|
762
|
+
pdfOptions.push(' --footer-html ' + options.output + 'temp/pdfFooter.html');
|
|
763
|
+
pdfOptions.push(' cover ' + options.output + 'temp/pdfCover.html');
|
|
764
|
+
pdfOptions.push(' toc --xsl-style-sheet ' + __dirname + '/pdf-contents.xsl');
|
|
735
765
|
var allPages = '';
|
|
736
766
|
for (var key in sortedPages) {
|
|
737
767
|
if (sortedPages.hasOwnProperty(key)) {
|
|
738
|
-
sortedPages[key].forEach(
|
|
739
|
-
section.pages.forEach(
|
|
768
|
+
sortedPages[key].forEach(function (section) {
|
|
769
|
+
section.pages.forEach(function (page) {
|
|
740
770
|
var key = page.source;
|
|
741
771
|
var name = key.substr(0, page.source.lastIndexOf('.'));
|
|
742
|
-
var path = options.output+name+'.html';
|
|
743
|
-
allPages += ' '+path;
|
|
772
|
+
var path = options.output + name + '.html';
|
|
773
|
+
allPages += ' ' + path;
|
|
744
774
|
});
|
|
745
775
|
});
|
|
746
776
|
}
|
|
747
777
|
}
|
|
748
778
|
var args = pdfOptions.join('');
|
|
749
779
|
args += allPages;
|
|
750
|
-
args += ' '+options.output+pdfName;
|
|
780
|
+
args += ' ' + options.output + pdfName;
|
|
751
781
|
return spawnArgs(args);
|
|
752
|
-
}
|
|
753
|
-
|
|
782
|
+
};
|
|
754
783
|
var checkPdfVersion = function () {
|
|
755
784
|
if (options.pdf === true) {
|
|
756
|
-
//first check that wkhtmltopdf is installed
|
|
757
|
-
|
|
785
|
+
//first check that wkhtmltopdf is installed
|
|
786
|
+
(0, child_process_1.exec)(options.wkhtmltopdfPath + ' -V', function (error, stdout, stderr) {
|
|
758
787
|
if (error) {
|
|
759
788
|
console.log(chalk.red('Unable to call wkhtmltopdf. Is it installed and in path? See http://wkhtmltopdf.org'));
|
|
760
789
|
if (options.verbose === true) {
|
|
761
790
|
console.log(chalk.red(error));
|
|
762
791
|
}
|
|
763
792
|
mainProcess.exit(1);
|
|
764
|
-
}
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
765
795
|
//warn if the version of wkhtmltopdf is not an expected version
|
|
766
796
|
var actualWkhtmltopdfVersion = stdout.trim();
|
|
767
797
|
if (actualWkhtmltopdfVersion !== wkhtmltopdfVersion) {
|
|
768
798
|
var warning = 'Warning: unexpected version of wkhtmltopdf, which may work but is not tested or supported';
|
|
769
|
-
var expectedVersion = ' expected version: '+wkhtmltopdfVersion;
|
|
770
|
-
var detectedVersion = ' detected version: '+actualWkhtmltopdfVersion;
|
|
799
|
+
var expectedVersion = ' expected version: ' + wkhtmltopdfVersion;
|
|
800
|
+
var detectedVersion = ' detected version: ' + actualWkhtmltopdfVersion;
|
|
771
801
|
console.log(chalk.yellow(warning));
|
|
772
802
|
console.log(chalk.yellow(expectedVersion));
|
|
773
803
|
console.log(chalk.yellow(detectedVersion));
|
|
@@ -775,46 +805,41 @@ function DocGen (process)
|
|
|
775
805
|
generatePdf();
|
|
776
806
|
}
|
|
777
807
|
});
|
|
778
|
-
}
|
|
808
|
+
}
|
|
809
|
+
else {
|
|
779
810
|
cleanUp();
|
|
780
811
|
}
|
|
781
|
-
}
|
|
782
|
-
|
|
812
|
+
};
|
|
783
813
|
/*
|
|
784
|
-
|
|
814
|
+
call wkhtmltopdf as an external executable
|
|
785
815
|
*/
|
|
786
|
-
|
|
787
816
|
var generatePdf = function () {
|
|
788
817
|
console.log(chalk.green('Creating the PDF copy (may take some time)'));
|
|
789
818
|
var args = getPdfArguments();
|
|
790
|
-
var wkhtmltopdf =
|
|
819
|
+
var wkhtmltopdf = (0, child_process_1.spawn)(options.wkhtmltopdfPath, args);
|
|
791
820
|
var spinner = new cliSpinner(chalk.green(' Processing... %s'));
|
|
792
821
|
spinner.setSpinnerString('|/-\\');
|
|
793
|
-
|
|
794
822
|
wkhtmltopdf.on('error', function (error) {
|
|
795
823
|
console.log(chalk.red('Error calling wkhtmltopdf to generate the PDF'));
|
|
796
824
|
if (options.verbose === true) {
|
|
797
825
|
console.log(chalk.red(error));
|
|
798
826
|
}
|
|
799
827
|
});
|
|
800
|
-
|
|
801
828
|
if (options.verbose !== true) {
|
|
802
829
|
spinner.start(); //only show spinner when verbose is off (otherwise show raw wkhtmltopdf output)
|
|
803
|
-
}
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
804
832
|
//pipe the output from wkhtmltopdf back to stdout
|
|
805
833
|
//however, wkhtmltpdf outputs to stderr, not stdout. See:
|
|
806
834
|
//https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1980
|
|
807
835
|
wkhtmltopdf.stderr.pipe(mainProcess.stdout);
|
|
808
836
|
}
|
|
809
|
-
|
|
810
837
|
wkhtmltopdf.stdout.on('data', function (data) {
|
|
811
838
|
//do nothing
|
|
812
839
|
});
|
|
813
|
-
|
|
814
840
|
wkhtmltopdf.stderr.on('data', function (data) {
|
|
815
841
|
//do nothing
|
|
816
842
|
});
|
|
817
|
-
|
|
818
843
|
wkhtmltopdf.on('close', function (code) {
|
|
819
844
|
if (options.verbose !== true) {
|
|
820
845
|
spinner.stop();
|
|
@@ -826,43 +851,41 @@ function DocGen (process)
|
|
|
826
851
|
}
|
|
827
852
|
cleanUp();
|
|
828
853
|
});
|
|
829
|
-
}
|
|
830
|
-
|
|
854
|
+
};
|
|
831
855
|
var createRedirect = function () {
|
|
832
856
|
if (options.redirect) {
|
|
833
|
-
var
|
|
834
|
-
|
|
857
|
+
var parent_1 = options.output.replace(/\/$/, ''); //trim any trailing slash
|
|
858
|
+
parent_1 = parent_1.split(path.sep).slice(-1).pop(); //get name of final directory in the path
|
|
835
859
|
var homepage = meta.contents[0].pages[0];
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
860
|
+
homepage =
|
|
861
|
+
homepage.source.substr(0, homepage.source.lastIndexOf('.')) + '.html';
|
|
862
|
+
var redirectLink = parent_1 + '/' + homepage;
|
|
863
|
+
var $ = templates.redirect;
|
|
839
864
|
$('a').attr('href', redirectLink);
|
|
840
|
-
$('meta[http-equiv=REFRESH]').attr('content', '0;url='+redirectLink);
|
|
841
|
-
var file = options.output+'../'+'index.html';
|
|
865
|
+
$('meta[http-equiv=REFRESH]').attr('content', '0;url=' + redirectLink);
|
|
866
|
+
var file = options.output + '../' + 'index.html';
|
|
842
867
|
try {
|
|
843
868
|
fs.outputFileSync(file, $.html(), 'utf-8');
|
|
844
|
-
}
|
|
845
|
-
|
|
869
|
+
}
|
|
870
|
+
catch (error) {
|
|
871
|
+
console.log(chalk.red('Error writing redirect file: ' + file));
|
|
846
872
|
if (options.verbose === true) {
|
|
847
873
|
console.log(chalk.red(error));
|
|
848
874
|
}
|
|
849
875
|
//don't exit because redirect error is not a fatal error
|
|
850
876
|
}
|
|
851
877
|
}
|
|
852
|
-
}
|
|
853
|
-
|
|
878
|
+
};
|
|
854
879
|
/*
|
|
855
|
-
|
|
880
|
+
cleanup
|
|
856
881
|
*/
|
|
857
|
-
|
|
858
882
|
var cleanUp = function () {
|
|
859
883
|
createRedirect();
|
|
860
884
|
//remove temp files
|
|
861
885
|
if (options.pdf === true) {
|
|
862
|
-
removeDirSync(options.output+'temp');
|
|
886
|
+
removeDirSync(options.output + 'temp');
|
|
863
887
|
}
|
|
864
888
|
console.log(chalk.green.bold('Done!'));
|
|
865
|
-
}
|
|
889
|
+
};
|
|
866
890
|
}
|
|
867
|
-
|
|
868
891
|
module.exports = DocGen;
|