the personal playground of evan louie; developer, designer, photographer, and breaker of the web.
   (  )   /\   _                 (     
    \ |  (  \ ( \.(               )                      _____
  \  \ \  `  `   ) \             (  ___                 / _   \
 (_`    \+   . x  ( .\            \/   \____-----------/ (o)   \_
- .-               \+  ;          (  O                           \____
                          )        \_____________  `              \  /
(__                +- .( -'.- <. - _  VVVVVVV VV V\                 \/
(_____            ._._: <_ - <- _  (--  _AAAAAAA__A_/                  |
  .    /./.+-  . .- /  +--  - .     \______________//_              \_______
  (__ ' /x  / x _/ (                                  \___'          \     /
 , x / ( '  . / .  /                                      |           \   /
    /  /  _/ /    +                                      /              \/
   '  (__/                                             /                  \

Rakefile -- Export A Directory Of Markdown to pdf/html/docx

A Rakefile for instrumenting Pandoc to export all markdown files to .pdf/.html/.docx.

Host Requirements

Usage

# Assuming a directory foo exists with the Rakefile at the root
cd foo
echo "# This is a header\nThis is some body" > test.md
rake
# frozen_string_literal: true

task default: %w[clean build]

task :clean do
  puts 'Deleting all none markdown export files...'
  Dir['**/*.{pdf,html,docx}'].each do |filename|
    File.delete(filename)
    puts "Deleted #{filename}"
  end
end

# Cross-platform way of finding an executable in the $PATH.
# https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
#   which('ruby') #=> /usr/bin/ruby
def which(cmd)
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
    exts.each do |ext|
      exe = File.join(path, "#{cmd}#{ext}")
      return exe if File.executable?(exe) && !File.directory?(exe)
    end
  end
  nil
end

def build_markdown(filename, dirname, output_name)
  header_path = File.join(Dir.getwd, 'table.header.tex')
  pdf_table_header = "--include-in-header=#{header_path}"
  write_path = dirname + '/' + output_name
  pandoc_args = ['pandoc', '-s', '--toc']
  pandoc_args.push(pdf_table_header) if output_name.downcase.end_with?('.pdf')
  pandoc_args.push(File.basename(filename), '-o', output_name, chdir: dirname)
  pid = spawn(*pandoc_args)
  { pid: pid,
    filename: File.expand_path(filename),
    path: File.expand_path(write_path) }
end

task :build do
  return puts 'Install pandoc' if which('pandoc').nil?

  puts 'Exporting markdown files...'
  pids = Dir['**/*.{md,markdown}'].reduce([]) do |pid_list, filename|
    new_pids = ['.pdf', '.html', '.docx'].map do |ext|
      output_name = "#{File.basename(filename, File.extname(filename))}#{ext}"
      build_markdown(filename, File.dirname(filename), output_name)
    end
    pid_list + new_pids
  end

  # Await all processes in their own thread so updates are printed live
  threads = pids.map do |pid|
    Thread.new do
      Process.wait pid[:pid]
      puts "[#{pid[:pid]}]: #{pid[:filename]} => #{pid[:path]}"
    end
  end

  threads.each(&:join)
end