@canopycanopycanopy/b-ber-lib 2.0.0 → 3.0.2
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/Config.js +1 -9
- package/EbookConvert.js +0 -28
- package/GuideItem.js +0 -5
- package/Html.js +0 -6
- package/HtmlToXml.js +0 -38
- package/ManifestItemProperties.js +19 -40
- package/Spine.js +15 -59
- package/SpineItem.js +4 -11
- package/State.js +68 -149
- package/Template.js +0 -8
- package/Theme.js +23 -79
- package/Url.js +0 -11
- package/Yaml.js +5 -38
- package/YamlAdaptor.js +0 -19
- package/index.js +0 -28
- package/package.json +7 -7
- package/utils/index.js +48 -117
package/utils/index.js
CHANGED
|
@@ -1,71 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
|
|
4
|
-
|
|
5
4
|
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
|
|
6
|
-
|
|
7
5
|
_Object$defineProperty(exports, "__esModule", {
|
|
8
6
|
value: true
|
|
9
7
|
});
|
|
10
|
-
|
|
11
8
|
exports.createUnsupportedInline = createUnsupportedInline;
|
|
12
9
|
exports.ensure = void 0;
|
|
13
10
|
exports.ensurePoster = ensurePoster;
|
|
14
11
|
exports.ensureSource = ensureSource;
|
|
15
12
|
exports.ensureSupportedClassNames = ensureSupportedClassNames;
|
|
16
|
-
exports.validatePosterImage = exports.safeWrite = exports.resolveIntersectingUrl = exports.renderPosterImage = exports.renderCaption = exports.opsPath = exports.getTitle = exports.getMediaType = exports.getImageOrientation = exports.getBookMetadata = exports.generateWebpubManifest = exports.
|
|
17
|
-
|
|
18
|
-
var _forEach = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/for-each"));
|
|
19
|
-
|
|
20
|
-
var _entries = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/entries"));
|
|
21
|
-
|
|
13
|
+
exports.validatePosterImage = exports.safeWrite = exports.resolveIntersectingUrl = exports.renderPosterImage = exports.renderCaption = exports.opsPath = exports.getTitle = exports.getMediaType = exports.getImageOrientation = exports.getBookMetadata = exports.generateWebpubManifest = exports.fileId = exports.fail = void 0;
|
|
22
14
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));
|
|
23
|
-
|
|
24
15
|
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
|
|
25
|
-
|
|
26
16
|
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
|
|
27
|
-
|
|
28
17
|
var _reduce = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/reduce"));
|
|
29
|
-
|
|
30
18
|
var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));
|
|
31
|
-
|
|
32
19
|
var _url = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/url"));
|
|
33
|
-
|
|
34
20
|
var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice"));
|
|
35
|
-
|
|
36
21
|
var _map2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/map"));
|
|
37
|
-
|
|
38
22
|
var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/index-of"));
|
|
39
|
-
|
|
40
23
|
var _fsExtra = _interopRequireDefault(require("fs-extra"));
|
|
41
|
-
|
|
42
24
|
var _path = _interopRequireDefault(require("path"));
|
|
43
|
-
|
|
44
25
|
var _find = _interopRequireDefault(require("lodash/find"));
|
|
45
|
-
|
|
46
26
|
var _uniq = _interopRequireDefault(require("lodash/uniq"));
|
|
47
|
-
|
|
48
27
|
var _bBerLogger = _interopRequireDefault(require("@canopycanopycanopy/b-ber-logger"));
|
|
49
|
-
|
|
50
28
|
var _findIndex = _interopRequireDefault(require("lodash/findIndex"));
|
|
51
|
-
|
|
52
29
|
var _mimeTypes = _interopRequireDefault(require("mime-types"));
|
|
53
|
-
|
|
54
30
|
var _ = require("..");
|
|
55
|
-
|
|
56
31
|
// import ffprobe from 'ffprobe'
|
|
57
32
|
// import ffprobeStatic from 'ffprobe-static'
|
|
58
|
-
// Get a file's relative path to the OPS
|
|
59
|
-
const opsPath = (fpath, base) => fpath.replace(new RegExp(`^${base}${_path.default.sep}OPS${_path.default.sep}?`), ''); // https://www.w3.org/TR/xml-names/#Conformance
|
|
60
33
|
|
|
34
|
+
// Get a file's relative path to the OPS
|
|
35
|
+
const opsPath = (fpath, base) => fpath.replace(new RegExp(`^${base}${_path.default.sep}OPS${_path.default.sep}?`), '');
|
|
61
36
|
|
|
37
|
+
// https://www.w3.org/TR/xml-names/#Conformance
|
|
62
38
|
exports.opsPath = opsPath;
|
|
39
|
+
const fileId = str => `_${str.replace(/[^a-zA-Z0-9_-]/g, '_')}`;
|
|
63
40
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
41
|
+
// Determine an image's orientation
|
|
67
42
|
exports.fileId = fileId;
|
|
68
|
-
|
|
69
43
|
const getImageOrientation = (w, h) => {
|
|
70
44
|
// assign image class based on w:h ratio
|
|
71
45
|
const widthToHeight = w / h;
|
|
@@ -75,128 +49,99 @@ const getImageOrientation = (w, h) => {
|
|
|
75
49
|
if (widthToHeight === 1) imageType = 'square';
|
|
76
50
|
if (widthToHeight > 1) imageType = 'landscape';
|
|
77
51
|
return imageType;
|
|
78
|
-
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// const getAspectRatioClassName = (key = '16:9') =>
|
|
79
55
|
// ({ '4:3': 'video--4x3', '16:9': 'video--16x9', '21:9': 'video--21x9' }[key])
|
|
56
|
+
|
|
80
57
|
// export const getVideoAspectRatio = async filePath => {
|
|
81
58
|
// if (!filePath) return getAspectRatioClassName()
|
|
59
|
+
|
|
82
60
|
// const { streams } = await ffprobe(filePath, { path: ffprobeStatic.path })
|
|
83
61
|
// if (!streams) return getAspectRatioClassName()
|
|
84
62
|
// const { display_aspect_ratio: aspectRatio } = streams
|
|
85
63
|
// return getAspectRatioClassName(aspectRatio)
|
|
86
64
|
// }
|
|
87
|
-
// Create an iterator from object's key/value pairs
|
|
88
65
|
|
|
89
|
-
|
|
90
|
-
exports.getImageOrientation = getImageOrientation;
|
|
91
|
-
|
|
92
|
-
const forOf = (collection, iterator) => {
|
|
93
|
-
var _context;
|
|
94
|
-
|
|
95
|
-
return (0, _forEach.default)(_context = (0, _entries.default)(collection)).call(_context, ([key, val]) => iterator(key, val));
|
|
96
|
-
}; // TODO: the whole figures/generated pages/user-configurable YAML thing should
|
|
66
|
+
// TODO: the whole figures/generated pages/user-configurable YAML thing should
|
|
97
67
|
// be worked out better. one reason is below, where we need the title of a
|
|
98
68
|
// generated page, but since metadata is attached in the frontmatter YAML of an
|
|
99
69
|
// MD file, there is no reference for the metadata.
|
|
100
70
|
// @issue: https://github.com/triplecanopy/b-ber/issues/208
|
|
101
71
|
//
|
|
102
72
|
// this is provisional, will just cause more confusion in the future
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
exports.forOf = forOf;
|
|
106
|
-
|
|
73
|
+
exports.getImageOrientation = getImageOrientation;
|
|
107
74
|
const getTitle = page => {
|
|
108
75
|
if (page.name === 'figures-titlepage') return 'Figures';
|
|
109
|
-
|
|
110
76
|
const meta = _.State.spine.frontMatter.get(page.name);
|
|
111
|
-
|
|
112
77
|
return meta && meta.title ? meta.title : page.title || page.name;
|
|
113
78
|
};
|
|
114
|
-
|
|
115
79
|
exports.getTitle = getTitle;
|
|
116
|
-
|
|
117
80
|
const getBookMetadata = term => {
|
|
118
81
|
const entry = (0, _find.default)(_.State.metadata.json(), {
|
|
119
82
|
term
|
|
120
83
|
});
|
|
121
84
|
if (entry && entry.value) return entry.value;
|
|
122
|
-
|
|
123
85
|
_bBerLogger.default.warn(`Could not find metadata value for ${term}`);
|
|
124
|
-
|
|
125
86
|
return '';
|
|
126
87
|
};
|
|
127
|
-
|
|
128
88
|
exports.getBookMetadata = getBookMetadata;
|
|
129
|
-
|
|
130
89
|
const safeWrite = (dest, data) => _fsExtra.default.existsSync(dest) ? _promise.default.resolve() : _fsExtra.default.writeFile(dest, data);
|
|
131
|
-
|
|
132
90
|
exports.safeWrite = safeWrite;
|
|
133
|
-
|
|
134
91
|
const fail = (_msg, _err, yargs) => {
|
|
135
92
|
yargs.showHelp();
|
|
136
93
|
process.exit(0);
|
|
137
94
|
};
|
|
138
|
-
|
|
139
95
|
exports.fail = fail;
|
|
140
|
-
|
|
141
96
|
const ensureDirs = (dirs, prefix) => {
|
|
142
|
-
var
|
|
143
|
-
|
|
97
|
+
var _context, _context2;
|
|
144
98
|
const cwd = process.cwd();
|
|
145
|
-
const dirs_ = (0, _map.default)(
|
|
99
|
+
const dirs_ = (0, _map.default)(_context = (0, _uniq.default)((0, _concat.default)(_context2 = [`${prefix}/_project`, `${prefix}/_project/_fonts`, `${prefix}/_project/_images`, `${prefix}/_project/_javascripts`, `${prefix}/_project/_markdown`, `${prefix}/_project/_media`, `${prefix}/_project/_stylesheets`, `${prefix}/themes`]).call(_context2, dirs))).call(_context, a => _fsExtra.default.ensureDir(_path.default.join(cwd, a)));
|
|
146
100
|
return _promise.default.all(dirs_);
|
|
147
101
|
};
|
|
148
|
-
|
|
149
102
|
const ensureFiles = (files, prefix) => {
|
|
150
|
-
var _context4, _context5
|
|
151
|
-
|
|
152
|
-
const files_ = (0, _reduce.default)(_context4 = (0, _concat.default)(_context5 = (0, _filter.default)(_context6 = [{
|
|
103
|
+
var _context3, _context4, _context5;
|
|
104
|
+
const files_ = (0, _reduce.default)(_context3 = (0, _concat.default)(_context4 = (0, _filter.default)(_context5 = [{
|
|
153
105
|
absolutePath: _path.default.resolve(prefix, '_project', 'toc.yml'),
|
|
154
106
|
content: ''
|
|
155
|
-
}]).call(
|
|
107
|
+
}]).call(_context5, ({
|
|
156
108
|
absolutePath
|
|
157
109
|
}) => (0, _findIndex.default)(files, {
|
|
158
110
|
absolutePath
|
|
159
|
-
}) < 0)).call(
|
|
111
|
+
}) < 0)).call(_context4, files)).call(_context3, (acc, curr) => _fsExtra.default.existsSync(curr.absolutePath) ? acc : (0, _concat.default)(acc).call(acc, _fsExtra.default.writeFile(curr.absolutePath, curr.content)), []);
|
|
160
112
|
return _promise.default.all(files_);
|
|
161
|
-
};
|
|
162
|
-
|
|
113
|
+
};
|
|
163
114
|
|
|
115
|
+
// make sure all necessary files and directories exist
|
|
164
116
|
const ensure = ({
|
|
165
117
|
files = [],
|
|
166
118
|
dirs = [],
|
|
167
119
|
prefix = ''
|
|
168
120
|
} = {}) => ensureDirs(dirs, prefix).then(() => ensureFiles(files, prefix)).catch(_bBerLogger.default.error);
|
|
169
|
-
|
|
170
121
|
exports.ensure = ensure;
|
|
171
|
-
|
|
172
122
|
const trimLeadingSlash = s => s.replace(/^\//, '');
|
|
173
|
-
|
|
174
123
|
const resolveIntersectingUrl = (u, p) => {
|
|
175
|
-
var
|
|
176
|
-
|
|
124
|
+
var _context6, _context7;
|
|
177
125
|
let url;
|
|
178
|
-
|
|
179
126
|
try {
|
|
180
127
|
url = new _url.default(u);
|
|
181
128
|
} catch (err) {
|
|
182
129
|
_bBerLogger.default.warn(`${err.message}: "${u}"`);
|
|
183
|
-
|
|
184
130
|
return u;
|
|
185
131
|
}
|
|
186
|
-
|
|
187
132
|
const {
|
|
188
133
|
pathname
|
|
189
134
|
} = url;
|
|
190
|
-
let urlParts = (0, _filter.default)(
|
|
191
|
-
let pathParts = (0, _filter.default)(
|
|
135
|
+
let urlParts = (0, _filter.default)(_context6 = pathname.split('/')).call(_context6, Boolean);
|
|
136
|
+
let pathParts = (0, _filter.default)(_context7 = p.split('/')).call(_context7, Boolean);
|
|
192
137
|
|
|
138
|
+
// Remove filename if there is one
|
|
193
139
|
if (/\./.test(urlParts[urlParts.length - 1])) {
|
|
194
140
|
urlParts.pop();
|
|
195
|
-
}
|
|
196
|
-
|
|
141
|
+
}
|
|
197
142
|
|
|
143
|
+
// Find indices where to slice arrays
|
|
198
144
|
let intersectionIndices = [];
|
|
199
|
-
|
|
200
145
|
for (let i = 0; i < urlParts.length; i++) {
|
|
201
146
|
for (let j = 0; j < pathParts.length; j++) {
|
|
202
147
|
if (urlParts[i] === pathParts[j]) {
|
|
@@ -205,7 +150,6 @@ const resolveIntersectingUrl = (u, p) => {
|
|
|
205
150
|
}
|
|
206
151
|
}
|
|
207
152
|
}
|
|
208
|
-
|
|
209
153
|
const [uIdx, pIdx] = intersectionIndices;
|
|
210
154
|
urlParts = (0, _slice.default)(urlParts).call(urlParts, 0, uIdx);
|
|
211
155
|
pathParts = (0, _slice.default)(pathParts).call(pathParts, pIdx);
|
|
@@ -213,9 +157,7 @@ const resolveIntersectingUrl = (u, p) => {
|
|
|
213
157
|
url.pathname = intersection.join('/');
|
|
214
158
|
return url.href;
|
|
215
159
|
};
|
|
216
|
-
|
|
217
160
|
exports.resolveIntersectingUrl = resolveIntersectingUrl;
|
|
218
|
-
|
|
219
161
|
const webpubManifestResource = base => file => {
|
|
220
162
|
const href = resolveIntersectingUrl(base, file);
|
|
221
163
|
return {
|
|
@@ -223,7 +165,6 @@ const webpubManifestResource = base => file => {
|
|
|
223
165
|
type: _mimeTypes.default.lookup(file)
|
|
224
166
|
};
|
|
225
167
|
};
|
|
226
|
-
|
|
227
168
|
const webpubManifestReadingOrderItem = base => ({
|
|
228
169
|
title,
|
|
229
170
|
file
|
|
@@ -234,18 +175,18 @@ const webpubManifestReadingOrderItem = base => ({
|
|
|
234
175
|
title,
|
|
235
176
|
type: 'text/xhtml'
|
|
236
177
|
};
|
|
237
|
-
};
|
|
238
|
-
|
|
178
|
+
};
|
|
239
179
|
|
|
180
|
+
// https://github.com/readium/webpub-manifest
|
|
240
181
|
const generateWebpubManifest = files => {
|
|
241
|
-
var
|
|
242
|
-
|
|
243
|
-
const remoteURL = _.Url.trimSlashes(_.State.config.remote_url); // Build a map to sort the files according to the position in the spine
|
|
244
|
-
|
|
182
|
+
var _context8, _context9;
|
|
183
|
+
const remoteURL = _.Url.trimSlashes(_.State.config.remote_url);
|
|
245
184
|
|
|
246
|
-
|
|
185
|
+
// Build a map to sort the files according to the position in the spine
|
|
186
|
+
const fileMap = new _map2.default((0, _map.default)(files).call(files, f => [_path.default.basename(f), f]));
|
|
247
187
|
|
|
248
|
-
|
|
188
|
+
// Create the items for the manifest's reading order
|
|
189
|
+
const readingOrderItems = (0, _reduce.default)(_context8 = _.State.spine.flattened).call(_context8, (acc, curr) => {
|
|
249
190
|
const file = fileMap.get(`${curr.fileName}.xhtml`);
|
|
250
191
|
return !file ? acc : (0, _concat.default)(acc).call(acc, {
|
|
251
192
|
file,
|
|
@@ -253,7 +194,7 @@ const generateWebpubManifest = files => {
|
|
|
253
194
|
});
|
|
254
195
|
}, []);
|
|
255
196
|
const readingOrder = (0, _map.default)(readingOrderItems).call(readingOrderItems, webpubManifestReadingOrderItem(remoteURL));
|
|
256
|
-
const resources = (0, _map.default)(
|
|
197
|
+
const resources = (0, _map.default)(_context9 = (0, _filter.default)(files).call(files, file => _path.default.basename(file).charAt(0) !== '.')).call(_context9, webpubManifestResource(remoteURL));
|
|
257
198
|
const manifest = {
|
|
258
199
|
'@context': 'https://readium.org/webpub-manifest/context.jsonld',
|
|
259
200
|
metadata: {
|
|
@@ -269,49 +210,41 @@ const generateWebpubManifest = files => {
|
|
|
269
210
|
rel: 'self',
|
|
270
211
|
href: `${remoteURL}/${trimLeadingSlash(_.State.distDir)}/manifest.json`,
|
|
271
212
|
type: 'application/webpub+json'
|
|
272
|
-
}
|
|
213
|
+
}
|
|
214
|
+
// { rel: 'alternate', href: `${remoteURL}/publication.epub`, type: 'application/epub+zip' },
|
|
273
215
|
// { rel: 'search', href: `${remoteURL}/search{?query}`, type: 'text/html', templated: true },
|
|
274
216
|
],
|
|
217
|
+
|
|
275
218
|
readingOrder,
|
|
276
219
|
resources
|
|
277
220
|
};
|
|
278
221
|
return manifest;
|
|
279
|
-
};
|
|
280
|
-
|
|
222
|
+
};
|
|
281
223
|
|
|
224
|
+
// b-ber-grammar-* utilities
|
|
282
225
|
exports.generateWebpubManifest = generateWebpubManifest;
|
|
283
|
-
|
|
284
226
|
const validatePosterImage = (asset, type) => {
|
|
285
227
|
const assetPath = _.State.src.images(asset);
|
|
286
|
-
|
|
287
228
|
if (!_fsExtra.default.existsSync(assetPath)) {
|
|
288
229
|
_bBerLogger.default.error(`bber-directives: Poster image for [${type}] does not exist`);
|
|
289
230
|
}
|
|
290
|
-
|
|
291
231
|
return asset;
|
|
292
232
|
};
|
|
293
|
-
|
|
294
233
|
exports.validatePosterImage = validatePosterImage;
|
|
295
|
-
|
|
296
234
|
const renderPosterImage = poster => poster ? `<img src="${poster}" alt="Poster Image"/>` : '';
|
|
297
|
-
|
|
298
235
|
exports.renderPosterImage = renderPosterImage;
|
|
299
|
-
|
|
300
236
|
const renderCaption = (caption, mediaType) => caption ? `<p class="caption caption__${mediaType}">${caption}</p>` : '';
|
|
301
|
-
|
|
302
237
|
exports.renderCaption = renderCaption;
|
|
303
|
-
|
|
304
238
|
const getMediaType = type => {
|
|
305
239
|
const index = (0, _indexOf.default)(type).call(type, '-');
|
|
306
240
|
return index > -1 ? type.substring(0, index) : type;
|
|
307
|
-
};
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// Only render unsupported HTML for inline embeds since the unsupported figure
|
|
308
244
|
// in the LOI is handled by b-ber-templates. Not great UI to have to click to
|
|
309
245
|
// the LOI to see that something is unsupported, but vimeo directives should
|
|
310
246
|
// mostly be managed by media.yml which supports fallbacks.
|
|
311
|
-
|
|
312
|
-
|
|
313
247
|
exports.getMediaType = getMediaType;
|
|
314
|
-
|
|
315
248
|
function createUnsupportedInline({
|
|
316
249
|
id,
|
|
317
250
|
commentStart,
|
|
@@ -334,21 +267,19 @@ function createUnsupportedInline({
|
|
|
334
267
|
</section>
|
|
335
268
|
${commentEnd}`;
|
|
336
269
|
}
|
|
337
|
-
|
|
338
270
|
function ensureSource(obj, type, fileName, lineNumber) {
|
|
339
271
|
if (!obj.source) {
|
|
340
272
|
_bBerLogger.default.error(`Directive [${type}] requires a [source] attribute at [${fileName}:${lineNumber}]`);
|
|
341
273
|
}
|
|
342
274
|
}
|
|
343
|
-
|
|
344
275
|
function ensurePoster(obj, type) {
|
|
345
276
|
if (!obj.poster) return;
|
|
346
|
-
validatePosterImage(obj.poster, type);
|
|
347
|
-
|
|
277
|
+
validatePosterImage(obj.poster, type);
|
|
278
|
+
// eslint-disable-next-line no-param-reassign
|
|
348
279
|
obj.poster = `../images/${encodeURIComponent(_path.default.basename(obj.poster))}`;
|
|
349
|
-
}
|
|
350
|
-
|
|
280
|
+
}
|
|
351
281
|
|
|
282
|
+
// Add mediaType to classes
|
|
352
283
|
function ensureSupportedClassNames(obj, supported) {
|
|
353
284
|
// eslint-disable-next-line no-param-reassign
|
|
354
285
|
obj.classes += ` embed ${supported(_.State.build) ? '' : 'un'}supported`;
|