Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Improve file selector not to include unnecessary files into Webpub/EPUB #464

Merged
merged 5 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"devDependencies": {
"@hyrious/esbuild-plugin-commonjs": "^0.2.2",
"@release-it/conventional-changelog": "^5.1.1",
"@types/adm-zip": "^0.5.5",
"@types/archiver": "^5.3.2",
"@types/command-exists": "1.2.0",
"@types/debug": "^4.1.7",
Expand All @@ -85,6 +86,7 @@
"@types/w3c-xmlserializer": "^2.0.2",
"@types/whatwg-mimetype": "^3.0.0",
"@vitest/coverage-v8": "^0.33.0",
"adm-zip": "^0.5.10",
"esbuild": "^0.18.11",
"file-type": "^16.5.3",
"fs-extra": "^11.1.1",
Expand Down
75 changes: 5 additions & 70 deletions src/build.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import chalk from 'chalk';
import { pathToFileURL } from 'node:url';
import terminalLink from 'terminal-link';
import { getExecutableBrowserPath } from './browser.js';
import {
Expand All @@ -8,22 +7,15 @@ import {
collectVivliostyleConfig,
mergeConfig,
} from './input/config.js';
import { exportEpub } from './output/epub.js';
import { buildPDF, buildPDFWithContainer } from './output/pdf.js';
import {
copyWebPublicationAssets,
prepareWebPublicationDirectory,
retrieveWebbookEntry,
supplyWebPublicationManifestForWebbook,
} from './output/webbook.js';
import { buildWebPublication } from './output/webbook.js';
import {
checkOverwriteViolation,
cleanupWorkspace,
compile,
copyAssets,
prepareThemeDirectory,
} from './processor/compile.js';
import type { PublicationManifest } from './schema/publication.schema.js';
import { teardownServer } from './server.js';
import {
checkContainerEnvironment,
Expand All @@ -34,7 +26,6 @@ import {
setLogLevel,
startLogging,
upath,
useTmpDirectory,
} from './util.js';

export interface BuildCliFlags extends CliFlags {
Expand Down Expand Up @@ -122,66 +113,10 @@ export async function build(cliFlags: BuildCliFlags) {
});
}
} else if (format === 'webpub' || format === 'epub') {
const { manifestPath, webbookEntryUrl } = config;
let outputDir: string;
if (format === 'webpub') {
outputDir = target.path;
await prepareWebPublicationDirectory({ outputDir });
} else if (format === 'epub') {
[outputDir] = await useTmpDirectory();
} else {
continue;
}

let entryContextUrl: string;
let entryHtmlFile: string | undefined;
let manifest: PublicationManifest;
if (manifestPath) {
entryContextUrl = pathToFileURL(manifestPath).href;
manifest = await copyWebPublicationAssets({
...config,
input: config.workspaceDir,
outputDir,
manifestPath,
});
if (config.input.format === 'markdown') {
const entry = [manifest.readingOrder].flat()[0];
if (entry) {
entryHtmlFile = upath.join(
outputDir,
typeof entry === 'string' ? entry : entry.url,
);
}
}
} else if (webbookEntryUrl) {
const ret = await retrieveWebbookEntry({
webbookEntryUrl,
outputDir,
});
entryContextUrl = webbookEntryUrl;
entryHtmlFile = ret.entryHtmlFile;
manifest =
ret.manifest ||
(await supplyWebPublicationManifestForWebbook({
...config,
entryHtmlFile: ret.entryHtmlFile,
outputDir,
}));
} else {
continue;
}

if (format === 'epub') {
await exportEpub({
webpubDir: outputDir,
entryHtmlFile,
entryContextUrl,
manifest,
target: target.path,
epubVersion: target.version,
});
}
output = target.path;
output = await buildWebPublication({
...config,
target,
});
}
if (output) {
const formattedOutput = chalk.bold.green(upath.relative(cwd, output));
Expand Down
38 changes: 10 additions & 28 deletions src/output/epub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,22 @@ const appendManifestProperty = (entry: ManifestEntry, newProperty: string) => {
export async function exportEpub({
webpubDir,
entryHtmlFile,
entryContextUrl,
manifest,
relManifestPath,
target,
epubVersion,
}: {
webpubDir: string;
entryHtmlFile?: string;
entryContextUrl?: string;
manifest: PublicationManifest;
relManifestPath?: string;
target: string;
epubVersion: '3.0';
}) {
debug('Export EPUB', {
webpubDir,
entryContextUrl,
entryHtmlFile,
relManifestPath,
target,
epubVersion,
});
Expand Down Expand Up @@ -221,9 +221,7 @@ export async function exportEpub({
const htmlFiles = Object.keys(manifestItem).filter((url) =>
/\.html?$/.test(url),
);
let tocHtml = htmlFiles.find(
(f) => f === (tocResource?.url || entryHtmlRelPath),
);
let tocHtml = htmlFiles.find((f) => f === tocResource?.url);
const readingOrder = [manifest.readingOrder || entryHtmlRelPath]
.flat()
.flatMap((v) => (v ? (typeof v === 'string' ? { url: v } : v) : []));
Expand All @@ -233,7 +231,8 @@ export async function exportEpub({
'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.',
),
);
tocHtml = readingOrder[0].url;
tocHtml =
htmlFiles.find((f) => f === entryHtmlRelPath) || readingOrder[0].url;
}
const spineItems = readingOrder.map<SpineEntry>(({ url }) => ({
href: changeExtname(url, '.xhtml'),
Expand Down Expand Up @@ -267,8 +266,6 @@ export async function exportEpub({
parseResult = await transpileHtmlToXhtml({
target,
contextDir: upath.join(tmpDir, 'EPUB'),
entryContextUrl:
entryContextUrl || pathToFileURL(upath.join(webpubDir, '/')).href,
landmarks,
isTocHtml,
isPagelistHtml: target === (pageListResource?.url || entryHtmlRelPath),
Expand Down Expand Up @@ -316,7 +313,7 @@ export async function exportEpub({
await processHtml(target, false);
}

let { tocParseTree, linkedPubManifest } = tocProcessResult;
let { tocParseTree } = tocProcessResult;
if (!tocParseTree) {
tocParseTree = await supplyTocNavElement({
tocHtml,
Expand All @@ -326,9 +323,9 @@ export async function exportEpub({
docLanguages,
});
}
if (linkedPubManifest) {
await remove(upath.join(tmpDir, 'EPUB', linkedPubManifest));
delete manifestItem[linkedPubManifest];
if (relManifestPath) {
await remove(upath.join(tmpDir, 'EPUB', relManifestPath));
delete manifestItem[relManifestPath];
}

// EPUB/toc.ncx
Expand Down Expand Up @@ -377,22 +374,19 @@ export async function exportEpub({
async function transpileHtmlToXhtml({
target,
contextDir,
entryContextUrl,
landmarks,
isTocHtml,
isPagelistHtml,
}: {
target: string;
contextDir: string;
entryContextUrl: string;
landmarks: LandmarkEntry[];
isTocHtml: boolean;
isPagelistHtml: boolean;
}): Promise<{
dom: JSDOM;
tocParseTree?: TocResourceTreeRoot;
pageListParseTree?: PageListResourceTreeRoot;
linkedPubManifest?: string;
hasMathmlContent: boolean;
hasRemoteResources: boolean;
hasScriptedContent: boolean;
Expand Down Expand Up @@ -424,7 +418,6 @@ async function transpileHtmlToXhtml({

let tocParseTree: TocResourceTreeRoot | undefined;
let pageListParseTree: PageListResourceTreeRoot | undefined;
let linkedPubManifest: string | undefined;

if (isTocHtml) {
if (!document.querySelector('[epub:type="toc"]')) {
Expand Down Expand Up @@ -473,16 +466,6 @@ async function transpileHtmlToXhtml({
if (scriptEl?.getAttribute('type') === 'application/ld+json') {
scriptEl.parentNode?.removeChild(scriptEl);
}
} else {
const entryUrl = entryContextUrl;
const publicationUrl = new URL(href, new URL(target, entryUrl)).href;
const rootUrl = /^https?:/i.test(entryUrl)
? new URL('/', entryUrl).href
: new URL('.', entryUrl).href;
const relPublicationPath = upath.relative(rootUrl, publicationUrl);
if (!relPublicationPath.startsWith('..')) {
linkedPubManifest = relPublicationPath;
}
}
publicationLinkEl.parentNode?.removeChild(publicationLinkEl);
}
Expand All @@ -505,7 +488,6 @@ async function transpileHtmlToXhtml({
dom,
tocParseTree,
pageListParseTree,
linkedPubManifest,
// FIXME: Yes, I recognize this implementation is inadequate.
hasMathmlContent: !!document.querySelector('math'),
hasRemoteResources: !!document.querySelector(
Expand Down
Loading