@vivliostyle/cli 10.3.1 → 10.4.0
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/{chunk-MU7JCDMK.js → chunk-4DTPH2XX.js} +2 -2
- package/dist/{chunk-PYPAYBFL.js → chunk-DEJL63H2.js} +29 -22
- package/dist/chunk-DEJL63H2.js.map +1 -0
- package/dist/{chunk-OAFXM4ES.js → chunk-DK3HFVHX.js} +27 -51
- package/dist/chunk-DK3HFVHX.js.map +1 -0
- package/dist/{chunk-7GIJVX4M.js → chunk-J2YGULSR.js} +45 -7
- package/dist/chunk-J2YGULSR.js.map +1 -0
- package/dist/{chunk-ERDN47XG.js → chunk-L4PJ2SP3.js} +17 -13
- package/dist/chunk-L4PJ2SP3.js.map +1 -0
- package/dist/{chunk-LWMSAGHL.js → chunk-LE3QOQ5F.js} +11 -9
- package/dist/{chunk-LWMSAGHL.js.map → chunk-LE3QOQ5F.js.map} +1 -1
- package/dist/{chunk-C4HQHRXQ.js → chunk-P33ELNYE.js} +323 -379
- package/dist/chunk-P33ELNYE.js.map +1 -0
- package/dist/chunk-Q4EIXB5V.js +330 -0
- package/dist/chunk-Q4EIXB5V.js.map +1 -0
- package/dist/{chunk-LGOHUEEQ.js → chunk-RLV2H3QB.js} +11 -11
- package/dist/chunk-RLV2H3QB.js.map +1 -0
- package/dist/{chunk-DBK27BAR.js → chunk-VAPIKX4A.js} +300 -502
- package/dist/chunk-VAPIKX4A.js.map +1 -0
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/build.js +10 -9
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/create.js +7 -6
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/init.js +7 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/preview.js +9 -8
- package/dist/commands/preview.js.map +1 -1
- package/dist/config/schema.d.ts +13247 -1767
- package/dist/config/schema.js +7 -2
- package/dist/constants.d.ts +250 -0
- package/dist/constants.js +60 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/vite-adapter.js +6 -5
- package/package.json +15 -11
- package/dist/chunk-7GIJVX4M.js.map +0 -1
- package/dist/chunk-C4HQHRXQ.js.map +0 -1
- package/dist/chunk-DBK27BAR.js.map +0 -1
- package/dist/chunk-ERDN47XG.js.map +0 -1
- package/dist/chunk-LGOHUEEQ.js.map +0 -1
- package/dist/chunk-OAFXM4ES.js.map +0 -1
- package/dist/chunk-PYPAYBFL.js.map +0 -1
- /package/dist/{chunk-MU7JCDMK.js.map → chunk-4DTPH2XX.js.map} +0 -0
|
@@ -2,42 +2,44 @@ import {
|
|
|
2
2
|
importNodeModule
|
|
3
3
|
} from "./chunk-ECEGM36O.js";
|
|
4
4
|
import {
|
|
5
|
-
DetailError,
|
|
6
5
|
GlobMatcher,
|
|
6
|
+
getAssetMatcher,
|
|
7
|
+
getWebPubResourceMatcher,
|
|
8
|
+
loadVivliostyleConfig,
|
|
9
|
+
locateVivliostyleConfig,
|
|
10
|
+
setupConfigFromFlags
|
|
11
|
+
} from "./chunk-Q4EIXB5V.js";
|
|
12
|
+
import {
|
|
13
|
+
DetailError,
|
|
7
14
|
Logger,
|
|
8
15
|
assertPubManifestSchema,
|
|
16
|
+
cliVersion,
|
|
9
17
|
cwd,
|
|
10
18
|
debounce,
|
|
11
19
|
detectBrowserPlatform,
|
|
12
|
-
getAssetMatcher,
|
|
13
20
|
getCacheDir,
|
|
14
21
|
getDefaultBrowserTag,
|
|
15
22
|
getDefaultEpubOpfPath,
|
|
16
23
|
getEpubRootDir,
|
|
17
24
|
getFormattedError,
|
|
18
25
|
getOsLocale,
|
|
19
|
-
getWebPubResourceMatcher,
|
|
20
26
|
isInContainer,
|
|
21
27
|
isRunningOnWSL,
|
|
22
28
|
isValidUri,
|
|
23
29
|
openEpub,
|
|
24
|
-
parseJsonc,
|
|
25
30
|
pathContains,
|
|
26
31
|
pathEquals,
|
|
27
|
-
prettifySchemaError,
|
|
28
32
|
readJSON,
|
|
29
33
|
registerExitHandler,
|
|
30
34
|
runExitHandlers,
|
|
31
|
-
setupConfigFromFlags,
|
|
32
35
|
statFileSync,
|
|
33
36
|
touchTmpFile,
|
|
34
37
|
useTmpDirectory,
|
|
38
|
+
viewerRoot,
|
|
35
39
|
writeFileIfChanged
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import {
|
|
38
|
-
VivliostyleConfigSchema
|
|
39
|
-
} from "./chunk-7GIJVX4M.js";
|
|
40
|
+
} from "./chunk-VAPIKX4A.js";
|
|
40
41
|
import {
|
|
42
|
+
CMYK_RESERVE_MAP_FILENAME,
|
|
41
43
|
CONTAINER_LOCAL_HOSTNAME,
|
|
42
44
|
CONTAINER_URL,
|
|
43
45
|
COVER_HTML_FILENAME,
|
|
@@ -54,122 +56,13 @@ import {
|
|
|
54
56
|
TOC_FILENAME,
|
|
55
57
|
TOC_TITLE,
|
|
56
58
|
VIEWER_ROOT_PATH,
|
|
57
|
-
XML_DECLARATION
|
|
58
|
-
|
|
59
|
-
viewerRoot
|
|
60
|
-
} from "./chunk-OAFXM4ES.js";
|
|
59
|
+
XML_DECLARATION
|
|
60
|
+
} from "./chunk-DK3HFVHX.js";
|
|
61
61
|
import {
|
|
62
62
|
__callDispose,
|
|
63
63
|
__using
|
|
64
64
|
} from "./chunk-I7BWSAN6.js";
|
|
65
65
|
|
|
66
|
-
// src/config/load.ts
|
|
67
|
-
import fs from "node:fs";
|
|
68
|
-
import { createRequire } from "node:module";
|
|
69
|
-
import { pathToFileURL } from "node:url";
|
|
70
|
-
import upath from "upath";
|
|
71
|
-
import * as v from "valibot";
|
|
72
|
-
var require2 = createRequire(import.meta.url);
|
|
73
|
-
function locateVivliostyleConfig({
|
|
74
|
-
config,
|
|
75
|
-
cwd: cwd2 = cwd
|
|
76
|
-
}) {
|
|
77
|
-
if (config) {
|
|
78
|
-
return upath.resolve(cwd2, config);
|
|
79
|
-
}
|
|
80
|
-
return [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts", ".json"].map((ext) => upath.join(cwd2, `vivliostyle.config${ext}`)).find((p) => fs.existsSync(p));
|
|
81
|
-
}
|
|
82
|
-
async function loadVivliostyleConfig({
|
|
83
|
-
config,
|
|
84
|
-
configData,
|
|
85
|
-
cwd: cwd2
|
|
86
|
-
}) {
|
|
87
|
-
if (configData) {
|
|
88
|
-
return v.parse(VivliostyleConfigSchema, configData);
|
|
89
|
-
}
|
|
90
|
-
const absPath = locateVivliostyleConfig({ config, cwd: cwd2 });
|
|
91
|
-
if (!absPath) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
let parsedConfig;
|
|
95
|
-
let jsonRaw;
|
|
96
|
-
try {
|
|
97
|
-
if (upath.extname(absPath) === ".json") {
|
|
98
|
-
jsonRaw = fs.readFileSync(absPath, "utf8");
|
|
99
|
-
parsedConfig = parseJsonc(jsonRaw);
|
|
100
|
-
} else {
|
|
101
|
-
delete require2.cache[require2.resolve(absPath)];
|
|
102
|
-
const url = pathToFileURL(absPath);
|
|
103
|
-
url.search = `version=${Date.now()}`;
|
|
104
|
-
parsedConfig = (await import(
|
|
105
|
-
/* @vite-ignore */
|
|
106
|
-
url.href
|
|
107
|
-
)).default;
|
|
108
|
-
jsonRaw = JSON.stringify(parsedConfig, null, 2);
|
|
109
|
-
}
|
|
110
|
-
} catch (error) {
|
|
111
|
-
const thrownError = error;
|
|
112
|
-
throw new DetailError(
|
|
113
|
-
`An error occurred on loading a config file: ${absPath}`,
|
|
114
|
-
thrownError.stack ?? thrownError.message
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
const result = v.safeParse(VivliostyleConfigSchema, parsedConfig);
|
|
118
|
-
if (result.success) {
|
|
119
|
-
const { tasks, inlineOptions } = result.output;
|
|
120
|
-
return {
|
|
121
|
-
tasks,
|
|
122
|
-
inlineOptions: {
|
|
123
|
-
...inlineOptions,
|
|
124
|
-
cwd: cwd2 ?? cwd,
|
|
125
|
-
config: absPath
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
} else {
|
|
129
|
-
const errorString = prettifySchemaError(jsonRaw, result.issues);
|
|
130
|
-
throw new DetailError(
|
|
131
|
-
`Validation of vivliostyle config failed. Please check the schema: ${config}`,
|
|
132
|
-
errorString
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
function warnDeprecatedConfig(config) {
|
|
137
|
-
if (config.tasks.some((task) => task.includeAssets)) {
|
|
138
|
-
Logger.logWarn(
|
|
139
|
-
"'includeAssets' property of Vivliostyle config was deprecated and will be removed in a future release. Please use 'copyAsset.includes' property instead."
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
if (config.tasks.some((task) => task.tocTitle)) {
|
|
143
|
-
Logger.logWarn(
|
|
144
|
-
"'tocTitle' property of Vivliostyle config was deprecated and will be removed in a future release. Please use 'toc.title' property instead."
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
if (config.tasks.some((task) => task.http)) {
|
|
148
|
-
Logger.logWarn(
|
|
149
|
-
"'http' property of Vivliostyle config was deprecated and will be removed in a future release. This option is enabled by default, and the file protocol is no longer supported."
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
if (config.tasks.some((task) => task.pressReady !== void 0)) {
|
|
153
|
-
Logger.logWarn(
|
|
154
|
-
`'pressReady' property of Vivliostyle config was deprecated and will be removed in a future release. Please use 'pdfPostprocess.preflight: "press-ready"' property instead.`
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
if (config.tasks.some(
|
|
158
|
-
(task) => task.output && [task.output].flat().some((o) => o.preflight)
|
|
159
|
-
)) {
|
|
160
|
-
Logger.logWarn(
|
|
161
|
-
"'preflight' property of output config was deprecated and will be removed in a future release. Please use 'pdfPostprocess.preflight' property instead."
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
if (config.tasks.some(
|
|
165
|
-
(task) => task.output && [task.output].flat().some((o) => o.preflightOption)
|
|
166
|
-
)) {
|
|
167
|
-
Logger.logWarn(
|
|
168
|
-
"'preflightOption' property of output config was deprecated and will be removed in a future release. Please use 'pdfPostprocess.preflightOption' property instead."
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
66
|
// src/config/merge.ts
|
|
174
67
|
var pruneObject = (obj) => {
|
|
175
68
|
const ret = { ...obj };
|
|
@@ -265,17 +158,17 @@ import {
|
|
|
265
158
|
VFM
|
|
266
159
|
} from "@vivliostyle/vfm";
|
|
267
160
|
import { lookup as mime } from "mime-types";
|
|
268
|
-
import
|
|
269
|
-
import { fileURLToPath, pathToFileURL
|
|
161
|
+
import fs2 from "node:fs";
|
|
162
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
270
163
|
import npa from "npm-package-arg";
|
|
271
164
|
import { globSync } from "tinyglobby";
|
|
272
|
-
import
|
|
165
|
+
import upath from "upath";
|
|
273
166
|
|
|
274
167
|
// src/processor/markdown.ts
|
|
275
|
-
import
|
|
168
|
+
import fs from "node:fs";
|
|
276
169
|
import vfile from "vfile";
|
|
277
170
|
async function processMarkdown(documentProcessorFactory, documentMetadataReader, filepath, options = {}) {
|
|
278
|
-
const markdownString =
|
|
171
|
+
const markdownString = fs.readFileSync(filepath, "utf8");
|
|
279
172
|
const processor = documentProcessorFactory(
|
|
280
173
|
options,
|
|
281
174
|
documentMetadataReader(markdownString)
|
|
@@ -286,7 +179,7 @@ async function processMarkdown(documentProcessorFactory, documentMetadataReader,
|
|
|
286
179
|
return processed;
|
|
287
180
|
}
|
|
288
181
|
function readMarkdownMetadata(filepath, documentMetadataReader) {
|
|
289
|
-
return documentMetadataReader(
|
|
182
|
+
return documentMetadataReader(fs.readFileSync(filepath, "utf8"));
|
|
290
183
|
}
|
|
291
184
|
|
|
292
185
|
// src/config/resolve.ts
|
|
@@ -298,6 +191,29 @@ var manuscriptMediaTypes = [
|
|
|
298
191
|
// a special MIME type indicates that a custom processor is used
|
|
299
192
|
"text/x-vivliostyle-custom"
|
|
300
193
|
];
|
|
194
|
+
function parseHexColor(hex) {
|
|
195
|
+
let r, g, b;
|
|
196
|
+
if (hex.length === 4 || hex.length === 5) {
|
|
197
|
+
r = parseInt(hex[1] + hex[1], 16);
|
|
198
|
+
g = parseInt(hex[2] + hex[2], 16);
|
|
199
|
+
b = parseInt(hex[3] + hex[3], 16);
|
|
200
|
+
} else {
|
|
201
|
+
r = parseInt(hex.slice(1, 3), 16);
|
|
202
|
+
g = parseInt(hex.slice(3, 5), 16);
|
|
203
|
+
b = parseInt(hex.slice(5, 7), 16);
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
r: Math.round(r / 255 * 1e4),
|
|
207
|
+
g: Math.round(g / 255 * 1e4),
|
|
208
|
+
b: Math.round(b / 255 * 1e4)
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function resolveMapEntries(entries) {
|
|
212
|
+
return entries.map(([rgb, cmyk]) => {
|
|
213
|
+
const resolvedRgb = typeof rgb === "string" ? parseHexColor(rgb) : rgb;
|
|
214
|
+
return [resolvedRgb, cmyk];
|
|
215
|
+
});
|
|
216
|
+
}
|
|
301
217
|
var UseTemporaryServerRoot = Symbol("UseTemporaryServerRoot");
|
|
302
218
|
var DEFAULT_ASSET_EXTENSIONS = [
|
|
303
219
|
"css",
|
|
@@ -319,7 +235,7 @@ function isManuscriptMediaType(mediaType) {
|
|
|
319
235
|
}
|
|
320
236
|
var htmlExtensions = [".html", ".htm", ".xhtml", ".xht"];
|
|
321
237
|
function toHtmlExtension(filename) {
|
|
322
|
-
const ext =
|
|
238
|
+
const ext = upath.extname(filename).toLowerCase();
|
|
323
239
|
if (htmlExtensions.includes(
|
|
324
240
|
// @ts-expect-error check membership
|
|
325
241
|
ext
|
|
@@ -355,18 +271,18 @@ function parseTheme({
|
|
|
355
271
|
if (isValidUri(specifier)) {
|
|
356
272
|
return {
|
|
357
273
|
type: "uri",
|
|
358
|
-
name:
|
|
274
|
+
name: upath.basename(specifier),
|
|
359
275
|
location: specifier
|
|
360
276
|
};
|
|
361
277
|
}
|
|
362
|
-
const stylePath =
|
|
363
|
-
if (
|
|
364
|
-
const sourceRelPath =
|
|
278
|
+
const stylePath = upath.resolve(context, specifier);
|
|
279
|
+
if (fs2.existsSync(stylePath) && stylePath.endsWith(".css")) {
|
|
280
|
+
const sourceRelPath = upath.relative(context, stylePath);
|
|
365
281
|
return {
|
|
366
282
|
type: "file",
|
|
367
|
-
name:
|
|
283
|
+
name: upath.basename(specifier),
|
|
368
284
|
source: stylePath,
|
|
369
|
-
location:
|
|
285
|
+
location: upath.resolve(workspaceDir, sourceRelPath)
|
|
370
286
|
};
|
|
371
287
|
}
|
|
372
288
|
const parsed = parsePackageName(specifier, context);
|
|
@@ -379,9 +295,9 @@ function parseTheme({
|
|
|
379
295
|
let name = parsed.name;
|
|
380
296
|
let resolvedSpecifier = specifier;
|
|
381
297
|
if (parsed.type === "directory" && parsed.fetchSpec) {
|
|
382
|
-
const pkgJsonPath =
|
|
383
|
-
if (
|
|
384
|
-
const packageJson = JSON.parse(
|
|
298
|
+
const pkgJsonPath = upath.join(parsed.fetchSpec, "package.json");
|
|
299
|
+
if (fs2.existsSync(pkgJsonPath)) {
|
|
300
|
+
const packageJson = JSON.parse(fs2.readFileSync(pkgJsonPath, "utf8"));
|
|
385
301
|
name = packageJson.name;
|
|
386
302
|
resolvedSpecifier = parsed.fetchSpec;
|
|
387
303
|
}
|
|
@@ -393,7 +309,7 @@ function parseTheme({
|
|
|
393
309
|
type: "package",
|
|
394
310
|
name,
|
|
395
311
|
specifier: resolvedSpecifier,
|
|
396
|
-
location:
|
|
312
|
+
location: upath.join(themesDir, "node_modules", name),
|
|
397
313
|
registry: Boolean(parsed.registry),
|
|
398
314
|
importPath
|
|
399
315
|
};
|
|
@@ -420,7 +336,7 @@ function parseFileMetadata({
|
|
|
420
336
|
themesDir,
|
|
421
337
|
documentMetadataReader
|
|
422
338
|
}) {
|
|
423
|
-
const sourceDir =
|
|
339
|
+
const sourceDir = upath.dirname(sourcePath);
|
|
424
340
|
let title;
|
|
425
341
|
let themes;
|
|
426
342
|
if (documentMetadataReader) {
|
|
@@ -439,7 +355,7 @@ function parseFileMetadata({
|
|
|
439
355
|
);
|
|
440
356
|
}
|
|
441
357
|
} else if (contentType === "text/html" || contentType === "application/xhtml+xml") {
|
|
442
|
-
const content =
|
|
358
|
+
const content = fs2.readFileSync(sourcePath, "utf8");
|
|
443
359
|
title = content.match(/<title>([^<]*)<\/title>/)?.[1] || void 0;
|
|
444
360
|
}
|
|
445
361
|
return { title, themes };
|
|
@@ -451,23 +367,23 @@ function parseCustomStyle({
|
|
|
451
367
|
if (isValidUri(customStyle)) {
|
|
452
368
|
return customStyle;
|
|
453
369
|
}
|
|
454
|
-
const stylePath =
|
|
370
|
+
const stylePath = upath.resolve(entryContextDir, customStyle);
|
|
455
371
|
if (!pathContains(entryContextDir, stylePath)) {
|
|
456
372
|
throw Error(
|
|
457
373
|
`Custom style file ${customStyle} is not in ${entryContextDir}. Make sure the file is located in the context directory or a subdirectory.`
|
|
458
374
|
);
|
|
459
375
|
}
|
|
460
|
-
if (!
|
|
376
|
+
if (!fs2.existsSync(stylePath)) {
|
|
461
377
|
throw new Error(`Custom style file not found: ${customStyle}`);
|
|
462
378
|
}
|
|
463
|
-
return
|
|
464
|
-
|
|
379
|
+
return pathToFileURL(stylePath).href.slice(
|
|
380
|
+
pathToFileURL(entryContextDir).href.replace(/\/$/, "").length + 1
|
|
465
381
|
);
|
|
466
382
|
}
|
|
467
383
|
function resolveTaskConfig(config, options) {
|
|
468
384
|
const context = options.cwd ?? cwd;
|
|
469
385
|
Logger.debug("resolveTaskConfig > context %s", context);
|
|
470
|
-
const entryContextDir = config.entryContext ?
|
|
386
|
+
const entryContextDir = config.entryContext ? upath.resolve(context, config.entryContext) : context;
|
|
471
387
|
const language = config.language;
|
|
472
388
|
const readingProgression = config.readingProgression;
|
|
473
389
|
const size = config.size ? parsePageSize(config.size) : void 0;
|
|
@@ -517,12 +433,18 @@ function resolveTaskConfig(config, options) {
|
|
|
517
433
|
if (cmykOption && typeof cmykOption === "object") {
|
|
518
434
|
return {
|
|
519
435
|
warnUnmapped: cmykOption.warnUnmapped ?? true,
|
|
520
|
-
overrideMap: cmykOption.overrideMap ?? [],
|
|
521
|
-
|
|
436
|
+
overrideMap: resolveMapEntries(cmykOption.overrideMap ?? []),
|
|
437
|
+
reserveMap: resolveMapEntries(cmykOption.reserveMap ?? []),
|
|
438
|
+
mapOutput: cmykOption.mapOutput ? upath.resolve(context, cmykOption.mapOutput) : void 0
|
|
522
439
|
};
|
|
523
440
|
}
|
|
524
441
|
if (options.cmyk || cmykOption === true) {
|
|
525
|
-
return {
|
|
442
|
+
return {
|
|
443
|
+
warnUnmapped: true,
|
|
444
|
+
overrideMap: [],
|
|
445
|
+
reserveMap: [],
|
|
446
|
+
mapOutput: void 0
|
|
447
|
+
};
|
|
526
448
|
}
|
|
527
449
|
return false;
|
|
528
450
|
};
|
|
@@ -537,16 +459,16 @@ function resolveTaskConfig(config, options) {
|
|
|
537
459
|
return replaceImageOption.flatMap(({ source, replacement }) => {
|
|
538
460
|
if (source instanceof RegExp) {
|
|
539
461
|
return allFiles.filter((file) => source.test(file)).map((file) => ({
|
|
540
|
-
source:
|
|
541
|
-
replacement:
|
|
462
|
+
source: upath.resolve(entryContextDir, file),
|
|
463
|
+
replacement: upath.resolve(
|
|
542
464
|
entryContextDir,
|
|
543
465
|
file.replace(source, replacement)
|
|
544
466
|
)
|
|
545
467
|
}));
|
|
546
468
|
}
|
|
547
469
|
return {
|
|
548
|
-
source:
|
|
549
|
-
replacement:
|
|
470
|
+
source: upath.resolve(entryContextDir, source),
|
|
471
|
+
replacement: upath.resolve(entryContextDir, replacement)
|
|
550
472
|
};
|
|
551
473
|
});
|
|
552
474
|
};
|
|
@@ -581,7 +503,7 @@ function resolveTaskConfig(config, options) {
|
|
|
581
503
|
};
|
|
582
504
|
if (config.output) {
|
|
583
505
|
return config.output.map((target) => {
|
|
584
|
-
const outputPath =
|
|
506
|
+
const outputPath = upath.resolve(context, target.path);
|
|
585
507
|
const format = target.format;
|
|
586
508
|
switch (format) {
|
|
587
509
|
case "pdf": {
|
|
@@ -634,7 +556,7 @@ function resolveTaskConfig(config, options) {
|
|
|
634
556
|
return [
|
|
635
557
|
{
|
|
636
558
|
...defaultPdfOptions,
|
|
637
|
-
path:
|
|
559
|
+
path: upath.resolve(context, filename)
|
|
638
560
|
}
|
|
639
561
|
];
|
|
640
562
|
})();
|
|
@@ -662,7 +584,7 @@ function resolveTaskConfig(config, options) {
|
|
|
662
584
|
};
|
|
663
585
|
})();
|
|
664
586
|
const cover = config.cover && {
|
|
665
|
-
src:
|
|
587
|
+
src: upath.resolve(entryContextDir, config.cover.src),
|
|
666
588
|
name: config.cover.name || COVER_HTML_IMAGE_ALT
|
|
667
589
|
};
|
|
668
590
|
const copyAsset = {
|
|
@@ -695,7 +617,7 @@ function resolveTaskConfig(config, options) {
|
|
|
695
617
|
cover
|
|
696
618
|
});
|
|
697
619
|
for (const output of outputs) {
|
|
698
|
-
const relPath =
|
|
620
|
+
const relPath = upath.relative(context, output.path);
|
|
699
621
|
if (pathContains(output.path, entryContextDir) || pathEquals(output.path, entryContextDir)) {
|
|
700
622
|
throw new Error(
|
|
701
623
|
`The output path is set to "${relPath}", but this will overwrite the original manuscript file. Please specify a different path.`
|
|
@@ -716,7 +638,7 @@ function resolveTaskConfig(config, options) {
|
|
|
716
638
|
(entry) => entry.target === duplicatedTarget && entry.source?.type === "file"
|
|
717
639
|
)?.source;
|
|
718
640
|
throw new Error(
|
|
719
|
-
`The output path "${
|
|
641
|
+
`The output path "${upath.relative(workspaceDir, duplicatedTarget)}" will overwrite existing content.` + (sourceFile ? ` Please choose a different name for the source file: ${sourceFile.pathname}` : "")
|
|
720
642
|
);
|
|
721
643
|
}
|
|
722
644
|
const resolvedConfig = {
|
|
@@ -784,7 +706,7 @@ function resolveSingleInputConfig({
|
|
|
784
706
|
sourcePath = input.entry;
|
|
785
707
|
}
|
|
786
708
|
} else {
|
|
787
|
-
sourcePath =
|
|
709
|
+
sourcePath = upath.resolve(context, input.entry);
|
|
788
710
|
}
|
|
789
711
|
if (isLocalResource) {
|
|
790
712
|
statFileSync(sourcePath);
|
|
@@ -793,7 +715,7 @@ function resolveSingleInputConfig({
|
|
|
793
715
|
case "markdown":
|
|
794
716
|
case "pub-manifest":
|
|
795
717
|
case "epub":
|
|
796
|
-
workspaceDir =
|
|
718
|
+
workspaceDir = upath.dirname(sourcePath);
|
|
797
719
|
break;
|
|
798
720
|
case "epub-opf": {
|
|
799
721
|
const rootDir = getEpubRootDir(sourcePath);
|
|
@@ -813,7 +735,7 @@ function resolveSingleInputConfig({
|
|
|
813
735
|
serverRootDir = UseTemporaryServerRoot;
|
|
814
736
|
workspaceDir = context;
|
|
815
737
|
}
|
|
816
|
-
const themesDir =
|
|
738
|
+
const themesDir = upath.resolve(workspaceDir, "themes");
|
|
817
739
|
if (input.format === "markdown") {
|
|
818
740
|
const contentType = "text/markdown";
|
|
819
741
|
const documentProcessor = {
|
|
@@ -827,9 +749,9 @@ function resolveSingleInputConfig({
|
|
|
827
749
|
documentMetadataReader: documentProcessor.metadataReader
|
|
828
750
|
});
|
|
829
751
|
const target = toHtmlExtension(
|
|
830
|
-
|
|
752
|
+
upath.resolve(
|
|
831
753
|
workspaceDir,
|
|
832
|
-
`${temporaryFilePrefix}${
|
|
754
|
+
`${temporaryFilePrefix}${upath.basename(sourcePath)}`
|
|
833
755
|
)
|
|
834
756
|
);
|
|
835
757
|
touchTmpFile(target);
|
|
@@ -856,25 +778,25 @@ function resolveSingleInputConfig({
|
|
|
856
778
|
});
|
|
857
779
|
exportAliases.push({
|
|
858
780
|
source: target,
|
|
859
|
-
target:
|
|
860
|
-
|
|
861
|
-
toHtmlExtension(
|
|
781
|
+
target: upath.resolve(
|
|
782
|
+
upath.dirname(target),
|
|
783
|
+
toHtmlExtension(upath.basename(sourcePath))
|
|
862
784
|
)
|
|
863
785
|
});
|
|
864
786
|
}
|
|
865
787
|
let fallbackTitle;
|
|
866
788
|
let viewerInput;
|
|
867
789
|
if (inputFormat === "markdown") {
|
|
868
|
-
const manifestPath =
|
|
790
|
+
const manifestPath = upath.resolve(
|
|
869
791
|
workspaceDir,
|
|
870
792
|
`${temporaryFilePrefix}${MANIFEST_FILENAME}`
|
|
871
793
|
);
|
|
872
794
|
touchTmpFile(manifestPath);
|
|
873
795
|
exportAliases.push({
|
|
874
796
|
source: manifestPath,
|
|
875
|
-
target:
|
|
797
|
+
target: upath.resolve(workspaceDir, MANIFEST_FILENAME)
|
|
876
798
|
});
|
|
877
|
-
fallbackTitle = entries.length === 1 && entries[0].title ? entries[0].title :
|
|
799
|
+
fallbackTitle = entries.length === 1 && entries[0].title ? entries[0].title : upath.basename(sourcePath);
|
|
878
800
|
viewerInput = {
|
|
879
801
|
type: "webpub",
|
|
880
802
|
manifestPath,
|
|
@@ -887,8 +809,8 @@ function resolveSingleInputConfig({
|
|
|
887
809
|
const url = new URL(sourcePath);
|
|
888
810
|
webbookEntryUrl = url.href;
|
|
889
811
|
} else {
|
|
890
|
-
const rootFileUrl =
|
|
891
|
-
const urlPath =
|
|
812
|
+
const rootFileUrl = pathToFileURL(workspaceDir).href;
|
|
813
|
+
const urlPath = pathToFileURL(sourcePath).href.slice(rootFileUrl.length);
|
|
892
814
|
webbookEntryUrl = `${base}${urlPath}`;
|
|
893
815
|
webbookPath = sourcePath;
|
|
894
816
|
}
|
|
@@ -905,9 +827,9 @@ function resolveSingleInputConfig({
|
|
|
905
827
|
viewerInput = {
|
|
906
828
|
type: "epub",
|
|
907
829
|
epubPath: sourcePath,
|
|
908
|
-
epubTmpOutputDir:
|
|
830
|
+
epubTmpOutputDir: upath.join(
|
|
909
831
|
sourcePath,
|
|
910
|
-
`../${temporaryFilePrefix}${
|
|
832
|
+
`../${temporaryFilePrefix}${upath.basename(sourcePath)}`
|
|
911
833
|
)
|
|
912
834
|
};
|
|
913
835
|
} else {
|
|
@@ -938,13 +860,13 @@ function resolveComposedProjectConfig({
|
|
|
938
860
|
cover
|
|
939
861
|
}) {
|
|
940
862
|
Logger.debug("entering composed project config mode");
|
|
941
|
-
const workspaceDir =
|
|
863
|
+
const workspaceDir = upath.resolve(
|
|
942
864
|
context,
|
|
943
865
|
config.workspaceDir ?? ".vivliostyle"
|
|
944
866
|
);
|
|
945
|
-
const themesDir =
|
|
946
|
-
const pkgJsonPath =
|
|
947
|
-
const pkgJson =
|
|
867
|
+
const themesDir = upath.resolve(workspaceDir, "themes");
|
|
868
|
+
const pkgJsonPath = upath.resolve(context, "package.json");
|
|
869
|
+
const pkgJson = fs2.existsSync(pkgJsonPath) ? readJSON(pkgJsonPath) : void 0;
|
|
948
870
|
if (pkgJson) {
|
|
949
871
|
Logger.debug("located package.json path", pkgJsonPath);
|
|
950
872
|
}
|
|
@@ -960,19 +882,19 @@ function resolveComposedProjectConfig({
|
|
|
960
882
|
rootThemes.forEach((t) => themeIndexes.add(t));
|
|
961
883
|
const tocConfig = {
|
|
962
884
|
tocTitle: config.toc?.title ?? config?.tocTitle ?? TOC_TITLE,
|
|
963
|
-
target:
|
|
885
|
+
target: upath.resolve(workspaceDir, config.toc?.htmlPath ?? TOC_FILENAME),
|
|
964
886
|
sectionDepth: config.toc?.sectionDepth ?? 0,
|
|
965
887
|
transform: {
|
|
966
888
|
transformDocumentList: config.toc?.transformDocumentList,
|
|
967
889
|
transformSectionList: config.toc?.transformSectionList
|
|
968
890
|
}
|
|
969
891
|
};
|
|
970
|
-
const coverHtml = config.cover && ("htmlPath" in config.cover && !config.cover.htmlPath ? void 0 :
|
|
892
|
+
const coverHtml = config.cover && ("htmlPath" in config.cover && !config.cover.htmlPath ? void 0 : upath.resolve(
|
|
971
893
|
workspaceDir,
|
|
972
894
|
config.cover?.htmlPath || COVER_HTML_FILENAME
|
|
973
895
|
));
|
|
974
896
|
const ensureCoverImage = (src) => {
|
|
975
|
-
const absPath = src &&
|
|
897
|
+
const absPath = src && upath.resolve(entryContextDir, src);
|
|
976
898
|
if (absPath) {
|
|
977
899
|
statFileSync(absPath, {
|
|
978
900
|
errorMessage: "Specified cover image does not exist"
|
|
@@ -995,16 +917,16 @@ function resolveComposedProjectConfig({
|
|
|
995
917
|
return {
|
|
996
918
|
type: "uri",
|
|
997
919
|
href: entryPath,
|
|
998
|
-
rootDir:
|
|
920
|
+
rootDir: upath.join(workspaceDir, new URL(entryPath).host)
|
|
999
921
|
};
|
|
1000
922
|
} else if (entryPath.startsWith("/")) {
|
|
1001
923
|
return {
|
|
1002
924
|
type: "uri",
|
|
1003
925
|
href: entryPath,
|
|
1004
|
-
rootDir:
|
|
926
|
+
rootDir: upath.join(workspaceDir, "localhost")
|
|
1005
927
|
};
|
|
1006
928
|
}
|
|
1007
|
-
const pathname =
|
|
929
|
+
const pathname = upath.resolve(entryContextDir, entryPath);
|
|
1008
930
|
statFileSync(pathname);
|
|
1009
931
|
const rawContentType = mime(pathname);
|
|
1010
932
|
const documentProcessor = {
|
|
@@ -1036,9 +958,9 @@ function resolveComposedProjectConfig({
|
|
|
1036
958
|
const getTargetPath = (source) => {
|
|
1037
959
|
switch (source.type) {
|
|
1038
960
|
case "file":
|
|
1039
|
-
return
|
|
961
|
+
return upath.resolve(
|
|
1040
962
|
workspaceDir,
|
|
1041
|
-
toHtmlExtension(
|
|
963
|
+
toHtmlExtension(upath.relative(entryContextDir, source.pathname))
|
|
1042
964
|
);
|
|
1043
965
|
case "uri": {
|
|
1044
966
|
const url = new URL(source.href, "a://dummy");
|
|
@@ -1046,14 +968,14 @@ function resolveComposedProjectConfig({
|
|
|
1046
968
|
if (!/\.\w+$/.test(pathname)) {
|
|
1047
969
|
pathname = `${pathname.replace(/\/$/, "")}/index.html`;
|
|
1048
970
|
}
|
|
1049
|
-
return
|
|
971
|
+
return upath.join(source.rootDir, pathname);
|
|
1050
972
|
}
|
|
1051
973
|
default:
|
|
1052
974
|
return source;
|
|
1053
975
|
}
|
|
1054
976
|
};
|
|
1055
977
|
if ((isContentsEntry(entry) || isCoverEntry(entry)) && entry.path) {
|
|
1056
|
-
const source =
|
|
978
|
+
const source = upath.resolve(entryContextDir, entry.path);
|
|
1057
979
|
try {
|
|
1058
980
|
statFileSync(source);
|
|
1059
981
|
} catch (error) {
|
|
@@ -1068,7 +990,7 @@ Maybe you want to set the "output" field instead.`
|
|
|
1068
990
|
if (isContentsEntry(entry)) {
|
|
1069
991
|
const inputInfo = entry.path ? getInputInfo(entry.path) : void 0;
|
|
1070
992
|
const { metadata, ...template } = inputInfo || {};
|
|
1071
|
-
let target = entry.output ?
|
|
993
|
+
let target = entry.output ? upath.resolve(workspaceDir, entry.output) : inputInfo && getTargetPath(inputInfo);
|
|
1072
994
|
const themes = entry.theme ? [entry.theme].flat().map(
|
|
1073
995
|
(theme) => parseTheme({
|
|
1074
996
|
theme,
|
|
@@ -1080,9 +1002,9 @@ Maybe you want to set the "output" field instead.`
|
|
|
1080
1002
|
themes.forEach((t) => themeIndexes.add(t));
|
|
1081
1003
|
target ??= tocConfig.target;
|
|
1082
1004
|
if (inputInfo?.type === "file" && pathEquals(inputInfo.pathname, target)) {
|
|
1083
|
-
const tmpPath =
|
|
1084
|
-
|
|
1085
|
-
`${temporaryFilePrefix}${
|
|
1005
|
+
const tmpPath = upath.resolve(
|
|
1006
|
+
upath.dirname(target),
|
|
1007
|
+
`${temporaryFilePrefix}${upath.basename(target)}`
|
|
1086
1008
|
);
|
|
1087
1009
|
exportAliases.push({ source: tmpPath, target });
|
|
1088
1010
|
touchTmpFile(tmpPath);
|
|
@@ -1103,7 +1025,7 @@ Maybe you want to set the "output" field instead.`
|
|
|
1103
1025
|
if (isCoverEntry(entry)) {
|
|
1104
1026
|
const inputInfo = entry.path ? getInputInfo(entry.path) : void 0;
|
|
1105
1027
|
const { metadata, ...template } = inputInfo || {};
|
|
1106
|
-
let target = entry.output ?
|
|
1028
|
+
let target = entry.output ? upath.resolve(workspaceDir, entry.output) : inputInfo && getTargetPath(inputInfo);
|
|
1107
1029
|
const themes = entry.theme ? [entry.theme].flat().map(
|
|
1108
1030
|
(theme) => parseTheme({
|
|
1109
1031
|
theme,
|
|
@@ -1119,14 +1041,14 @@ Maybe you want to set the "output" field instead.`
|
|
|
1119
1041
|
`A CoverEntryConfig is set in the entry list but a location of cover file is not set. Please set 'cover' property in your config file.`
|
|
1120
1042
|
);
|
|
1121
1043
|
}
|
|
1122
|
-
target ??=
|
|
1044
|
+
target ??= upath.resolve(
|
|
1123
1045
|
workspaceDir,
|
|
1124
1046
|
entry.path || coverHtml || COVER_HTML_FILENAME
|
|
1125
1047
|
);
|
|
1126
1048
|
if (inputInfo?.type === "file" && pathEquals(inputInfo.pathname, target)) {
|
|
1127
|
-
const tmpPath =
|
|
1128
|
-
|
|
1129
|
-
`${temporaryFilePrefix}${
|
|
1049
|
+
const tmpPath = upath.resolve(
|
|
1050
|
+
upath.dirname(target),
|
|
1051
|
+
`${temporaryFilePrefix}${upath.basename(target)}`
|
|
1130
1052
|
);
|
|
1131
1053
|
exportAliases.push({ source: tmpPath, target });
|
|
1132
1054
|
touchTmpFile(tmpPath);
|
|
@@ -1147,7 +1069,7 @@ Maybe you want to set the "output" field instead.`
|
|
|
1147
1069
|
if (isArticleEntry(entry)) {
|
|
1148
1070
|
const inputInfo = getInputInfo(entry.path);
|
|
1149
1071
|
const { metadata, ...source } = inputInfo;
|
|
1150
|
-
const target = entry.output ?
|
|
1072
|
+
const target = entry.output ? upath.resolve(workspaceDir, entry.output) : getTargetPath(inputInfo);
|
|
1151
1073
|
const themes = entry.theme ? [entry.theme].flat().map(
|
|
1152
1074
|
(theme) => parseTheme({ theme, context, workspaceDir, themesDir })
|
|
1153
1075
|
) : metadata?.themes ?? [...rootThemes];
|
|
@@ -1170,7 +1092,7 @@ Maybe you want to set the "output" field instead.`
|
|
|
1170
1092
|
if (entries.length === 1 && entries[0].title) {
|
|
1171
1093
|
fallbackProjectTitle = entries[0].title;
|
|
1172
1094
|
} else {
|
|
1173
|
-
fallbackProjectTitle =
|
|
1095
|
+
fallbackProjectTitle = upath.basename(outputs[0].path);
|
|
1174
1096
|
}
|
|
1175
1097
|
}
|
|
1176
1098
|
if (!!config?.toc && !entries.find(({ rel }) => rel === "contents")) {
|
|
@@ -1198,11 +1120,11 @@ Maybe you want to set the "output" field instead.`
|
|
|
1198
1120
|
entries,
|
|
1199
1121
|
input: {
|
|
1200
1122
|
format: "pub-manifest",
|
|
1201
|
-
entry:
|
|
1123
|
+
entry: upath.join(workspaceDir, MANIFEST_FILENAME)
|
|
1202
1124
|
},
|
|
1203
1125
|
viewerInput: {
|
|
1204
1126
|
type: "webpub",
|
|
1205
|
-
manifestPath:
|
|
1127
|
+
manifestPath: upath.join(workspaceDir, MANIFEST_FILENAME),
|
|
1206
1128
|
needToGenerateManifest: true
|
|
1207
1129
|
},
|
|
1208
1130
|
exportAliases,
|
|
@@ -1215,8 +1137,8 @@ Maybe you want to set the "output" field instead.`
|
|
|
1215
1137
|
import "vite";
|
|
1216
1138
|
|
|
1217
1139
|
// src/browser.ts
|
|
1218
|
-
import
|
|
1219
|
-
import
|
|
1140
|
+
import fs3 from "node:fs";
|
|
1141
|
+
import upath2 from "upath";
|
|
1220
1142
|
var browserEnumMap = {
|
|
1221
1143
|
chrome: "chrome",
|
|
1222
1144
|
chromium: "chromium",
|
|
@@ -1317,20 +1239,20 @@ function getPuppeteerCacheDir() {
|
|
|
1317
1239
|
if (isInContainer()) {
|
|
1318
1240
|
return "/opt/puppeteer";
|
|
1319
1241
|
}
|
|
1320
|
-
return
|
|
1242
|
+
return upath2.join(getCacheDir(), "browsers");
|
|
1321
1243
|
}
|
|
1322
1244
|
async function resolveBuildId({
|
|
1323
1245
|
type,
|
|
1324
1246
|
tag,
|
|
1325
1247
|
browsers
|
|
1326
1248
|
}) {
|
|
1327
|
-
const cacheDataFilename =
|
|
1249
|
+
const cacheDataFilename = upath2.join(
|
|
1328
1250
|
getPuppeteerCacheDir(),
|
|
1329
1251
|
"build-ids.json"
|
|
1330
1252
|
);
|
|
1331
1253
|
let cacheData;
|
|
1332
1254
|
try {
|
|
1333
|
-
cacheData = JSON.parse(
|
|
1255
|
+
cacheData = JSON.parse(fs3.readFileSync(cacheDataFilename, "utf-8"));
|
|
1334
1256
|
if (Date.now() - cacheData.createdAt > 24 * 60 * 60 * 1e3) {
|
|
1335
1257
|
cacheData = { createdAt: Date.now(), buildIds: {} };
|
|
1336
1258
|
}
|
|
@@ -1350,23 +1272,23 @@ async function resolveBuildId({
|
|
|
1350
1272
|
tag
|
|
1351
1273
|
);
|
|
1352
1274
|
(cacheData.buildIds[type] ??= {})[tag] = buildId;
|
|
1353
|
-
|
|
1354
|
-
|
|
1275
|
+
fs3.mkdirSync(upath2.dirname(cacheDataFilename), { recursive: true });
|
|
1276
|
+
fs3.writeFileSync(cacheDataFilename, JSON.stringify(cacheData));
|
|
1355
1277
|
return buildId;
|
|
1356
1278
|
}
|
|
1357
1279
|
async function cleanupOutdatedBrowsers() {
|
|
1358
1280
|
for (const browser of Object.values(browserEnumMap)) {
|
|
1359
|
-
const browsersDir =
|
|
1360
|
-
if (!
|
|
1281
|
+
const browsersDir = upath2.join(getPuppeteerCacheDir(), browser);
|
|
1282
|
+
if (!fs3.existsSync(browsersDir)) {
|
|
1361
1283
|
continue;
|
|
1362
1284
|
}
|
|
1363
|
-
const entries =
|
|
1285
|
+
const entries = fs3.readdirSync(browsersDir);
|
|
1364
1286
|
for (const entry of entries) {
|
|
1365
|
-
const entryPath =
|
|
1366
|
-
const stat =
|
|
1287
|
+
const entryPath = upath2.join(browsersDir, entry);
|
|
1288
|
+
const stat = fs3.statSync(entryPath);
|
|
1367
1289
|
if (!stat.isDirectory() || Date.now() - stat.mtimeMs > 7 * 24 * 60 * 60 * 1e3) {
|
|
1368
1290
|
Logger.debug(`Removing outdated browser at ${entryPath}`);
|
|
1369
|
-
await
|
|
1291
|
+
await fs3.promises.rm(entryPath, { recursive: true, force: true });
|
|
1370
1292
|
}
|
|
1371
1293
|
}
|
|
1372
1294
|
}
|
|
@@ -1384,7 +1306,7 @@ async function getExecutableBrowserPath({
|
|
|
1384
1306
|
});
|
|
1385
1307
|
}
|
|
1386
1308
|
function checkBrowserAvailability(path) {
|
|
1387
|
-
return
|
|
1309
|
+
return fs3.existsSync(path);
|
|
1388
1310
|
}
|
|
1389
1311
|
async function downloadBrowser({
|
|
1390
1312
|
type,
|
|
@@ -1486,9 +1408,9 @@ async function launchPreview({
|
|
|
1486
1408
|
}
|
|
1487
1409
|
|
|
1488
1410
|
// src/server.ts
|
|
1489
|
-
import
|
|
1411
|
+
import fs9 from "node:fs";
|
|
1490
1412
|
import { URL as URL2 } from "node:url";
|
|
1491
|
-
import
|
|
1413
|
+
import upath11 from "upath";
|
|
1492
1414
|
import {
|
|
1493
1415
|
createServer,
|
|
1494
1416
|
preview
|
|
@@ -1496,26 +1418,26 @@ import {
|
|
|
1496
1418
|
|
|
1497
1419
|
// src/vite/vite-plugin-dev-server.ts
|
|
1498
1420
|
import escapeRe from "escape-string-regexp";
|
|
1499
|
-
import { pathToFileURL as
|
|
1421
|
+
import { pathToFileURL as pathToFileURL5 } from "node:url";
|
|
1500
1422
|
import sirv from "sirv";
|
|
1501
|
-
import
|
|
1423
|
+
import upath8 from "upath";
|
|
1502
1424
|
import "vite";
|
|
1503
1425
|
|
|
1504
1426
|
// src/processor/compile.ts
|
|
1505
1427
|
import "@vivliostyle/jsdom";
|
|
1506
1428
|
import { copy as copy3, move } from "fs-extra/esm";
|
|
1507
|
-
import
|
|
1508
|
-
import
|
|
1429
|
+
import fs7 from "node:fs";
|
|
1430
|
+
import upath7 from "upath";
|
|
1509
1431
|
import serializeToXml2 from "w3c-xmlserializer";
|
|
1510
1432
|
import MIMEType2 from "whatwg-mimetype";
|
|
1511
1433
|
|
|
1512
1434
|
// src/output/webbook.ts
|
|
1513
1435
|
import { copy as copy2 } from "fs-extra/esm";
|
|
1514
1436
|
import { lookup as mime3 } from "mime-types";
|
|
1515
|
-
import
|
|
1516
|
-
import { pathToFileURL as
|
|
1437
|
+
import fs5 from "node:fs";
|
|
1438
|
+
import { pathToFileURL as pathToFileURL4 } from "node:url";
|
|
1517
1439
|
import { glob } from "tinyglobby";
|
|
1518
|
-
import
|
|
1440
|
+
import upath5 from "upath";
|
|
1519
1441
|
|
|
1520
1442
|
// src/processor/html.tsx
|
|
1521
1443
|
import jsdom, {
|
|
@@ -1524,8 +1446,8 @@ import jsdom, {
|
|
|
1524
1446
|
} from "@vivliostyle/jsdom";
|
|
1525
1447
|
import DOMPurify from "dompurify";
|
|
1526
1448
|
import { toHtml } from "hast-util-to-html";
|
|
1527
|
-
import { fileURLToPath as fileURLToPath2, pathToFileURL as
|
|
1528
|
-
import
|
|
1449
|
+
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
1450
|
+
import upath3 from "upath";
|
|
1529
1451
|
import MIMEType from "whatwg-mimetype";
|
|
1530
1452
|
import { jsx, jsxs } from "hastscript/jsx-runtime";
|
|
1531
1453
|
var createVirtualConsole = (onError) => {
|
|
@@ -1558,10 +1480,7 @@ var createVirtualConsole = (onError) => {
|
|
|
1558
1480
|
});
|
|
1559
1481
|
return virtualConsole;
|
|
1560
1482
|
};
|
|
1561
|
-
var htmlPurify = DOMPurify(
|
|
1562
|
-
// @ts-expect-error: jsdom.DOMWindow should have trustedTypes property
|
|
1563
|
-
new JSDOM("").window
|
|
1564
|
-
);
|
|
1483
|
+
var htmlPurify = DOMPurify(new JSDOM("").window);
|
|
1565
1484
|
var ResourceLoader = class _ResourceLoader extends BaseResourceLoader {
|
|
1566
1485
|
static dataUrlOrigin = "http://localhost/";
|
|
1567
1486
|
fetcherMap = /* @__PURE__ */ new Map();
|
|
@@ -1586,7 +1505,7 @@ var ResourceLoader = class _ResourceLoader extends BaseResourceLoader {
|
|
|
1586
1505
|
if (mimeType === "text/html" && !/\.html?$/.test(url.pathname)) {
|
|
1587
1506
|
url.pathname = `${url.pathname.replace(/\/$/, "")}/index.html`;
|
|
1588
1507
|
}
|
|
1589
|
-
let relTarget =
|
|
1508
|
+
let relTarget = upath3.relative(rootHref, url.href);
|
|
1590
1509
|
return decodeURI(relTarget);
|
|
1591
1510
|
};
|
|
1592
1511
|
const fetchedResources = [];
|
|
@@ -1605,7 +1524,7 @@ var ResourceLoader = class _ResourceLoader extends BaseResourceLoader {
|
|
|
1605
1524
|
} catch (e) {
|
|
1606
1525
|
}
|
|
1607
1526
|
const relTarget = normalizeToLocalPath(url, encodingFormat);
|
|
1608
|
-
const target =
|
|
1527
|
+
const target = upath3.join(outputDir, relTarget);
|
|
1609
1528
|
fetchedResources.push({ url: relTarget, encodingFormat });
|
|
1610
1529
|
writeFileIfChanged(target, buffer);
|
|
1611
1530
|
}).catch(onError);
|
|
@@ -1621,7 +1540,7 @@ async function getJsdomFromUrlOrFile({
|
|
|
1621
1540
|
throw error;
|
|
1622
1541
|
})
|
|
1623
1542
|
}) {
|
|
1624
|
-
const url = isValidUri(src) ? new URL(src) :
|
|
1543
|
+
const url = isValidUri(src) ? new URL(src) : pathToFileURL2(src);
|
|
1625
1544
|
let dom;
|
|
1626
1545
|
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
1627
1546
|
dom = await JSDOM.fromURL(src, {
|
|
@@ -1802,11 +1721,11 @@ async function generateTocListSection({
|
|
|
1802
1721
|
} = transform;
|
|
1803
1722
|
const structure = await Promise.all(
|
|
1804
1723
|
entries.map(async (entry) => {
|
|
1805
|
-
const href = encodeURI(
|
|
1724
|
+
const href = encodeURI(upath3.relative(distDir, entry.target));
|
|
1806
1725
|
const sections = sectionDepth >= 1 ? await getStructuredSectionFromHtml(entry.target, href) : [];
|
|
1807
1726
|
return {
|
|
1808
|
-
title: entry.title ||
|
|
1809
|
-
href: encodeURI(
|
|
1727
|
+
title: entry.title || upath3.basename(entry.target, ".html"),
|
|
1728
|
+
href: encodeURI(upath3.relative(distDir, entry.target)),
|
|
1810
1729
|
sections,
|
|
1811
1730
|
children: []
|
|
1812
1731
|
// TODO
|
|
@@ -1854,7 +1773,7 @@ async function processTocHtml(dom, {
|
|
|
1854
1773
|
const l = document2.createElement("link");
|
|
1855
1774
|
l.setAttribute("rel", "publication");
|
|
1856
1775
|
l.setAttribute("type", "application/ld+json");
|
|
1857
|
-
l.setAttribute("href", encodeURI(
|
|
1776
|
+
l.setAttribute("href", encodeURI(upath3.relative(distDir, manifestPath)));
|
|
1858
1777
|
document2.head.appendChild(l);
|
|
1859
1778
|
}
|
|
1860
1779
|
const style = document2.querySelector("style[data-vv-style]");
|
|
@@ -2112,13 +2031,13 @@ function parsePageListDocument(dom) {
|
|
|
2112
2031
|
// src/output/epub.ts
|
|
2113
2032
|
import archiver from "archiver";
|
|
2114
2033
|
import { lookup as lookupLanguage } from "bcp-47-match";
|
|
2115
|
-
import
|
|
2034
|
+
import XMLBuilder from "fast-xml-builder";
|
|
2116
2035
|
import { copy } from "fs-extra/esm";
|
|
2117
2036
|
import GithubSlugger from "github-slugger";
|
|
2118
2037
|
import { lookup as mime2 } from "mime-types";
|
|
2119
|
-
import
|
|
2120
|
-
import { pathToFileURL as
|
|
2121
|
-
import
|
|
2038
|
+
import fs4 from "node:fs";
|
|
2039
|
+
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
2040
|
+
import upath4 from "upath";
|
|
2122
2041
|
import { v4 as uuid } from "uuid";
|
|
2123
2042
|
import serializeToXml from "w3c-xmlserializer";
|
|
2124
2043
|
var TOC_ID = "toc";
|
|
@@ -2132,21 +2051,21 @@ var COVER_IMAGE_MIMETYPES = [
|
|
|
2132
2051
|
"image/webp"
|
|
2133
2052
|
];
|
|
2134
2053
|
var changeExtname = (filepath, newExt) => {
|
|
2135
|
-
let ext =
|
|
2054
|
+
let ext = upath4.extname(filepath);
|
|
2136
2055
|
return `${filepath.slice(0, -ext.length)}${newExt}`;
|
|
2137
2056
|
};
|
|
2138
2057
|
var getRelativeHref = (target, baseUrl, rootUrl) => {
|
|
2139
|
-
const absBasePath =
|
|
2140
|
-
const absRootPath =
|
|
2141
|
-
const hrefUrl = new URL(encodeURI(target),
|
|
2058
|
+
const absBasePath = upath4.join("/", baseUrl);
|
|
2059
|
+
const absRootPath = upath4.join("/", rootUrl);
|
|
2060
|
+
const hrefUrl = new URL(encodeURI(target), pathToFileURL3(absBasePath));
|
|
2142
2061
|
if (hrefUrl.protocol !== "file:") {
|
|
2143
2062
|
return target;
|
|
2144
2063
|
}
|
|
2145
2064
|
if (/\.html?$/.test(hrefUrl.pathname)) {
|
|
2146
2065
|
hrefUrl.pathname = changeExtname(hrefUrl.pathname, ".xhtml");
|
|
2147
2066
|
}
|
|
2148
|
-
const pathname =
|
|
2149
|
-
|
|
2067
|
+
const pathname = upath4.posix.relative(
|
|
2068
|
+
pathToFileURL3(upath4.dirname(absRootPath)).pathname,
|
|
2150
2069
|
hrefUrl.pathname
|
|
2151
2070
|
);
|
|
2152
2071
|
return `${pathname}${hrefUrl.search}${hrefUrl.hash}`;
|
|
@@ -2157,16 +2076,16 @@ var normalizeLocalizableString = (value, availableLanguages) => {
|
|
|
2157
2076
|
}
|
|
2158
2077
|
const values = [value].flat().map((value2) => typeof value2 === "string" ? { value: value2 } : value2);
|
|
2159
2078
|
const localizedValues = values.filter(
|
|
2160
|
-
(
|
|
2079
|
+
(v) => !!v.language
|
|
2161
2080
|
);
|
|
2162
2081
|
const preferredLang = lookupLanguage(
|
|
2163
|
-
localizedValues.map((
|
|
2082
|
+
localizedValues.map((v) => v.language),
|
|
2164
2083
|
availableLanguages
|
|
2165
2084
|
);
|
|
2166
2085
|
if (preferredLang) {
|
|
2167
|
-
return localizedValues[localizedValues.findIndex((
|
|
2086
|
+
return localizedValues[localizedValues.findIndex((v) => v.language === preferredLang)].value;
|
|
2168
2087
|
}
|
|
2169
|
-
return values.find((
|
|
2088
|
+
return values.find((v) => !v.language)?.value;
|
|
2170
2089
|
};
|
|
2171
2090
|
var appendManifestProperty = (entry, newProperty) => {
|
|
2172
2091
|
entry.properties = entry.properties ? Array.from(/* @__PURE__ */ new Set([...entry.properties.split(" "), newProperty])).join(
|
|
@@ -2189,10 +2108,10 @@ async function exportEpub({
|
|
|
2189
2108
|
epubVersion
|
|
2190
2109
|
});
|
|
2191
2110
|
const [tmpDir] = await useTmpDirectory();
|
|
2192
|
-
|
|
2193
|
-
await copy(webpubDir,
|
|
2111
|
+
fs4.mkdirSync(upath4.join(tmpDir, "META-INF"), { recursive: true });
|
|
2112
|
+
await copy(webpubDir, upath4.join(tmpDir, "EPUB"));
|
|
2194
2113
|
const uid = `urn:uuid:${uuid()}`;
|
|
2195
|
-
const entryHtmlRelPath = entryHtmlFile &&
|
|
2114
|
+
const entryHtmlRelPath = entryHtmlFile && upath4.relative(webpubDir, upath4.resolve(webpubDir, entryHtmlFile));
|
|
2196
2115
|
const findPublicationLink = (relType, list, filter) => [list].flat().find(
|
|
2197
2116
|
(e) => typeof e === "object" && e.rel === relType && (!filter || filter(e))
|
|
2198
2117
|
);
|
|
@@ -2229,7 +2148,7 @@ async function exportEpub({
|
|
|
2229
2148
|
return acc;
|
|
2230
2149
|
} catch (e) {
|
|
2231
2150
|
}
|
|
2232
|
-
if (!
|
|
2151
|
+
if (!fs4.existsSync(upath4.join(tmpDir, "EPUB", url))) {
|
|
2233
2152
|
return acc;
|
|
2234
2153
|
}
|
|
2235
2154
|
const mediaType = encodingFormat || mime2(url) || "text/plain";
|
|
@@ -2252,7 +2171,7 @@ async function exportEpub({
|
|
|
2252
2171
|
(url) => /\.html?$/.test(url)
|
|
2253
2172
|
);
|
|
2254
2173
|
let tocHtml = htmlFiles.find((f) => f === tocResource?.url);
|
|
2255
|
-
const readingOrder = [manifest.readingOrder || entryHtmlRelPath].flat().flatMap((
|
|
2174
|
+
const readingOrder = [manifest.readingOrder || entryHtmlRelPath].flat().flatMap((v) => v ? typeof v === "string" ? { url: v } : v : []);
|
|
2256
2175
|
if (!tocHtml) {
|
|
2257
2176
|
Logger.logWarn(
|
|
2258
2177
|
"No table of contents document was found. for EPUB output, we recommend to enable `toc` option in your Vivliostyle config file to generate a table of contents document."
|
|
@@ -2283,7 +2202,7 @@ async function exportEpub({
|
|
|
2283
2202
|
text: EPUB_LANDMARKS_COVER_ENTRY
|
|
2284
2203
|
});
|
|
2285
2204
|
}
|
|
2286
|
-
const contextDir =
|
|
2205
|
+
const contextDir = upath4.join(tmpDir, "EPUB");
|
|
2287
2206
|
const processHtml = async (target2) => {
|
|
2288
2207
|
let parseResult;
|
|
2289
2208
|
try {
|
|
@@ -2320,7 +2239,7 @@ async function exportEpub({
|
|
|
2320
2239
|
processResult[target2] = await processHtml(target2);
|
|
2321
2240
|
}
|
|
2322
2241
|
const { document: entryDocument } = processResult[tocHtml].dom.window;
|
|
2323
|
-
const docLanguages = [manifest.inLanguage].flat().filter((
|
|
2242
|
+
const docLanguages = [manifest.inLanguage].flat().filter((v) => Boolean(v));
|
|
2324
2243
|
if (docLanguages.length === 0) {
|
|
2325
2244
|
docLanguages.push(entryDocument.documentElement.lang || "en");
|
|
2326
2245
|
}
|
|
@@ -2345,20 +2264,20 @@ async function exportEpub({
|
|
|
2345
2264
|
});
|
|
2346
2265
|
}
|
|
2347
2266
|
if (relManifestPath) {
|
|
2348
|
-
await
|
|
2267
|
+
await fs4.promises.rm(upath4.join(tmpDir, "EPUB", relManifestPath), {
|
|
2349
2268
|
force: true,
|
|
2350
2269
|
recursive: true
|
|
2351
2270
|
});
|
|
2352
2271
|
delete manifestItem[relManifestPath];
|
|
2353
2272
|
}
|
|
2354
|
-
|
|
2355
|
-
|
|
2273
|
+
fs4.writeFileSync(
|
|
2274
|
+
upath4.join(tmpDir, "META-INF/container.xml"),
|
|
2356
2275
|
EPUB_CONTAINER_XML,
|
|
2357
2276
|
"utf8"
|
|
2358
2277
|
);
|
|
2359
2278
|
Logger.debug(`Generating content.opf`);
|
|
2360
|
-
|
|
2361
|
-
|
|
2279
|
+
fs4.writeFileSync(
|
|
2280
|
+
upath4.join(tmpDir, "EPUB/content.opf"),
|
|
2362
2281
|
buildEpubPackageDocument({
|
|
2363
2282
|
epubVersion,
|
|
2364
2283
|
uid,
|
|
@@ -2375,13 +2294,13 @@ async function exportEpub({
|
|
|
2375
2294
|
async function writeAsXhtml(dom, absPath) {
|
|
2376
2295
|
const xhtml = `${XML_DECLARATION}
|
|
2377
2296
|
${serializeToXml(dom.window.document)}`;
|
|
2378
|
-
await
|
|
2297
|
+
await fs4.promises.writeFile(changeExtname(absPath, ".xhtml"), xhtml, "utf8");
|
|
2379
2298
|
}
|
|
2380
2299
|
async function transpileHtmlToXhtml({
|
|
2381
2300
|
target,
|
|
2382
2301
|
contextDir
|
|
2383
2302
|
}) {
|
|
2384
|
-
const absPath =
|
|
2303
|
+
const absPath = upath4.join(contextDir, target);
|
|
2385
2304
|
const dom = await getJsdomFromUrlOrFile({ src: absPath });
|
|
2386
2305
|
const { document: document2 } = dom.window;
|
|
2387
2306
|
document2.documentElement.removeAttribute("xmlns");
|
|
@@ -2391,7 +2310,7 @@ async function transpileHtmlToXhtml({
|
|
|
2391
2310
|
el.setAttribute("href", getRelativeHref(href, target, target));
|
|
2392
2311
|
});
|
|
2393
2312
|
await writeAsXhtml(dom, absPath);
|
|
2394
|
-
await
|
|
2313
|
+
await fs4.promises.unlink(absPath);
|
|
2395
2314
|
return {
|
|
2396
2315
|
dom,
|
|
2397
2316
|
// FIXME: Yes, I recognize this implementation is inadequate.
|
|
@@ -2449,7 +2368,7 @@ async function processTocDocument({
|
|
|
2449
2368
|
let name = normalizeLocalizableString(content.name, docLanguages);
|
|
2450
2369
|
if (!name) {
|
|
2451
2370
|
const dom2 = await getJsdomFromUrlOrFile({
|
|
2452
|
-
src:
|
|
2371
|
+
src: upath4.join(contextDir, changeExtname(content.url, ".xhtml"))
|
|
2453
2372
|
});
|
|
2454
2373
|
name = dom2.window.document.title;
|
|
2455
2374
|
}
|
|
@@ -2502,7 +2421,7 @@ async function processTocDocument({
|
|
|
2502
2421
|
}
|
|
2503
2422
|
publicationLinkEl.parentNode?.removeChild(publicationLinkEl);
|
|
2504
2423
|
}
|
|
2505
|
-
const absPath =
|
|
2424
|
+
const absPath = upath4.join(contextDir, target);
|
|
2506
2425
|
await writeAsXhtml(dom, absPath);
|
|
2507
2426
|
return { tocResourceTree };
|
|
2508
2427
|
}
|
|
@@ -2517,7 +2436,7 @@ async function processPagelistDocument({
|
|
|
2517
2436
|
nav.setAttribute("id", PAGELIST_ID);
|
|
2518
2437
|
nav.setAttribute("epub:type", "page-list");
|
|
2519
2438
|
}
|
|
2520
|
-
const absPath =
|
|
2439
|
+
const absPath = upath4.join(contextDir, target);
|
|
2521
2440
|
await writeAsXhtml(dom, absPath);
|
|
2522
2441
|
return { pageListResourceTree };
|
|
2523
2442
|
}
|
|
@@ -2534,7 +2453,7 @@ function buildEpubPackageDocument({
|
|
|
2534
2453
|
slugger.reset();
|
|
2535
2454
|
const bookIdentifier = slugger.slug("bookid");
|
|
2536
2455
|
const normalizeDate = (value) => value && `${new Date(value).toISOString().split(".")[0]}Z`;
|
|
2537
|
-
const transformToGenericTextNode = (value, attributes) => [value].flat().filter(Boolean).map((
|
|
2456
|
+
const transformToGenericTextNode = (value, attributes) => [value].flat().filter(Boolean).map((v) => ({ ...attributes || {}, "#text": `${value}` }));
|
|
2538
2457
|
const transformContributor = (contributorMap) => Object.entries(contributorMap).flatMap(
|
|
2539
2458
|
([type, contributor]) => contributor ? [contributor].flat().map((entry, index) => ({
|
|
2540
2459
|
_id: slugger.slug(`${type}-${index + 1}`),
|
|
@@ -2636,7 +2555,7 @@ async function compressEpub({
|
|
|
2636
2555
|
sourceDir
|
|
2637
2556
|
}) {
|
|
2638
2557
|
Logger.debug(`Compressing EPUB: ${target}`);
|
|
2639
|
-
const output =
|
|
2558
|
+
const output = fs4.createWriteStream(target);
|
|
2640
2559
|
const archive = archiver("zip", {
|
|
2641
2560
|
zlib: { level: 9 }
|
|
2642
2561
|
// Compression level
|
|
@@ -2656,8 +2575,8 @@ async function compressEpub({
|
|
|
2656
2575
|
// https://www.w3.org/TR/epub-33/#sec-zip-container-mime
|
|
2657
2576
|
store: true
|
|
2658
2577
|
});
|
|
2659
|
-
archive.directory(
|
|
2660
|
-
archive.directory(
|
|
2578
|
+
archive.directory(upath4.join(sourceDir, "META-INF"), "META-INF");
|
|
2579
|
+
archive.directory(upath4.join(sourceDir, "EPUB"), "EPUB");
|
|
2661
2580
|
archive.finalize();
|
|
2662
2581
|
});
|
|
2663
2582
|
}
|
|
@@ -2674,11 +2593,11 @@ function sortManifestResources(manifest) {
|
|
|
2674
2593
|
async function prepareWebPublicationDirectory({
|
|
2675
2594
|
outputDir
|
|
2676
2595
|
}) {
|
|
2677
|
-
if (
|
|
2596
|
+
if (fs5.existsSync(outputDir)) {
|
|
2678
2597
|
Logger.debug("going to remove existing webpub", outputDir);
|
|
2679
|
-
await
|
|
2598
|
+
await fs5.promises.rm(outputDir, { force: true, recursive: true });
|
|
2680
2599
|
}
|
|
2681
|
-
|
|
2600
|
+
fs5.mkdirSync(outputDir, { recursive: true });
|
|
2682
2601
|
}
|
|
2683
2602
|
function transformPublicationManifest(entity, transformer) {
|
|
2684
2603
|
const { url: transformUrl } = transformer;
|
|
@@ -2775,15 +2694,15 @@ function writePublicationManifest(output, options) {
|
|
|
2775
2694
|
typeof thrownError === "string" ? thrownError : thrownError.stack ?? thrownError.message
|
|
2776
2695
|
);
|
|
2777
2696
|
}
|
|
2778
|
-
|
|
2779
|
-
|
|
2697
|
+
fs5.mkdirSync(upath5.dirname(output), { recursive: true });
|
|
2698
|
+
fs5.writeFileSync(output, JSON.stringify(encodedManifest, null, 2));
|
|
2780
2699
|
return publication;
|
|
2781
2700
|
}
|
|
2782
2701
|
async function retrieveWebbookEntry({
|
|
2783
2702
|
viewerInput,
|
|
2784
2703
|
outputDir
|
|
2785
2704
|
}) {
|
|
2786
|
-
const webbookEntryUrl = viewerInput.webbookPath ?
|
|
2705
|
+
const webbookEntryUrl = viewerInput.webbookPath ? pathToFileURL4(viewerInput.webbookPath).href : viewerInput.webbookEntryUrl;
|
|
2787
2706
|
if (/^https?:/i.test(webbookEntryUrl)) {
|
|
2788
2707
|
Logger.logUpdate("Fetching remote contents");
|
|
2789
2708
|
}
|
|
@@ -2792,7 +2711,7 @@ async function retrieveWebbookEntry({
|
|
|
2792
2711
|
src: webbookEntryUrl,
|
|
2793
2712
|
resourceLoader
|
|
2794
2713
|
});
|
|
2795
|
-
const entryHtml = viewerInput.webbookPath ?
|
|
2714
|
+
const entryHtml = viewerInput.webbookPath ? upath5.basename(viewerInput.webbookPath) : decodeURI(dom.window.location.pathname);
|
|
2796
2715
|
const { manifest, manifestUrl } = await fetchLinkedPublicationManifest({
|
|
2797
2716
|
dom,
|
|
2798
2717
|
resourceLoader,
|
|
@@ -2803,12 +2722,12 @@ async function retrieveWebbookEntry({
|
|
|
2803
2722
|
pathContains2 = (url) => false;
|
|
2804
2723
|
} else {
|
|
2805
2724
|
const rootUrl = /^https?:/i.test(webbookEntryUrl) ? new URL("/", webbookEntryUrl).href : new URL(".", webbookEntryUrl).href;
|
|
2806
|
-
pathContains2 = (url) => !
|
|
2725
|
+
pathContains2 = (url) => !upath5.relative(rootUrl, url).startsWith("..");
|
|
2807
2726
|
}
|
|
2808
2727
|
const retriever = new Map(resourceLoader.fetcherMap);
|
|
2809
2728
|
if (manifest && manifestUrl) {
|
|
2810
|
-
[manifest.resources || []].flat().forEach((
|
|
2811
|
-
const url = typeof
|
|
2729
|
+
[manifest.resources || []].flat().forEach((v) => {
|
|
2730
|
+
const url = typeof v === "string" ? v : v.url;
|
|
2812
2731
|
const fullUrl = new URL(encodeURI(url), manifestUrl).href;
|
|
2813
2732
|
if (!pathContains2(fullUrl) || retriever.has(fullUrl)) {
|
|
2814
2733
|
return;
|
|
@@ -2818,9 +2737,9 @@ async function retrieveWebbookEntry({
|
|
|
2818
2737
|
retriever.set(fullUrl, fetchPromise);
|
|
2819
2738
|
}
|
|
2820
2739
|
});
|
|
2821
|
-
for (const
|
|
2822
|
-
const url = typeof
|
|
2823
|
-
if (!/\.html?$/.test(url) && !(typeof
|
|
2740
|
+
for (const v of [manifest.readingOrder || []].flat()) {
|
|
2741
|
+
const url = typeof v === "string" ? v : v.url;
|
|
2742
|
+
if (!/\.html?$/.test(url) && !(typeof v === "string" || v.encodingFormat === "text/html")) {
|
|
2824
2743
|
continue;
|
|
2825
2744
|
}
|
|
2826
2745
|
const fullUrl = new URL(encodeURI(url), manifestUrl).href;
|
|
@@ -2836,7 +2755,7 @@ async function retrieveWebbookEntry({
|
|
|
2836
2755
|
})
|
|
2837
2756
|
});
|
|
2838
2757
|
subpathResourceLoader.fetcherMap.forEach(
|
|
2839
|
-
(
|
|
2758
|
+
(v2, k) => !retriever.has(k) && retriever.set(k, v2)
|
|
2840
2759
|
);
|
|
2841
2760
|
}
|
|
2842
2761
|
}
|
|
@@ -2854,7 +2773,7 @@ async function retrieveWebbookEntry({
|
|
|
2854
2773
|
const referencedContents = [
|
|
2855
2774
|
...[manifest.readingOrder || []].flat(),
|
|
2856
2775
|
...[manifest.resources || []].flat()
|
|
2857
|
-
].map((
|
|
2776
|
+
].map((v) => typeof v === "string" ? v : v.url);
|
|
2858
2777
|
manifest.resources = [
|
|
2859
2778
|
...[manifest.resources || []].flat(),
|
|
2860
2779
|
...fetchedResources.filter(
|
|
@@ -2865,17 +2784,17 @@ async function retrieveWebbookEntry({
|
|
|
2865
2784
|
}
|
|
2866
2785
|
Logger.debug(
|
|
2867
2786
|
"Saved webbook resources",
|
|
2868
|
-
fetchedResources.map((
|
|
2787
|
+
fetchedResources.map((v) => v.url)
|
|
2869
2788
|
);
|
|
2870
2789
|
Logger.debug(
|
|
2871
2790
|
"Publication manifest from webbook",
|
|
2872
2791
|
manifest && JSON.stringify(manifest, null, 2)
|
|
2873
2792
|
);
|
|
2874
2793
|
return {
|
|
2875
|
-
entryHtmlFile:
|
|
2794
|
+
entryHtmlFile: upath5.join(
|
|
2876
2795
|
outputDir,
|
|
2877
2796
|
entryHtml,
|
|
2878
|
-
...
|
|
2797
|
+
...upath5.extname(entryHtml) ? [] : ["index.html"]
|
|
2879
2798
|
),
|
|
2880
2799
|
manifest
|
|
2881
2800
|
};
|
|
@@ -2891,12 +2810,12 @@ async function supplyWebPublicationManifestForWebbook({
|
|
|
2891
2810
|
const language = config.language || document2.documentElement.lang || void 0;
|
|
2892
2811
|
const title = config.title || document2.title || "";
|
|
2893
2812
|
const author = config.author || document2.querySelector('meta[name="author"]')?.getAttribute("content") || "";
|
|
2894
|
-
const entry =
|
|
2813
|
+
const entry = upath5.relative(outputDir, entryHtmlFile);
|
|
2895
2814
|
const allFiles = await glob("**", {
|
|
2896
2815
|
cwd: outputDir
|
|
2897
2816
|
});
|
|
2898
2817
|
const manifest = writePublicationManifest(
|
|
2899
|
-
|
|
2818
|
+
upath5.join(outputDir, MANIFEST_FILENAME),
|
|
2900
2819
|
{
|
|
2901
2820
|
title,
|
|
2902
2821
|
author,
|
|
@@ -2913,13 +2832,13 @@ async function supplyWebPublicationManifestForWebbook({
|
|
|
2913
2832
|
link.setAttribute("type", "application/ld+json");
|
|
2914
2833
|
link.setAttribute(
|
|
2915
2834
|
"href",
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2835
|
+
upath5.relative(
|
|
2836
|
+
upath5.dirname(entryHtmlFile),
|
|
2837
|
+
upath5.join(outputDir, MANIFEST_FILENAME)
|
|
2919
2838
|
)
|
|
2920
2839
|
);
|
|
2921
2840
|
document2.head.appendChild(link);
|
|
2922
|
-
await
|
|
2841
|
+
await fs5.promises.writeFile(entryHtmlFile, dom.serialize(), "utf8");
|
|
2923
2842
|
Logger.debug(
|
|
2924
2843
|
"Generated publication manifest from HTML",
|
|
2925
2844
|
JSON.stringify(manifest, null, 2)
|
|
@@ -2937,8 +2856,8 @@ async function copyWebPublicationAssets({
|
|
|
2937
2856
|
entries
|
|
2938
2857
|
}) {
|
|
2939
2858
|
const relExportAliases = exportAliases.map(({ source, target }) => ({
|
|
2940
|
-
source:
|
|
2941
|
-
target:
|
|
2859
|
+
source: upath5.relative(input, source),
|
|
2860
|
+
target: upath5.relative(input, target)
|
|
2942
2861
|
})).filter(({ source }) => !source.startsWith(".."));
|
|
2943
2862
|
const assetMatcher = getAssetMatcher({
|
|
2944
2863
|
copyAsset,
|
|
@@ -2977,24 +2896,24 @@ async function copyWebPublicationAssets({
|
|
|
2977
2896
|
)
|
|
2978
2897
|
);
|
|
2979
2898
|
const resources = [];
|
|
2980
|
-
let actualManifestPath =
|
|
2899
|
+
let actualManifestPath = upath5.join(
|
|
2981
2900
|
outputDir,
|
|
2982
|
-
|
|
2901
|
+
upath5.relative(input, manifestPath)
|
|
2983
2902
|
);
|
|
2984
2903
|
for (const file of allFiles) {
|
|
2985
2904
|
const alias = relExportAliases.find(({ source }) => source === file);
|
|
2986
2905
|
const relTarget = alias?.target || file;
|
|
2987
2906
|
resources.push(relTarget);
|
|
2988
|
-
const target =
|
|
2989
|
-
|
|
2990
|
-
await copy2(
|
|
2991
|
-
if (alias && pathEquals(
|
|
2907
|
+
const target = upath5.join(outputDir, relTarget);
|
|
2908
|
+
fs5.mkdirSync(upath5.dirname(target), { recursive: true });
|
|
2909
|
+
await copy2(upath5.join(input, file), target);
|
|
2910
|
+
if (alias && pathEquals(upath5.join(input, alias.source), manifestPath)) {
|
|
2992
2911
|
actualManifestPath = target;
|
|
2993
2912
|
}
|
|
2994
2913
|
}
|
|
2995
2914
|
Logger.debug("webbook publication.json", actualManifestPath);
|
|
2996
2915
|
const manifest = decodePublicationManifest(
|
|
2997
|
-
JSON.parse(
|
|
2916
|
+
JSON.parse(fs5.readFileSync(actualManifestPath, "utf8"))
|
|
2998
2917
|
);
|
|
2999
2918
|
for (const entry of relExportAliases) {
|
|
3000
2919
|
const rewriteAliasPath = (e) => {
|
|
@@ -3026,14 +2945,14 @@ async function copyWebPublicationAssets({
|
|
|
3026
2945
|
...[manifest.resources || []].flat(),
|
|
3027
2946
|
...resources.flatMap((file) => {
|
|
3028
2947
|
if (preDefinedResources.includes(file) || // Omit publication.json itself
|
|
3029
|
-
pathEquals(file,
|
|
2948
|
+
pathEquals(file, upath5.relative(outputDir, actualManifestPath))) {
|
|
3030
2949
|
return [];
|
|
3031
2950
|
}
|
|
3032
2951
|
return file;
|
|
3033
2952
|
})
|
|
3034
2953
|
];
|
|
3035
2954
|
sortManifestResources(manifest);
|
|
3036
|
-
|
|
2955
|
+
fs5.writeFileSync(
|
|
3037
2956
|
actualManifestPath,
|
|
3038
2957
|
JSON.stringify(encodePublicationManifest(manifest), null, 2)
|
|
3039
2958
|
);
|
|
@@ -3065,7 +2984,7 @@ async function buildWebPublication({
|
|
|
3065
2984
|
if (config.input.format === "markdown") {
|
|
3066
2985
|
const entry = [manifest.readingOrder].flat()[0];
|
|
3067
2986
|
if (entry) {
|
|
3068
|
-
entryHtmlFile =
|
|
2987
|
+
entryHtmlFile = upath5.join(
|
|
3069
2988
|
outputDir,
|
|
3070
2989
|
typeof entry === "string" ? entry : entry.url
|
|
3071
2990
|
);
|
|
@@ -3090,7 +3009,7 @@ async function buildWebPublication({
|
|
|
3090
3009
|
webpubDir: outputDir,
|
|
3091
3010
|
entryHtmlFile,
|
|
3092
3011
|
manifest,
|
|
3093
|
-
relManifestPath: actualManifestPath &&
|
|
3012
|
+
relManifestPath: actualManifestPath && upath5.relative(outputDir, actualManifestPath),
|
|
3094
3013
|
target: target.path,
|
|
3095
3014
|
epubVersion: target.version
|
|
3096
3015
|
});
|
|
@@ -3100,29 +3019,29 @@ async function buildWebPublication({
|
|
|
3100
3019
|
|
|
3101
3020
|
// src/processor/theme.ts
|
|
3102
3021
|
import Arborist from "@npmcli/arborist";
|
|
3103
|
-
import
|
|
3104
|
-
import
|
|
3022
|
+
import fs6 from "node:fs";
|
|
3023
|
+
import upath6 from "upath";
|
|
3105
3024
|
function* iterateSymlinksInThemesNodeModules(themesDir) {
|
|
3106
|
-
if (!
|
|
3025
|
+
if (!fs6.existsSync(themesDir)) {
|
|
3107
3026
|
return;
|
|
3108
3027
|
}
|
|
3109
|
-
const nodeModulesDir =
|
|
3110
|
-
if (!
|
|
3028
|
+
const nodeModulesDir = upath6.join(themesDir, "node_modules");
|
|
3029
|
+
if (!fs6.existsSync(nodeModulesDir)) {
|
|
3111
3030
|
return;
|
|
3112
3031
|
}
|
|
3113
|
-
for (const entry of
|
|
3032
|
+
for (const entry of fs6.readdirSync(nodeModulesDir, { withFileTypes: true })) {
|
|
3114
3033
|
if (!entry.isSymbolicLink()) {
|
|
3115
3034
|
continue;
|
|
3116
3035
|
}
|
|
3117
|
-
const linkPath =
|
|
3118
|
-
const target =
|
|
3119
|
-
yield
|
|
3036
|
+
const linkPath = upath6.join(nodeModulesDir, entry.name);
|
|
3037
|
+
const target = fs6.readlinkSync(linkPath);
|
|
3038
|
+
yield upath6.resolve(nodeModulesDir, target);
|
|
3120
3039
|
}
|
|
3121
3040
|
}
|
|
3122
3041
|
function removeThemesDirIfBrokenSymlinks(themesDir) {
|
|
3123
3042
|
for (const target of iterateSymlinksInThemesNodeModules(themesDir)) {
|
|
3124
|
-
if (!
|
|
3125
|
-
|
|
3043
|
+
if (!fs6.existsSync(target)) {
|
|
3044
|
+
fs6.rmSync(themesDir, { recursive: true });
|
|
3126
3045
|
return;
|
|
3127
3046
|
}
|
|
3128
3047
|
}
|
|
@@ -3132,7 +3051,7 @@ async function checkThemeInstallationNecessity({
|
|
|
3132
3051
|
themeIndexes
|
|
3133
3052
|
}) {
|
|
3134
3053
|
removeThemesDirIfBrokenSymlinks(themesDir);
|
|
3135
|
-
if (!
|
|
3054
|
+
if (!fs6.existsSync(themesDir)) {
|
|
3136
3055
|
return [...themeIndexes].some((theme) => theme.type === "package");
|
|
3137
3056
|
}
|
|
3138
3057
|
const commonOpt = {
|
|
@@ -3156,7 +3075,7 @@ async function installThemeDependencies({
|
|
|
3156
3075
|
themesDir,
|
|
3157
3076
|
themeIndexes
|
|
3158
3077
|
}) {
|
|
3159
|
-
|
|
3078
|
+
fs6.mkdirSync(themesDir, { recursive: true });
|
|
3160
3079
|
removeThemesDirIfBrokenSymlinks(themesDir);
|
|
3161
3080
|
try {
|
|
3162
3081
|
const commonOpt = {
|
|
@@ -3173,18 +3092,18 @@ async function installThemeDependencies({
|
|
|
3173
3092
|
)
|
|
3174
3093
|
)
|
|
3175
3094
|
];
|
|
3176
|
-
const rm = existing.filter((
|
|
3095
|
+
const rm = existing.filter((v) => !add.includes(v));
|
|
3177
3096
|
const opt = { ...commonOpt, rm, add };
|
|
3178
3097
|
const arb = new Arborist(opt);
|
|
3179
3098
|
const actualTree = await arb.reify(opt);
|
|
3180
3099
|
for (const child of actualTree.children.values()) {
|
|
3181
3100
|
if (child.resolved?.startsWith("file:")) {
|
|
3182
|
-
const sourcePath =
|
|
3183
|
-
if (
|
|
3184
|
-
|
|
3101
|
+
const sourcePath = upath6.resolve(themesDir, child.resolved.slice(5));
|
|
3102
|
+
if (fs6.existsSync(child.path)) {
|
|
3103
|
+
fs6.rmSync(child.path, { recursive: true });
|
|
3185
3104
|
}
|
|
3186
|
-
const relPath =
|
|
3187
|
-
|
|
3105
|
+
const relPath = upath6.relative(upath6.dirname(child.path), sourcePath);
|
|
3106
|
+
fs6.symlinkSync(relPath, child.path, "junction");
|
|
3188
3107
|
}
|
|
3189
3108
|
}
|
|
3190
3109
|
} catch (error) {
|
|
@@ -3202,21 +3121,21 @@ function locateThemePath(theme, from) {
|
|
|
3202
3121
|
return theme.location;
|
|
3203
3122
|
}
|
|
3204
3123
|
if (theme.type === "file") {
|
|
3205
|
-
return
|
|
3124
|
+
return upath7.relative(from, theme.location);
|
|
3206
3125
|
}
|
|
3207
3126
|
if (theme.importPath) {
|
|
3208
3127
|
return [theme.importPath].flat().map((locator) => {
|
|
3209
|
-
const resolvedPath =
|
|
3210
|
-
if (!pathContains(theme.location, resolvedPath) || !
|
|
3128
|
+
const resolvedPath = upath7.resolve(theme.location, locator);
|
|
3129
|
+
if (!pathContains(theme.location, resolvedPath) || !fs7.existsSync(resolvedPath)) {
|
|
3211
3130
|
throw new Error(
|
|
3212
3131
|
`Could not find a style path ${theme.importPath} for the theme: ${theme.name}.`
|
|
3213
3132
|
);
|
|
3214
3133
|
}
|
|
3215
|
-
return
|
|
3134
|
+
return upath7.relative(from, resolvedPath);
|
|
3216
3135
|
});
|
|
3217
3136
|
} else {
|
|
3218
|
-
const pkgJsonPath =
|
|
3219
|
-
const packageJson = JSON.parse(
|
|
3137
|
+
const pkgJsonPath = upath7.join(theme.location, "package.json");
|
|
3138
|
+
const packageJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf8"));
|
|
3220
3139
|
const maybeStyle = packageJson?.vivliostyle?.theme?.style ?? packageJson.style ?? packageJson.main;
|
|
3221
3140
|
if (!maybeStyle) {
|
|
3222
3141
|
throw new DetailError(
|
|
@@ -3224,7 +3143,7 @@ function locateThemePath(theme, from) {
|
|
|
3224
3143
|
"Please ensure this package satisfies a `vivliostyle.theme.style` property."
|
|
3225
3144
|
);
|
|
3226
3145
|
}
|
|
3227
|
-
return
|
|
3146
|
+
return upath7.relative(from, upath7.join(theme.location, maybeStyle));
|
|
3228
3147
|
}
|
|
3229
3148
|
}
|
|
3230
3149
|
async function cleanupWorkspace({
|
|
@@ -3240,27 +3159,27 @@ async function cleanupWorkspace({
|
|
|
3240
3159
|
}
|
|
3241
3160
|
Logger.debug("cleanup workspace files", workspaceDir);
|
|
3242
3161
|
let movedWorkspacePath;
|
|
3243
|
-
if (pathContains(workspaceDir, themesDir) &&
|
|
3244
|
-
movedWorkspacePath =
|
|
3245
|
-
|
|
3162
|
+
if (pathContains(workspaceDir, themesDir) && fs7.existsSync(themesDir)) {
|
|
3163
|
+
movedWorkspacePath = upath7.join(
|
|
3164
|
+
upath7.dirname(workspaceDir),
|
|
3246
3165
|
`.vs-${Date.now()}`
|
|
3247
3166
|
);
|
|
3248
|
-
const movedThemePath =
|
|
3167
|
+
const movedThemePath = upath7.join(
|
|
3249
3168
|
movedWorkspacePath,
|
|
3250
|
-
|
|
3169
|
+
upath7.relative(workspaceDir, themesDir)
|
|
3251
3170
|
);
|
|
3252
|
-
|
|
3171
|
+
fs7.mkdirSync(upath7.dirname(movedThemePath), { recursive: true });
|
|
3253
3172
|
registerExitHandler(
|
|
3254
3173
|
`Removing the moved workspace directory: ${movedWorkspacePath}`,
|
|
3255
3174
|
() => {
|
|
3256
|
-
if (movedWorkspacePath &&
|
|
3257
|
-
|
|
3175
|
+
if (movedWorkspacePath && fs7.existsSync(movedWorkspacePath)) {
|
|
3176
|
+
fs7.rmSync(movedWorkspacePath, { recursive: true, force: true });
|
|
3258
3177
|
}
|
|
3259
3178
|
}
|
|
3260
3179
|
);
|
|
3261
3180
|
await move(themesDir, movedThemePath);
|
|
3262
3181
|
}
|
|
3263
|
-
await
|
|
3182
|
+
await fs7.promises.rm(workspaceDir, { recursive: true, force: true });
|
|
3264
3183
|
if (movedWorkspacePath) {
|
|
3265
3184
|
await move(movedWorkspacePath, workspaceDir);
|
|
3266
3185
|
}
|
|
@@ -3269,10 +3188,10 @@ async function prepareThemeDirectory({
|
|
|
3269
3188
|
themesDir,
|
|
3270
3189
|
themeIndexes
|
|
3271
3190
|
}) {
|
|
3272
|
-
if (
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3191
|
+
if (fs7.existsSync(upath7.join(themesDir, "packages")) && !fs7.existsSync(upath7.join(themesDir, "node_modules"))) {
|
|
3192
|
+
fs7.renameSync(
|
|
3193
|
+
upath7.join(themesDir, "packages"),
|
|
3194
|
+
upath7.join(themesDir, "node_modules")
|
|
3276
3195
|
);
|
|
3277
3196
|
}
|
|
3278
3197
|
if (await checkThemeInstallationNecessity({ themesDir, themeIndexes })) {
|
|
@@ -3281,7 +3200,7 @@ async function prepareThemeDirectory({
|
|
|
3281
3200
|
}
|
|
3282
3201
|
for (const theme of themeIndexes) {
|
|
3283
3202
|
if (theme.type === "file" && !pathEquals(theme.source, theme.location)) {
|
|
3284
|
-
|
|
3203
|
+
fs7.mkdirSync(upath7.dirname(theme.location), { recursive: true });
|
|
3285
3204
|
await copy3(theme.source, theme.location);
|
|
3286
3205
|
}
|
|
3287
3206
|
}
|
|
@@ -3302,7 +3221,7 @@ async function transformManuscript(entry, {
|
|
|
3302
3221
|
let resourceLoader;
|
|
3303
3222
|
let resourceUrl;
|
|
3304
3223
|
const style = entry.themes.flatMap(
|
|
3305
|
-
(theme) => locateThemePath(theme,
|
|
3224
|
+
(theme) => locateThemePath(theme, upath7.dirname(entry.target))
|
|
3306
3225
|
);
|
|
3307
3226
|
if (source?.type === "file") {
|
|
3308
3227
|
if (source.documentProcessor) {
|
|
@@ -3398,7 +3317,7 @@ async function transformManuscript(entry, {
|
|
|
3398
3317
|
content = await processTocHtml(content, {
|
|
3399
3318
|
entries: manuscriptEntries,
|
|
3400
3319
|
manifestPath,
|
|
3401
|
-
distDir:
|
|
3320
|
+
distDir: upath7.dirname(contentsEntry.target),
|
|
3402
3321
|
tocTitle: contentsEntry.tocTitle,
|
|
3403
3322
|
sectionDepth: contentsEntry.sectionDepth,
|
|
3404
3323
|
styleOptions: contentsEntry,
|
|
@@ -3408,10 +3327,10 @@ async function transformManuscript(entry, {
|
|
|
3408
3327
|
if (entry.rel === "cover") {
|
|
3409
3328
|
const coverEntry = entry;
|
|
3410
3329
|
content = await processCoverHtml(content, {
|
|
3411
|
-
imageSrc:
|
|
3412
|
-
|
|
3330
|
+
imageSrc: upath7.relative(
|
|
3331
|
+
upath7.join(
|
|
3413
3332
|
entryContextDir,
|
|
3414
|
-
|
|
3333
|
+
upath7.relative(workspaceDir, coverEntry.target),
|
|
3415
3334
|
".."
|
|
3416
3335
|
),
|
|
3417
3336
|
coverEntry.coverImageSrc
|
|
@@ -3461,7 +3380,7 @@ async function generateManifest({
|
|
|
3461
3380
|
}) {
|
|
3462
3381
|
const manifestEntries = entries.map((entry) => ({
|
|
3463
3382
|
title: entry.rel === "contents" && entry.tocTitle || entry.title,
|
|
3464
|
-
path:
|
|
3383
|
+
path: upath7.relative(workspaceDir, entry.target),
|
|
3465
3384
|
encodingFormat: !("contentType" in entry) || entry.contentType === "text/markdown" || entry.contentType === "text/x-vivliostyle-custom" || entry.contentType === "text/html" ? void 0 : entry.contentType,
|
|
3466
3385
|
rel: entry.rel
|
|
3467
3386
|
}));
|
|
@@ -3471,7 +3390,7 @@ async function generateManifest({
|
|
|
3471
3390
|
language,
|
|
3472
3391
|
readingProgression,
|
|
3473
3392
|
cover: cover && {
|
|
3474
|
-
url:
|
|
3393
|
+
url: upath7.relative(entryContextDir, cover.src),
|
|
3475
3394
|
name: cover.name
|
|
3476
3395
|
},
|
|
3477
3396
|
entries: manifestEntries,
|
|
@@ -3527,7 +3446,7 @@ function createEntriesRouteLookup(entries, cwd2) {
|
|
|
3527
3446
|
return arr;
|
|
3528
3447
|
};
|
|
3529
3448
|
const cache = entries.reduce((acc, e) => {
|
|
3530
|
-
acc[`/${
|
|
3449
|
+
acc[`/${upath8.relative(cwd2, e.target).normalize().replace(/\\+/g, "/")}`] = e;
|
|
3531
3450
|
return acc;
|
|
3532
3451
|
}, {});
|
|
3533
3452
|
return (uri) => {
|
|
@@ -3546,6 +3465,9 @@ function getWorkspaceMatcher({
|
|
|
3546
3465
|
outputs,
|
|
3547
3466
|
copyAsset
|
|
3548
3467
|
}) {
|
|
3468
|
+
const hasCmykReserveMap = outputs.some(
|
|
3469
|
+
(o) => o.format === "pdf" && o.cmyk && o.cmyk.reserveMap.length > 0
|
|
3470
|
+
);
|
|
3549
3471
|
if (viewerInput.type === "webpub") {
|
|
3550
3472
|
return getWebPubResourceMatcher({
|
|
3551
3473
|
outputs,
|
|
@@ -3553,15 +3475,16 @@ function getWorkspaceMatcher({
|
|
|
3553
3475
|
entries,
|
|
3554
3476
|
cwd: workspaceDir,
|
|
3555
3477
|
manifestPath: viewerInput.manifestPath,
|
|
3556
|
-
copyAsset
|
|
3478
|
+
copyAsset,
|
|
3479
|
+
additionalPatterns: hasCmykReserveMap ? [CMYK_RESERVE_MAP_FILENAME] : []
|
|
3557
3480
|
});
|
|
3558
3481
|
}
|
|
3559
3482
|
let entryFiles = [];
|
|
3560
3483
|
switch (viewerInput.type) {
|
|
3561
3484
|
case "epub":
|
|
3562
3485
|
entryFiles = [
|
|
3563
|
-
|
|
3564
|
-
|
|
3486
|
+
upath8.join(
|
|
3487
|
+
upath8.relative(workspaceDir, viewerInput.epubTmpOutputDir),
|
|
3565
3488
|
"**"
|
|
3566
3489
|
)
|
|
3567
3490
|
];
|
|
@@ -3600,6 +3523,7 @@ function vsDevServerPlugin({
|
|
|
3600
3523
|
if (isWebPubConfig(config) && config.viewerInput.needToGenerateManifest && needToUpdateManifest) {
|
|
3601
3524
|
await generateManifest(config);
|
|
3602
3525
|
}
|
|
3526
|
+
generateCmykReserveMap(config);
|
|
3603
3527
|
const localThemePaths = await prepareThemeDirectory(config);
|
|
3604
3528
|
const entriesLookup = createEntriesRouteLookup(
|
|
3605
3529
|
config.entries,
|
|
@@ -3714,8 +3638,8 @@ function vsDevServerPlugin({
|
|
|
3714
3638
|
}
|
|
3715
3639
|
}
|
|
3716
3640
|
async function invalidate(entry) {
|
|
3717
|
-
const cwd2 =
|
|
3718
|
-
const target =
|
|
3641
|
+
const cwd2 = pathToFileURL5(config.workspaceDir);
|
|
3642
|
+
const target = pathToFileURL5(entry.target);
|
|
3719
3643
|
if (target.href.indexOf(cwd2.href) !== 0) {
|
|
3720
3644
|
return;
|
|
3721
3645
|
}
|
|
@@ -3882,7 +3806,7 @@ function vsDevServerPlugin({
|
|
|
3882
3806
|
|
|
3883
3807
|
// src/vite/vite-plugin-static-serve.ts
|
|
3884
3808
|
import sirv2 from "sirv";
|
|
3885
|
-
import
|
|
3809
|
+
import upath9 from "upath";
|
|
3886
3810
|
import "vite";
|
|
3887
3811
|
function vsStaticServePlugin({
|
|
3888
3812
|
config: _config,
|
|
@@ -3897,7 +3821,7 @@ function vsStaticServePlugin({
|
|
|
3897
3821
|
([base, dirs]) => dirs.map(
|
|
3898
3822
|
(dir) => [
|
|
3899
3823
|
base,
|
|
3900
|
-
sirv2(
|
|
3824
|
+
sirv2(upath9.resolve(config.serverRootDir, dir), {
|
|
3901
3825
|
dev: true,
|
|
3902
3826
|
etag: false
|
|
3903
3827
|
})
|
|
@@ -3926,9 +3850,9 @@ function vsStaticServePlugin({
|
|
|
3926
3850
|
}
|
|
3927
3851
|
|
|
3928
3852
|
// src/vite/vite-plugin-viewer.ts
|
|
3929
|
-
import
|
|
3853
|
+
import fs8 from "node:fs";
|
|
3930
3854
|
import sirv3 from "sirv";
|
|
3931
|
-
import
|
|
3855
|
+
import upath10 from "upath";
|
|
3932
3856
|
import "vite";
|
|
3933
3857
|
var viewerClientId = "@vivliostyle:viewer:client";
|
|
3934
3858
|
var viewerClientRequestPath = `/${viewerClientId}`;
|
|
@@ -3942,13 +3866,13 @@ if (import.meta.hot) {
|
|
|
3942
3866
|
}`
|
|
3943
3867
|
);
|
|
3944
3868
|
function vsViewerPlugin(_) {
|
|
3945
|
-
const serveRootDir =
|
|
3869
|
+
const serveRootDir = upath10.join(viewerRoot, "lib");
|
|
3946
3870
|
const serve = sirv3(serveRootDir, { dev: false, etag: true });
|
|
3947
3871
|
let cachedIndexHtml;
|
|
3948
3872
|
const middleware = async function vivliostyleViewerMiddleware(req, res, next) {
|
|
3949
3873
|
if (req.url === "/" || req.url === "/index.html") {
|
|
3950
3874
|
cachedIndexHtml ??= prependToHead(
|
|
3951
|
-
|
|
3875
|
+
fs8.readFileSync(upath10.join(serveRootDir, "index.html"), "utf-8"),
|
|
3952
3876
|
`<script type="module" src="${viewerClientRequestPath}"></script>`
|
|
3953
3877
|
);
|
|
3954
3878
|
res.statusCode = 200;
|
|
@@ -3983,6 +3907,18 @@ function vsViewerPlugin(_) {
|
|
|
3983
3907
|
}
|
|
3984
3908
|
|
|
3985
3909
|
// src/server.ts
|
|
3910
|
+
function generateCmykReserveMap({
|
|
3911
|
+
outputs,
|
|
3912
|
+
workspaceDir
|
|
3913
|
+
}) {
|
|
3914
|
+
const pdfOutput = outputs.find((o) => o.format === "pdf");
|
|
3915
|
+
if (pdfOutput && "cmyk" in pdfOutput && pdfOutput.cmyk && pdfOutput.cmyk.reserveMap.length) {
|
|
3916
|
+
fs9.writeFileSync(
|
|
3917
|
+
upath11.join(workspaceDir, CMYK_RESERVE_MAP_FILENAME),
|
|
3918
|
+
JSON.stringify(pdfOutput.cmyk.reserveMap)
|
|
3919
|
+
);
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3986
3922
|
function getViewerParams(src, {
|
|
3987
3923
|
size,
|
|
3988
3924
|
cropMarks,
|
|
@@ -3994,8 +3930,9 @@ function getViewerParams(src, {
|
|
|
3994
3930
|
singleDoc,
|
|
3995
3931
|
quick,
|
|
3996
3932
|
viewerParam,
|
|
3997
|
-
base
|
|
3998
|
-
|
|
3933
|
+
base,
|
|
3934
|
+
rootUrl
|
|
3935
|
+
}, { cmykReserveMapUrl } = {}) {
|
|
3999
3936
|
const pageSizeValue = size && ("format" in size ? size.format : `${size.width} ${size.height}`);
|
|
4000
3937
|
function escapeParam(url) {
|
|
4001
3938
|
return url.replace(/&/g, "%26");
|
|
@@ -4003,11 +3940,11 @@ function getViewerParams(src, {
|
|
|
4003
3940
|
let viewerParams = src ? `src=${escapeParam(src)}` : "";
|
|
4004
3941
|
viewerParams += `&bookMode=${!singleDoc}&renderAllPages=${!quick}`;
|
|
4005
3942
|
if (customStyle) {
|
|
4006
|
-
const param = isValidUri(customStyle) ? customStyle :
|
|
3943
|
+
const param = isValidUri(customStyle) ? customStyle : new URL2(upath11.posix.join(base, customStyle), rootUrl).href;
|
|
4007
3944
|
viewerParams += `&style=${escapeParam(param)}`;
|
|
4008
3945
|
}
|
|
4009
3946
|
if (customUserStyle) {
|
|
4010
|
-
const param = isValidUri(customUserStyle) ? customUserStyle :
|
|
3947
|
+
const param = isValidUri(customUserStyle) ? customUserStyle : new URL2(upath11.posix.join(base, customUserStyle), rootUrl).href;
|
|
4011
3948
|
viewerParams += `&userStyle=${escapeParam(param)}`;
|
|
4012
3949
|
}
|
|
4013
3950
|
if (pageSizeValue || cropMarks || bleed || cropOffset || css) {
|
|
@@ -4029,6 +3966,9 @@ function getViewerParams(src, {
|
|
|
4029
3966
|
pageStyle
|
|
4030
3967
|
)}/*</viewer>*/${encodeURIComponent(css ?? "")}`;
|
|
4031
3968
|
}
|
|
3969
|
+
if (cmykReserveMapUrl) {
|
|
3970
|
+
viewerParams += `&cmykReserveMap=${escapeParam(cmykReserveMapUrl)}`;
|
|
3971
|
+
}
|
|
4032
3972
|
if (viewerParam) {
|
|
4033
3973
|
viewerParams += `&${viewerParam}`;
|
|
4034
3974
|
}
|
|
@@ -4052,7 +3992,7 @@ async function getSourceUrl({
|
|
|
4052
3992
|
input = viewerInput.epubOpfPath;
|
|
4053
3993
|
break;
|
|
4054
3994
|
case "epub": {
|
|
4055
|
-
if (!
|
|
3995
|
+
if (!fs9.existsSync(viewerInput.epubTmpOutputDir)) {
|
|
4056
3996
|
await openEpub(viewerInput.epubPath, viewerInput.epubTmpOutputDir);
|
|
4057
3997
|
}
|
|
4058
3998
|
input = getDefaultEpubOpfPath(viewerInput.epubTmpOutputDir);
|
|
@@ -4062,7 +4002,7 @@ async function getSourceUrl({
|
|
|
4062
4002
|
input = viewerInput;
|
|
4063
4003
|
}
|
|
4064
4004
|
return (isValidUri(input) ? new URL2(input) : new URL2(
|
|
4065
|
-
|
|
4005
|
+
upath11.posix.join(base, upath11.relative(workspaceDir, input)),
|
|
4066
4006
|
rootUrl
|
|
4067
4007
|
)).href;
|
|
4068
4008
|
}
|
|
@@ -4081,9 +4021,14 @@ async function getViewerFullUrl({
|
|
|
4081
4021
|
workspaceDir,
|
|
4082
4022
|
rootUrl
|
|
4083
4023
|
});
|
|
4024
|
+
const cmykOutput = config.outputs.find(
|
|
4025
|
+
(o) => o.format === "pdf" && o.cmyk && o.cmyk.reserveMap.length
|
|
4026
|
+
);
|
|
4027
|
+
const cmykReserveMapUrl = cmykOutput ? new URL2(upath11.posix.join(base, CMYK_RESERVE_MAP_FILENAME), rootUrl).href : void 0;
|
|
4084
4028
|
const viewerParams = getViewerParams(
|
|
4085
4029
|
sourceUrl === EMPTY_DATA_URI ? void 0 : sourceUrl,
|
|
4086
|
-
{ base, ...config }
|
|
4030
|
+
{ base, rootUrl, ...config },
|
|
4031
|
+
{ cmykReserveMapUrl }
|
|
4087
4032
|
);
|
|
4088
4033
|
viewerUrl.hash = "";
|
|
4089
4034
|
return `${viewerUrl.href}#${viewerParams}`;
|
|
@@ -4114,8 +4059,8 @@ async function createViteServer({
|
|
|
4114
4059
|
if (config.serverRootDir === config.workspaceDir) {
|
|
4115
4060
|
const { cacheDir } = viteInlineConfig;
|
|
4116
4061
|
registerExitHandler("Removing the Vite cacheDir", () => {
|
|
4117
|
-
if (
|
|
4118
|
-
|
|
4062
|
+
if (fs9.existsSync(cacheDir)) {
|
|
4063
|
+
fs9.rmSync(cacheDir, { recursive: true });
|
|
4119
4064
|
}
|
|
4120
4065
|
});
|
|
4121
4066
|
}
|
|
@@ -4186,8 +4131,6 @@ function vsBrowserPlugin({
|
|
|
4186
4131
|
}
|
|
4187
4132
|
|
|
4188
4133
|
export {
|
|
4189
|
-
loadVivliostyleConfig,
|
|
4190
|
-
warnDeprecatedConfig,
|
|
4191
4134
|
mergeConfig,
|
|
4192
4135
|
mergeInlineConfig,
|
|
4193
4136
|
isWebPubConfig,
|
|
@@ -4201,8 +4144,9 @@ export {
|
|
|
4201
4144
|
vsDevServerPlugin,
|
|
4202
4145
|
vsStaticServePlugin,
|
|
4203
4146
|
vsViewerPlugin,
|
|
4147
|
+
generateCmykReserveMap,
|
|
4204
4148
|
getSourceUrl,
|
|
4205
4149
|
getViewerFullUrl,
|
|
4206
4150
|
createViteServer
|
|
4207
4151
|
};
|
|
4208
|
-
//# sourceMappingURL=chunk-
|
|
4152
|
+
//# sourceMappingURL=chunk-P33ELNYE.js.map
|