Skip to content

Commit

Permalink
Start some upgrades
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotblackburn committed Dec 26, 2023
1 parent ce285ed commit a698f5d
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 98 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ In text emoji's are also supported, but there are a few instances of shorthand w

## Programatic API

The API is very straight forward with a single function `convert()` which takes some options. The convert method uses a promise generated by the [Bluebird.js](bluebirdjs.com) library. For a full example see the [bin/index.js](./bin/index.js)!
The API is very straight forward with a single function `convert()` which takes some options. The convert method uses a promise. For a full example see the [bin/index.js](./bin/index.js)!

### Example API usage

Expand Down
2 changes: 1 addition & 1 deletion examples/api/md-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ In text emoji's are also supported, but there are a few instances of shorthand w

## Programatic API

The API is very straight forward with a single function `convert()` which takes some options. The convert method uses a promise generated by the [Bluebird.js](bluebirdjs.com) library. For a full example see the [bin/index.js](./bin/index.js)!
The API is very straight forward with a single function `convert()` which takes some options. The convert method uses a promise. For a full example see the [bin/index.js](./bin/index.js)!

### Example API Usage

Expand Down
2 changes: 1 addition & 1 deletion examples/footers/md-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ In text emoji's are also supported, but there are a few instances of shorthand w

## Programatic API

The API is very straight forward with a single function `convert()` which takes some options. The convert method uses a promise generated by the [Bluebird.js](bluebirdjs.com) library. For a full example see the [bin/index.js](./bin/index.js)!
The API is very straight forward with a single function `convert()` which takes some options. The convert method uses a promise. For a full example see the [bin/index.js](./bin/index.js)!

### Example API Usage

Expand Down
2 changes: 1 addition & 1 deletion examples/headers/md-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ In text emoji's are also supported, but there are a few instances of shorthand w

## Programatic API

The API is very straight forward with a single function `convert()` which takes some options. The convert method uses a promise generated by the [Bluebird.js](bluebirdjs.com) library. For a full example see the [bin/index.js](./bin/index.js)!
The API is very straight forward with a single function `convert()` which takes some options. The convert method uses a promise. For a full example see the [bin/index.js](./bin/index.js)!

### Example API Usage

Expand Down
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "mdpdf",
"version": "2.0.4",
"description": "Markdown to PDF command line converter",
"type": "module",
"main": "./src/index.js",
"scripts": {
"lint": "prettier --trailing-comma es5 --single-quote --list-different '{src,tests,bin}/**/*.js'",
Expand Down Expand Up @@ -36,20 +37,19 @@
},
"homepage": "https://github.com/bluehatbrit/mdpdf#readme",
"dependencies": {
"bluebird": "^3.4.7",
"cheerio": "^0.22.0",
"file-url": "^2.0.2",
"handlebars": "^4.1.2",
"file-url": "^4.0.0",
"handlebars": "^4.7.8",
"loophole": "^1.1.0",
"meow": "^3.7.0",
"prettier": "^1.15.3",
"puppeteer": "^1.3.0",
"showdown": "^1.9.0",
"showdown-emoji": "^1.0.3"
"prettier": "^3.1.1",
"puppeteer": "^21.6.1",
"showdown": "^2.1.0",
"showdown-emoji": "^3.0.0"
},
"devDependencies": {
"execa": "^0.6.3",
"mocha": "^5.2.0",
"should": "^11.2.1"
"execa": "^8.0.1",
"mocha": "^10.2.0",
"should": "^13.2.3"
}
}
84 changes: 42 additions & 42 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
const fs = require('fs');
const path = require('path');
const Promise = require('bluebird');
const showdown = require('showdown');
const showdownEmoji = require('showdown-emoji');
const puppeteer = require('puppeteer');
const Handlebars = require('handlebars');
const loophole = require('loophole');
const utils = require('./utils');
const puppeteerHelper = require('./puppeteer-helper');

const readFile = Promise.promisify(fs.readFile);
const writeFile = Promise.promisify(fs.writeFile);
import { readFile as _readFile, writeFile as _writeFile, renameSync, unlinkSync } from 'fs';
import { join, dirname, resolve } from 'path';
import { promisify } from 'util';
import { setFlavor, Converter } from 'showdown';
import showdownEmoji from 'showdown-emoji';
import { launch } from 'puppeteer';
import { SafeString, compile } from 'handlebars';
import { allowUnsafeNewFunction } from 'loophole';
import { getStyles, getStyleBlock, qualifyImgSources } from './utils';
import { getOptions } from './puppeteer-helper';

const readFile = promisify(_readFile);
const writeFile = promisify(_writeFile);

// Main layout template
const layoutPath = path.join(__dirname, '/layouts/doc-body.hbs');
const headerLayoutPath = path.join(__dirname, '/layouts/header.hbs');
const footerLayoutPath = path.join(__dirname, '/layouts/footer.hbs');
const layoutPath = join(__dirname, '/layouts/doc-body.hbs');
const headerLayoutPath = join(__dirname, '/layouts/header.hbs');
const footerLayoutPath = join(__dirname, '/layouts/footer.hbs');

// Syntax highlighting
const highlightJs =
'file://' + path.join(__dirname, '/assets/highlight/highlight.pack.js');
'file://' + join(__dirname, '/assets/highlight/highlight.pack.js');

function getAllStyles(options) {
const cssStyleSheets = [];

// GitHub Markdown Style
if (options.ghStyle) {
cssStyleSheets.push(
path.join(__dirname, '/assets/github-markdown-css.css')
join(__dirname, '/assets/github-markdown-css.css')
);
}
// Highlight CSS
cssStyleSheets.push(
path.join(__dirname, '/assets/highlight/styles/github.css')
join(__dirname, '/assets/highlight/styles/github.css')
);

// Some additional defaults such as margins
if (options.defaultStyle) {
cssStyleSheets.push(path.join(__dirname, '/assets/default.css'));
cssStyleSheets.push(join(__dirname, '/assets/default.css'));
}

// Optional user given CSS
Expand All @@ -46,13 +46,13 @@ function getAllStyles(options) {
}

return {
styles: utils.getStyles(cssStyleSheets),
styleBlock: utils.getStyleBlock(cssStyleSheets),
styles: getStyles(cssStyleSheets),
styleBlock: getStyleBlock(cssStyleSheets),
};
}

function parseMarkdownToHtml(markdown, convertEmojis) {
showdown.setFlavor('github');
setFlavor('github');
const options = {
prefixHeaderId: false,
ghCompatibleHeaderId: true,
Expand All @@ -64,7 +64,7 @@ function parseMarkdownToHtml(markdown, convertEmojis) {
options.extensions = [showdownEmoji];
}

const converter = new showdown.Converter(options);
const converter = new Converter(options);

return converter.makeHtml(markdown);
}
Expand All @@ -79,11 +79,11 @@ function convert(options) {
throw new Error('Destination path must be provided');
}

options.assetDir = path.dirname(path.resolve(options.source));
options.assetDir = dirname(resolve(options.source));

let template = {};
const styles = getAllStyles(options);
let css = new Handlebars.SafeString(styles.styleBlock);
let css = new SafeString(styles.styleBlock);
const local = {
highlightJs,
css: css,
Expand All @@ -104,7 +104,7 @@ function convert(options) {
return readFile(layoutPath, 'utf8');
})
.then(layout => {
template = Handlebars.compile(layout);
template = compile(layout);

// Pull in the document source markdown
return readFile(options.source, 'utf8');
Expand All @@ -113,11 +113,11 @@ function convert(options) {
// Compile the main document
let content = parseMarkdownToHtml(mdDoc, !options.noEmoji);

content = utils.qualifyImgSources(content, options);
content = qualifyImgSources(content, options);

local.body = new Handlebars.SafeString(content);
local.body = new SafeString(content);
// Use loophole for this body template to avoid issues with editor extensions
const html = loophole.allowUnsafeNewFunction(() => template(local));
const html = allowUnsafeNewFunction(() => template(local));

return createPdf(html, options);
});
Expand All @@ -130,18 +130,18 @@ function prepareHeader(options, css) {
// Get the hbs layout
return readFile(headerLayoutPath, 'utf8')
.then(headerLayout => {
headerTemplate = Handlebars.compile(headerLayout);
headerTemplate = compile(headerLayout);

// Get the header html
return readFile(options.header, 'utf8');
})
.then(headerContent => {
const preparedHeader = utils.qualifyImgSources(headerContent, options);
const preparedHeader = qualifyImgSources(headerContent, options);

// Compile the header template
const headerHtml = headerTemplate({
content: new Handlebars.SafeString(preparedHeader),
css: new Handlebars.SafeString(css.replace(/"/gm, "'")),
content: new SafeString(preparedHeader),
css: new SafeString(css.replace(/"/gm, "'")),
});

return headerHtml;
Expand All @@ -154,7 +154,7 @@ function prepareHeader(options, css) {
function prepareFooter(options) {
if (options.footer) {
return readFile(options.footer, 'utf8').then(footerContent => {
const preparedFooter = utils.qualifyImgSources(footerContent, options);
const preparedFooter = qualifyImgSources(footerContent, options);

return preparedFooter;
});
Expand All @@ -168,14 +168,14 @@ function createPdf(html, options) {
let browser;
let page;

const tempHtmlPath = path.join(
path.dirname(options.destination),
const tempHtmlPath = join(
dirname(options.destination),
'_temp.html'
);

return writeFile(tempHtmlPath, html)
.then(() => {
return puppeteer.launch({ headless: true });
return launch({ headless: true });
})
.then(newBrowser => {
browser = newBrowser;
Expand All @@ -187,7 +187,7 @@ function createPdf(html, options) {
return page.goto('file:' + tempHtmlPath, { waitUntil: 'networkidle2' });
})
.then(() => {
const puppetOptions = puppeteerHelper.getOptions(options);
const puppetOptions = getOptions(options);

return page.pdf(puppetOptions);
})
Expand All @@ -196,15 +196,15 @@ function createPdf(html, options) {
})
.then(() => {
if (options.debug) {
fs.renameSync(tempHtmlPath, options.debug);
renameSync(tempHtmlPath, options.debug);
} else {
fs.unlinkSync(tempHtmlPath);
unlinkSync(tempHtmlPath);
}

return options.destination;
});
}

module.exports = {
export default {
convert,
};
22 changes: 11 additions & 11 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const path = require('path');
const fs = require('fs');
const url = require('url');
const fileUrl = require('file-url');
const cheerio = require('cheerio');
import { resolve } from 'path';
import { readFileSync } from 'fs';
import { parse } from 'url';
import fileUrl from 'file-url';
import { load } from 'cheerio';

function getStyleBlock(stylesheets) {
// Read in all stylesheets and format them into HTML to
Expand All @@ -11,7 +11,7 @@ function getStyleBlock(stylesheets) {
let styleHtml = '';
for (const i in stylesheets) {
if (Object.prototype.hasOwnProperty.call(stylesheets, i)) {
const style = fs.readFileSync(stylesheets[i], 'utf8');
const style = readFileSync(stylesheets[i], 'utf8');
styleHtml += '<style>' + style + '</style>';
}
}
Expand All @@ -23,7 +23,7 @@ function getStyles(stylesheets) {
let styleHtml = '';
for (const i in stylesheets) {
if (Object.prototype.hasOwnProperty.call(stylesheets, i)) {
const style = fs.readFileSync(stylesheets[i], 'utf8');
const style = readFileSync(stylesheets[i], 'utf8');
styleHtml += style;
}
}
Expand All @@ -34,7 +34,7 @@ function getStyles(stylesheets) {
function hasAcceptableProtocol(src) {
const acceptableProtocols = ['http:', 'https:'].join('|');

const theUrl = url.parse(src);
const theUrl = parse(src);

if (!theUrl.protocol) {
return false;
Expand All @@ -49,12 +49,12 @@ function processSrc(src, options) {
}

// We need to convert it
const resolvedSrc = path.resolve(options.assetDir, src);
const resolvedSrc = resolve(options.assetDir, src);
return fileUrl(resolvedSrc);
}

function qualifyImgSources(html, options) {
const $ = cheerio.load(html);
const $ = load(html);

$('img').each((i, img) => {
img.attribs.src = processSrc(img.attribs.src, options);
Expand All @@ -63,7 +63,7 @@ function qualifyImgSources(html, options) {
return $.html();
}

module.exports = {
export default {
getStyleBlock,
getStyles,
hasAcceptableProtocol,
Expand Down
Loading

0 comments on commit a698f5d

Please sign in to comment.