Tutorial: Creating a markdown to image conversion route

Creating a markdown to image conversion route

Creating a markdown to image route

  • concept is equal to the video route:
    • add a preprocessor that converts an md string to an image stream
  • means we can extend the image route in the same way video does (class MarkdownRoute extends MarkdownPreprocess(Image) {})

Example usage:

<img src="http://localhost:3000/md/preview-image/%23%20headline%0A%0Awasd?size=500" alt="headline wasd">

Implementation

  • route url /md/{profile}/{md}
  • input extraction resolves md request param
  • reader returns {markdown: <MardownString>} object
  • use markdown-it to generate html from markdown
  • use node-webshot to generate image stream from html (Note: node-webshot is currently not compatible with node@6 until node-webshot/#150 is merged. Use npm i "github:brenden/node-webshot#pull/150/head")

Route mixin

function MarkdownPreprocess(SuperClass) {
  return class MarkdownPreprocessor extends SuperClass {
    extractInput(operation) {
      return Promise.resolve(decodeURIComponent(operation.request.params.md));
    }

    extractReader(input) {
      return Promise.resolve((operation) => ({markdown: input}));
    }

    preprocess(operation) {
      return markdownPreprocessor(operation);
    }
  };
}

Markdown preprocessor function

function markdownPreprocessor() {
  return (readerResult) =>
    Promise.resolve(webshot(`<html><body>${md.render(readerResult.markdown)}</body></html>`, {siteType: 'html'}));
}

Route

class MarkdownRoute extends MarkdownPreprocess(Image) {
  constructor(conf, method = 'GET', path = '/md/{profile}/{md}', description = 'Profile markdown conversion') {
    super(conf, method, path, description);
  }
}

starting the server

Config.fromEnv().then(config => new Server(config, new AddonLoader(__dirname, {}).load())
    .withProfiles([require('../src/profiles/examples')])
    .withRoutes([new MarkdownRoute(config)])
    .start()
    .then(server => logger.info(`server running at ${server.hapi.info.uri}`)));