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