Skip to content

Commit

Permalink
fix: re-enable using commands as api
Browse files Browse the repository at this point in the history
  • Loading branch information
zwaldowski committed Jan 24, 2022
1 parent 3569a0d commit 2c98e90
Show file tree
Hide file tree
Showing 12 changed files with 433 additions and 387 deletions.
125 changes: 125 additions & 0 deletions src/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import chalk from 'chalk';
import terminalLink from 'terminal-link';
import path from 'upath';
import { getExecutableBrowserPath } from './browser';
import { checkOverwriteViolation, compile, copyAssets } from './builder';
import {
CliFlags,
collectVivliostyleConfig,
mergeConfig,
MergedConfig,
} from './config';
import { checkContainerEnvironment } from './container';
import { buildPDF, buildPDFWithContainer } from './pdf';
import { teardownServer } from './server';
import { cwd, debug, log, startLogging, stopLogging } from './util';
import { exportWebPublication } from './webbook';

export interface BuildCliFlags extends CliFlags {
output?: {
output?: string;
format?: string;
}[];
bypassedPdfBuilderOption?: string;
}

export async function build(cliFlags: BuildCliFlags) {
if (cliFlags.bypassedPdfBuilderOption) {
const option = JSON.parse(cliFlags.bypassedPdfBuilderOption);
// Host doesn't know inside path of chromium path
option.executableChromium = getExecutableBrowserPath();
debug('bypassedPdfBuilderOption', option);

await buildPDF(option);
log();
return;
}

const isInContainer = checkContainerEnvironment();
if (!isInContainer) {
startLogging('Collecting build config');
}

const loadedConf = collectVivliostyleConfig(cliFlags);
const { vivliostyleConfig, vivliostyleConfigPath } = loadedConf;
cliFlags = loadedConf.cliFlags;

const context = vivliostyleConfig ? path.dirname(vivliostyleConfigPath) : cwd;

const config = await mergeConfig(cliFlags, vivliostyleConfig, context);
checkUnsupportedOutputs(config);

// check output path not to overwrite source files
for (const target of config.outputs) {
checkOverwriteViolation(config, target.path, target.format);
}

// build artifacts
if (config.manifestPath) {
await compile(config);
await copyAssets(config);
}

// generate files
for (const target of config.outputs) {
let output: string | null = null;
if (target.format === 'pdf') {
if (!isInContainer && target.renderMode === 'docker') {
output = await buildPDFWithContainer({
...config,
input: (config.manifestPath ??
config.webbookEntryPath ??
config.epubOpfPath) as string,
target,
});
} else {
output = await buildPDF({
...config,
input: (config.manifestPath ??
config.webbookEntryPath ??
config.epubOpfPath) as string,
target,
});
}
} else if (target.format === 'webpub') {
if (!config.manifestPath) {
continue;
}
output = await exportWebPublication({
...config,
input: config.workspaceDir,
output: target.path,
});
}
if (output) {
const formattedOutput = chalk.bold.green(path.relative(cwd, output));
log(
`\n${terminalLink(formattedOutput, 'file://' + output, {
fallback: () => formattedOutput,
})} has been created.`,
);
}
}

if (!isInContainer) {
stopLogging('Built successfully.', '🎉');
}

teardownServer();
}

function checkUnsupportedOutputs({
webbookEntryPath,
epubOpfPath,
outputs,
}: MergedConfig) {
if (webbookEntryPath && outputs.some((t) => t.format === 'webpub')) {
throw new Error(
'Exporting webpub format from single HTML input is not supported.',
);
} else if (epubOpfPath && outputs.some((t) => t.format === 'webpub')) {
throw new Error(
'Exporting webpub format from EPUB or OPF file is not supported.',
);
}
}
11 changes: 2 additions & 9 deletions src/commands/build.parser.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import commander from 'commander';
import { CliFlags, validateTimeoutFlag } from '../config';
import { BuildCliFlags } from '../build';
import { validateTimeoutFlag } from '../config';
import { checkOutputFormat, detectOutputFormat, OutputFormat } from '../output';

export interface BuildCliFlags extends CliFlags {
output?: {
output?: string;
format?: string;
}[];
bypassedPdfBuilderOption?: string;
}

export function setupBuildParserProgram(): commander.Command {
// Provide an order-sensitive command parser
// ex: "-o foo -o bar -f baz"
Expand Down
124 changes: 3 additions & 121 deletions src/commands/build.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
import chalk from 'chalk';
import process from 'process';
import terminalLink from 'terminal-link';
import path from 'upath';
import { getExecutableBrowserPath } from '../browser';
import { checkOverwriteViolation, compile, copyAssets } from '../builder';
import { collectVivliostyleConfig, mergeConfig, MergedConfig } from '../config';
import { checkContainerEnvironment } from '../container';
import { buildPDF, buildPDFWithContainer } from '../pdf';
import { teardownServer } from '../server';
import {
cwd,
debug,
gracefulError,
log,
startLogging,
stopLogging,
} from '../util';
import { exportWebPublication } from '../webbook';
import { BuildCliFlags, setupBuildParserProgram } from './build.parser';
import { build } from '../build';
import { gracefulError } from '../util';
import { setupBuildParserProgram } from './build.parser';

try {
const program = setupBuildParserProgram();
Expand Down Expand Up @@ -51,105 +35,3 @@ try {
} catch (err) {
gracefulError(err);
}

export default async function build(cliFlags: BuildCliFlags) {
if (cliFlags.bypassedPdfBuilderOption) {
const option = JSON.parse(cliFlags.bypassedPdfBuilderOption);
// Host doesn't know inside path of chromium path
option.executableChromium = getExecutableBrowserPath();
debug('bypassedPdfBuilderOption', option);

await buildPDF(option);
log();
process.exit(0);
}

const isInContainer = checkContainerEnvironment();
if (!isInContainer) {
startLogging('Collecting build config');
}

const loadedConf = collectVivliostyleConfig(cliFlags);
const { vivliostyleConfig, vivliostyleConfigPath } = loadedConf;
cliFlags = loadedConf.cliFlags;

const context = vivliostyleConfig ? path.dirname(vivliostyleConfigPath) : cwd;

const config = await mergeConfig(cliFlags, vivliostyleConfig, context);
checkUnsupportedOutputs(config);

// check output path not to overwrite source files
for (const target of config.outputs) {
checkOverwriteViolation(config, target.path, target.format);
}

// build artifacts
if (config.manifestPath) {
await compile(config);
await copyAssets(config);
}

// generate files
for (const target of config.outputs) {
let output: string | null = null;
if (target.format === 'pdf') {
if (!isInContainer && target.renderMode === 'docker') {
output = await buildPDFWithContainer({
...config,
input: (config.manifestPath ??
config.webbookEntryPath ??
config.epubOpfPath) as string,
target,
});
} else {
output = await buildPDF({
...config,
input: (config.manifestPath ??
config.webbookEntryPath ??
config.epubOpfPath) as string,
target,
});
}
} else if (target.format === 'webpub') {
if (!config.manifestPath) {
continue;
}
output = await exportWebPublication({
...config,
input: config.workspaceDir,
output: target.path,
});
}
if (output) {
const formattedOutput = chalk.bold.green(path.relative(cwd, output));
log(
`\n${terminalLink(formattedOutput, 'file://' + output, {
fallback: () => formattedOutput,
})} has been created.`,
);
}
}

if (!isInContainer) {
stopLogging('Built successfully.', '🎉');
}

teardownServer();
process.exit(0);
}

export function checkUnsupportedOutputs({
webbookEntryPath,
epubOpfPath,
outputs,
}: MergedConfig) {
if (webbookEntryPath && outputs.some((t) => t.format === 'webpub')) {
throw new Error(
'Exporting webpub format from single HTML input is not supported.',
);
} else if (epubOpfPath && outputs.some((t) => t.format === 'webpub')) {
throw new Error(
'Exporting webpub format from EPUB or OPF file is not supported.',
);
}
}
8 changes: 0 additions & 8 deletions src/commands/init.parser.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import commander from 'commander';

export interface InitCliFlags {
title?: string;
author?: string;
language?: string;
theme?: string;
size?: string;
}

export function setupInitParserProgram(): commander.Command {
const program = new commander.Command();
program
Expand Down
57 changes: 3 additions & 54 deletions src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import chalk from 'chalk';
import fs from 'fs';
import path from 'upath';
import { CONTAINER_IMAGE } from '../container';
import { cwd, gracefulError, log } from '../util';
import { InitCliFlags, setupInitParserProgram } from './init.parser';
import { init } from '../init';
import { gracefulError } from '../util';
import { setupInitParserProgram } from './init.parser';

try {
const program = setupInitParserProgram();
Expand All @@ -19,51 +16,3 @@ try {
} catch (err) {
gracefulError(err);
}

export default async function init(cliFlags: InitCliFlags) {
const vivliostyleConfigPath = path.join(cwd, 'vivliostyle.config.js');

if (fs.existsSync(vivliostyleConfigPath)) {
return log(
`${chalk.yellow('vivliostyle.config.js already exists. aborting.')}`,
);
}

// prettier-ignore
const vivliostyleConfig = `module.exports = {
title: '${ cliFlags.title || 'Principia'}', // populated into 'publication.json', default to 'title' of the first entry or 'name' in 'package.json'.
author: '${cliFlags.author || 'Isaac Newton'}', // default to 'author' in 'package.json' or undefined
${cliFlags.language ? '' : '// '}language: '${cliFlags.language || 'la'}',
${cliFlags.size ? '' : '// '}size: '${cliFlags.size || 'A4'}',
${cliFlags.theme ? '' : '// '}theme: '${cliFlags.theme || ''}', // .css or local dir or npm package. default to undefined
image: '${CONTAINER_IMAGE}',
entry: [ // **required field**
// 'introduction.md', // 'title' is automatically guessed from the file (frontmatter > first heading)
// {
// path: 'epigraph.md',
// title: 'おわりに', // title can be overwritten (entry > file),
// theme: '@vivliostyle/theme-whatever' // theme can be set indivisually. default to root 'theme'
// },
// 'glossary.html' // html is also acceptable
], // 'entry' can be 'string' or 'object' if there's only single markdown file
// entryContext: './manuscripts', // default to '.' (relative to 'vivliostyle.config.js')
// output: [ // path to generate draft file(s). default to '{title}.pdf'
// './output.pdf', // the output format will be inferred from the name.
// {
// path: './book',
// format: 'webpub',
// },
// ],
// workspaceDir: '.vivliostyle', // directory which is saved intermediate files.
// toc: true, // whether generate and include ToC HTML or not, default to 'false'.
// cover: './cover.png', // cover image. default to undefined.
// vfm: { // options of VFM processor
// hardLineBreaks: true, // converts line breaks of VFM to <br> tags. default to 'false'.
// disableFormatHtml: true, // disables HTML formatting. default to 'false'.
// },
};
`;

fs.writeFileSync(vivliostyleConfigPath, vivliostyleConfig);
log(`Successfully created ${chalk.cyan('vivliostyle.config.js')}`);
}
3 changes: 0 additions & 3 deletions src/commands/preview.parser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import commander from 'commander';
import { CliFlags } from '../config';

export interface PreviewCliFlags extends CliFlags {}

export function setupPreviewParserProgram(): commander.Command {
const program = new commander.Command();
Expand Down
Loading

0 comments on commit 2c98e90

Please sign in to comment.