#!/usr/bin/ruby.ruby4.0 
#/ Usage: rocco [-l <lang>] [-c <chars>] [-o <dir>] <file>...
#/ Generate literate-programming-style documentation for Ruby source <file>s.
#/
#/ Options:
#/   -l, --language=<lang>  The Pygments lexer to use to highlight code
#/   -c, --comment-chars=<chars>
#/                          The string to recognize as a comment marker
#/   -o, --output=<dir>     Directory where generated HTML files are written
#/   -t, --template=<path>  The file to use as template when rendering HTML
#/   -d, --docblocks        Parse Docblock @annotations in comments
#/       --help             Show this help message

require 'optparse'
require 'fileutils'
require 'rocco'

# Write usage message to stdout and exit.
def usage(stream=$stderr, status=1)
  stream.puts File.readlines(__FILE__).
    grep(/^#\//).
    map { |line| line.sub(/^#. ?/, '') }.
    join
  exit status
end

# Like `Kernel#abort` but writes a note encouraging the user to consult
# `rocco --help` for more information.
def abort_with_note(message=nil)
  $stderr.puts message if message
  abort "See `rocco --help' for usage information."
end

# Parse command line options, aborting if anything goes wrong.
output_dir = '.'
sources = []
options = {}
ARGV.options { |o|
  o.program_name = File.basename($0)
  o.on("-o", "--output=DIR") { |dir| output_dir = dir }
  o.on("-l", "--language=LANG") { |lang| options[:language] = lang }
  o.on("-c", "--comment-chars=CHARS") { |chars| options[:comment_chars] = Regexp.escape(chars) }
  o.on("-t", "--template=TEMPLATE") { |template| options[:template_file] = template }
  o.on("-d", "--docblocks") { options[:docblocks] = true }
  o.on_tail("-h", "--help") { usage($stdout, 0) }
  o.parse!
} or abort_with_note

# Use http://pygments.appspot.com in case `pygmentize(1)` isn't available.
if ! ENV['PATH'].split(':').any? { |dir| File.exist?("#{dir}/pygmentize") }
  unless options[:webservice]
    $stderr.puts "pygmentize not in PATH; using pygments.appspot.com instead"
    options[:webservice] = true
  end
end

# Eat sources from ARGV.
sources << ARGV.shift while ARGV.any?

# Make sure we have some files to work with.
if sources.empty?
  abort_with_note "#{File.basename($0)}: no input <file>s given"
end

# Run each file through Rocco and write output.
sources.each do |filename|
  rocco = Rocco.new(filename, sources, options)
  dest = filename.sub(Regexp.new("#{File.extname(filename)}$"),".html")
  dest = File.join(output_dir, dest) if output_dir != '.'
  puts "rocco: #{filename} -> #{dest}"
  FileUtils.mkdir_p File.dirname(dest)
  File.open(dest, 'wb') { |fd| fd.write(rocco.to_html) }
end
