Reveal.js : generate pdf using phantomjs

08 Dec 2014

Since I started giving tech talks in meetups I used reveal.js to build my slides. As a web developer its the finest tool to create and share slides for me. I either share the slides on github or upload to slide hosting sites.

To upload the slides to hosting sites I need to convert html slides to pdf. The reveal.js have a workflow to convert the html slides into pdf using chrome. But since I love CLI, I was looking for a way to convert my slides to pdf using phantom.js. Then a stackoverflow thread got me into the following solution.

Before seeing the stackoverflow I never knew that reveal.js have equiped with a plugin print-pdf.js to do this. For this solution to work, you need phantomjs to be installed. You can either download the compiled phantomjs or install using npm.

npm install -g phantomjs

After installing the phantomjs you can run the following command to generate the pdf.

phantomjs path/to/print-pdf.js "http://localhost:9000/index.html?print-pdf" file-name.pdf

Since I installed revealjs using bower, my path to print-pdf.js plugin is bower_components/reveal.js/plugin/print-pdf/print-pdf.js and my slides are served using simple http server running at localhost:9000.

But when I tried this first time, I got the blank slides because reveal.js load the slide content via ajax after loading the index.html and as per the plugin phantomjs won’t wait for the ajax to complete. So I found a simple hack to wait phantomjs to load the slide contents using setTimeout.

page.open( revealFile, function( status ) {
  // console.log( 'Printed succesfully' );
  // page.render( slideFile );
  // phantom.exit();
  console.log(status);
  if (status !== 'success') {
      console.log('Unable to load the address!');
      phantom.exit();
  } else {
      setTimeout(function () {
          page.render(slideFile);
          phantom.exit();
      }, 1000); // Change timeout as required to allow sufficient time
  }
} );

If you are using grunt, you can register the task to generate pdf.

grunt.registerTask('pdf', function(){

    var childProcess  = require('child_process');
    var phantomjs     = require('phantomjs');
    var binPath       = phantomjs.path;
    var done          = grunt.task.current.async();

    childArgs = [
      'bower_components/reveal.js/plugin/print-pdf/print-pdf.js',
      'http://localhost:9000/index.html?print-pdf',
      'filename.pdf'
    ];

    childProcess.execFile(binPath, childArgs, function(error, stdout, stderr) {
      grunt.log.writeln(stdout);
      done(error);
    });
});

So from now generating pdf from reveal.js slides have become really easy, I just need to run

grunt pdf

If you have a better solution to check whether phantomjs finished loading the slides contents other than the above hack, please do let me know.

Thank You.

If you particularly enjoy my work, I appreciate donations given with Gittip.
comments powered by Disqus