# 99bottles.gp: # script for gnuplot version 4.2 to create the famous 99-bottles-of-beer-song # Gnuplot is a plotting program, so of course we also make a plot of the bottles. # # March 2007 - Bastian Märkisch & Ethan Merritt # Define a maximum number of bottles in case we do not want the whole song. max = 99 # Initialize the plot only once (bottles is undefined on first entry). # Open the "dumb" terminal to generate ascii art # Define the plot layout such that there are 99 character slots for bottles, # leaving room for a margin and a shelf-divider at each end. if (!exists("bottles")) \ set term dumb 104 6 ;\ set border 1 front;\ unset xtics ;\ unset ytics ;\ set lmargin 1;\ set rmargin 1;\ set xrange [0:100] ;\ set yrange [-1:1] ;\ unset key # Create and initialize the bottles counter if (!exists("bottles")) bottles = max # String valued function to create the "bottle(s)" string # To decide wether we should a plural 's' a dirty substring trick is used, but # we could always use a ternary operator instead # Note that there is no name conflict with the bottles variable. bottles(b) = "bottle" . "s"[0:(b != 1)] # Function which returns the number b or the string "no more" iff b=0. # The case of the first letter can be switched by the parameter c. # Please note that this function can be string or number valued. number(b,c) = (b > 0) ? sprintf("%d",b) : "nN"[c+1:c+1] . "o more" # We use a ternary operator to decide what to do next ;-) action = (bottles != 0) ? \ "Take one down and pass it around" : \ "Go to the store and buy some more" # Write the new verse into a label # On the sceond line the modulo trick is used to wrap around the number of bottles Label1 = sprintf("%s %s of beer on the wall, %s %s of beer.\n", \ number(bottles,1), bottles(bottles), number(bottles,0), bottles(bottles)) Label2 = action . ", " . sprintf("%s %s of beer on the wall.", \ number((bottles + max) % (max + 1), 0), bottles(bottles-1)) # Use the verse as a label for the x-axis set xlabel Label1.Label2 offset 0,-1 # We will use the sampling grid to control how many bottles are drawn. # But the set of samples always includes the two end points, which we # don't want. So we over-write the endpoints with shelf dividers. set label 1 "|" at 0,1 front set label 2 "|" at 100,1 front # Draw the shelf # In the "dumb" terminal, linetype 6 is an ampersand set samples bottles+2 plot 1 with impulses linetype 6 # gnuplot's loop mechanism is a restart of the current script file (reread) bottles = bottles - 1 if (bottles >= 0) reread # We only get here once the song is finished. # Prepare the bottle counter for a new start... bottles = max