diff --git a/readme.markdown b/readme.markdown new file mode 100644 index 0000000..3facbbf --- /dev/null +++ b/readme.markdown @@ -0,0 +1,46 @@ +Helix +===== +I built a script to help create the poem I wrote called helix +you can find it at [helix.byJP.me](http://helix.byJP.me). + +You can build your own similarly styled poem using this script - +I'm releasing the artwork that is the poetry and this script that generates it under a +[Creative Commons licence](http://creativecommons.org/licenses/by-nc-sa/3.0/), this +means that you can reproduce my version or your own as much as you like under these conditions + + * You aren't making money from it + * You reference the original work (at [helix.byJP.me](http://helix.byJP.me])) + * You share *your* work under this same licence + +Of course, if you'd like to contravene any of these you only need to ask me — this licence is +just a catch-all! + +I would also really appreciate it if you told me about your work! +[this.was.byjp.me](http://this.was.byjp.me) lists other people's work based on my own and I'd +love to put a link to your works on there. + +Installation +------------ + +You will need a standard ruby installation -- that's it! + +On Mac OS X and linux, you're probably ready to go, windows users may need to [download ruby](www.ruby-lang.org/en/downloads/) + +Once ruby is up and running, you need to do some editing: + +You need to create a `thoughts.txt` file, one 'thought' per line. My code only copes with 100 slots +at the moment, so I'd probably have about 25 if I were you. + +The file `random.txt` needs to be filled with random words you like (one per line), I'd make about +30 or so. + +At the top of `thoughts.rb` you can change `num_random = 4` to any integer, the greater the number +the more dense the non-thought slots will be. `tags` should be an array of unique integers, these +are the slots that will be filled with your thoughts, you need to have at least as many tags as you +do thoughts, elsewise you won't see your final thoughts in the piece. Finally, `slots` is the number of slots that will be created. You can't have more than 99! + +All done! Just open up a prompt and run the script: + + $ ruby thoughts.rb + +You'll have all the files you need created for you :) Have fun! \ No newline at end of file diff --git a/thoughts.rb b/thoughts.rb new file mode 100644 index 0000000..063e555 --- /dev/null +++ b/thoughts.rb @@ -0,0 +1,616 @@ +##################### +# This'll be fun :P +##################### +# The max number of random (fake) numbers each word is attached to +num_random = 4 +# The numbers that will have real phrases (should be at least as many as phrases). Stay below 100 for now +tags = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97] +# The number of slots to create +slots = 99 +##################### +# Nothing more to edit +##################### + +raise "Woah! You need a 'thoughts.txt' file with your phrases (one per line) and a 'random.txt' with a few random words (any way you like)!" if not File.exists?("thoughts.txt") or not File.exist?("random.txt") + +thoughts = "" +open("thoughts.txt") do |f| + thoughts = f.read +end +randomwords = "" +open("random.txt") do |f| + randomwords = f.read +end + +tags = tags.uniq[0..thoughts.split("\n").length].collect{|n| n.to_s} + +$stderr.puts " - You've not got enough tags for the number of thoughts you've entered.\nThe last #{thoughts.split("\n").length - tags.length} will not feature in your helix!" if tags.length < thoughts.split("\n").length + +others = (0..[slots,99].min).to_a.delete_if{|number| tags.include?(number.to_s)}.collect{|n| n.to_s} + +class Array + # sees how many items of 'match' exist in array + def seq_match(match) + n = 0 + match = match.dup + self.each do |word| + if not(index = match.index(word)).nil? + n += 1 + match.delete_at(index) + end + end + return n + end + + def shuffle! + size.downto(1) { |n| push delete_at(rand(n)) } + self + end +end + +stream = [] + +thought_n = 0 +thoughts.split("\n").each do |thought| + words = thought.scan(/[a-zA-Z']+|\S|\d+/) + pos = 0 + #puts "-- New phrase" + while words.length > 0 do + # Our current word + word = words.shift + + #puts "Is '#{word.downcase}' in \""+stream.collect{|position| position['word']}.join(",")+"\" from #{pos}" + # Does the stream already have this word in it? + if not (index = stream[pos..-1].collect{|position| position['word']}.index(word.downcase)).nil? + #puts " - yes" + index += pos + # Does contain the word, check to see that if we used this index we're not preventing a huge number of other link-ins + #puts pos.to_s + " #{word}" + if stream[(index+1)..-1].collect{|position| position['word']}.seq_match(words) < stream[pos..-1].collect{|position| position['word']}.seq_match(words) + #puts "Prevent" + # we are preventing too many link-ins, insert the word afresh (before the other version) + pos = rand(stream.length - pos + 1).to_i + pos + stream = stream.insert(pos,{'word' => word.downcase,'thoughts' => [thought_n]}) + pos += 1 + else + #puts "AllGood @ #{index}" + # all is well, use this index + stream[index]['thoughts'].push(thought_n) + pos = index + 1 + end + else + pos = rand(stream.length - pos + 1).to_i + pos + stream = stream.insert(pos,{'word' => word.downcase,'thoughts' => [thought_n]}) + pos += 1 + end + + end + thought_n += 1 +end + +randomwords.scan(/[a-zA-Z']+|\S|\d+/).each do |word| + stream = stream.insert(rand(stream.length).to_i,{'word' => word.downcase,'thoughts' => []}) +end + +puts stream.collect{|position| position['word']}.join(" ") +puts stream.length.to_s+" chunks long" + +########################################################### + +html = <<-HTML + + + +
+