#! /usr/bin/env ruby # == Synopsis # stories2cards parses stories saved in the RSpec plain text story # format and saves a PDF file with printable 3"x5"" index cards # suitable for using in agile planning and prioritization. # # == Examples # This command outputs a PDF consisting of one card for each story and # narrative defined in stories.txt and saves it as stories.pdf # # stories2cards < stories.txt # # Other examples # # stories2cards -o /tmp/cards.pdf < stories.txt # stories2cards --style=4up < stories.txt # # == Usage # stories2cards [options] < text_file_with_stories # # For help use stories2cards -h # # == Options # -h, --help Displays help message # -v, --version Display the version, then exit # -o, --output=PATH (optional) Specify the path to the PDF file # to be created, writes to stdout by default # -s, --style=1up|4up Defaults to 1up # -l, --lowerleft=key (optional) MetaData key for value to be printed in lower left # -r, --lowerright=key (optional) MetaData key for value to be printed in lower right # -b, --[no-]borders Print borders (only has effect with 4up style) # -m, --makesentences, Make english narratives into sentences # # == Author # Luke Melia # # == Copyright # Copyright (c) 2007-2008 Luke Melia. Licensed under the MIT License # http://www.opensource.org/licenses/mit-license.php require 'optparse' require 'rdoc/usage' require 'ostruct' begin require 'pdf/storycards' rescue LoadError => le if le.message =~ %r{pdf/storycards$} root = File.dirname(File.dirname(File.expand_path(__FILE__))) $LOAD_PATH.unshift(File.join(root, "lib")) require 'pdf/storycards' else raise end end class App attr_reader :options def initialize(arguments, stdin, stdout) @arguments = arguments @stdin = stdin @stdout = stdout # Set defaults @options = OpenStruct.new @options.style = :"1up" end # Parse options, check arguments, then process the command def run if parsed_options? && arguments_valid? process_arguments @story_text = @stdin.read process_command else output_usage end end protected def parsed_options? # Specify options opts = OptionParser.new opts.on('-v', '--version') { output_version ; exit 0 } opts.on('-h', '--help') { output_help } opts.on('-o', '--output [PATH]') { |path| @options.output = path } opts.on('-s', '--style [STYLE]', [:"1up", :"4up"]) { |style| @options.style = style } opts.on('-l', '--lowerleft [METADATA_KEY]') { |metadata_key| @options.lower_left = metadata_key } opts.on('-r', '--lowerright [METADATA_KEY]') { |metadata_key| @options.lower_right = metadata_key } opts.on("-b", "--[no-]borders", "Print borders") { |b| @options.borders = b } opts.on('-m', '--makesentences', "Make english narratives into sentences") { |m| @options.make_sentences = m } opts.parse!(@arguments) rescue return false true end # True if required arguments were provided def arguments_valid? return false if @arguments.length > 0 return true end # Setup the arguments def process_arguments end def output_help output_version RDoc::usage() #exits app end def output_usage RDoc::usage('usage') # gets usage from comments above end def output_version puts "#{File.basename(__FILE__)} version #{PDF::Storycards::VERSION}" end def process_command @options.style = :card_1up if @options.style == :"1up" @options.style = :letter_4up if @options.style == :"4up" options_as_hash = @options.instance_variable_get('@table') pdf_text = PDF::Storycards::Writer.make_pdf(@story_text, options_as_hash) if @options.output File.open(@options.output, 'w') {|f| f.write(pdf_text) } else @stdout.print pdf_text end end end # Create and run the application app = App.new(ARGV, $stdin, $stdout) app.run