@epubook/core 0.0.3 → 0.0.4

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/dist/index.cjs CHANGED
@@ -4,9 +4,9 @@ const path = require('node:path');
4
4
  const node_crypto = require('node:crypto');
5
5
  const defu$1 = require('defu');
6
6
  const path$1 = require('pathe');
7
- const node_fs = require('node:fs');
8
7
  const fflate = require('fflate');
9
8
  const fastXmlParser = require('fast-xml-parser');
9
+ const node_fs = require('node:fs');
10
10
 
11
11
  function _interopNamespaceDefault(e) {
12
12
  const n = Object.create(null);
@@ -22,6 +22,19 @@ function _interopNamespaceDefault(e) {
22
22
  const path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
23
23
  const path__namespace$1 = /*#__PURE__*/_interopNamespaceDefault(path$1);
24
24
 
25
+ const Fragment = "Fragment";
26
+ function h(tag, attrs = {}, ...children) {
27
+ const sub = children.flatMap(
28
+ (c) => typeof c === "object" && !Array.isArray(c) && c.tag === Fragment ? c.children ?? [] : c
29
+ ).filter((c) => c !== void 0 && c !== null && c !== false);
30
+ const o = {
31
+ tag,
32
+ attrs: attrs ?? {},
33
+ children: sub
34
+ };
35
+ return o;
36
+ }
37
+
25
38
  const MIMETYPE = "application/epub+zip";
26
39
  const ImageGif = "image/gif";
27
40
  const ImageJpeg = "image/jpeg";
@@ -49,19 +62,6 @@ function getImageMediaType(file) {
49
62
  }
50
63
  }
51
64
 
52
- const Fragment = "Fragment";
53
- function h(tag, attrs = {}, ...children) {
54
- const sub = children.flatMap(
55
- (c) => typeof c === "object" && !Array.isArray(c) && c.tag === Fragment ? c.children ?? [] : c
56
- ).filter((c) => c !== void 0 && c !== null && c !== false);
57
- const o = {
58
- tag,
59
- attrs: attrs ?? {},
60
- children: sub
61
- };
62
- return o;
63
- }
64
-
65
65
  class ManifestItem {
66
66
  constructor(href, id) {
67
67
  this.optional = {};
@@ -215,59 +215,67 @@ const builder = new fastXmlParser.XMLBuilder({
215
215
  class XHTML extends Item {
216
216
  constructor(file, meta, content) {
217
217
  super(file, TextXHTML);
218
- this.meta = meta;
219
- this.content = content;
218
+ this._meta = meta;
219
+ this._content = content;
220
+ }
221
+ meta() {
222
+ return this._meta;
220
223
  }
221
224
  title() {
222
- return this.meta.title;
225
+ return this._meta.title;
223
226
  }
224
227
  language() {
225
- return this.meta.language;
228
+ return this._meta.language;
229
+ }
230
+ content() {
231
+ return this._content;
226
232
  }
227
233
  async bundle() {
228
- return fflate.strToU8(this.content);
234
+ return fflate.strToU8(this._content);
229
235
  }
230
236
  }
231
237
  class XHTMLBuilder {
232
238
  constructor(filename) {
233
- this.meta = {
239
+ this._meta = {
234
240
  language: "en",
235
241
  title: ""
236
242
  };
237
243
  this._head = [];
238
244
  this._body = [];
239
245
  this._filename = filename;
240
- this.meta.title = path__namespace$1.basename(filename);
246
+ this._meta.title = path__namespace$1.basename(filename);
241
247
  }
242
248
  language(value) {
243
- this.meta.language = value;
249
+ this._meta.language = value;
244
250
  return this;
245
251
  }
246
252
  title(value) {
247
- this.meta.title = value;
253
+ this._meta.title = value;
248
254
  return this;
249
255
  }
250
- style(href) {
251
- if (typeof href === "string") {
252
- this._head.push({
253
- tag: "link",
254
- attrs: {
255
- href,
256
- rel: "stylesheet",
257
- type: TextCSS
258
- },
259
- children: [""]
260
- });
261
- } else {
262
- this._head.push({
263
- tag: "link",
264
- attrs: {
265
- href: href.relative(this._filename),
266
- rel: "stylesheet",
267
- type: TextCSS
268
- },
269
- children: [""]
270
- });
256
+ style(...list) {
257
+ for (const href of list) {
258
+ if (typeof href === "string") {
259
+ this._head.push({
260
+ tag: "link",
261
+ attrs: {
262
+ href,
263
+ rel: "stylesheet",
264
+ type: TextCSS
265
+ },
266
+ children: [""]
267
+ });
268
+ } else {
269
+ this._head.push({
270
+ tag: "link",
271
+ attrs: {
272
+ href: href.relative(this._filename),
273
+ rel: "stylesheet",
274
+ type: TextCSS
275
+ },
276
+ children: [""]
277
+ });
278
+ }
271
279
  }
272
280
  return this;
273
281
  }
@@ -284,16 +292,16 @@ class XHTMLBuilder {
284
292
  html: {
285
293
  "@_xmlns": "http://www.w3.org/1999/xhtml",
286
294
  "@_xmlns:epub": "http://www.idpf.org/2007/ops",
287
- "@_lang": this.meta.language,
288
- "@_xml:lang": this.meta.language,
295
+ "@_lang": this._meta.language,
296
+ "@_xml:lang": this._meta.language,
289
297
  head: {
290
- title: this.meta.title,
298
+ title: this._meta.title,
291
299
  ...list(this._head)
292
300
  },
293
301
  body: list(this._body)
294
302
  }
295
303
  });
296
- return new XHTML(this._filename, this.meta, content);
304
+ return new XHTML(this._filename, this._meta, content);
297
305
  function build(node) {
298
306
  const attrs = Object.fromEntries(
299
307
  Object.entries(node.attrs ?? {}).map(([key, value]) => ["@_" + key, value])
@@ -311,10 +319,17 @@ class XHTMLBuilder {
311
319
  }
312
320
  return obj;
313
321
  }
314
- function list(nodes) {
322
+ function list(list2) {
315
323
  const obj = {};
324
+ const nodes = list2.flatMap((n) => n.tag === Fragment ? n.children ?? [] : [n]);
316
325
  for (const c of nodes) {
317
- if (c.tag in obj) {
326
+ if (typeof c === "string") {
327
+ if (obj["#text"]) {
328
+ obj["#text"] += c;
329
+ } else {
330
+ obj["#text"] = c;
331
+ }
332
+ } else if (c.tag in obj) {
318
333
  obj[c.tag].push(build(c));
319
334
  } else {
320
335
  obj[c.tag] = [build(c)];
@@ -325,14 +340,18 @@ class XHTMLBuilder {
325
340
  }
326
341
  }
327
342
 
328
- class Toc extends Item {
329
- constructor(file) {
330
- super(file, TextXHTML);
331
- this._builder = new XHTMLBuilder(this.filename());
343
+ class Toc extends XHTML {
344
+ constructor(file, meta, content) {
345
+ super(file, meta, content);
332
346
  this.update({ properties: "nav" });
333
347
  }
334
- generate(nav, { title = "Nav", heading = 1, titleAttrs = {}, head = [], body = [] } = {}) {
335
- const builder = new XHTMLBuilder(this.filename());
348
+ static from(xhtml) {
349
+ return new Toc(xhtml.filename(), xhtml.meta(), xhtml.content());
350
+ }
351
+ static generate(file, nav, { title = "Nav", heading = 1, titleAttrs = {}, builder } = {}) {
352
+ if (!builder) {
353
+ builder = new XHTMLBuilder(file);
354
+ }
336
355
  const root = {
337
356
  tag: "nav",
338
357
  attrs: {
@@ -342,17 +361,13 @@ class Toc extends Item {
342
361
  };
343
362
  root.children.push(h("h" + heading, titleAttrs, title));
344
363
  root.children.push(/* @__PURE__ */ h("ol", null, list(nav)));
345
- builder.title(title).body(root).head(...head).body(...body);
346
- return this._builder = builder;
364
+ return builder.body(root);
347
365
  function list(items) {
348
366
  return items.map(
349
367
  (i) => "page" in i ? /* @__PURE__ */ h("li", { ...i.attrs }, /* @__PURE__ */ h("a", { href: i.page.filename() }, i.title)) : "list" in i ? /* @__PURE__ */ h("li", { ...i.attrs }, /* @__PURE__ */ h("span", null, i.title), /* @__PURE__ */ h("ol", null, list(i.list))) : false
350
368
  );
351
369
  }
352
370
  }
353
- async bundle() {
354
- return this._builder.build().bundle();
355
- }
356
371
  }
357
372
 
358
373
  const defu = defu$1.createDefu((obj, key, value) => {
@@ -440,9 +455,11 @@ class PackageDocument {
440
455
  return this._toc;
441
456
  }
442
457
  setToc(nav, option = {}) {
443
- const toc = new Toc("nav.xhtml");
444
- toc.generate(nav, option).language(this._metadata.language).build();
445
- this._toc = toc;
458
+ const toc = Toc.generate("nav.xhtml", nav, option);
459
+ if (!option.builder) {
460
+ toc.title(option.title ?? "Nav").language(this._metadata.language);
461
+ }
462
+ this._toc = Toc.from(toc.build());
446
463
  return this;
447
464
  }
448
465
  // --- identifier ---
package/dist/index.d.ts CHANGED
@@ -120,22 +120,24 @@ interface HTMLMeta {
120
120
  title: string;
121
121
  }
122
122
  declare class XHTML extends Item {
123
- private meta;
124
- private content;
123
+ private _meta;
124
+ private _content;
125
125
  constructor(file: string, meta: HTMLMeta, content: string);
126
+ meta(): HTMLMeta;
126
127
  title(): string;
127
128
  language(): string;
129
+ content(): string;
128
130
  bundle(): Promise<Uint8Array>;
129
131
  }
130
132
  declare class XHTMLBuilder {
131
- private meta;
133
+ private _meta;
132
134
  private _filename;
133
135
  private _head;
134
136
  private _body;
135
137
  constructor(filename: string);
136
138
  language(value: string): this;
137
139
  title(value: string): this;
138
- style(href: string | Style): this;
140
+ style(...list: Array<string | Style>): this;
139
141
  head(...node: XHTMLNode[]): this;
140
142
  body(...node: XHTMLNode[]): this;
141
143
  build(): XHTML;
@@ -156,14 +158,12 @@ interface NavOption {
156
158
  title: string;
157
159
  heading: 1 | 2 | 3 | 4 | 5 | 6;
158
160
  titleAttrs: Record<string, string>;
159
- head: XHTMLNode[];
160
- body: XHTMLNode[];
161
+ builder?: XHTMLBuilder;
161
162
  }
162
- declare class Toc extends Item {
163
- private _builder;
164
- constructor(file: string);
165
- generate(nav: NavList, { title, heading, titleAttrs, head, body }?: Partial<NavOption>): XHTMLBuilder;
166
- bundle(): Promise<Uint8Array>;
163
+ declare class Toc extends XHTML {
164
+ constructor(file: string, meta: HTMLMeta, content: string);
165
+ static from(xhtml: XHTML): Toc;
166
+ static generate(file: string, nav: NavList, { title, heading, titleAttrs, builder }?: Partial<NavOption>): XHTMLBuilder;
167
167
  }
168
168
 
169
169
  interface Author {
@@ -249,6 +249,11 @@ interface Theme<P extends Record<string, PageTemplate<any>>> {
249
249
  pages: Prettify<{
250
250
  cover(file: string, props: {
251
251
  image: Image;
252
+ title?: string;
253
+ }): XHTMLBuilder;
254
+ nav(file: string, props: {
255
+ nav: NavList;
256
+ option: Partial<NavOption>;
252
257
  }): XHTMLBuilder;
253
258
  } & P>;
254
259
  }
@@ -258,4 +263,4 @@ declare const UnbuildPreset: (options?: {
258
263
  }) => BuildConfig;
259
264
  declare function Rollup(): Plugin;
260
265
 
261
- export { Author, BundleError, Epub, EpubIntrinsicElements, Fragment, HTML, Image, ImageExtension, ImageGif, ImageJpeg, ImageMediaType, ImagePng, ImageSvg, ImageWebp, Item, MIMETYPE, ManifestItem, ManifestItemRef, MediaType, NavList, NavOption, PackageDocument, PackageDocumentMeta, PageTemplate, Rollup, Style, TextCSS, TextXHTML, Theme, Toc, UnbuildPreset, XHTML, XHTMLBuilder, XHTMLNode, getImageMediaType, h };
266
+ export { Author, BundleError, Epub, EpubIntrinsicElements, Fragment, HTML, HTMLMeta, Image, ImageExtension, ImageGif, ImageJpeg, ImageMediaType, ImagePng, ImageSvg, ImageWebp, Item, MIMETYPE, ManifestItem, ManifestItemRef, MediaType, NavList, NavOption, PackageDocument, PackageDocumentMeta, PageTemplate, Rollup, Style, TextCSS, TextXHTML, Theme, Toc, UnbuildPreset, XHTML, XHTMLBuilder, XHTMLNode, getImageMediaType, h };
package/dist/index.mjs CHANGED
@@ -2,9 +2,22 @@ import * as path from 'node:path';
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { createDefu } from 'defu';
4
4
  import * as path$1 from 'pathe';
5
- import { promises, existsSync, mkdirSync } from 'node:fs';
6
5
  import { strToU8 } from 'fflate';
7
6
  import { XMLBuilder } from 'fast-xml-parser';
7
+ import { promises, existsSync, mkdirSync } from 'node:fs';
8
+
9
+ const Fragment = "Fragment";
10
+ function h(tag, attrs = {}, ...children) {
11
+ const sub = children.flatMap(
12
+ (c) => typeof c === "object" && !Array.isArray(c) && c.tag === Fragment ? c.children ?? [] : c
13
+ ).filter((c) => c !== void 0 && c !== null && c !== false);
14
+ const o = {
15
+ tag,
16
+ attrs: attrs ?? {},
17
+ children: sub
18
+ };
19
+ return o;
20
+ }
8
21
 
9
22
  const MIMETYPE = "application/epub+zip";
10
23
  const ImageGif = "image/gif";
@@ -33,19 +46,6 @@ function getImageMediaType(file) {
33
46
  }
34
47
  }
35
48
 
36
- const Fragment = "Fragment";
37
- function h(tag, attrs = {}, ...children) {
38
- const sub = children.flatMap(
39
- (c) => typeof c === "object" && !Array.isArray(c) && c.tag === Fragment ? c.children ?? [] : c
40
- ).filter((c) => c !== void 0 && c !== null && c !== false);
41
- const o = {
42
- tag,
43
- attrs: attrs ?? {},
44
- children: sub
45
- };
46
- return o;
47
- }
48
-
49
49
  class ManifestItem {
50
50
  constructor(href, id) {
51
51
  this.optional = {};
@@ -199,59 +199,67 @@ const builder = new XMLBuilder({
199
199
  class XHTML extends Item {
200
200
  constructor(file, meta, content) {
201
201
  super(file, TextXHTML);
202
- this.meta = meta;
203
- this.content = content;
202
+ this._meta = meta;
203
+ this._content = content;
204
+ }
205
+ meta() {
206
+ return this._meta;
204
207
  }
205
208
  title() {
206
- return this.meta.title;
209
+ return this._meta.title;
207
210
  }
208
211
  language() {
209
- return this.meta.language;
212
+ return this._meta.language;
213
+ }
214
+ content() {
215
+ return this._content;
210
216
  }
211
217
  async bundle() {
212
- return strToU8(this.content);
218
+ return strToU8(this._content);
213
219
  }
214
220
  }
215
221
  class XHTMLBuilder {
216
222
  constructor(filename) {
217
- this.meta = {
223
+ this._meta = {
218
224
  language: "en",
219
225
  title: ""
220
226
  };
221
227
  this._head = [];
222
228
  this._body = [];
223
229
  this._filename = filename;
224
- this.meta.title = path$1.basename(filename);
230
+ this._meta.title = path$1.basename(filename);
225
231
  }
226
232
  language(value) {
227
- this.meta.language = value;
233
+ this._meta.language = value;
228
234
  return this;
229
235
  }
230
236
  title(value) {
231
- this.meta.title = value;
237
+ this._meta.title = value;
232
238
  return this;
233
239
  }
234
- style(href) {
235
- if (typeof href === "string") {
236
- this._head.push({
237
- tag: "link",
238
- attrs: {
239
- href,
240
- rel: "stylesheet",
241
- type: TextCSS
242
- },
243
- children: [""]
244
- });
245
- } else {
246
- this._head.push({
247
- tag: "link",
248
- attrs: {
249
- href: href.relative(this._filename),
250
- rel: "stylesheet",
251
- type: TextCSS
252
- },
253
- children: [""]
254
- });
240
+ style(...list) {
241
+ for (const href of list) {
242
+ if (typeof href === "string") {
243
+ this._head.push({
244
+ tag: "link",
245
+ attrs: {
246
+ href,
247
+ rel: "stylesheet",
248
+ type: TextCSS
249
+ },
250
+ children: [""]
251
+ });
252
+ } else {
253
+ this._head.push({
254
+ tag: "link",
255
+ attrs: {
256
+ href: href.relative(this._filename),
257
+ rel: "stylesheet",
258
+ type: TextCSS
259
+ },
260
+ children: [""]
261
+ });
262
+ }
255
263
  }
256
264
  return this;
257
265
  }
@@ -268,16 +276,16 @@ class XHTMLBuilder {
268
276
  html: {
269
277
  "@_xmlns": "http://www.w3.org/1999/xhtml",
270
278
  "@_xmlns:epub": "http://www.idpf.org/2007/ops",
271
- "@_lang": this.meta.language,
272
- "@_xml:lang": this.meta.language,
279
+ "@_lang": this._meta.language,
280
+ "@_xml:lang": this._meta.language,
273
281
  head: {
274
- title: this.meta.title,
282
+ title: this._meta.title,
275
283
  ...list(this._head)
276
284
  },
277
285
  body: list(this._body)
278
286
  }
279
287
  });
280
- return new XHTML(this._filename, this.meta, content);
288
+ return new XHTML(this._filename, this._meta, content);
281
289
  function build(node) {
282
290
  const attrs = Object.fromEntries(
283
291
  Object.entries(node.attrs ?? {}).map(([key, value]) => ["@_" + key, value])
@@ -295,10 +303,17 @@ class XHTMLBuilder {
295
303
  }
296
304
  return obj;
297
305
  }
298
- function list(nodes) {
306
+ function list(list2) {
299
307
  const obj = {};
308
+ const nodes = list2.flatMap((n) => n.tag === Fragment ? n.children ?? [] : [n]);
300
309
  for (const c of nodes) {
301
- if (c.tag in obj) {
310
+ if (typeof c === "string") {
311
+ if (obj["#text"]) {
312
+ obj["#text"] += c;
313
+ } else {
314
+ obj["#text"] = c;
315
+ }
316
+ } else if (c.tag in obj) {
302
317
  obj[c.tag].push(build(c));
303
318
  } else {
304
319
  obj[c.tag] = [build(c)];
@@ -309,14 +324,18 @@ class XHTMLBuilder {
309
324
  }
310
325
  }
311
326
 
312
- class Toc extends Item {
313
- constructor(file) {
314
- super(file, TextXHTML);
315
- this._builder = new XHTMLBuilder(this.filename());
327
+ class Toc extends XHTML {
328
+ constructor(file, meta, content) {
329
+ super(file, meta, content);
316
330
  this.update({ properties: "nav" });
317
331
  }
318
- generate(nav, { title = "Nav", heading = 1, titleAttrs = {}, head = [], body = [] } = {}) {
319
- const builder = new XHTMLBuilder(this.filename());
332
+ static from(xhtml) {
333
+ return new Toc(xhtml.filename(), xhtml.meta(), xhtml.content());
334
+ }
335
+ static generate(file, nav, { title = "Nav", heading = 1, titleAttrs = {}, builder } = {}) {
336
+ if (!builder) {
337
+ builder = new XHTMLBuilder(file);
338
+ }
320
339
  const root = {
321
340
  tag: "nav",
322
341
  attrs: {
@@ -326,17 +345,13 @@ class Toc extends Item {
326
345
  };
327
346
  root.children.push(h("h" + heading, titleAttrs, title));
328
347
  root.children.push(/* @__PURE__ */ h("ol", null, list(nav)));
329
- builder.title(title).body(root).head(...head).body(...body);
330
- return this._builder = builder;
348
+ return builder.body(root);
331
349
  function list(items) {
332
350
  return items.map(
333
351
  (i) => "page" in i ? /* @__PURE__ */ h("li", { ...i.attrs }, /* @__PURE__ */ h("a", { href: i.page.filename() }, i.title)) : "list" in i ? /* @__PURE__ */ h("li", { ...i.attrs }, /* @__PURE__ */ h("span", null, i.title), /* @__PURE__ */ h("ol", null, list(i.list))) : false
334
352
  );
335
353
  }
336
354
  }
337
- async bundle() {
338
- return this._builder.build().bundle();
339
- }
340
355
  }
341
356
 
342
357
  const defu = createDefu((obj, key, value) => {
@@ -424,9 +439,11 @@ class PackageDocument {
424
439
  return this._toc;
425
440
  }
426
441
  setToc(nav, option = {}) {
427
- const toc = new Toc("nav.xhtml");
428
- toc.generate(nav, option).language(this._metadata.language).build();
429
- this._toc = toc;
442
+ const toc = Toc.generate("nav.xhtml", nav, option);
443
+ if (!option.builder) {
444
+ toc.title(option.title ?? "Nav").language(this._metadata.language);
445
+ }
446
+ this._toc = Toc.from(toc.build());
430
447
  return this;
431
448
  }
432
449
  // --- identifier ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epubook/core",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "ebook",