wp-epub-gen 0.4.0 → 0.4.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/build/index.cjs +42 -65
- package/build/index.d.ts +10 -0
- package/build/index.js +41 -64
- package/package.json +10 -3
- package/vite.config.ts +8 -4
package/build/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
3
|
const os = require("os");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const url = require("url");
|
|
@@ -316,13 +316,13 @@ const ALLOWED_XHTML11_TAGS = [
|
|
|
316
316
|
const ALLOWED_ATTRIBUTES_SET = new Set(ALLOWED_ATTRIBUTES);
|
|
317
317
|
const ALLOWED_XHTML11_TAGS_SET = new Set(ALLOWED_XHTML11_TAGS);
|
|
318
318
|
const SELF_CLOSING_TAGS = /* @__PURE__ */ new Set(["img", "br", "hr"]);
|
|
319
|
-
function initializeChapterInfo(content,
|
|
319
|
+
function initializeChapterInfo(content, index2, epubConfigs) {
|
|
320
320
|
const chapter = { ...content };
|
|
321
321
|
let { filename } = chapter;
|
|
322
322
|
if (!filename) {
|
|
323
323
|
let titleSlug = uslug(diacritics.remove(chapter.title || "no title"));
|
|
324
324
|
titleSlug = titleSlug.replace(/[/\\]/g, "_");
|
|
325
|
-
chapter.href = `${
|
|
325
|
+
chapter.href = `${index2}_${titleSlug}.xhtml`;
|
|
326
326
|
chapter.filePath = path.join(epubConfigs.dir, "OEBPS", chapter.href);
|
|
327
327
|
} else {
|
|
328
328
|
filename = safeFineName(filename);
|
|
@@ -334,7 +334,7 @@ function initializeChapterInfo(content, index, epubConfigs) {
|
|
|
334
334
|
chapter.filePath = path.join(epubConfigs.dir, "OEBPS", `${filename}.xhtml`);
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
-
chapter.id = `item_${
|
|
337
|
+
chapter.id = `item_${index2}`;
|
|
338
338
|
chapter.dir = path.dirname(chapter.filePath);
|
|
339
339
|
chapter.excludeFromToc = chapter.excludeFromToc || false;
|
|
340
340
|
chapter.beforeToc = chapter.beforeToc || false;
|
|
@@ -363,20 +363,24 @@ function loadAndProcessHtml(data) {
|
|
|
363
363
|
}
|
|
364
364
|
try {
|
|
365
365
|
let $ = cheerio__namespace.load(trimmedData, {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
366
|
+
xmlMode: true,
|
|
367
|
+
// @ts-ignore
|
|
368
|
+
decodeEntities: false,
|
|
369
|
+
lowerCaseTags: true,
|
|
370
|
+
recognizeSelfClosing: true,
|
|
371
|
+
lowerCaseAttributeNames: true
|
|
370
372
|
});
|
|
371
373
|
const body = $("body");
|
|
372
374
|
if (body.length) {
|
|
373
375
|
const html = body.html();
|
|
374
376
|
if (html) {
|
|
375
377
|
$ = cheerio__namespace.load(html, {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
xmlMode: true,
|
|
379
|
+
// @ts-ignore
|
|
380
|
+
decodeEntities: false,
|
|
381
|
+
lowerCaseTags: true,
|
|
382
|
+
recognizeSelfClosing: true,
|
|
383
|
+
lowerCaseAttributeNames: true
|
|
380
384
|
});
|
|
381
385
|
}
|
|
382
386
|
}
|
|
@@ -387,7 +391,7 @@ function loadAndProcessHtml(data) {
|
|
|
387
391
|
);
|
|
388
392
|
}
|
|
389
393
|
}
|
|
390
|
-
function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfigs,
|
|
394
|
+
function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfigs, index2) {
|
|
391
395
|
const allowedAttrsSet = ALLOWED_ATTRIBUTES_SET;
|
|
392
396
|
const allowedTagsSet = ALLOWED_XHTML11_TAGS_SET;
|
|
393
397
|
const selfClosingTags = SELF_CLOSING_TAGS;
|
|
@@ -417,7 +421,7 @@ function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfi
|
|
|
417
421
|
if (!allowedTagsSet.has(tagName)) {
|
|
418
422
|
if (epubConfigs.verbose) {
|
|
419
423
|
logger.warn(
|
|
420
|
-
`Warning (content[${
|
|
424
|
+
`Warning (content[${index2}]): ${tagName} tag isn't allowed on EPUB 2/XHTML 1.1 DTD.`
|
|
421
425
|
);
|
|
422
426
|
}
|
|
423
427
|
const child = $elem.html();
|
|
@@ -427,16 +431,16 @@ function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfi
|
|
|
427
431
|
});
|
|
428
432
|
}
|
|
429
433
|
function processImages($, chapter, epubConfigs) {
|
|
430
|
-
$("img").each((
|
|
434
|
+
$("img").each((index2, elem) => {
|
|
431
435
|
const url2 = $(elem).attr("src") || "";
|
|
432
436
|
if (!url2 || url2.trim().length === 0) {
|
|
433
|
-
logger.warn(`Image at index ${
|
|
437
|
+
logger.warn(`Image at index ${index2} in chapter has empty src attribute, removing element`);
|
|
434
438
|
$(elem).remove();
|
|
435
439
|
return;
|
|
436
440
|
}
|
|
437
441
|
const trimmedUrl = url2.trim();
|
|
438
442
|
try {
|
|
439
|
-
if (!trimmedUrl.match(/^(https?:\/\/|data:|\.\/|\/)/)) {
|
|
443
|
+
if (!trimmedUrl.match(/^(https?:\/\/|file:\/\/|data:|\.\/|\/)/)) {
|
|
440
444
|
logger.warn(`Image URL "${trimmedUrl}" appears to be invalid, but processing anyway`);
|
|
441
445
|
}
|
|
442
446
|
} catch (error) {
|
|
@@ -493,90 +497,56 @@ function processImages($, chapter, epubConfigs) {
|
|
|
493
497
|
}
|
|
494
498
|
});
|
|
495
499
|
}
|
|
496
|
-
function extractAndCleanHtmlContent(
|
|
500
|
+
function extractAndCleanHtmlContent($) {
|
|
497
501
|
let data;
|
|
498
502
|
if ($("body").length) {
|
|
499
503
|
data = $("body").html() || "";
|
|
500
504
|
} else {
|
|
501
505
|
data = $.root().html() || "";
|
|
502
506
|
}
|
|
503
|
-
|
|
504
|
-
return data.replace(
|
|
505
|
-
/<(br|hr|img|input|meta|area|base|col|embed|link|source|track|wbr)([^>]*?)><\/\1>/gi,
|
|
506
|
-
"<$1$2/>"
|
|
507
|
-
).replace(
|
|
508
|
-
new RegExp("<(br|hr|img|input|meta|area|base|col|embed|link|source|track|wbr)([^>]*?)(?<!\\/)>", "gi"),
|
|
509
|
-
"<$1$2/>"
|
|
510
|
-
);
|
|
511
|
-
}
|
|
512
|
-
const entityMap = /* @__PURE__ */ new Map();
|
|
513
|
-
const entityRegex = /&[a-zA-Z][a-zA-Z0-9]*;|&#[0-9]+;|&#x[0-9a-fA-F]+;/g;
|
|
514
|
-
const matches = Array.from(originalData.matchAll(entityRegex));
|
|
515
|
-
let processedOriginal = originalData;
|
|
516
|
-
const timestamp = Date.now();
|
|
517
|
-
const randomId = Math.random().toString(36).substring(2, 8);
|
|
518
|
-
const placeholderPrefix = `__ENTITY_${timestamp}_${randomId}_`;
|
|
519
|
-
for (let i = matches.length - 1; i >= 0; i--) {
|
|
520
|
-
const match = matches[i];
|
|
521
|
-
const placeholder = `${placeholderPrefix}${i}__`;
|
|
522
|
-
entityMap.set(placeholder, match[0]);
|
|
523
|
-
processedOriginal = processedOriginal.substring(0, match.index) + placeholder + processedOriginal.substring(match.index + match[0].length);
|
|
524
|
-
}
|
|
525
|
-
const $temp = cheerio__namespace.load(processedOriginal, {
|
|
526
|
-
xmlMode: false
|
|
527
|
-
});
|
|
528
|
-
let tempData;
|
|
529
|
-
if ($temp("body").length) {
|
|
530
|
-
tempData = $temp("body").html() || "";
|
|
531
|
-
} else {
|
|
532
|
-
tempData = $temp.root().html() || "";
|
|
533
|
-
}
|
|
534
|
-
for (const [placeholder, entity] of entityMap) {
|
|
535
|
-
tempData = tempData.replace(new RegExp(placeholder, "g"), entity);
|
|
536
|
-
}
|
|
537
|
-
return tempData.replace(
|
|
507
|
+
return data.replace(
|
|
538
508
|
/<(br|hr|img|input|meta|area|base|col|embed|link|source|track|wbr)([^>]*?)><\/\1>/gi,
|
|
539
509
|
"<$1$2/>"
|
|
540
510
|
).replace(
|
|
541
511
|
new RegExp("<(br|hr|img|input|meta|area|base|col|embed|link|source|track|wbr)([^>]*?)(?<!\\/)>", "gi"),
|
|
542
512
|
"<$1$2/>"
|
|
543
|
-
);
|
|
513
|
+
).replace(/<\/img\s*>/gi, "");
|
|
544
514
|
}
|
|
545
|
-
function processChildrenChapters(chapter,
|
|
515
|
+
function processChildrenChapters(chapter, index2, epubConfigs) {
|
|
546
516
|
if (Array.isArray(chapter.children)) {
|
|
547
517
|
chapter.children = chapter.children.map(
|
|
548
|
-
(content, idx) => parseContent(content, `${
|
|
518
|
+
(content, idx) => parseContent(content, `${index2}_${idx}`, epubConfigs)
|
|
549
519
|
);
|
|
550
520
|
}
|
|
551
521
|
}
|
|
552
|
-
function parseContent(content,
|
|
522
|
+
function parseContent(content, index2, epubConfigs) {
|
|
553
523
|
if (!content) {
|
|
554
524
|
throw new Error("Content cannot be null or undefined");
|
|
555
525
|
}
|
|
556
526
|
if (!content.data) {
|
|
557
|
-
logger.warn(`Chapter at index ${
|
|
527
|
+
logger.warn(`Chapter at index ${index2} has no data, using empty string`);
|
|
558
528
|
content.data = "";
|
|
559
529
|
}
|
|
560
|
-
const chapter = initializeChapterInfo(content,
|
|
530
|
+
const chapter = initializeChapterInfo(content, index2, epubConfigs);
|
|
561
531
|
normalizeAuthorInfo(chapter);
|
|
562
532
|
const allowedAttributes = getAllowedAttributes();
|
|
563
533
|
const allowedXhtml11Tags = getAllowedXhtml11Tags();
|
|
564
534
|
if (!chapter.data || chapter.data.trim().length === 0) {
|
|
565
|
-
logger.warn(`Chapter at index ${
|
|
535
|
+
logger.warn(`Chapter at index ${index2} has empty data, setting empty content`);
|
|
566
536
|
chapter.data = "";
|
|
567
537
|
} else {
|
|
568
538
|
let $;
|
|
569
539
|
try {
|
|
570
540
|
$ = loadAndProcessHtml(chapter.data);
|
|
571
541
|
} catch (error) {
|
|
572
|
-
logger.error(`Failed to process HTML for chapter ${
|
|
542
|
+
logger.error(`Failed to process HTML for chapter ${index2}: ${error}`);
|
|
573
543
|
$ = cheerio__namespace.load(`<div>${chapter.data}</div>`);
|
|
574
544
|
}
|
|
575
|
-
processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfigs,
|
|
545
|
+
processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfigs, index2);
|
|
576
546
|
processImages($, chapter, epubConfigs);
|
|
577
|
-
chapter.data = extractAndCleanHtmlContent(
|
|
547
|
+
chapter.data = extractAndCleanHtmlContent($);
|
|
578
548
|
}
|
|
579
|
-
processChildrenChapters(chapter,
|
|
549
|
+
processChildrenChapters(chapter, index2, epubConfigs);
|
|
580
550
|
return chapter;
|
|
581
551
|
}
|
|
582
552
|
util.promisify(fs.readFile);
|
|
@@ -1234,7 +1204,7 @@ function parseOptions(options) {
|
|
|
1234
1204
|
if (typeof data.author === "string") {
|
|
1235
1205
|
data.author = [data.author];
|
|
1236
1206
|
}
|
|
1237
|
-
data.content = options.content.map((content,
|
|
1207
|
+
data.content = options.content.map((content, index2) => parseContent(content, index2, data));
|
|
1238
1208
|
if (data.cover) {
|
|
1239
1209
|
data._coverMediaType = mime.getType(data.cover) || "";
|
|
1240
1210
|
data._coverExtension = mime.getExtension(data._coverMediaType) || "";
|
|
@@ -1245,6 +1215,7 @@ async function epubGen(options, configs) {
|
|
|
1245
1215
|
if (configs?.logger) {
|
|
1246
1216
|
logger.setLogger(configs.logger);
|
|
1247
1217
|
}
|
|
1218
|
+
logger.info("EpubGen started 101...");
|
|
1248
1219
|
options = { ...options };
|
|
1249
1220
|
const o = check(options);
|
|
1250
1221
|
const verbose = options.verbose !== false;
|
|
@@ -1274,6 +1245,12 @@ async function epubGen(options, configs) {
|
|
|
1274
1245
|
}
|
|
1275
1246
|
}
|
|
1276
1247
|
const gen = epubGen;
|
|
1248
|
+
const index = {
|
|
1249
|
+
epubGen,
|
|
1250
|
+
gen,
|
|
1251
|
+
errors
|
|
1252
|
+
};
|
|
1253
|
+
exports.default = index;
|
|
1277
1254
|
exports.epubGen = epubGen;
|
|
1278
1255
|
exports.errors = errors;
|
|
1279
1256
|
exports.gen = gen;
|
package/build/index.d.ts
CHANGED
|
@@ -2,4 +2,14 @@ import { IEpubGenOptions, IGenConfigs, IOut } from './types';
|
|
|
2
2
|
export declare function epubGen(options: IEpubGenOptions, configs?: IGenConfigs): Promise<IOut>;
|
|
3
3
|
export declare const gen: typeof epubGen;
|
|
4
4
|
export { errors } from './errors';
|
|
5
|
+
declare const _default: {
|
|
6
|
+
epubGen: typeof epubGen;
|
|
7
|
+
gen: typeof epubGen;
|
|
8
|
+
errors: {
|
|
9
|
+
no_output_path: string;
|
|
10
|
+
no_title: string;
|
|
11
|
+
no_content: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export default _default;
|
|
5
15
|
export type { IChapter, IChapterData, IEpubData, IEpubGenOptions, IEpubImage, IOut } from './types';
|
package/build/index.js
CHANGED
|
@@ -295,13 +295,13 @@ const ALLOWED_XHTML11_TAGS = [
|
|
|
295
295
|
const ALLOWED_ATTRIBUTES_SET = new Set(ALLOWED_ATTRIBUTES);
|
|
296
296
|
const ALLOWED_XHTML11_TAGS_SET = new Set(ALLOWED_XHTML11_TAGS);
|
|
297
297
|
const SELF_CLOSING_TAGS = /* @__PURE__ */ new Set(["img", "br", "hr"]);
|
|
298
|
-
function initializeChapterInfo(content,
|
|
298
|
+
function initializeChapterInfo(content, index2, epubConfigs) {
|
|
299
299
|
const chapter = { ...content };
|
|
300
300
|
let { filename } = chapter;
|
|
301
301
|
if (!filename) {
|
|
302
302
|
let titleSlug = uslug(remove(chapter.title || "no title"));
|
|
303
303
|
titleSlug = titleSlug.replace(/[/\\]/g, "_");
|
|
304
|
-
chapter.href = `${
|
|
304
|
+
chapter.href = `${index2}_${titleSlug}.xhtml`;
|
|
305
305
|
chapter.filePath = path.join(epubConfigs.dir, "OEBPS", chapter.href);
|
|
306
306
|
} else {
|
|
307
307
|
filename = safeFineName(filename);
|
|
@@ -313,7 +313,7 @@ function initializeChapterInfo(content, index, epubConfigs) {
|
|
|
313
313
|
chapter.filePath = path.join(epubConfigs.dir, "OEBPS", `${filename}.xhtml`);
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
-
chapter.id = `item_${
|
|
316
|
+
chapter.id = `item_${index2}`;
|
|
317
317
|
chapter.dir = path.dirname(chapter.filePath);
|
|
318
318
|
chapter.excludeFromToc = chapter.excludeFromToc || false;
|
|
319
319
|
chapter.beforeToc = chapter.beforeToc || false;
|
|
@@ -342,20 +342,24 @@ function loadAndProcessHtml(data) {
|
|
|
342
342
|
}
|
|
343
343
|
try {
|
|
344
344
|
let $ = cheerio.load(trimmedData, {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
345
|
+
xmlMode: true,
|
|
346
|
+
// @ts-ignore
|
|
347
|
+
decodeEntities: false,
|
|
348
|
+
lowerCaseTags: true,
|
|
349
|
+
recognizeSelfClosing: true,
|
|
350
|
+
lowerCaseAttributeNames: true
|
|
349
351
|
});
|
|
350
352
|
const body = $("body");
|
|
351
353
|
if (body.length) {
|
|
352
354
|
const html = body.html();
|
|
353
355
|
if (html) {
|
|
354
356
|
$ = cheerio.load(html, {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
357
|
+
xmlMode: true,
|
|
358
|
+
// @ts-ignore
|
|
359
|
+
decodeEntities: false,
|
|
360
|
+
lowerCaseTags: true,
|
|
361
|
+
recognizeSelfClosing: true,
|
|
362
|
+
lowerCaseAttributeNames: true
|
|
359
363
|
});
|
|
360
364
|
}
|
|
361
365
|
}
|
|
@@ -366,7 +370,7 @@ function loadAndProcessHtml(data) {
|
|
|
366
370
|
);
|
|
367
371
|
}
|
|
368
372
|
}
|
|
369
|
-
function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfigs,
|
|
373
|
+
function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfigs, index2) {
|
|
370
374
|
const allowedAttrsSet = ALLOWED_ATTRIBUTES_SET;
|
|
371
375
|
const allowedTagsSet = ALLOWED_XHTML11_TAGS_SET;
|
|
372
376
|
const selfClosingTags = SELF_CLOSING_TAGS;
|
|
@@ -396,7 +400,7 @@ function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfi
|
|
|
396
400
|
if (!allowedTagsSet.has(tagName)) {
|
|
397
401
|
if (epubConfigs.verbose) {
|
|
398
402
|
logger.warn(
|
|
399
|
-
`Warning (content[${
|
|
403
|
+
`Warning (content[${index2}]): ${tagName} tag isn't allowed on EPUB 2/XHTML 1.1 DTD.`
|
|
400
404
|
);
|
|
401
405
|
}
|
|
402
406
|
const child = $elem.html();
|
|
@@ -406,16 +410,16 @@ function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfi
|
|
|
406
410
|
});
|
|
407
411
|
}
|
|
408
412
|
function processImages($, chapter, epubConfigs) {
|
|
409
|
-
$("img").each((
|
|
413
|
+
$("img").each((index2, elem) => {
|
|
410
414
|
const url = $(elem).attr("src") || "";
|
|
411
415
|
if (!url || url.trim().length === 0) {
|
|
412
|
-
logger.warn(`Image at index ${
|
|
416
|
+
logger.warn(`Image at index ${index2} in chapter has empty src attribute, removing element`);
|
|
413
417
|
$(elem).remove();
|
|
414
418
|
return;
|
|
415
419
|
}
|
|
416
420
|
const trimmedUrl = url.trim();
|
|
417
421
|
try {
|
|
418
|
-
if (!trimmedUrl.match(/^(https?:\/\/|data:|\.\/|\/)/)) {
|
|
422
|
+
if (!trimmedUrl.match(/^(https?:\/\/|file:\/\/|data:|\.\/|\/)/)) {
|
|
419
423
|
logger.warn(`Image URL "${trimmedUrl}" appears to be invalid, but processing anyway`);
|
|
420
424
|
}
|
|
421
425
|
} catch (error) {
|
|
@@ -472,90 +476,56 @@ function processImages($, chapter, epubConfigs) {
|
|
|
472
476
|
}
|
|
473
477
|
});
|
|
474
478
|
}
|
|
475
|
-
function extractAndCleanHtmlContent(
|
|
479
|
+
function extractAndCleanHtmlContent($) {
|
|
476
480
|
let data;
|
|
477
481
|
if ($("body").length) {
|
|
478
482
|
data = $("body").html() || "";
|
|
479
483
|
} else {
|
|
480
484
|
data = $.root().html() || "";
|
|
481
485
|
}
|
|
482
|
-
|
|
483
|
-
return data.replace(
|
|
484
|
-
/<(br|hr|img|input|meta|area|base|col|embed|link|source|track|wbr)([^>]*?)><\/\1>/gi,
|
|
485
|
-
"<$1$2/>"
|
|
486
|
-
).replace(
|
|
487
|
-
new RegExp("<(br|hr|img|input|meta|area|base|col|embed|link|source|track|wbr)([^>]*?)(?<!\\/)>", "gi"),
|
|
488
|
-
"<$1$2/>"
|
|
489
|
-
);
|
|
490
|
-
}
|
|
491
|
-
const entityMap = /* @__PURE__ */ new Map();
|
|
492
|
-
const entityRegex = /&[a-zA-Z][a-zA-Z0-9]*;|&#[0-9]+;|&#x[0-9a-fA-F]+;/g;
|
|
493
|
-
const matches = Array.from(originalData.matchAll(entityRegex));
|
|
494
|
-
let processedOriginal = originalData;
|
|
495
|
-
const timestamp = Date.now();
|
|
496
|
-
const randomId = Math.random().toString(36).substring(2, 8);
|
|
497
|
-
const placeholderPrefix = `__ENTITY_${timestamp}_${randomId}_`;
|
|
498
|
-
for (let i = matches.length - 1; i >= 0; i--) {
|
|
499
|
-
const match = matches[i];
|
|
500
|
-
const placeholder = `${placeholderPrefix}${i}__`;
|
|
501
|
-
entityMap.set(placeholder, match[0]);
|
|
502
|
-
processedOriginal = processedOriginal.substring(0, match.index) + placeholder + processedOriginal.substring(match.index + match[0].length);
|
|
503
|
-
}
|
|
504
|
-
const $temp = cheerio.load(processedOriginal, {
|
|
505
|
-
xmlMode: false
|
|
506
|
-
});
|
|
507
|
-
let tempData;
|
|
508
|
-
if ($temp("body").length) {
|
|
509
|
-
tempData = $temp("body").html() || "";
|
|
510
|
-
} else {
|
|
511
|
-
tempData = $temp.root().html() || "";
|
|
512
|
-
}
|
|
513
|
-
for (const [placeholder, entity] of entityMap) {
|
|
514
|
-
tempData = tempData.replace(new RegExp(placeholder, "g"), entity);
|
|
515
|
-
}
|
|
516
|
-
return tempData.replace(
|
|
486
|
+
return data.replace(
|
|
517
487
|
/<(br|hr|img|input|meta|area|base|col|embed|link|source|track|wbr)([^>]*?)><\/\1>/gi,
|
|
518
488
|
"<$1$2/>"
|
|
519
489
|
).replace(
|
|
520
490
|
new RegExp("<(br|hr|img|input|meta|area|base|col|embed|link|source|track|wbr)([^>]*?)(?<!\\/)>", "gi"),
|
|
521
491
|
"<$1$2/>"
|
|
522
|
-
);
|
|
492
|
+
).replace(/<\/img\s*>/gi, "");
|
|
523
493
|
}
|
|
524
|
-
function processChildrenChapters(chapter,
|
|
494
|
+
function processChildrenChapters(chapter, index2, epubConfigs) {
|
|
525
495
|
if (Array.isArray(chapter.children)) {
|
|
526
496
|
chapter.children = chapter.children.map(
|
|
527
|
-
(content, idx) => parseContent(content, `${
|
|
497
|
+
(content, idx) => parseContent(content, `${index2}_${idx}`, epubConfigs)
|
|
528
498
|
);
|
|
529
499
|
}
|
|
530
500
|
}
|
|
531
|
-
function parseContent(content,
|
|
501
|
+
function parseContent(content, index2, epubConfigs) {
|
|
532
502
|
if (!content) {
|
|
533
503
|
throw new Error("Content cannot be null or undefined");
|
|
534
504
|
}
|
|
535
505
|
if (!content.data) {
|
|
536
|
-
logger.warn(`Chapter at index ${
|
|
506
|
+
logger.warn(`Chapter at index ${index2} has no data, using empty string`);
|
|
537
507
|
content.data = "";
|
|
538
508
|
}
|
|
539
|
-
const chapter = initializeChapterInfo(content,
|
|
509
|
+
const chapter = initializeChapterInfo(content, index2, epubConfigs);
|
|
540
510
|
normalizeAuthorInfo(chapter);
|
|
541
511
|
const allowedAttributes = getAllowedAttributes();
|
|
542
512
|
const allowedXhtml11Tags = getAllowedXhtml11Tags();
|
|
543
513
|
if (!chapter.data || chapter.data.trim().length === 0) {
|
|
544
|
-
logger.warn(`Chapter at index ${
|
|
514
|
+
logger.warn(`Chapter at index ${index2} has empty data, setting empty content`);
|
|
545
515
|
chapter.data = "";
|
|
546
516
|
} else {
|
|
547
517
|
let $;
|
|
548
518
|
try {
|
|
549
519
|
$ = loadAndProcessHtml(chapter.data);
|
|
550
520
|
} catch (error) {
|
|
551
|
-
logger.error(`Failed to process HTML for chapter ${
|
|
521
|
+
logger.error(`Failed to process HTML for chapter ${index2}: ${error}`);
|
|
552
522
|
$ = cheerio.load(`<div>${chapter.data}</div>`);
|
|
553
523
|
}
|
|
554
|
-
processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfigs,
|
|
524
|
+
processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfigs, index2);
|
|
555
525
|
processImages($, chapter, epubConfigs);
|
|
556
|
-
chapter.data = extractAndCleanHtmlContent(
|
|
526
|
+
chapter.data = extractAndCleanHtmlContent($);
|
|
557
527
|
}
|
|
558
|
-
processChildrenChapters(chapter,
|
|
528
|
+
processChildrenChapters(chapter, index2, epubConfigs);
|
|
559
529
|
return chapter;
|
|
560
530
|
}
|
|
561
531
|
promisify(fs.readFile);
|
|
@@ -1213,7 +1183,7 @@ function parseOptions(options) {
|
|
|
1213
1183
|
if (typeof data.author === "string") {
|
|
1214
1184
|
data.author = [data.author];
|
|
1215
1185
|
}
|
|
1216
|
-
data.content = options.content.map((content,
|
|
1186
|
+
data.content = options.content.map((content, index2) => parseContent(content, index2, data));
|
|
1217
1187
|
if (data.cover) {
|
|
1218
1188
|
data._coverMediaType = mime.getType(data.cover) || "";
|
|
1219
1189
|
data._coverExtension = mime.getExtension(data._coverMediaType) || "";
|
|
@@ -1224,6 +1194,7 @@ async function epubGen(options, configs) {
|
|
|
1224
1194
|
if (configs?.logger) {
|
|
1225
1195
|
logger.setLogger(configs.logger);
|
|
1226
1196
|
}
|
|
1197
|
+
logger.info("EpubGen started 101...");
|
|
1227
1198
|
options = { ...options };
|
|
1228
1199
|
const o = check(options);
|
|
1229
1200
|
const verbose = options.verbose !== false;
|
|
@@ -1253,7 +1224,13 @@ async function epubGen(options, configs) {
|
|
|
1253
1224
|
}
|
|
1254
1225
|
}
|
|
1255
1226
|
const gen = epubGen;
|
|
1227
|
+
const index = {
|
|
1228
|
+
epubGen,
|
|
1229
|
+
gen,
|
|
1230
|
+
errors
|
|
1231
|
+
};
|
|
1256
1232
|
export {
|
|
1233
|
+
index as default,
|
|
1257
1234
|
epubGen,
|
|
1258
1235
|
errors,
|
|
1259
1236
|
gen
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wp-epub-gen",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Epub generator.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "build/index.
|
|
7
|
-
"module": "build/index.
|
|
6
|
+
"main": "build/index.cjs",
|
|
7
|
+
"module": "build/index.js",
|
|
8
8
|
"types": "build/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./build/index.d.ts",
|
|
12
|
+
"import": "./build/index.js",
|
|
13
|
+
"require": "./build/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
9
16
|
"scripts": {
|
|
10
17
|
"tsc": "tsc",
|
|
11
18
|
"test": "vitest --watch=false run",
|
package/vite.config.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'fs'
|
|
1
2
|
import * as path from 'path'
|
|
2
3
|
import { defineConfig } from 'vite'
|
|
3
4
|
import dts from 'vite-plugin-dts'
|
|
4
5
|
import tsconfigPaths from 'vite-tsconfig-paths'
|
|
5
|
-
import { readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'fs'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* 生成模板文件的 TypeScript 代码
|
|
@@ -76,15 +76,19 @@ export default defineConfig({
|
|
|
76
76
|
base: './',
|
|
77
77
|
build: {
|
|
78
78
|
rollupOptions: {
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
output: {
|
|
80
|
+
exports: 'named',
|
|
81
81
|
},
|
|
82
82
|
},
|
|
83
83
|
lib: {
|
|
84
84
|
entry: path.join(__dirname, 'src', 'index.ts'),
|
|
85
85
|
name: 'index',
|
|
86
86
|
formats: ['cjs', 'es'],
|
|
87
|
-
fileName: (format) =>
|
|
87
|
+
// fileName: (format) => {
|
|
88
|
+
// if (format === 'es') return 'index.mjs'
|
|
89
|
+
// if (format === 'cjs') return 'index.js'
|
|
90
|
+
// return `index.${format}`
|
|
91
|
+
// },
|
|
88
92
|
},
|
|
89
93
|
outDir: path.join(__dirname, 'build'),
|
|
90
94
|
minify: false,
|