From: Ryan Leavengood Date: 2005-04-17T22:25:40+09:00 Subject: [SOLUTION] Madlibs (#28) Here is my solution to the current quiz. While implementing this I learned more about the power of gsub, which I don't think I've ever used so much in one program as small as this one ;) I output the result in either text or PDF if given the proper command-line options. To use the PDF feature you will need to install PDF::Writer, available from here: http://rubyforge.org/projects/ruby-pdf/ What a fun quiz this was, especially using the program to create some Madlibs. I also decided to create an additional madlib file for testing/having fun with. This is below following the code. The source for this was http://www.geocities.com/pezheadpaul/madlibs/prints/printprojects.htm and all credit goes to the author of that site. This is a good test because it has multiple paragraphs. I hereby decree than an additional rule for this quiz would be that every solution include a new madlib file :) Ryan Leavengood CODE (beware of wrapping): def do_madlib(madlib_file, output_pdf, underline) substitutions = {} # Put paragraphs all on one line (there has got to be a better way!) madlib = IO.readlines(madlib_file).join('').split(/\n\n/).collect{|l|l.gsub(/\n/,' ')}.join("\n\n") madlib_result = madlib.gsub(/\(\([^)]*\)\)/) do |match| match.gsub!(/\(|\)/,'') # Bye bye parens if substitutions[match] substitution = substitutions[match] else if match =~ /(.*):(.*)/ key = $1 match = $2 end print "Please enter #{match}: " substitution = $stdin.gets.chomp if key substitutions[key] = substitution end end if output_pdf and underline "#{substitution}" else substitution end end if output_pdf filename = madlib_file+".pdf" print "Outputting PDF file #{filename}..." require 'pdf/ezwriter' pdf = PDF::EZWriter.new pdf.select_font("pdf/fonts/Helvetica") pdf.ez_text(madlib_result, 14) File.open(filename, File::RDWR|File::CREAT|File::TRUNC) do |file| file.print(pdf.ez_output) end puts "done." else puts "\n Your MadLib:\n\n" madlib_result.split("\n").each do |paragraph| # Lazy man's wrapping puts paragraph.gsub(/.{72}[^ ]* /){|l|"#{l}\n"} end end end if $0 == __FILE__ if ARGV.length < 1 puts "Usage: #$0 [-pdf] [-u] " puts " -pdf Output a PDF file." puts " -u Underline the replaced words in the PDF output file." exit(1) end output_pdf = false underline = false filename = nil while ARGV.length > 0 arg = ARGV.shift case arg when '-pdf': output_pdf = true when '-u': underline = true else filename = arg end end if filename if test(?e, filename) do_madlib(filename, output_pdf, underline) else puts "Provided madlib file does not exist!" end else puts "No madlib filename provided!" end end Science_Fair.madlib: According to ((principal:a school principal's name)), the school science fair this year was 'very educational.' At the same time, ((principal)) announced plans to quit the school system and become a ((a dangerous job)). 'It sounds like a safer job,' the principal said. Several ((an adjective)) projects were disqualified this year. The experiment on 'Animal Magnetism' by ((a girl's name)) was canceled before she could plug in her ((an animal)). The project by ((a male bully's name)) on 'Gravity's Effect on First Graders' was canceled when the custodians wouldn't let him borrow a ladder. And the Nuclear Powered ((a noun)) built by ((name:a proper noun)) was taken away by the police, who said ((name)) will be back in school 'any day now.' ((your name)) won second prize with an experiment that asked, 'Can ((animals:a plural animal)) Learn Karate?' The answer was 'yes.' The ((animals)) tossed ((principal)) over a ((a noun)) and left the science fair. Anyone who sees them should call the main office. ((a girl's name)) won first prize with her TNT ((veggies:a plural vegetable)). By planting seeds in gunpowder and watering them with nitroglycerin, ((veggies)) grew that explode when you drop them. 'What a dynamite idea,' the principal joked ((an adverb)). So far, nobody has figured out how the prize-winning ((veggies)) got into the salad served to ((principal)) at lunchtime. Just to be safe, though, the 'Vegetable Surprise' has been taken off tomorrow's lunch menu.