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