bin/ronn in ronn-0.5 vs bin/ronn in ronn-0.6.0

- old
+ new

@@ -1,93 +1,123 @@ #!/usr/bin/env ruby -## Usage: ronn [ OPTIONS ] [ FILE ] -## ronn --build FILE ... -## ronn --install FILE ... -## ronn --man FILE ... -## Convert ronn FILE to roff man page or HTML and write to standard -## output. With no FILE, ronn reads from standard input. The build, -## install, and man forms accept multiple FILE arguments. -## -## Modes: -## --pipe write to standard output (default behavior) -## -b, --build write to files instead of standard output -## -i, --install write to file in MAN_HOME or system man path -## -m, --man open man page like man(1) -## -## Formats: -## -r, --roff generate roff/man text; this is the default behavior -## -5, --html generate entire HTML page with layout -## -f, --fragment generate HTML fragment instead of entire HTML page -## -## Document attributes: -## --date=DATE published date in YYYY-MM-DD format; -## displayed bottom-center in footer -## --manual=NAME name of the manual this document belongs to; -## displayed top-center in header -## --organization=NAME publishing group, organization, or individual; -## displayed bottom-left in footer -## -## --help show this help message -## +#/ Usage: ronn <options> <file>... +#/ ronn -m|--man <file> ... +#/ ronn -S|--server <file> ... +#/ ronn --pipe [<file>...] +#/ Convert ronn source <file>s to roff or HTML manpage. In the first synopsis form, +#/ build HTML and roff output files based on the input file names. +#/ +#/ Mode options alter the default file generating behavior: +#/ --pipe write to standard output instead of generating files +#/ -m, --man show manual like with man(1) +#/ -S, --server serve <file>s at http://localhost:1207/ +#/ +#/ Format options control which files are generated: +#/ -r, --roff generate roff output +#/ -5, --html generate entire HTML page with layout +#/ -f, --fragment generate HTML fragment +#/ +#/ Document attributes: +#/ --date=DATE published date in YYYY-MM-DD format (bottom-center) +#/ --manual=NAME name of the manual (top-center) +#/ --organization=NAME publishing group or individual (bottom-left) +#/ +#/ Misc options: +#/ -w, --warnings show troff warnings on stderr +#/ -W disable previously enabled troff warnings +#/ --help show this help message +#/ +#/ A <file> named example.1.ronn generates example.1.html (HTML manpage) +#/ and example.1 (roff manpage) by default. require 'date' require 'optparse' -formats = [] -options = {} -build = false -install = false -man = false -groff = "groff -Wall -mtty-char -mandoc -Tascii" -pager = ENV['MANPAGER'] || ENV['PAGER'] || 'more' - -def info(message, *args) - STDERR.puts message % args -end - def usage puts File.readlines(__FILE__). - grep(/^##.*/). + grep(/^#\/.*/). map { |line| line.chomp[3..-1] }. join("\n") end -# parse command line options -ARGV.options do |option| +## +# Argument defaults + +build = true +view = false +server = false +formats = nil +options = {} +styles = %w[man] +groff = "groff -Wall -mtty-char -mandoc -Tascii" +pager = ENV['MANPAGER'] || ENV['PAGER'] || 'more' + +## +# Environment variables + +%w[manual organization date].each do |attribute| + value = ENV["RONN_#{attribute.upcase}"] + next if value.nil? or value.empty? + options[attribute] = value +end + +## +# Argument parsing + +ARGV.options do |argv| # modes - option.on("--pipe") { } - option.on("-b", "--build") { build = true } - option.on("-i", "--install") { install = true } - option.on("-m", "--man") { man = true } + argv.on("--pipe") { build = server = false } + argv.on("-b", "--build") { build = true; server = false } + argv.on("-m", "--man") { build = server = false; view = true } + argv.on("-S", "--server") { build = view = false; server = true } + argv.on("-w", "--warnings") { groff += ' -ww' } + argv.on("-W") { groff += ' -Ww' } # format options - option.on("-r", "--roff") { formats << 'roff' } - option.on("-5", "--html") { formats << 'html' } - option.on("-f", "--fragment") { formats << 'html_fragment' } + argv.on("-r", "--roff") { (formats ||= []) << 'roff' } + argv.on("-5", "--html") { (formats ||= []) << 'html' } + argv.on("-f", "--fragment") { (formats ||= []) << 'html_fragment' } + # html output options + argv.on("-s", "--style=V") { |val| styles += val.split(/[, \n]+/) } + # manual attribute options - [:name, :section, :manual, :organization, :date].each do |option_attr| - option.on("--#{option_attr}=VALUE") { |val| options[option_attr] = val } + %w[name section manual organization date].each do |attribute| + argv.on("--#{attribute}=VALUE") { |val| options[attribute] = val } end - option.on_tail("--help") { usage ; exit } - option.parse! + argv.on_tail("--help") { usage ; exit 0 } + argv.parse! end -if ARGV.empty? && STDIN.tty? +## +# Modes, Formats, Options + +case +when ARGV.empty? && $stdin.tty? usage - exit -elsif ARGV.empty? + exit 2 +when ARGV.empty? && !server ARGV.push '-' + build = false + formats ||= %w[roff] +when view + formats ||= %w[roff] +when build + formats ||= %w[roff html] end +formats ||= [] +formats.delete('html') if formats.include?('html_fragment') # turn the --date arg into a real date object -options[:date] &&= Date.strptime(options[:date], '%Y-%m-%d') +options['date'] &&= Date.strptime(options['date'], '%Y-%m-%d') -formats = ['roff'] if formats.empty? -formats.delete('html') if formats.include?('html_fragment') -pid = nil +# pass the styles option +options['styles'] = styles +## +# Libraries and LOAD_PATH shenanigans + begin require 'hpricot' require 'rdiscount' rescue LoadError if !defined?(Gem) @@ -95,10 +125,12 @@ require 'rubygems' retry end end +# load ronn libs, setting up the load path if something fails and +# we're in a development environment. begin require 'ronn' rescue LoadError raise if $!.to_s !~ /ronn/ libdir = File.expand_path("../../lib", __FILE__).sub(/^#{Dir.pwd}/, '.') @@ -108,16 +140,29 @@ retry end raise end +## +# Server + +if server + require 'ronn/server' + Ronn::Server.run(ARGV, options) + exit 0 +end + +## +# Build Pipeline + +pid = nil wr = STDOUT ARGV.each do |file| doc = Ronn.new(file, options) { file == '-' ? STDIN.read : File.read(file) } # setup the man pipeline if the --man option was specified - if man && !build + if view && !build rd, wr = IO.pipe if pid = fork rd.close else wr.close @@ -128,19 +173,33 @@ # write output for each format formats.each do |format| if build path = doc.path_for(format) - info "building: #{path}" if build + case format + when 'html' + warn "%5s: %-48s%15s" % [format, path, '+' + doc.styles.join(',')] + when 'roff', 'html_fragment' + warn "%5s: %-48s" % [format, path] + end + output = doc.convert(format) File.open(path, 'wb') { |f| f.puts(output) } - system "man #{path}" if man && format == 'roff' + + if format == 'roff' + if view + system "man #{path}" + else + system "#{groff} <#{path} >/dev/null" + end + end else output = doc.convert(format) wr.puts(output) end end + # wait for children to exit if pid wr.close Process.wait end end