From a21a14a7cca5bc449342dfa4ca0338c4fbd6c067 Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Sun, 19 Apr 2020 17:29:37 +0200 Subject: [PATCH] Allow to include own style(s) into HTML produced by CLI Resolves #6 --- packages/ipynb2html-cli/src/cli.ts | 38 +++++++++++++++++++++++------ packages/ipynb2html-cli/src/page.ts | 14 ++++++----- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/packages/ipynb2html-cli/src/cli.ts b/packages/ipynb2html-cli/src/cli.ts index d7d0f6f..78c640d 100644 --- a/packages/ipynb2html-cli/src/cli.ts +++ b/packages/ipynb2html-cli/src/cli.ts @@ -3,7 +3,7 @@ import minimist from 'minimist' import minimistOptions from 'minimist-options' import { Document } from 'nodom' import { exit } from 'process' -import { $INLINE_JSON } from 'ts-transformer-inline-file' +import { $INLINE_FILE, $INLINE_JSON } from 'ts-transformer-inline-file' import * as ipynb2html from 'ipynb2html' @@ -11,6 +11,8 @@ import renderPage from './page' const { version, bugs: bugsUrl } = $INLINE_JSON('../package.json') +const notebookCss = $INLINE_FILE('../../ipynb2html/styles/notebook.css') +const pageCss = $INLINE_FILE('./page.css') const progName = 'ipynb2html' const helpMsg = `\ @@ -24,13 +26,20 @@ Arguments: provided, the output will be written to STDOUT. Options: - -d --debug Print debug messages. - -h --help Show this message and exit. - -V --version Print version and exit. + -d --debug Print debug messages. + + -s --style Comma separated stylesheet(s) to embed into the output + HTML. The stylesheet may be a path to a CSS file, + "@base" for the base ipynb2html style, or "@default" + for the default full page style. Default is @default. + + -h --help Show this message and exit. + + -V --version Print version and exit. Exit Codes: - 1 Generic error code. - 2 Missing required arguments or invalid option. + 1 Generic error code. + 2 Missing required arguments or invalid option. Please report bugs at <${bugsUrl}>. ` @@ -39,9 +48,14 @@ function logErr (msg: string): void { console.error(`${progName}: ${msg}`) } +function arrify (obj: T | T[]): T[] { + return Array.isArray(obj) ? obj : [obj] +} + function parseCliArgs (argv: string[]) { const opts = minimist(argv, minimistOptions({ debug: { alias: 'd', type: 'boolean' }, + style: { alias: 's', type: 'string', default: '@default' }, version: { alias: 'V', type: 'boolean' }, help: { alias: 'h', type: 'boolean' }, arguments: 'string', @@ -73,24 +87,34 @@ function parseCliArgs (argv: string[]) { const [input, output] = opts._ return { + styles: arrify(opts.style).join(',').split(/,\s*/), debug: opts.debug as boolean, input: input === '-' ? 0 : input, // 0 = stdin output, } } +function loadStyle (name: string): string { + switch (name) { + case '@base': return notebookCss + case '@default': return pageCss + notebookCss + default: return fs.readFileSync(name, 'utf8') + } +} + export default (argv: string[]): void => { const opts = parseCliArgs(argv) try { const notebook = JSON.parse(fs.readFileSync(opts.input, 'utf-8')) + const style = opts.styles.map(loadStyle).join('\n') const title = ipynb2html.readNotebookTitle(notebook) ?? 'Notebook' const renderNotebook = ipynb2html.createRenderer(new Document()) const contents = renderNotebook(notebook).outerHTML - const html = renderPage(contents, title) + const html = renderPage({ contents, title, style }) if (opts.output) { fs.writeFileSync(opts.output, html) diff --git a/packages/ipynb2html-cli/src/page.ts b/packages/ipynb2html-cli/src/page.ts index ad8083e..8552e4c 100644 --- a/packages/ipynb2html-cli/src/page.ts +++ b/packages/ipynb2html-cli/src/page.ts @@ -1,11 +1,13 @@ import { version } from 'ipynb2html' -import { $INLINE_FILE } from 'ts-transformer-inline-file' - -const notebookCss = $INLINE_FILE('../../ipynb2html/styles/notebook.css') -const pageCss = $INLINE_FILE('./page.css') -export default (contents: string, title: string): string => `\ +export type Options = { + contents: string, + title: string, + style: string, +} + +export default ({ contents, title, style }: Options): string => `\ @@ -22,7 +24,7 @@ export default (contents: string, title: string): string => `\ integrity="sha384-BdGj8xC2eZkQaxoQ8nSLefg4AV4/AwB3Fj+8SUSo7pnKP6Eoy18liIKTPn9oBYNG" crossorigin="anonymous">