pdf-storycards 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ == 0.0.1 / 2007-12-27
2
+
3
+ * Initial release
4
+
@@ -0,0 +1,17 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/stories2cards
6
+ lib/pdf/storycards.rb
7
+ lib/pdf/storycards/scenario.rb
8
+ lib/pdf/storycards/story.rb
9
+ lib/pdf/storycards/story_capturing_mediator.rb
10
+ lib/pdf/storycards/writer.rb
11
+ spec/addition
12
+ spec/calculator_stories
13
+ spec/pdf/storycards/story_capturing_mediator_spec.rb
14
+ spec/pdf/storycards/story_spec.rb
15
+ spec/pdf/storycards/writer_spec.rb
16
+ spec/rspec_suite.rb
17
+ spec/spec_helper.rb
@@ -0,0 +1,55 @@
1
+ PDF StoryCards
2
+ by Luke Melia
3
+ http://www.lukemelia.com/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Provides a script and library to parses stories saved in the RSpec
8
+ plain text story format and saves a PDF file with printable 3"x5"
9
+ index cards suitable for using in agile planning and prioritization.
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ * Create a PDF with each page as a 3x5 sheet, or as 4 cards per 8.5 x 11 sheet
14
+ * Currently reads stories from a single file.
15
+ * TODO: Take a directory and find all stories in it
16
+ * TODO: Take stories via STDIN
17
+ * TODO: Improve test coverage
18
+
19
+ == SYNOPSIS:
20
+
21
+ StorycardPdfWriter.make_pdf("/tmp/stories.txt", "/tmp/storycards.pdf", :style => :card_1up)
22
+
23
+ == REQUIREMENTS:
24
+
25
+ * RSpec (for parsing stories)
26
+ * PDF::Writer (for creating PDFs)
27
+
28
+ == INSTALL:
29
+
30
+ sudo gem install storycards
31
+
32
+ == LICENSE:
33
+
34
+ (The MIT License)
35
+
36
+ Copyright (c) 2007 Luke Melia
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining
39
+ a copy of this software and associated documentation files (the
40
+ 'Software'), to deal in the Software without restriction, including
41
+ without limitation the rights to use, copy, modify, merge, publish,
42
+ distribute, sublicense, and/or sell copies of the Software, and to
43
+ permit persons to whom the Software is furnished to do so, subject to
44
+ the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be
47
+ included in all copies or substantial portions of the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
50
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
53
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
54
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
55
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ dir = File.dirname(__FILE__)
6
+ lib_path = File.expand_path("#{dir}/lib")
7
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
8
+ require 'pdf/storycards'
9
+ ENV["VERSION"] = PDF::Storycards::VERSION
10
+
11
+ Hoe.new('pdf-storycards', PDF::Storycards::VERSION) do |p|
12
+ p.rubyforge_name = 'pdf-storycards'
13
+ p.author = 'Luke Melia'
14
+ p.email = 'luke@lukemelia.com'
15
+ p.summary = 'Utilities for generating printable story cards for agile planning and measurement'
16
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
17
+ # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
18
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
19
+ p.extra_deps << ['pdf-writer', '>= 1.1.7']
20
+ p.extra_deps << ['rspec', '>= 1.1.1']
21
+ end
22
+
23
+ # vim: syntax=Ruby
@@ -0,0 +1,129 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ # == Synopsis
4
+ # stories2cards parses stories saved in the RSpec plain text story
5
+ # format and saves a PDF file with printable 3"x5"" index cards
6
+ # suitable for using in agile planning and prioritization.
7
+ #
8
+ # == Examples
9
+ # This command outputs a PDF consisting of one card for each story and
10
+ # narrative defined in stories.txt and saves it as stories.pdf
11
+ #
12
+ # stories2cards stories.txt
13
+ #
14
+ # Other examples
15
+ #
16
+ # stories2cards stories.txt -o /tmp/cards.pdf
17
+ # stories2cards stories.txt --style=4up
18
+ #
19
+ # == Usage
20
+ # stories2cards [options] text_file_with_stories
21
+ #
22
+ # For help use stories2cards -h
23
+ #
24
+ # == Options
25
+ # -h, --help Displays help message
26
+ # -v, --version Display the version, then exit
27
+ # -o, --output=PATH Specify the path to the PDF file
28
+ # to be created, defaults to storycards.pdf
29
+ # -s, --style=1up|4up Defaults to 1up
30
+ # -b, --[no-]borders Print borders (only has effect with 4up style
31
+ #
32
+ # == Author
33
+ # Luke Melia
34
+ #
35
+ # == Copyright
36
+ # Copyright (c) 2007 Luke Melia. Licensed under the MIT License
37
+ # http://www.opensource.org/licenses/mit-license.php
38
+
39
+ require 'optparse'
40
+ require 'rdoc/usage'
41
+ require 'ostruct'
42
+
43
+ begin
44
+ require 'pdf/storycards'
45
+ rescue LoadError => le
46
+ if le.message =~ %r{pdf/storycards$}
47
+ root = File.dirname(File.dirname(File.expand_path(__FILE__)))
48
+ $LOAD_PATH.unshift(File.join(root, "lib"))
49
+ require 'pdf/storycards'
50
+ else
51
+ raise
52
+ end
53
+ end
54
+
55
+ class App
56
+
57
+ attr_reader :options
58
+
59
+ def initialize(arguments, stdin)
60
+ @arguments = arguments
61
+ @stdin = stdin
62
+
63
+ # Set defaults
64
+ @options = OpenStruct.new
65
+ @options.output = "storycards.pdf"
66
+ @options.style = :"1up"
67
+ end
68
+
69
+ # Parse options, check arguments, then process the command
70
+ def run
71
+ if parsed_options? && arguments_valid?
72
+ process_arguments
73
+ process_command
74
+ else
75
+ output_usage
76
+ end
77
+ end
78
+
79
+ protected
80
+
81
+ def parsed_options?
82
+
83
+ # Specify options
84
+ opts = OptionParser.new
85
+ opts.on('-v', '--version') { output_version ; exit 0 }
86
+ opts.on('-h', '--help') { output_help }
87
+ opts.on('-o', '--output [PATH]') { |path| @options.output = path }
88
+ opts.on('-s', '--style [STYLE]', [:"1up", :"4up"]) { |style| @options.style = style }
89
+ opts.on("-b", "--[no-]borders", "Print borders") { |b| options.borders = b }
90
+ opts.parse!(@arguments) rescue return false
91
+
92
+ true
93
+ end
94
+
95
+ # True if required arguments were provided
96
+ def arguments_valid?
97
+ return false unless @arguments.length == 1
98
+ return false unless File.exists?(@arguments[0])
99
+ return true
100
+ end
101
+
102
+ # Setup the arguments
103
+ def process_arguments
104
+ @source_file = @arguments[0]
105
+ end
106
+
107
+ def output_help
108
+ output_version
109
+ RDoc::usage() #exits app
110
+ end
111
+
112
+ def output_usage
113
+ RDoc::usage('usage') # gets usage from comments above
114
+ end
115
+
116
+ def output_version
117
+ puts "#{File.basename(__FILE__)} version #{PDF::Storycards::VERSION}"
118
+ end
119
+
120
+ def process_command
121
+ style = :card_1up if @options.style == :"1up"
122
+ style = :letter_4up if @options.style == :"4up"
123
+ PDF::Storycards::Writer.make_pdf(@source_file, @options.output, :style => style)
124
+ end
125
+ end
126
+
127
+ # Create and run the application
128
+ app = App.new(ARGV, STDIN)
129
+ app.run
@@ -0,0 +1,10 @@
1
+ module PDF
2
+ module Storycards
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
6
+
7
+ require 'pdf/storycards/scenario'
8
+ require 'pdf/storycards/story'
9
+ require 'pdf/storycards/story_capturing_mediator'
10
+ require 'pdf/storycards/writer'
@@ -0,0 +1,21 @@
1
+ module PDF
2
+ module Storycards
3
+ class Scenario
4
+ def initialize(name)
5
+ @name = name
6
+ @steps = []
7
+ end
8
+
9
+ def add_step(step)
10
+ @steps << step
11
+ end
12
+ end
13
+
14
+ class Step
15
+ def initialize(type, name)
16
+ @type = type
17
+ @name = name
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module PDF
2
+ module Storycards
3
+ class Story
4
+ def initialize(title, narrative)
5
+ @title = title
6
+ @narrative = narrative
7
+ def @narrative.to_sentence
8
+ self.sub(/^\s*I want/, ", I want").gsub(/^\s*So that/, ", so that").split($/).join(" ").gsub(' ,',',').squeeze(" ")
9
+ end
10
+ @scenarios = []
11
+ end
12
+
13
+ attr_accessor :title, :narrative
14
+
15
+ def add_scenario(scenario)
16
+ @scenarios << scenario
17
+ end
18
+
19
+ def current_scenario
20
+ @scenarios.last
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,52 @@
1
+ # RSpec's story parser needs to be constructed with a Mediator. The mediator defined in the class
2
+ # below simply collects stories and exposes the collection as StoryCapturingMediator#stories.
3
+ #
4
+ # It also sprinkles in a magic method on Story#narrative called to_sentence, which formats the
5
+ # story narrative as a single sentence without newlines.
6
+ module PDF
7
+ module Storycards
8
+
9
+ class StoryCapturingMediator
10
+
11
+ def initialize
12
+ @stories = []
13
+ end
14
+
15
+ attr_reader :stories
16
+
17
+ def create_story(title, narrative)
18
+ @stories << Story.new(title, narrative)
19
+ end
20
+
21
+ def create_scenario(title)
22
+ current_story.add_scenario Scenario.new(title)
23
+ end
24
+
25
+ def create_given(name)
26
+ current_scenario.add_step Step.new('Given', name)
27
+ end
28
+
29
+ def create_given_scenario(name)
30
+ current_scenario.add_step Step.new('GivenScenario', name)
31
+ end
32
+
33
+ def create_when(name)
34
+ current_scenario.add_step Step.new('When', name)
35
+ end
36
+
37
+ def create_then(name)
38
+ current_scenario.add_step Step.new('Then', name)
39
+ end
40
+
41
+ private
42
+ def current_story
43
+ @stories.last
44
+ end
45
+
46
+ def current_scenario
47
+ current_story.current_scenario
48
+ end
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,91 @@
1
+ require 'pdf/writer'
2
+ require 'spec/story/runner/story_parser.rb'
3
+
4
+ module PDF
5
+ module Storycards
6
+ class Writer
7
+
8
+ def self.make_pdf( path, output_path = 'storycards.pdf', opts = {} )
9
+ output_path = 'storycards.pdf' if output_path.nil?
10
+ opts[:style] = :card_1up unless opts[:style]
11
+ opts[:border] = false unless opts[:border]
12
+
13
+ stories = self.parse_stories(path)
14
+
15
+ if opts[:style] == :card_1up
16
+ pdf = PDF::Writer.new(:paper => [7.62, 12.7], :orientation => :landscape) #3x5 card
17
+ pdf.margins_mm 8
18
+ pdf.move_pointer(-60)
19
+
20
+ stories.each_with_index do |story, index|
21
+ pdf.y = 0 if index > 0
22
+ print_card_text(pdf, story)
23
+ end
24
+
25
+ pdf.save_as(output_path)
26
+ return output_path
27
+
28
+ elsif opts[:style] == :letter_4up
29
+
30
+ pdf = PDF::Writer.new(:paper => "LETTER", :orientation => :landscape)
31
+ card_width = PDF::Writer.in2pts(5)
32
+ card_height = PDF::Writer.in2pts(3)
33
+ margin = PDF::Writer.in2pts(0.33)
34
+ gutter = margin
35
+ padding = 10
36
+
37
+ pdf.start_columns(2, gutter)
38
+ stories.each_with_index do |story, index|
39
+
40
+ is_laying_out_left_hand_column = (index < 2)
41
+ if is_laying_out_left_hand_column
42
+ rect_x = margin
43
+ else
44
+ rect_x = pdf.page_width - margin - card_width
45
+ end
46
+
47
+ is_laying_out_top_row = (index % 2 == 0)
48
+ if is_laying_out_top_row
49
+ pdf.start_new_page unless index == 0
50
+ pdf.y = pdf.page_height - margin - padding
51
+ rect_y = pdf.page_height - margin - card_height
52
+ else
53
+ rect_y = margin
54
+ pdf.y = margin + card_height - padding
55
+ end
56
+
57
+ print_border(pdf, rect_x, rect_y, card_width, card_height) if opts[:border]
58
+ print_card_text(pdf, story, padding)
59
+ end
60
+
61
+ pdf.save_as(output_path)
62
+ return output_path
63
+
64
+ end
65
+ end
66
+ private
67
+
68
+ def self.print_border(pdf, x, y, width, height)
69
+ pdf.stroke_color(Color::RGB::Black)
70
+ pdf.stroke_style(PDF::Writer::StrokeStyle.new(1))
71
+ pdf.rectangle(rect_x, rect_y, card_width, card_height).close_stroke
72
+ end
73
+
74
+ def self.parse_stories(path)
75
+ story_mediator = StoryCapturingMediator.new
76
+ story_parser = Spec::Story::Runner::StoryParser.new(story_mediator)
77
+ story_text = File.read(path)
78
+ story_parser.parse(story_text.split("\n"))
79
+ return story_mediator.stories
80
+ end
81
+
82
+ def self.print_card_text(pdf, story, padding = 0)
83
+ pdf.text "<b>#{story.title}</b>", :font_size => 18, :justification => :center,
84
+ :left => padding, :right => padding
85
+ pdf.move_pointer(12)
86
+ pdf.text story.narrative.to_sentence, :justification => :left, :font_size => 14,
87
+ :left => padding, :right => padding
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,34 @@
1
+ This is a story about a calculator. The text up here above the Story: declaration
2
+ won't be processed, so you can write whatever you wish!
3
+
4
+ Story: simple addition
5
+
6
+ As an accountant
7
+ I want to add numbers
8
+ So that I can count beans
9
+
10
+ Scenario: add one plus one
11
+ Given an addend of 1
12
+ And an addend of 1
13
+
14
+ When the addends are addeds
15
+
16
+ Then the sum should be 3
17
+ And the corks should be popped
18
+
19
+ Scenario: add two plus five
20
+ Given an addend of 2
21
+ And an addend of 5
22
+
23
+ When the addends are added
24
+
25
+ Then the sum should be 7
26
+ Then it should snow
27
+
28
+ Scenario: add three more
29
+ GivenScenario add two plus five
30
+ And an addend of 3
31
+
32
+ When the addends are added
33
+
34
+ Then the sum should be 10
@@ -0,0 +1,66 @@
1
+ This is a story about a calculator. The text up here above the Story: declaration
2
+ won't be processed, so you can write whatever you wish!
3
+
4
+ Story: simple addition
5
+
6
+ As an accountant
7
+ I want to add numbers
8
+ So that I can count beans
9
+
10
+ Scenario: add one plus one
11
+ Given an addend of 1
12
+ And an addend of 1
13
+
14
+ When the addends are addeds
15
+
16
+ Then the sum should be 3
17
+ And the corks should be popped
18
+
19
+ Scenario: add two plus five
20
+ Given an addend of 2
21
+ And an addend of 5
22
+
23
+ When the addends are added
24
+
25
+ Then the sum should be 7
26
+ Then it should snow
27
+
28
+ Scenario: add three more
29
+ GivenScenario add two plus five
30
+ And an addend of 3
31
+
32
+ When the addends are added
33
+
34
+ Then the sum should be 10
35
+
36
+ Story: simple subtraction
37
+
38
+ As an accountant
39
+ I want to subtract numbers
40
+ So that I can count beans
41
+
42
+ Scenario: subtract one minus one
43
+ Given an argument of 1
44
+ And an argument of 1
45
+
46
+ When the second argument is subtracted from the first argument
47
+
48
+ Then the different should be 0
49
+ And the corks should be popped
50
+
51
+ Scenario: subtract two from five
52
+ Given an argument of 5
53
+ And an argument of 2
54
+
55
+ When the second argument is subtracted from the first argument
56
+
57
+ Then the difference should be 3
58
+ Then it should snow
59
+
60
+ Scenario: subtract two more
61
+ GivenScenario subtract two from five
62
+ And an argument of 2
63
+
64
+ When the result is reduced by the argument
65
+
66
+ Then the result should be 1
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ describe PDF::Storycards::StoryCapturingMediator do
4
+
5
+ before(:each) do
6
+ @mediator = PDF::Storycards::StoryCapturingMediator.new
7
+ end
8
+
9
+ describe "initial state" do
10
+ it "should have an empty list of stories" do
11
+ @mediator.stories.should == []
12
+ end
13
+ end
14
+
15
+ it "should add stories when sent :create_story" do
16
+ @mediator.create_story('my title', 'my narrative')
17
+ @mediator.stories.length.should == 1
18
+ @mediator.stories.first.should be_an_instance_of(PDF::Storycards::Story)
19
+ end
20
+
21
+ describe "after having a story added" do
22
+ before(:each) do
23
+ @mediator.create_story('User joins a Group',
24
+ "As a user
25
+ I want to be able to join a group
26
+ So that I can connect to members with similar interests")
27
+ end
28
+
29
+ it "should have a story with the specified title" do
30
+ @mediator.stories.first.title.should == 'User joins a Group'
31
+ end
32
+
33
+ it "should have a story with the specified narrative" do
34
+ @mediator.stories.first.narrative.should =~ /As a user\s+I want to be able to join a group\s+So that I can connect to members with similar interests/
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ describe PDF::Storycards::Story do
4
+ before(:each) do
5
+ @story = PDF::Storycards::Story.new('User joins a Group',
6
+ "As a user
7
+ I want to be able to join a group
8
+ So that I can connect to members with similar interests")
9
+ end
10
+
11
+ it "should have the specified title" do
12
+ @story.title.should == 'User joins a Group'
13
+ end
14
+
15
+ it "should have the specified narrative" do
16
+ @story.narrative.should =~ /As a user\s+I want to be able to join a group\s+So that I can connect to members with similar interests/
17
+ end
18
+
19
+ it "should have a narrative that can be converted to a sentence without newlines" do
20
+ @story.narrative.to_sentence.should == 'As a user, I want to be able to join a group, so that I can connect to members with similar interests'
21
+ end
22
+
23
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ module PDF
4
+ class Writer
5
+ def save_as(path)
6
+ #no op
7
+ end
8
+ end
9
+ end
10
+
11
+ describe PDF::Storycards::Writer do
12
+
13
+ before(:all) do
14
+ @single_story_path = File.dirname(__FILE__) + '/../../addition'
15
+ @multiple_stories_path = File.dirname(__FILE__) + '/../../calculator_stories'
16
+ end
17
+
18
+ it "should parse an example plain text story file and create a new story" do
19
+ stories = PDF::Storycards::Writer.send(:parse_stories, @single_story_path)
20
+ stories.first.title.should == 'simple addition'
21
+ stories.first.narrative.should == "As an accountant\nI want to add numbers\nSo that I can count beans"
22
+ end
23
+
24
+ it "should not print border when printing 1-up" do
25
+ PDF::Storycards::Writer.should_not_receive(:print_border)
26
+ PDF::Storycards::Writer.make_pdf(@multiple_stories_path, 'storycards.pdf', :style => :card_1up)
27
+ end
28
+
29
+ it "should not print border when printing 4-up with default options" do
30
+ PDF::Storycards::Writer.should_not_receive(:print_border)
31
+ PDF::Storycards::Writer.make_pdf(@multiple_stories_path, 'storycards.pdf', :style => :letter_4up)
32
+ end
33
+
34
+ it "should print border when printing 4-up with border option set to true" do
35
+ PDF::Storycards::Writer.should_receive(:print_border).twice
36
+ PDF::Storycards::Writer.make_pdf(@multiple_stories_path, 'storycards.pdf', :style => :letter_4up, :border => true)
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ if __FILE__ == $0
5
+ dir = File.dirname(__FILE__)
6
+ Dir["#{dir}/**/*_spec.rb"].each do |file|
7
+ # puts "require '#{file}'"
8
+ require file
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'stringio'
2
+ require 'spec'
3
+ require 'spec/mocks'
4
+
5
+ dir = File.dirname(__FILE__)
6
+ lib_path = File.expand_path("#{dir}/../lib")
7
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
8
+
9
+ require 'pdf/storycards'
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pdf-storycards
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Luke Melia
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2007-12-29 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: pdf-writer
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.7
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: rspec
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.1.1
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: hoe
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.4.0
41
+ version:
42
+ description: "== FEATURES/PROBLEMS: * Create a PDF with each page as a 3x5 sheet, or as 4 cards per 8.5 x 11 sheet * Currently reads stories from a single file. * TODO: Take a directory and find all stories in it * TODO: Take stories via STDIN * TODO: Improve test coverage == SYNOPSIS: StorycardPdfWriter.make_pdf(\"/tmp/stories.txt\", \"/tmp/storycards.pdf\", :style => :card_1up) == REQUIREMENTS:"
43
+ email: luke@lukemelia.com
44
+ executables:
45
+ - stories2cards
46
+ extensions: []
47
+
48
+ extra_rdoc_files:
49
+ - History.txt
50
+ - Manifest.txt
51
+ - README.txt
52
+ files:
53
+ - History.txt
54
+ - Manifest.txt
55
+ - README.txt
56
+ - Rakefile
57
+ - bin/stories2cards
58
+ - lib/pdf/storycards.rb
59
+ - lib/pdf/storycards/scenario.rb
60
+ - lib/pdf/storycards/story.rb
61
+ - lib/pdf/storycards/story_capturing_mediator.rb
62
+ - lib/pdf/storycards/writer.rb
63
+ - spec/addition
64
+ - spec/calculator_stories
65
+ - spec/pdf/storycards/story_capturing_mediator_spec.rb
66
+ - spec/pdf/storycards/story_spec.rb
67
+ - spec/pdf/storycards/writer_spec.rb
68
+ - spec/rspec_suite.rb
69
+ - spec/spec_helper.rb
70
+ has_rdoc: true
71
+ homepage: http://www.zenspider.com/ZSS/Products/pdf-storycards/
72
+ post_install_message:
73
+ rdoc_options:
74
+ - --main
75
+ - README.txt
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ version:
90
+ requirements: []
91
+
92
+ rubyforge_project: pdf-storycards
93
+ rubygems_version: 1.0.1
94
+ signing_key:
95
+ specification_version: 2
96
+ summary: Utilities for generating printable story cards for agile planning and measurement
97
+ test_files: []
98
+