From bb466261ba28f283e01e01260a4de04c2c398c6d Mon Sep 17 00:00:00 2001 From: simonhaenisch Date: Sun, 26 Jan 2020 19:04:29 +0800 Subject: [PATCH] fix: relative paths --- readme.md | 2 ++ src/lib/get-output-file-path.ts | 10 ++++------ src/lib/md-to-pdf.ts | 12 +++++++----- src/lib/write-output.ts | 29 ++++++++++++++--------------- src/test/lib.spec.ts | 4 ++-- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/readme.md b/readme.md index f82849f..d4e80d3 100644 --- a/readme.md +++ b/readme.md @@ -78,6 +78,8 @@ The pdf is generated into the same directory as the source file and uses the sam md-to-pdf ./**/*.md ``` +_(You might need to enable the `globstar` option in bash for recursive globbing)_ + Alternatively, you can pass the markdown in from `stdin`: ```sh diff --git a/src/lib/get-output-file-path.ts b/src/lib/get-output-file-path.ts index d5be34e..5abdb47 100644 --- a/src/lib/get-output-file-path.ts +++ b/src/lib/get-output-file-path.ts @@ -1,12 +1,10 @@ -import { parse, join } from 'path'; -import { Config } from './config'; +import { parse, resolve } from 'path'; /** - * Derive the output file path from the source markdown file. + * Derive the output file path from a source file. */ -export const getOutputFilePath = (mdFilePath: string, config: Partial) => { +export const getOutputFilePath = (mdFilePath: string, extension: 'html' | 'pdf') => { const { dir, name } = parse(mdFilePath); - const extension = config.as_html ? 'html' : 'pdf'; - return join(dir, `${name}.${extension}`); + return resolve(dir, `${name}.${extension}`); }; diff --git a/src/lib/md-to-pdf.ts b/src/lib/md-to-pdf.ts index af759f7..c3ec1b8 100644 --- a/src/lib/md-to-pdf.ts +++ b/src/lib/md-to-pdf.ts @@ -12,12 +12,12 @@ import { writeOutput } from './write-output'; * Convert markdown to pdf. */ export const convertMdToPdf = async (input: { path: string } | { content: string }, config: Config, args: any = {}) => { - const mdContent = + const mdFileContent = 'content' in input ? input.content - : await readFile(resolve(input.path), args['--md-file-encoding'] || config.md_file_encoding); + : await readFile(input.path, args['--md-file-encoding'] || config.md_file_encoding); - const { content: md, data: frontMatterConfig } = grayMatter(mdContent); + const { content: md, data: frontMatterConfig } = grayMatter(mdFileContent); // merge front-matter config config = { @@ -57,7 +57,7 @@ export const convertMdToPdf = async (input: { path: string } | { content: string if (!config.dest) { config.dest = 'path' in input - ? getOutputFilePath(input.path, config) + ? getOutputFilePath(input.path, config.as_html ? 'html' : 'pdf') : resolve(process.cwd(), `output.${config.as_html ? 'html' : 'pdf'}`); } @@ -72,7 +72,9 @@ export const convertMdToPdf = async (input: { path: string } | { content: string const html = getHtml(md, config); - const output = await writeOutput(mdContent, html, config); + const relativePath = 'path' in input ? resolve(input.path).replace(config.basedir, '') : '/'; + + const output = await writeOutput(html, relativePath, config); if (!('filename' in output)) { throw new Error(`Failed to create ${config.as_html ? 'HTML' : 'PDF'}.`); diff --git a/src/lib/write-output.ts b/src/lib/write-output.ts index 082f3ce..c057702 100644 --- a/src/lib/write-output.ts +++ b/src/lib/write-output.ts @@ -1,7 +1,6 @@ import { writeFile as fsWriteFile } from 'fs'; import { promisify } from 'util'; import puppeteer from 'puppeteer'; -import { getOutputFilePath } from './get-output-file-path'; import { isHttpUrl } from './is-http-url'; import { Config } from './config'; @@ -13,15 +12,19 @@ const writeFile = promisify(fsWriteFile); * The reason that relative paths are resolved properly is that the base dir is served locally */ export const writeOutput = async ( - mdContent: string, html: string, + relativePath: string, config: Config, ): Promise<{} | { filename: string; content: string | Buffer }> => { + if (!config.dest) { + throw new Error('No output file destination has been specified.'); + } + const browser = await puppeteer.launch({ devtools: config.devtools, ...config.launch_options }); const page = await browser.newPage(); - await page.goto(`http://localhost:${config.port}`); + await page.goto(`http://localhost:${config.port}${relativePath}`); // make sure relative paths work as expected await page.setContent(html); // overwrite the page content with what was generated from the markdown await Promise.all([ @@ -42,26 +45,22 @@ export const writeOutput = async ( page.evaluate(() => history.pushState(undefined, '', '#')), ]); - /** - * @todo should it be `getOutputFilePath(config.dest || mdFilePath, config)`? - */ - const outputFilePath = config.dest || getOutputFilePath(mdContent, config); - let outputFileContent: string | Buffer = ''; if (config.devtools) { await new Promise(resolve => page.on('close', resolve)); - } else if (config.as_html) { - outputFileContent = await page.content(); - await writeFile(outputFilePath, outputFileContent); } else { - await page.emulateMediaType('screen'); - outputFileContent = await page.pdf(config.pdf_options); + if (config.as_html) { + outputFileContent = await page.content(); + } else { + await page.emulateMediaType('screen'); + outputFileContent = await page.pdf(config.pdf_options); + } - await writeFile(outputFilePath, outputFileContent); + await writeFile(config.dest, outputFileContent); } await browser.close(); - return config.devtools ? {} : { filename: outputFilePath, content: outputFileContent }; + return config.devtools ? {} : { filename: config.dest, content: outputFileContent }; }; diff --git a/src/test/lib.spec.ts b/src/test/lib.spec.ts index df78087..c67177a 100644 --- a/src/test/lib.spec.ts +++ b/src/test/lib.spec.ts @@ -105,8 +105,8 @@ test('getMarked should accept a custom renderer with custom code highlighter', t test('getOutputFilePath should return the same path but with different extension', t => { const mdFilePath = posix.join('/', 'var', 'foo', 'bar.md'); - t.is(getOutputFilePath(mdFilePath, {}), `${sep}var${sep}foo${sep}bar.pdf`); - t.is(getOutputFilePath(mdFilePath, { as_html: true }), `${sep}var${sep}foo${sep}bar.html`); + t.is(getOutputFilePath(mdFilePath, 'pdf'), `${sep}var${sep}foo${sep}bar.pdf`); + t.is(getOutputFilePath(mdFilePath, 'html'), `${sep}var${sep}foo${sep}bar.html`); }); // --