@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/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.forOf = exports.fileId = exports.fail = void 0;
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
- const fileId = str => `_${str.replace(/[^a-zA-Z0-9_-]/g, '_')}`; // Determine an image's orientation
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
- }; // const getAspectRatioClassName = (key = '16:9') =>
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 _context2, _context3;
143
-
97
+ var _context, _context2;
144
98
  const cwd = process.cwd();
145
- 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)));
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, _context6;
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(_context6, ({
107
+ }]).call(_context5, ({
156
108
  absolutePath
157
109
  }) => (0, _findIndex.default)(files, {
158
110
  absolutePath
159
- }) < 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)), []);
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
- }; // make sure all necessary files and directories exist
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 _context7, _context8;
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)(_context7 = pathname.split('/')).call(_context7, Boolean);
191
- let pathParts = (0, _filter.default)(_context8 = p.split('/')).call(_context8, Boolean); // Remove filename if there is one
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
- } // Find indices where to slice arrays
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
- }; // https://github.com/readium/webpub-manifest
238
-
178
+ };
239
179
 
180
+ // https://github.com/readium/webpub-manifest
240
181
  const generateWebpubManifest = files => {
241
- var _context9, _context10;
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
- 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]));
247
187
 
248
- const readingOrderItems = (0, _reduce.default)(_context9 = _.State.spine.flattened).call(_context9, (acc, curr) => {
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)(_context10 = (0, _filter.default)(files).call(files, file => _path.default.basename(file).charAt(0) !== '.')).call(_context10, webpubManifestResource(remoteURL));
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
- } // { rel: 'alternate', href: `${remoteURL}/publication.epub`, type: 'application/epub+zip' },
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
- }; // b-ber-grammar-* utilities
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
- }; // Only render unsupported HTML for inline embeds since the unsupported figure
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); // eslint-disable-next-line no-param-reassign
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
- } // Add mediaType to classes
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`;