UNPKG

mdpdf

Version:

Markdown to PDF command line converter

188 lines (183 loc) 6.72 kB
#!/usr/bin/env node import { resolve, join, dirname } from 'path'; import { existsSync } from 'fs'; import { fileURLToPath } from 'url'; import meow from 'meow'; import { convert } from '../src/index.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const cli = meow(` Usage: $ mdpdf <source> [<destination>] [options] <source> must be a markdown file, with the extension '.md'. Examples: $ mdpdf README.md $ mdpdf README.md --style=styles.css --header=header.hbs --h-height=22mm $ mdpdf README.md --footer=footer.hbs --f-height=22mm --debug $ mdpdf README.md --border-left=30mm Options: --style=<filename> A single css stylesheet you wish to apply to the PDF --header=<filename> A HTML (.html) file to inject into the header of the PDF --h-height=<height> The height of the header section --footer=<filename> A HTML (.html) file to inject into the footer of the PDF --f-height=<height> The height of the footer section --border=<size> Border (top, left, bottom, right; default: 20mm) --border-top=<size> Top border (default: 20mm) --border-left=<size> Left border (default: 20mm) --border-bottom=<size> Bottom border (default: 20mm) --border-right=<size> Right border (default: 20mm) --gh-style Enable default gh-styles, when --style is used --no-emoji Disables emoji conversions --no-highlight Disables syntax highlighting --debug Save the generated html for debugging --help Display this menu --version Display the application version --format=<format> PDF size format: A3, A4, A5, Legal, Letter, Tabloid (Default: A4) --orientation=<orientation> PDF orientation: portrait or landscape (Default: portrait) --title=<title> PDF title, primarily used by some PDF viewers (Default: source filename without extension) --timeout=<timeout> Timeout to apply pass to puppeteer for the maximum duration of rendering. (Default: 30_000) Length parameters (<height> and <size>) require a unit. Valid units are mm, cm, in and px. Global Settings: You can also set a global default stylesheet by setting the MDPDF_STYLES environment variable as the path to your single css stylesheet. The --style flag will override this. `, { importMeta: import.meta, flags: { style: { type: 'string', shortFlag: 's', isMultiple: true, }, header: { type: 'string', shortFlag: 'h', }, footer: { type: 'string', shortFlag: 'f', }, html: { type: 'string', shortFlag: 'html', }, format: { type: 'string', shortFlag: 'r', // 'f' usually denotes file, so we chose 'r' here. }, orientation: { type: 'string', shortFlag: 'o', }, title: { type: 'string', shortFlag: 't', }, timeout: { type: 'number', default: 30000, }, }, }); function isMd(path) { if (!path) { return true; } const accepted = ['md', 'markdown']; const current = path.split('.').pop(); if (current && accepted.indexOf(current) !== -1) { return true; } return false; } const source = cli.input[0]; if (!source || !isMd(source)) { // Invalid source, show help and exit console.error('Source was not provided, or was not a markdown file'); cli.showHelp(1); } const destination = cli.input[1] || source.slice(0, source.indexOf('.md')) + '.pdf'; const debug = cli.flags.debug || false; let style = cli.flags.style || []; const header = cli.flags.header; const headerHeight = cli.flags.hHeight; const footer = cli.flags.footer; const footerHeight = cli.flags.fHeight; const border = cli.flags.border || '20mm'; const borderTop = cli.flags.borderTop || border; const borderLeft = cli.flags.borderLeft || border; const borderBottom = cli.flags.borderBottom || border; const borderRight = cli.flags.borderRight || border; const pdfFormat = cli.flags.format || 'A4'; const pdfOrientation = cli.flags.orientation || 'portrait'; const ghStyleFlag = cli.flags.ghStyle || false; const title = cli.flags.title || null; const timeout = cli.flags.timeout; // Name of the environement variable const envStyleName = 'MDPDF_STYLES'; // If styles have not been provided through the CLI flag, but the environment variable exists if (!style && process.env[envStyleName]) { // Ensure the css file exists const envCssPath = resolve(process.env[envStyleName]); if (existsSync(envCssPath)) { style = [envCssPath]; } } const options = { ghStyle: style.length > 0 ? !!ghStyleFlag : true, // Convert to boolean defaultStyle: true, source: resolve(source), destination: resolve(destination), assetDir: dirname(resolve(source)), // Added assetDir styles: style ? style.map(function (s) { return resolve(s); }) : null, header: header ? resolve(header) : null, footer: footer ? resolve(footer) : null, noEmoji: !!cli.flags.noEmoji || false, // Convert to boolean noHighlight: !!cli.flags.noHighlight || false, // Convert to boolean debug: debug ? resolve(source.slice(0, source.indexOf('.md')) + '.html') : null, pdf: { title: title, format: pdfFormat, orientation: pdfOrientation, quality: '100', base: join('file://', __dirname, '/assets/'), header: headerHeight ? { height: headerHeight, } : undefined, footer: footerHeight ? { height: footerHeight, } : undefined, border: { top: borderTop, left: borderLeft, bottom: borderBottom, right: borderRight, }, timeout: timeout, }, }; (async () => { try { const pdfPath = await convert(options); if (process.stdout.isTTY) { console.log('✨ PDF created successfully at:', pdfPath); } else { console.log(pdfPath); } } catch (err) { console.error(err); process.exitCode = 1; } })(); //# sourceMappingURL=index.js.map